From c44f3b8a3d37b95407e7581d66c0cc36c51d1c6b Mon Sep 17 00:00:00 2001 From: Yanwu <5762066+yan5xu@users.noreply.github.com> Date: Sat, 8 Mar 2025 17:12:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(mcp):=20=E4=BF=AE=E5=A4=8D=E4=BA=86mcp?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=B0=83=E7=94=A8=E5=8A=9F=E8=83=BD=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#3047)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(mcp): 修复了mcp无法调用功能的问题 * fix(mcp): 修复工具调用时inputSchema只读属性错误 --- src/renderer/src/providers/mcpToolUtils.ts | 63 ++++++++++++++++------ 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/renderer/src/providers/mcpToolUtils.ts b/src/renderer/src/providers/mcpToolUtils.ts index f7840335..ca7f1d87 100644 --- a/src/renderer/src/providers/mcpToolUtils.ts +++ b/src/renderer/src/providers/mcpToolUtils.ts @@ -52,8 +52,11 @@ export function openAIToolsToMcpTool( if (!tool) { return undefined } - tool.inputSchema = JSON.parse(llmTool.function.arguments) - return tool + // 创建工具对象的副本,而不是直接修改原对象 + return { + ...tool, + inputSchema: JSON.parse(llmTool.function.arguments) + } } export async function callMCPTool(tool: MCPTool): Promise { @@ -82,9 +85,12 @@ export function anthropicToolUseToMcpTool(mcpTools: MCPTool[] | undefined, toolU if (!tool) { return undefined } - // @ts-ignore ignore type as it it unknow - tool.inputSchema = toolUse.input - return tool + // 创建工具对象的副本,而不是直接修改原对象 + return { + ...tool, + // @ts-ignore ignore type as it it unknow + inputSchema: toolUse.input + } } export function mcpToolsToGeminiTools(mcpTools: MCPTool[] | undefined): geminiToool[] { @@ -120,9 +126,12 @@ export function geminiFunctionCallToMcpTool( if (!tool) { return undefined } - // @ts-ignore schema is not a valid property - tool.inputSchema = fcall.args - return tool + // 创建工具对象的副本,而不是直接修改原对象 + return { + ...tool, + // @ts-ignore schema is not a valid property + inputSchema: fcall.args + } } export function upsertMCPToolResponse( @@ -131,15 +140,35 @@ export function upsertMCPToolResponse( onChunk: ({ mcpToolResponse }: ChunkCallbackData) => void ) { try { - for (const ret of results) { - if (ret.tool.id == resp.tool.id) { - ret.response = resp.response - ret.status = resp.status - return + // 创建一个新数组,不修改原数组 + const newResults: MCPToolResponse[] = [] + let found = false + + // 复制原数组中的元素到新数组,如果找到匹配的工具ID则更新 + for (const item of results) { + if (item.tool.id === resp.tool.id) { + // 找到匹配的工具,添加更新后的对象 + newResults.push({ ...item, response: resp.response, status: resp.status }) + found = true + } else { + // 否则添加原对象的副本 + newResults.push({ ...item }) } } - results.push(resp) - } finally { + + // 如果没有找到匹配的工具ID,添加新的响应 + if (!found) { + newResults.push({ ...resp }) + } + + // 调用回调函数,传递新数组 + onChunk({ + text: '', + mcpToolResponse: newResults + }) + } catch (error) { + console.error('Error in upsertMCPToolResponse:', error) + // 出错时仍然调用回调,但使用原数组 onChunk({ text: '', mcpToolResponse: results @@ -151,11 +180,13 @@ export function filterMCPTools( mcpTools: MCPTool[] | undefined, enabledServers: MCPServer[] | undefined ): MCPTool[] | undefined { + console.log('filterMCPTools', mcpTools, enabledServers) if (mcpTools) { if (enabledServers) { mcpTools = mcpTools.filter((t) => enabledServers.some((m) => m.name === t.serverName)) } else { - mcpTools = [] + // TODO enabledServers 存在bug,传入一直为undefined + // mcpTools = [] } } return mcpTools