From 13504626b950ba992f4e50011a5b29615abb995d Mon Sep 17 00:00:00 2001 From: hoarfrost32 Date: Mon, 15 Jun 2026 20:02:55 +0530 Subject: [PATCH] fix(console): preserve tool names in anthropic to oa-compat conversion Read tool fields from function.* so Claude Code requests keep function.name when forwarded to DeepSeek and other oa-compat models. Fixes #27047. Co-authored-by: Cursor --- .../zen/util/provider/openai-compatible.ts | 6 +- .../app/test/providerConversion.test.ts | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 packages/console/app/test/providerConversion.test.ts diff --git a/packages/console/app/src/routes/zen/util/provider/openai-compatible.ts b/packages/console/app/src/routes/zen/util/provider/openai-compatible.ts index 9e5e15d94480..a2a544e3d05f 100644 --- a/packages/console/app/src/routes/zen/util/provider/openai-compatible.ts +++ b/packages/console/app/src/routes/zen/util/provider/openai-compatible.ts @@ -200,9 +200,9 @@ export function toOaCompatibleRequest(body: CommonRequest) { ? body.tools.map((tool: any) => ({ type: "function", function: { - name: tool.name, - description: tool.description, - parameters: tool.parameters, + name: tool.function?.name, + description: tool.function?.description, + parameters: tool.function?.parameters ?? tool.function?.input_schema, }, })) : undefined diff --git a/packages/console/app/test/providerConversion.test.ts b/packages/console/app/test/providerConversion.test.ts new file mode 100644 index 000000000000..c60520f4922f --- /dev/null +++ b/packages/console/app/test/providerConversion.test.ts @@ -0,0 +1,61 @@ +import { describe, expect, test } from "bun:test" +import { fromAnthropicRequest } from "../src/routes/zen/util/provider/anthropic" +import { toOaCompatibleRequest } from "../src/routes/zen/util/provider/openai-compatible" + +describe("anthropic to oa-compat tool conversion", () => { + test("preserves tool names from Claude Code style anthropic requests", () => { + const anthropicBody = { + model: "deepseek-v4-flash-free", + max_tokens: 1024, + tools: [ + { + name: "Bash", + description: "Run a bash command", + input_schema: { + type: "object", + properties: { + command: { type: "string" }, + }, + required: ["command"], + }, + }, + ], + messages: [{ role: "user", content: "run echo hello" }], + } + + const common = fromAnthropicRequest(anthropicBody) + const oaCompat = toOaCompatibleRequest(common) + + expect(oaCompat.tools).toEqual([ + { + type: "function", + function: { + name: "Bash", + description: "Run a bash command", + parameters: anthropicBody.tools[0].input_schema, + }, + }, + ]) + }) + + test("passes through already-normalized common request tools", () => { + const common = { + model: "north-mini-code-free", + messages: [{ role: "user" as const, content: "hi" }], + tools: [ + { + type: "function" as const, + function: { + name: "Read", + description: "Read a file", + parameters: { type: "object", properties: { path: { type: "string" } } }, + }, + }, + ], + } + + const oaCompat = toOaCompatibleRequest(common) + + expect(oaCompat.tools?.[0]?.function?.name).toBe("Read") + }) +})