From c2d438fba32aec239f9cb799c6a084a72aa875f7 Mon Sep 17 00:00:00 2001 From: Phantom <59059173+EurFelux@users.noreply.github.com> Date: Mon, 14 Jul 2025 22:44:51 +0800 Subject: [PATCH] fix(openai): add compatibility mode for handling tool call responses (#7983) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(openai): 添加兼容模式处理工具调用响应 在兼容模式下处理工具调用响应时,添加对数组内容的特殊处理逻辑。当isCompatibleMode为true时,将响应内容转换为特定格式的字符串输出,包括对文本、图片和音频等不同类型内容的处理。 --- .../aiCore/clients/openai/OpenAIApiClient.ts | 7 +++- src/renderer/src/utils/mcp-tools.ts | 32 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts b/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts index bbf862d97e..16a4409ffa 100644 --- a/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts +++ b/src/renderer/src/aiCore/clients/openai/OpenAIApiClient.ts @@ -371,7 +371,12 @@ export class OpenAIAPIClient extends OpenAIBaseClient< if ('toolUseId' in mcpToolResponse && mcpToolResponse.toolUseId) { // This case is for Anthropic/Claude like tool usage, OpenAI uses tool_call_id // For OpenAI, we primarily expect toolCallId. This might need adjustment if mixing provider concepts. - return mcpToolCallResponseToOpenAICompatibleMessage(mcpToolResponse, resp, isVisionModel(model)) + return mcpToolCallResponseToOpenAICompatibleMessage( + mcpToolResponse, + resp, + isVisionModel(model), + this.provider.isNotSupportArrayContent ?? false + ) } else if ('toolCallId' in mcpToolResponse && mcpToolResponse.toolCallId) { return { role: 'tool', diff --git a/src/renderer/src/utils/mcp-tools.ts b/src/renderer/src/utils/mcp-tools.ts index 05180e3303..8beffb4cd2 100644 --- a/src/renderer/src/utils/mcp-tools.ts +++ b/src/renderer/src/utils/mcp-tools.ts @@ -729,14 +729,42 @@ export async function parseAndCallTools( export function mcpToolCallResponseToOpenAICompatibleMessage( mcpToolResponse: MCPToolResponse, resp: MCPCallToolResponse, - isVisionModel: boolean = false + isVisionModel: boolean = false, + isCompatibleMode: boolean = false ): ChatCompletionMessageParam { const message = { role: 'user' } as ChatCompletionMessageParam - if (resp.isError) { message.content = JSON.stringify(resp.content) + } else if (isCompatibleMode) { + let content: string = `Here is the result of mcp tool use \`${mcpToolResponse.tool.name}\`:\n` + + if (isVisionModel) { + for (const item of resp.content) { + switch (item.type) { + case 'text': + content += (item.text || 'no content') + '\n' + break + case 'image': + // NOTE: 假设兼容模式下支持解析base64图片,虽然我觉得应该不支持 + content += `Here is a image result: data:${item.mimeType};base64,${item.data}\n` + break + case 'audio': + // NOTE: 假设兼容模式下支持解析base64音频,虽然我觉得应该不支持 + content += `Here is a audio result: data:${item.mimeType};base64,${item.data}\n` + break + default: + content += `Here is a unsupported result type: ${item.type}\n` + break + } + } + } else { + content += JSON.stringify(resp.content) + content += '\n' + } + + message.content = content } else { const content: ChatCompletionContentPart[] = [ {