mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
fix(openai-to-claude): unwrap bare {function:{…}} tools without parent type (#2473)
Translator only unwrapped tool.function when both tool.type==="function"
and tool.function were truthy. Loose/legacy OpenAI clients emit the bare
{ function: { name, parameters } } shape (no parent type), which fell
through and forwarded name: undefined upstream, rejected by strict
Anthropic-compatible gateways (MiniMax M3) as (2013) invalid tool type.
Unwrap tool.function whenever present. Built-in tools stay pass-through.
Adds regression coverage for the 4 tool shapes. See #2435.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
288940960a
commit
ddd5509e97
@@ -153,7 +153,15 @@ Respond ONLY with the JSON object, no other text.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const toolData = toolType === OPENAI_BLOCK.FUNCTION && tool.function ? tool.function : tool;
|
||||
// Function-shaped tools arrive in two flavors from real clients:
|
||||
// (a) openai-spec: { type: "function", function: { name, ... } }
|
||||
// (b) legacy/loose: { function: { name, ... } } (no parent `type`)
|
||||
// Both must yield toolData.name = "echo". Treat the bare-function shape
|
||||
// as a function tool too — Anthropic-compatible gateways (notably
|
||||
// MiniMax M3 at api.minimaxi.com) reject payloads where this branch
|
||||
// falls through with `toolData.name === undefined`, returning their
|
||||
// upstream code (2013) "invalid tool type". See #2435.
|
||||
const toolData = tool.function ?? tool;
|
||||
const originalName = toolData.name;
|
||||
|
||||
// Claude OAuth requires prefixed tool names to avoid conflicts
|
||||
|
||||
Reference in New Issue
Block a user