fix(ai写作): 技能流式每步主动让出事件循环,custom 事件实时刷给前端
前端 skill_search_step 已是 pushImmediate(实时渲染),但事件在节点内的嵌套 agent.astream 里发出后没及时让出事件循环,被攒到整段跑完才一次性吐到 SSE, 前端看着像卡死。每个 chunk 处理完 await asyncio.sleep(0) 主动让出,促使刚 emit 的 custom 事件实时刷给前端(对齐 draft_chunk 的实时行为)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8f773d3f1b
commit
a4a67c1a00
1 file changed
+6
+6
@@ -210,6 +210,7 @@ async def run_skill_via_real_agent(
|
||||
init_state, config=run_config, context=run_context, stream_mode="values"
|
||||
):
|
||||
msgs = chunk.get("messages") or []
|
||||
emitted = False
|
||||
for m in msgs:
|
||||
mid = getattr(m, "id", None)
|
||||
if not mid or mid in seen_msg_ids:
|
||||
@@ -221,11 +222,16 @@ async def run_skill_via_real_agent(
|
||||
break
|
||||
tname = (tc.get("name") or "").strip() or "工具"
|
||||
emit_query(f"技能「{skill_name}」调用 {tname}:{_summarize_tool_args(tc.get('args') or {})}")
|
||||
emitted = True
|
||||
# 记录最后一条 AIMessage 正文(含最终 JSON 素材)
|
||||
if isinstance(m, AIMessage):
|
||||
text = _content_to_text(m.content)
|
||||
if text.strip():
|
||||
final_text = text
|
||||
# 关键:每个 chunk 处理完主动让出事件循环,促使刚 emit 的 custom 事件**实时**
|
||||
# 刷给前端 SSE;否则嵌套 astream 会把它们攒到整段跑完才一次性吐出(前端看着像卡死)。
|
||||
if emitted:
|
||||
await asyncio.sleep(0)
|
||||
|
||||
try:
|
||||
await asyncio.wait_for(_drive(), timeout=max(timeout_s, _REAL_AGENT_TIMEOUT_SECONDS))
|
||||
|
||||
Reference in new issue
Block a user