From 2bdc18c00aa5e81d13d39e94ac03df2dd4e97f49 Mon Sep 17 00:00:00 2001 From: ROOG Date: Mon, 23 Mar 2026 08:39:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B7=A5=E5=85=B7=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=A0=BC=E5=BC=8F=E8=A7=A3=E6=9E=90=E4=B8=8E=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=B7=A5=E5=85=B7=E8=B0=83=E7=94=A8=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E9=80=BB=E8=BE=91=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=88=97=E8=A1=A8=E5=B7=A5=E5=85=B7=E7=9A=84?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=86=85=E5=AE=B9=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/routers/chat.py | 46 +++++++++++++++--------- frontend/src/composables/useChatAgent.ts | 4 +-- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/backend/app/routers/chat.py b/backend/app/routers/chat.py index be8417f..3b0dc44 100644 --- a/backend/app/routers/chat.py +++ b/backend/app/routers/chat.py @@ -115,20 +115,24 @@ def _sse(data: dict) -> str: def _save_assistant_message(novel_id: int | None, full_response: str, tool_call_logs: list[str]): - """保存 AI 回复到 DB(含工具调用摘要)。在 finally 中调用,确保断连也能保存。""" - save_content = full_response - if tool_call_logs: - tool_summary = "\n".join(tool_call_logs) - save_content = f"[以下操作已执行]\n{tool_summary}\n\n{full_response}" - if save_content.strip(): - with Session(engine) as s: - ai_msg = ChatMessage( + """保存 AI 回复到 DB。工具调用日志和回复文本分别存为独立记录。""" + with Session(engine) as s: + # 工具调用日志作为单独一条记录 + if tool_call_logs: + tool_summary = "\n".join(tool_call_logs) + s.add(ChatMessage( novel_id=novel_id, role="assistant", - content=save_content, - ) - s.add(ai_msg) - s.commit() + content=f"[以下操作已执行]\n{tool_summary}", + )) + # AI 回复文本作为单独一条记录 + if full_response.strip(): + s.add(ChatMessage( + novel_id=novel_id, + role="assistant", + content=full_response, + )) + s.commit() async def _run_subagent( @@ -225,15 +229,23 @@ def _summarize_result(tool_name: str, result_json: str) -> str: if "error" in data: return f"错误: {data['error']}" - # 列表类工具 → 仅显示数量 + # 列表类工具 → 显示数量 + 各条目 ID 和标题 if tool_name == "list_outlines": - return f"{data.get('total', 0)}条大纲" + items = data.get("outlines", []) + brief = ", ".join(f"#{o['id']}{o.get('summary', '')[:15]}" for o in items[:10]) + return f"{data.get('total', 0)}条大纲: {brief}" if brief else f"{data.get('total', 0)}条大纲" if tool_name == "list_characters": - return f"{data.get('total', 0)}个角色" + items = data.get("characters", []) + brief = ", ".join(f"#{c['id']}{c.get('name', '')}" for c in items[:15]) + return f"{data.get('total', 0)}个角色: {brief}" if brief else f"{data.get('total', 0)}个角色" if tool_name == "list_chapters": - return f"{data.get('total', 0)}个章节" + items = data.get("chapters", []) + brief = ", ".join(f"#{c['id']}{c.get('title', '')[:15]}" for c in items[:10]) + return f"{data.get('total', 0)}个章节: {brief}" if brief else f"{data.get('total', 0)}个章节" if tool_name == "list_files": - return f"{data.get('total', 0)}个文件" + items = data.get("files", []) + brief = ", ".join(f"#{f['id']}{f.get('filename', '')}" for f in items[:5]) + return f"{data.get('total', 0)}个文件: {brief}" if brief else f"{data.get('total', 0)}个文件" # 创建类 → ID + 标题 if tool_name == "create_outline": diff --git a/frontend/src/composables/useChatAgent.ts b/frontend/src/composables/useChatAgent.ts index 3e4cad7..941c3c0 100644 --- a/frontend/src/composables/useChatAgent.ts +++ b/frontend/src/composables/useChatAgent.ts @@ -82,8 +82,8 @@ function parseHistoryMessage(msg: ChatMessage): ChatEntry[] { continue } - // 尝试匹配普通工具调用格式 - const toolMatch = line.match(/^\[工具调用: (.+?)\] 参数: (.+?) → 结果: (.+)$/) + // 尝试匹配普通工具调用格式(兼容 "→ 结果: xxx" 和 "→ xxx" 两种格式) + const toolMatch = line.match(/^\[工具调用: (.+?)\] 参数: (.+?) → (?:结果: )?(.+)$/) if (toolMatch) { const label = toolMatch[1] const name = LABEL_TO_TOOL_NAME[label] || label