From 803afa5cfea3b9ae0eadf82a3e5e24f1bd701afc Mon Sep 17 00:00:00 2001 From: ymq Date: Thu, 13 Aug 2026 18:19:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20cockpit=5Fchat=5Fv2=20=E8=BE=93=E5=87=BA?= =?UTF-8?q?=20content=20=E6=B5=81=E5=BC=8F=E6=A0=BC=E5=BC=8F=EF=BC=88Agent?= =?UTF-8?q?IO=E2=86=92AgentOut=20=E6=9C=9F=E6=9C=9B=20content/reasoning=5F?= =?UTF-8?q?content/error=EF=BC=8C=E9=9D=9E=20widget=20JSON=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wwwroot/api/cockpit_chat_v2.dspy | 34 ++++++++++++-------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/wwwroot/api/cockpit_chat_v2.dspy b/wwwroot/api/cockpit_chat_v2.dspy index a81873a..43836fd 100644 --- a/wwwroot/api/cockpit_chat_v2.dspy +++ b/wwwroot/api/cockpit_chat_v2.dspy @@ -41,7 +41,7 @@ if action == 'send_message': stop_keywords = ['停止', '取消', '停下', '终止', '停', 'stop', 'cancel', 'abort'] if any(kw == prompt.strip().lower() or kw in prompt.strip().lower() for kw in stop_keywords): async def _stop_stream(): - yield json.dumps(_w_md("已停止当前任务。"), ensure_ascii=False) + '\n' + yield json.dumps({"content": "已停止当前任务。"}, ensure_ascii=False) + '\n' return await stream_response(request, _stop_stream, 'text/plain; charset=utf-8') uid = await get_user() @@ -76,40 +76,32 @@ if action == 'send_message': async def agent_stream(): # 项目上下文 if ctx['name']: - d = json.dumps(_w_progress("项目: " + ctx['name']), ensure_ascii=False) + '\n' - yield d + yield json.dumps({"reasoning_content": "项目: " + ctx['name'] + "\n"}, ensure_ascii=False) + '\n' - # 运行 AgentExecutor + # 运行 AgentExecutor(输出 content 流式格式,供前端 AgentIO→AgentOut 渲染) async for chunk in executor.run(prompt): data = json.loads(chunk) t = data.get('type', '') - + if t == 'progress': - d = json.dumps(_w_progress(data.get('message', '')), ensure_ascii=False) + '\n' + yield json.dumps({"reasoning_content": data.get('message', '') + "\n"}, ensure_ascii=False) + '\n' elif t == 'auto_tool': - d = json.dumps(_w_progress("🔄 " + data.get('message', '')), ensure_ascii=False) + '\n' + yield json.dumps({"reasoning_content": "🔄 " + data.get('message', '') + "\n"}, ensure_ascii=False) + '\n' elif t == 'debug': - d = '' # skip debug in UI - continue + continue # skip debug in UI elif t == 'tool_call': tool = data.get('tool', '') - d = json.dumps(_w_card("调用: " + tool, "参数: " + json.dumps(data.get('params', {}), ensure_ascii=False), "info"), ensure_ascii=False) + '\n' + params = json.dumps(data.get('params', {}), ensure_ascii=False) + yield json.dumps({"content": "**🔧 调用: " + tool + "**\n```\n" + params + "\n```\n\n"}, ensure_ascii=False) + '\n' elif t == 'tool_result': - tool = data.get('tool', '') result = data.get('result', '') - good = not result.startswith('ERROR') and not result.startswith('未知工具') - # markdown 内容用 MdWidget 渲染(表格、列表等) - is_md = result.startswith('|') or result.startswith('#') or result.startswith('- ') - body = _w_md(result[:2000]) if is_md else result[:600] - d = json.dumps(_w_card(tool + " 结果", body, "success" if good else "error"), ensure_ascii=False) + '\n' + yield json.dumps({"content": result + "\n\n"}, ensure_ascii=False) + '\n' elif t == 'reply': - d = json.dumps(_w_md(data.get('message', '')), ensure_ascii=False) + '\n' + yield json.dumps({"content": data.get('message', '')}, ensure_ascii=False) + '\n' elif t == 'error': - d = json.dumps(_w_card("错误", data.get('message', ''), "error"), ensure_ascii=False) + '\n' + yield json.dumps({"error": data.get('message', '')}, ensure_ascii=False) + '\n' else: - d = chunk # 透传 - - yield d + yield json.dumps({"content": chunk}, ensure_ascii=False) + '\n' return await stream_response(request, agent_stream, 'text/plain; charset=utf-8')