From 45240c19e577001e74365a2a48c00822d9849048 Mon Sep 17 00:00:00 2001 From: decolua Date: Sun, 21 Jun 2026 16:26:17 +0700 Subject: [PATCH] fix(translator): normalize tools to Anthropic-native shape for non-Anthropic providers Strip `type` field and fold `function.{name,description,parameters}` into top-level {name, description, input_schema} before forwarding to Claude-format endpoints. MiniMax (and other Anthropic-compatible providers) reject tools carrying a `type` field with error code 2013 ("invalid tool type"). Refs #1939 Co-authored-by: Cursor --- open-sse/translator/formats/claude.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/open-sse/translator/formats/claude.js b/open-sse/translator/formats/claude.js index 3e93e4d5..4c8454b8 100644 --- a/open-sse/translator/formats/claude.js +++ b/open-sse/translator/formats/claude.js @@ -257,9 +257,22 @@ export function prepareClaudeRequest(body, provider = null, apiKey = null, conne // 3. Tools: filter built-in tools for non-Anthropic providers, then handle cache_control if (body.tools && Array.isArray(body.tools)) { - // Strip built-in tools (e.g. web_search_20250305) for providers that don't support them + // Strip built-in tools (e.g. web_search_20250305) and normalize to Anthropic-native shape + // (drop `type` field, fold `function.{name,description,parameters}`) for non-Anthropic providers if (provider !== "claude") { - body.tools = body.tools.filter(tool => !tool.type || tool.type === "function"); + body.tools = body.tools + .filter(tool => !tool.type || tool.type === "function") + .map(tool => { + if (tool.function) { + return { + name: tool.function.name, + description: tool.function.description, + input_schema: tool.function.parameters, + }; + } + const { type, ...rest } = tool; + return rest; + }); } body.tools = body.tools.map((tool, i) => {