fix: regulatory 对话模式改用 event_stream_handler 修复工具调用截断,优化节点 prompt 和日志展示

- regulatory_node: stream_working 从 run_stream 改为 agent.run + event_stream_handler,
  解决工具调用后文本被截断的问题;添加 PartStartEvent 处理修复首字丢失
- consciousness_node: prompt 重写为三模式(生成/执行/报告),强调禁止编造 agent_id
- workflow API: _merge_runtime_status 暴露步骤输出内容(workflow_log 第三元素)
- 前端日志: 系统日志改为终端滚动样式,工作流步骤可展开查看输出

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 13:19:52 +00:00
parent ad5da2a118
commit d39c80743d
4 changed files with 153 additions and 107 deletions
@@ -126,11 +126,23 @@ class RegulatoryNode:
"""
return await self._run(payload)
async def stream_working(self, payload: MessageRequest, token_queue: "asyncio.Queue") -> None:
"""流式工具调用版本:逐 token 推送到 queue,工具调用结果也会通过 token 输出。
_CHAT_INSTRUCTIONS = (
"你是 kilostar 智能助手。你现在处于【直接对话模式】,请直接回答用户的问题。\n"
"规则:\n"
"1. 直接、详细地回答用户问题,像一个专业且友好的助手。\n"
"2. 如果你有可用工具,可以调用工具来辅助回答(如搜索、读文件等)。\n"
"3. 不要输出内部思考过程,不要做路由判断,不要提及 ForUser/ForConsciousnessNode 等格式。\n"
"4. 回复应当完整、有帮助,避免过于简短。\n"
)
完成后 push None 作为终止信号。
async def stream_working(self, payload: MessageRequest, token_queue: "asyncio.Queue") -> None:
"""流式对话:完整执行 agent graph(含工具调用),逐 token 推送文本到 queue。
使用 event_stream_handler 回调拿到每个 text delta,保证工具调用后
的文本也能被流式输出。完成后 push None 作为终止信号。
"""
from pydantic_ai.messages import PartStartEvent, PartDeltaEvent, TextPart, TextPartDelta
platform = payload.platform
user_name = payload.user_name
message = payload.message
@@ -140,17 +152,27 @@ class RegulatoryNode:
await token_queue.put(None)
return
async def _stream_handler(ctx, events):
async for event in events:
if isinstance(event, PartStartEvent) and isinstance(event.part, TextPart):
if event.part.content:
await token_queue.put(event.part.content)
elif isinstance(event, PartDeltaEvent) and isinstance(event.delta, TextPartDelta):
await token_queue.put(event.delta.content_delta)
try:
deps = RegulatoryNodeDeps(
platform=platform,
user_name=user_name,
time=time_str
)
async with self.agent.run_stream(
user_prompt=message, deps=deps, output_type=str
) as stream_result:
async for delta in stream_result.stream_text(delta=True):
await token_queue.put(delta)
await self.agent.run(
user_prompt=message,
deps=deps,
output_type=str,
instructions=self._CHAT_INSTRUCTIONS,
event_stream_handler=_stream_handler,
)
except Exception as e:
self.logger.exception(f"RegulatoryNode.stream_working failed: {e}")
await token_queue.put(f"\n\n[错误: {str(e)}]")