-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: AstrBot Live Chat Mode on ChatUI #4534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c0846bc
1d426a7
19e6253
856d349
2e53d81
dcd699d
e92b103
06fa7be
fa4df28
ddff652
92de106
ad2dae3
831907b
c95bbd1
625401a
242cf87
97ee36b
e7540b8
4d28de6
93cc4ce
473d258
991b85e
aec5f4e
c0c9673
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,3 +50,7 @@ venv/* | |
| pytest.ini | ||
| AGENTS.md | ||
| IFLOW.md | ||
|
|
||
| # genie_tts data | ||
| CharacterModels/ | ||
| GenieData/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ | |
|
|
||
| from .....astr_agent_context import AgentContextWrapper | ||
| from .....astr_agent_hooks import MAIN_AGENT_HOOKS | ||
| from .....astr_agent_run_util import AgentRunner, run_agent | ||
| from .....astr_agent_run_util import AgentRunner, run_agent, run_live_agent | ||
| from .....astr_agent_tool_exec import FunctionToolExecutor | ||
| from ....context import PipelineContext, call_event_hook | ||
| from ...stage import Stage | ||
|
|
@@ -41,6 +41,7 @@ | |
| FILE_DOWNLOAD_TOOL, | ||
| FILE_UPLOAD_TOOL, | ||
| KNOWLEDGE_BASE_QUERY_TOOL, | ||
| LIVE_MODE_SYSTEM_PROMPT, | ||
| LLM_SAFETY_MODE_SYSTEM_PROMPT, | ||
| PYTHON_TOOL, | ||
| SANDBOX_MODE_PROMPT, | ||
|
|
@@ -668,6 +669,10 @@ async def process( | |
| if req.func_tool and req.func_tool.tools: | ||
| req.system_prompt += f"\n{TOOL_CALL_PROMPT}\n" | ||
|
|
||
| action_type = event.get_extra("action_type") | ||
| if action_type == "live": | ||
| req.system_prompt += f"\n{LIVE_MODE_SYSTEM_PROMPT}\n" | ||
|
|
||
| await agent_runner.reset( | ||
| provider=provider, | ||
| request=req, | ||
|
|
@@ -685,7 +690,50 @@ async def process( | |
| enforce_max_turns=self.max_context_length, | ||
| ) | ||
|
|
||
| if streaming_response and not stream_to_general: | ||
| # 检测 Live Mode | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (complexity): 建议将 Live Mode 的处理提取到独立的异步 helper 中,让 Live Mode 相关的分支确实增加了 一种方式是把所有 Live Mode 相关逻辑(包括历史记录保存)迁移到一个异步生成器 helper 中,并在 # inside the class
async def _handle_live_mode(self, event, req, agent_runner):
logger.info("[Internal Agent] 检测到 Live Mode,启用 TTS 处理")
tts_provider = self.ctx.plugin_manager.context.get_using_tts_provider(
event.unified_msg_origin
)
if not tts_provider:
logger.warning("[Live Mode] TTS Provider 未配置,将使用普通流式模式")
event.set_result(
MessageEventResult()
.set_result_content_type(ResultContentType.STREAMING_RESULT)
.set_async_stream(
run_live_agent(
agent_runner,
tts_provider,
self.max_step,
self.show_tool_use,
show_reasoning=self.show_reasoning,
)
)
)
# mirror the original control flow: emit once, then post-process
yield
if not event.is_stopped() and agent_runner.done():
await self._save_to_history(
event,
req,
agent_runner.get_final_llm_resp(),
agent_runner.run_context.messages,
agent_runner.stats,
)然后在 action_type = event.get_extra("action_type")
if action_type == "live":
async for _ in self._handle_live_mode(event, req, agent_runner):
yield
elif streaming_response and not stream_to_general:
event.set_result(
MessageEventResult()
.set_result_content_type(ResultContentType.STREAMING_RESULT)
.set_async_stream(
run_agent(
agent_runner,
self.max_step,
self.show_tool_use,
show_reasoning=self.show_reasoning,
)
)
)
# existing yield / history handling remains unchanged这样可以在保留全部功能(包括日志、TTS provider 解析、流式行为以及流结束后的历史保存)的同时,降低 Original comment in Englishissue (complexity): Consider extracting the Live Mode handling into a dedicated async helper to keep The Live Mode branch does increase the complexity of One way is to move all Live Mode–specific logic (including the history save) into an async generator helper and delegate from # inside the class
async def _handle_live_mode(self, event, req, agent_runner):
logger.info("[Internal Agent] 检测到 Live Mode,启用 TTS 处理")
tts_provider = self.ctx.plugin_manager.context.get_using_tts_provider(
event.unified_msg_origin
)
if not tts_provider:
logger.warning("[Live Mode] TTS Provider 未配置,将使用普通流式模式")
event.set_result(
MessageEventResult()
.set_result_content_type(ResultContentType.STREAMING_RESULT)
.set_async_stream(
run_live_agent(
agent_runner,
tts_provider,
self.max_step,
self.show_tool_use,
show_reasoning=self.show_reasoning,
)
)
)
# mirror the original control flow: emit once, then post-process
yield
if not event.is_stopped() and agent_runner.done():
await self._save_to_history(
event,
req,
agent_runner.get_final_llm_resp(),
agent_runner.run_context.messages,
agent_runner.stats,
)Then in action_type = event.get_extra("action_type")
if action_type == "live":
async for _ in self._handle_live_mode(event, req, agent_runner):
yield
elif streaming_response and not stream_to_general:
event.set_result(
MessageEventResult()
.set_result_content_type(ResultContentType.STREAMING_RESULT)
.set_async_stream(
run_agent(
agent_runner,
self.max_step,
self.show_tool_use,
show_reasoning=self.show_reasoning,
)
)
)
# existing yield / history handling remains unchangedThis keeps all functionality (including logging, TTS provider resolution, streaming behavior, and post-stream history saving) while reducing the cognitive load in |
||
| if action_type == "live": | ||
| # Live Mode: 使用 run_live_agent | ||
| logger.info("[Internal Agent] 检测到 Live Mode,启用 TTS 处理") | ||
|
|
||
| # 获取 TTS Provider | ||
| tts_provider = ( | ||
| self.ctx.plugin_manager.context.get_using_tts_provider( | ||
| event.unified_msg_origin | ||
| ) | ||
| ) | ||
|
|
||
| if not tts_provider: | ||
| logger.warning( | ||
| "[Live Mode] TTS Provider 未配置,将使用普通流式模式" | ||
| ) | ||
|
|
||
| # 使用 run_live_agent,总是使用流式响应 | ||
| event.set_result( | ||
| MessageEventResult() | ||
| .set_result_content_type(ResultContentType.STREAMING_RESULT) | ||
| .set_async_stream( | ||
| run_live_agent( | ||
| agent_runner, | ||
| tts_provider, | ||
| self.max_step, | ||
| self.show_tool_use, | ||
| show_reasoning=self.show_reasoning, | ||
| ), | ||
| ), | ||
| ) | ||
| yield | ||
|
|
||
| # 保存历史记录 | ||
| if not event.is_stopped() and agent_runner.done(): | ||
| await self._save_to_history( | ||
| event, | ||
| req, | ||
| agent_runner.get_final_llm_resp(), | ||
| agent_runner.run_context.messages, | ||
| agent_runner.stats, | ||
| ) | ||
|
|
||
| elif streaming_response and not stream_to_general: | ||
| # 流式响应 | ||
| event.set_result( | ||
| MessageEventResult() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.