From 3deee59f2eeaf4707ab7c5b9be24ae8da32daf3f Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Mon, 10 Aug 2026 09:40:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=BC=95=E6=93=8E=EF=BC=8C=E5=A4=84=E7=90=86=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=AE=B0=E5=BD=95=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9C=80=E7=BB=88=E5=9B=9E=E5=A4=8D=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/composables/useAgentChat.ts | 10 ++++++++++ packages/drizzle-pkg/db.sqlite | Bin 1220608 -> 1277952 bytes server/service/agent/chat-engine.ts | 33 ++++++++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/app/composables/useAgentChat.ts b/app/composables/useAgentChat.ts index 4abd59d..a12b1ac 100644 --- a/app/composables/useAgentChat.ts +++ b/app/composables/useAgentChat.ts @@ -423,6 +423,14 @@ export function useAgentChat(options: UseAgentChatOptions) { type: "text", text: "(模型仅返回了思考过程,未生成正式回复。请尝试更换模型或调整问题后重试。)", }); + } else if (!hasText && hasToolCall) { + finalMsg.parts?.push({ + id: generateId(), + type: "text", + text: isStopped.value + ? "(对话已停止,以上是已完成的工具调用记录。)" + : "(已达到工具调用次数上限,模型未能生成最终回答。以上是工具调用的执行记录。)", + }); } } } @@ -533,6 +541,7 @@ export function useAgentChat(options: UseAgentChatOptions) { const msg = messages.value[assistantIdx]; if (msg) { cleanupInProgressToolCalls(msg); + validateAssistantContent(assistantIdx); } } else { errorMessage.value = err.message || "请求失败"; @@ -645,6 +654,7 @@ export function useAgentChat(options: UseAgentChatOptions) { const msg = messages.value[messages.value.indexOf(assistantMsg)]; if (msg) { cleanupInProgressToolCalls(msg); + validateAssistantContent(messages.value.indexOf(assistantMsg), true); } } else { errorMessage.value = err.message || "请求失败"; diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite index 0b85290acdfda1606721664e32435206562990f1..31bd9e6a0d91e25c77b4797e1982abc2cc799c01 100644 GIT binary patch delta 41704 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 H`KSL6!itg5 delta 3682 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 = []; + let hasTextPart = false; for (const step of steps) { const toolResultMap = new Map(step.toolResults.map((tr) => [tr.toolCallId, tr.output])); const contentArr = step.content as Array>; @@ -518,6 +519,7 @@ export async function executeChat(params: ChatEngineParams): Promise p.type === "tool-call"); + const stepLimitReached = finishReason === "tool-calls" && !hasTextPart && hasToolCallPart; + let finalText = assistantText; + if (stepLimitReached) { + const noticeText = "(已达到工具调用次数上限,模型未能生成最终回答。以上是工具调用的执行记录。)"; + parts.push({ id: `p_${parts.length}`, type: "text", text: noticeText }); + finalText = (finalText || "") + noticeText; + logger.info("[%s] [CHAT-ENGINE] step limit reached, appended notice part", requestId); + } + if (isApprovalContinue) { const lastAssistant = historyMessages.filter((m) => m.role === "assistant").pop(); if (lastAssistant) { @@ -590,7 +602,7 @@ export async function executeChat(params: ChatEngineParams): Promise 0 ? JSON.stringify(parts) : null, modelId: resolvedModel.dbId, inputTokens: usage?.inputTokens ?? null, @@ -641,11 +653,13 @@ export async function executeChat(params: ChatEngineParams): Promise> = []; + let hasTextPart = false; if (streamedReasoning.trim()) { parts.push({ id: `p_${parts.length}`, type: "reasoning", text: streamedReasoning }); } if (partialText.trim()) { parts.push({ id: `p_${parts.length}`, type: "text", text: partialText }); + hasTextPart = true; } for (const tc of streamedToolCalls) { parts.push({ @@ -659,6 +673,15 @@ export async function executeChat(params: ChatEngineParams): Promise p.type === "tool-call"); + let finalText = partialText; + if (!hasTextPart && hasToolCallPart) { + const noticeText = "(对话已停止,以上是已完成的工具调用记录。)"; + parts.push({ id: `p_${parts.length}`, type: "text", text: noticeText }); + finalText = (finalText || "") + noticeText; + logger.info("[%s] [CHAT-ENGINE] aborted with tool calls but no text, appended notice", requestId); + } + if (isApprovalContinue) { const lastAssistant = historyMessages.filter((m) => m.role === "assistant").pop(); if (lastAssistant) { @@ -688,18 +711,18 @@ export async function executeChat(params: ChatEngineParams): Promise 0 || parts.length > 0; + const hasContent = finalText.trim().length > 0 || parts.length > 0; if (hasContent) { const assistantSortOrder = (await getMaxSortOrder(sessionId)) + 1; await saveMessage({ sessionId, role: "assistant", - content: partialText, + content: finalText, parts: parts.length > 0 ? JSON.stringify(parts) : null, modelId: resolvedModel.dbId, sortOrder: assistantSortOrder,