fix: Conform yield once + system action reads nested params + skip timeout text after widget

This commit is contained in:
ymq 2026-08-09 20:06:16 +08:00
parent a2106e4365
commit d076a0a9f2

View File

@ -366,14 +366,15 @@ if action == 'send_message':
if not message_text: return json.dumps({"error":"message_text is required"},ensure_ascii=False)
# ── System action: bypass LLM, execute directly ──
sys_action = p.get('_system_action', '')
sys_action = p.get('_system_action', '') or (p.get('params', {}) or {}).get('_system_action', '')
sys_params = p if p.get('_system_action') else (p.get('params', {}) or {})
if sys_action:
async def sys_stream():
async with DBPools().sqlorContext(dbname) as sor:
uid = await get_user()
org_id = await get_userorgid() or '0'
ctx = await _load_ctx(sor, uid)
result = await _exec_tool(sor, sys_action, p, ctx, uid, org_id)
result = await _exec_tool(sor, sys_action, sys_params, ctx, uid, org_id)
d = json.dumps(_w_text(result), ensure_ascii=False)+'\n'
yield d
return await stream_response(request, sys_stream, 'text/plain; charset=utf-8')
@ -416,9 +417,13 @@ if action == 'send_message':
debug(f"YIELD progress: {d[:60]}")
yield d
result = await _exec_tool(sor, tool, act.get('params',{}), ctx, uid, org_id)
# If result is a raw widget descriptor, yield it directly
# If result is a raw widget descriptor, yield it directly and break loop
if result.startswith('{"widgettype":'):
d = result + '\n'
debug(f"YIELD widget: {d[:60]}")
yield d
agent_reply = '__widget_handled__'
break
else:
ok = result.startswith("OK:")
d = json.dumps(_w_card(label, _w_text(result), "success" if ok else "error"), ensure_ascii=False)+'\n'
@ -430,10 +435,11 @@ if action == 'send_message':
agent_reply = raw; break
if not agent_reply: agent_reply = "处理超时"
d = json.dumps(_w_text(agent_reply), ensure_ascii=False)+'\n'
debug(f"YIELD final: {d[:60]}")
yield d
await sor.C('pipeline_conversations',{'id':getID(),'role':'agent','content':agent_reply,'msg_type':'text','org_id':org_id,'created_by':'system'})
if agent_reply != '__widget_handled__':
d = json.dumps(_w_text(agent_reply), ensure_ascii=False)+'\n'
debug(f"YIELD final: {d[:60]}")
yield d
await sor.C('pipeline_conversations',{'id':getID(),'role':'agent','content':agent_reply,'msg_type':'text','org_id':org_id,'created_by':'system'})
return await stream_response(request, agent_stream, 'text/plain; charset=utf-8')