From 0d107dd566e4e7992f3fe3b56e2b3dba6812810b Mon Sep 17 00:00:00 2001 From: sususu98 Date: Wed, 29 Apr 2026 19:24:53 +0800 Subject: [PATCH] fix: respect declared claude web search tool names --- .../codex/claude/codex_claude_request.go | 2 -- .../codex/claude/codex_claude_request_test.go | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/internal/translator/codex/claude/codex_claude_request.go b/internal/translator/codex/claude/codex_claude_request.go index 85d2b3e2..1e168f09 100644 --- a/internal/translator/codex/claude/codex_claude_request.go +++ b/internal/translator/codex/claude/codex_claude_request.go @@ -377,8 +377,6 @@ func buildClaudeWebSearchToolNameSet(tools gjson.Result) map[string]struct{} { return true } - names["web_search"] = struct{}{} - names[toolType] = struct{}{} if name := tool.Get("name").String(); name != "" { names[name] = struct{}{} } diff --git a/internal/translator/codex/claude/codex_claude_request_test.go b/internal/translator/codex/claude/codex_claude_request_test.go index 4866b470..16bb46c9 100644 --- a/internal/translator/codex/claude/codex_claude_request_test.go +++ b/internal/translator/codex/claude/codex_claude_request_test.go @@ -248,6 +248,28 @@ func TestConvertClaudeRequestToCodex_WebSearchToolMapping(t *testing.T) { } } +func TestConvertClaudeRequestToCodex_WebSearchToolChoiceUsesDeclaredTypedToolName(t *testing.T) { + inputJSON := `{ + "model": "claude-opus-4-7", + "tools": [ + {"type": "web_search_20250305", "name": "browser_search"}, + {"name": "web_search", "description": "Local search", "input_schema": {"type":"object","properties":{}}} + ], + "tool_choice": {"type":"tool","name":"web_search"}, + "messages": [{"role": "user", "content": "hello"}] + }` + + result := ConvertClaudeRequestToCodex("test-model", []byte(inputJSON), false) + resultJSON := gjson.ParseBytes(result) + + if got := resultJSON.Get("tool_choice.type").String(); got != "function" { + t.Fatalf("tool_choice.type = %q, want function. Output: %s", got, string(result)) + } + if got := resultJSON.Get("tool_choice.name").String(); got != "web_search" { + t.Fatalf("tool_choice.name = %q, want web_search. Output: %s", got, string(result)) + } +} + func TestConvertClaudeRequestToCodex_AssistantThinkingSignatureToReasoningItem(t *testing.T) { signature := validCodexReasoningSignature() inputJSON := `{