mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-23 17:03:54 +08:00
When Claude Code sends a stop-hook evaluator request (or any request without tools), the payload includes "tools": [] (empty array). The claude->codex translator unconditionally emits tools: [] + tool_choice: "auto" + parallel_tool_calls: true into the Codex Responses shape. When that payload is routed to xAI, the upstream rejects with HTTP 400: "A tool_choice was set on the request but no tools were specified." Fix entirely in the xAI executor (translator package is policy-locked): add normalizeXAIToolChoiceForTools() after normalizeXAITools() to drop tool_choice and parallel_tool_calls whenever tools end up absent or empty (covering both the empty-from-source case and the all-filtered-out case where every tool was an unsupported type such as tool_search or image_generation). Per code-review feedback: always remove parallel_tool_calls when tools are missing (not gated on tool_choice presence) and existence-check each key before sjson delete to avoid unnecessary JSON parse/copy. Verification: - go build -o test-output ./cmd/server - go test ./internal/runtime/executor/... -count=1 - 5 new regression tests cover empty / missing / present / orphaned parallel_tool_calls / no-op-when-both-absent.