From d26ad8224d6e3d0af2e912d0dbd9d996bfe3769c Mon Sep 17 00:00:00 2001 From: sususu98 Date: Wed, 4 Mar 2026 14:21:30 +0800 Subject: [PATCH] fix(translator): strip defer_loading from Claude tool declarations in Codex and Gemini translators Claude's Tool Search feature (advanced-tool-use-2025-11-20 beta) adds defer_loading field to tool definitions. When proxying Claude requests to Codex or Gemini, this unknown field causes 400 errors upstream. Strip defer_loading (and cache_control where missing) in all three Claude-to-upstream translation paths: - codex/claude: defer_loading + cache_control - gemini-cli/claude: defer_loading - gemini/claude: defer_loading Fixes #1725, Fixes #1375 --- internal/translator/codex/claude/codex_claude_request.go | 2 ++ .../translator/gemini-cli/claude/gemini-cli_claude_request.go | 1 + internal/translator/gemini/claude/gemini_claude_request.go | 1 + 3 files changed, 4 insertions(+) diff --git a/internal/translator/codex/claude/codex_claude_request.go b/internal/translator/codex/claude/codex_claude_request.go index e3ddd0b8..6373e693 100644 --- a/internal/translator/codex/claude/codex_claude_request.go +++ b/internal/translator/codex/claude/codex_claude_request.go @@ -255,6 +255,8 @@ func ConvertClaudeRequestToCodex(modelName string, inputRawJSON []byte, _ bool) tool, _ = sjson.SetRaw(tool, "parameters", normalizeToolParameters(toolResult.Get("input_schema").Raw)) tool, _ = sjson.Delete(tool, "input_schema") tool, _ = sjson.Delete(tool, "parameters.$schema") + tool, _ = sjson.Delete(tool, "cache_control") + tool, _ = sjson.Delete(tool, "defer_loading") tool, _ = sjson.Set(tool, "strict", false) template, _ = sjson.SetRaw(template, "tools.-1", tool) } diff --git a/internal/translator/gemini-cli/claude/gemini-cli_claude_request.go b/internal/translator/gemini-cli/claude/gemini-cli_claude_request.go index 3f8921dc..076e09db 100644 --- a/internal/translator/gemini-cli/claude/gemini-cli_claude_request.go +++ b/internal/translator/gemini-cli/claude/gemini-cli_claude_request.go @@ -156,6 +156,7 @@ func ConvertClaudeRequestToCLI(modelName string, inputRawJSON []byte, _ bool) [] tool, _ = sjson.Delete(tool, "input_examples") tool, _ = sjson.Delete(tool, "type") tool, _ = sjson.Delete(tool, "cache_control") + tool, _ = sjson.Delete(tool, "defer_loading") if gjson.Valid(tool) && gjson.Parse(tool).IsObject() { if !hasTools { out, _ = sjson.SetRaw(out, "request.tools", `[{"functionDeclarations":[]}]`) diff --git a/internal/translator/gemini/claude/gemini_claude_request.go b/internal/translator/gemini/claude/gemini_claude_request.go index 172884bd..0e367c0d 100644 --- a/internal/translator/gemini/claude/gemini_claude_request.go +++ b/internal/translator/gemini/claude/gemini_claude_request.go @@ -137,6 +137,7 @@ func ConvertClaudeRequestToGemini(modelName string, inputRawJSON []byte, _ bool) tool, _ = sjson.Delete(tool, "input_examples") tool, _ = sjson.Delete(tool, "type") tool, _ = sjson.Delete(tool, "cache_control") + tool, _ = sjson.Delete(tool, "defer_loading") if gjson.Valid(tool) && gjson.Parse(tool).IsObject() { if !hasTools { out, _ = sjson.SetRaw(out, "tools", `[{"functionDeclarations":[]}]`)