From 6506eafd77737d7092f07297053e948843dee992 Mon Sep 17 00:00:00 2001 From: digua Date: Tue, 3 Feb 2026 00:09:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E4=B8=AD=E8=BD=ACAPI=E8=B0=83?= =?UTF-8?q?=E7=94=A8tool=5Fcall=E5=AF=BC=E8=87=B4=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E7=BB=93=E6=9D=9F=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20#67?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main/ai/agent.ts | 14 ++++++++++++-- electron/main/ai/llm/openai-compatible.ts | 12 ++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/electron/main/ai/agent.ts b/electron/main/ai/agent.ts index e3125f8..33d94d2 100644 --- a/electron/main/ai/agent.ts +++ b/electron/main/ai/agent.ts @@ -735,6 +735,10 @@ export class Agent { if (chunk.tool_calls) { toolCalls = chunk.tool_calls + aiLogger.info('Agent', '收到 tool_calls', { + count: chunk.tool_calls.length, + names: chunk.tool_calls.map((tc) => tc.function.name), + }) } // 累加 Token 使用量(流式响应在最后一个 chunk 返回 usage) @@ -743,11 +747,17 @@ export class Agent { } if (chunk.isFinished) { + aiLogger.info('Agent', '流结束', { + finishReason: chunk.finishReason, + hasToolCalls: !!toolCalls, + toolCallsCount: toolCalls?.length ?? 0, + }) // 收尾:清空解析器缓冲 parser.flush() - // 如果没有标准 tool_calls,尝试 fallback 解析 - if (chunk.finishReason !== 'tool_calls' || !toolCalls) { + // 只有当 finishReason 不是 tool_calls 且 没有收到 toolCalls 时,才尝试 fallback 解析 + // 修复:某些第三方 API(如 Gemini 中转)返回 finishReason="stop" 但实际有 tool_calls + if (chunk.finishReason !== 'tool_calls' && !toolCalls) { // Fallback: 检查内容中是否有 标签 if (hasToolCallTags(accumulatedContent)) { // 提取 thinking 内容 diff --git a/electron/main/ai/llm/openai-compatible.ts b/electron/main/ai/llm/openai-compatible.ts index 324c169..91da78c 100644 --- a/electron/main/ai/llm/openai-compatible.ts +++ b/electron/main/ai/llm/openai-compatible.ts @@ -436,17 +436,21 @@ export class OpenAICompatibleService implements ILLMService { } } else if (part.type === 'finish') { // 流结束 + const finishReason = mapFinishReason(part.finishReason) + const toolCalls = await result.toolCalls + const usage = mapUsage(part.totalUsage) + + // 详细记录流式请求完成信息,包括工具调用 aiLogger.info(this.providerId, '流式请求完成', { partCount, textChunkCount, reasoningChunkCount, finishReason: part.finishReason, + mappedFinishReason: finishReason, + toolCallsCount: toolCalls.length, + toolCallNames: toolCalls.map((tc) => tc.toolName), }) - const finishReason = mapFinishReason(part.finishReason) - const toolCalls = await result.toolCalls - const usage = mapUsage(part.totalUsage) - yield { content: '', isFinished: true,