Skip to content

fix(xai): omit tool_choice when no tools are available - #20606

Closed
Ade5954 wants to merge 1 commit into
NousResearch:mainfrom
Ade5954:fix/xai-tool-choice-empty-tools
Closed

fix(xai): omit tool_choice when no tools are available#20606
Ade5954 wants to merge 1 commit into
NousResearch:mainfrom
Ade5954:fix/xai-tool-choice-empty-tools

Conversation

@Ade5954

@Ade5954 Ade5954 commented May 6, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a bug where xAI/Grok providers reject requests with HTTP 400
"tool_choice was set but no tools were specified" when no local function
tools are available (e.g. the web_search toolset is filtered out by
check_web_api_key).

Root cause: The ResponsesApiTransport.build_kwargs() unconditionally
sets tool_choice: "auto" and parallel_tool_calls: true in every request,
regardless of whether any function tools were resolved. When
_responses_tools(tools) returns None (empty input list), the outgoing
body contains tool_choice and parallel_tool_calls but no tools array
— which xAI's Responses API rejects.

Related Issue

Fixes #20590

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

agent/transports/codex.py

  • Moved tool_choice/parallel_tool_calls out of the static kwargs dict
    into a conditional block that only executes when _responses_tools()
    returns a non-empty list
  • When no function tools are available, these fields are omitted entirely

agent/codex_responses_adapter.py

  • Added defense-in-depth in _preflight_codex_api_kwargs(): after the
    tool_choice/parallel_tool_calls passthrough, strip both fields when
    the normalized tools array is empty or absent

How to Test

  1. Configure xAI/Grok as provider
  2. Remove/disable all function tools (e.g. remove API keys for web_search)
  3. Run a query — the outgoing request should have no tool_choice field
    when tools is empty
  4. The request should no longer receive HTTP 400 from xAI

…ransport

When using xAI/Grok as provider, all requests are routed through the
Codex Responses transport. If no local function tools are available
(e.g. web_search toolset is filtered out), the transport still sends
tool_choice:'auto' and parallel_tool_calls:true but with an empty
tools array. xAI rejects this with HTTP 400 'tool_choice was set but
no tools were specified' (issue NousResearch#20590).

Changes:
- agent/transports/codex.py: Only set tool_choice and
  parallel_tool_calls when _responses_tools() returns a non-empty
  list. When no function tools are available, omit these fields
  entirely so providers don't reject the request.
- agent/codex_responses_adapter.py: Add defense-in-depth in
  _preflight_codex_api_kwargs() to strip tool_choice and
  parallel_tool_calls when the normalized tools array is empty.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/xai xAI (Grok) labels May 6, 2026
@Ade5954 Ade5954 closed this May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/xai xAI (Grok) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: xAI Responses transport: no code path registers server-side web_search/x_search tools

2 participants