Skip to content

fix(xai): OAuth Responses native web_search, incomplete guard, grok-composer 262k context - #44341

Closed
XVVH wants to merge 1 commit into
NousResearch:mainfrom
XVVH:fix/xai-oauth-responses-native-web-search
Closed

fix(xai): OAuth Responses native web_search, incomplete guard, grok-composer 262k context#44341
XVVH wants to merge 1 commit into
NousResearch:mainfrom
XVVH:fix/xai-oauth-responses-native-web-search

Conversation

@XVVH

@XVVH XVVH commented Jun 11, 2026

Copy link
Copy Markdown

Summary

Fixes grok-composer-2.5-fast (and other xAI OAuth / codex_responses) sessions that failed web-research turns or showed a 131k context cap.

Supersedes the earlier context-only PR #40046 (closed while we finished root-causing search). This is one consolidated change: metadata + transport + adapter.

Problems

  1. Context: grok-composer-2.5-fast is absent from GET /v1/models on OAuth; Hermes fell through to the generic grok131072 substring rule. Live /v1/responses enforces ~262144 total (input+output). Users hit premature compression and a misleading context UI.

  2. Incomplete loop: When Hermes declared web_search as a client function, xAI routed to server-side search without a matching {"type":"web_search"} built-in. Streams often ended reasoning-only → finish_reason="incomplete" → three continuation retries → Codex response remained incomplete after 3 continuation attempts.

  3. Declaration: xAI returns HTTP 400 on duplicate tool names if both client web_search and native built-in are sent. Fix: for is_xai_responses, drop the client function and inject native {"type":"web_search"} (same path for composer and grok-4.x).

Changes

Area What
agent/model_metadata.py "grok-composer": 262144
agent/transports/codex.py Native web_search inject + drop client web_search for xAI Responses
agent/codex_responses_adapter.py Ignore in-flight server-side *_call items (e.g. web_search_call) when judging incomplete; preflight allowlist for built-in tool types

Tests

uv run pytest tests/agent/test_codex_responses_adapter.py \
  tests/agent/transports/test_codex_transport.py::TestCodexBuildKwargs \
  tests/run_agent/test_codex_xai_oauth_recovery.py -q

118 passed on this branch.

Trade-off (explicit)

On xAI Responses, web_search uses Grok's native search, not Hermes Tavily/citation plumbing. Results appear in the assistant message rather than as a client-observed tool result. Scoped to is_xai_responses only; other providers unchanged.

Verification

  • Exercised on SuperGrok OAuth: previously failing composer search turns complete with sourced answers.
  • Post-merge smoke on a production gateway (Telegram): composer web search OK.

Related

…omposer context

- model_metadata: grok-composer-2.5-fast → 262144 (OAuth slug not in /v1/models)
- codex transport: inject native {"type":"web_search"} for is_xai_responses;
  drop client web_search to avoid duplicate-name 400s
- codex adapter: do not treat in-progress server-side *_call items as incomplete
- tests: adapter, transport build_kwargs, model_metadata, oauth recovery
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/xai xAI (Grok) labels Jun 11, 2026
@liuhao1024

Copy link
Copy Markdown
Contributor

Verification review — Reviewed the full diff (7 files, +310/-2) for xAI OAuth Responses native web_search support.

What I verified:

  1. _RESPONSES_BUILTIN_TOOL_TYPES declaration — the set correctly lists all provider-executed built-in tool types (web_search, web_search_preview, file_search, code_interpreter, image_generation, computer_use_preview, local_shell). The preflight validator now passes these through verbatim instead of rejecting with "unsupported type".
  2. _SERVER_SIDE_TOOL_CALL_TYPES guard — server-side *_call items with status="in_progress" no longer flip has_incomplete_items. The guard correctly scopes to server-side types only; an in_progress message item (genuine model output still streaming) still marks the turn incomplete. This prevents the 3-fruitless-retry burn observed with grok-composer-2.5-fast.
  3. Client-side web_search filtering — when is_xai_responses is true, the client-side web_search function tool is removed and replaced with {"type": "web_search"} native declaration. The comment correctly notes this routes search to Grok's native engine instead of Hermes's configured web provider (Tavily/etc.), and results bypass tool-trace/citation plumbing.
  4. grok-composer context window — 262144 tokens added to _MODEL_CONTEXT_WINDOWS with correct substring matching. Test updated.
  5. Test coverage — 4 new test functions covering: in_progress server-side tool calls ignored, in_progress messages still incomplete, native web_search passes preflight, unknown tool types still rejected.

Clean implementation. The inline comments thoroughly document the exact failure mode (incomplete status not reconciled by xAI's /v1/responses surface) and the architectural tradeoff (native search bypasses Hermes tool-trace).

@liuhao1024

Copy link
Copy Markdown
Contributor

✅ Code Review — Clean

Reviewed the full diff across 5 files (codex_responses_adapter.py, model_metadata.py, codex.py, and 3 test files).

What I verified:

  • Server-side tool call exemption: _SERVER_SIDE_TOOL_CALL_TYPES correctly scopes the incomplete-status exemption to provider-executed *_call types only — genuine message items with in_progress status still correctly mark the turn incomplete (tested in test_normalize_codex_response_in_progress_message_still_incomplete)
  • Native web_search injection: The xAI path correctly drops client-side web_search function tools before appending {"type": "web_search"} built-in, preventing HTTP 400 "Duplicate tool names" (tested in test_xai_drops_clientside_web_search_to_avoid_duplicate)
  • Non-xAI scoping: The injection is gated on is_xai_responses — Codex/GitHub paths keep client-side web_search untouched (tested in test_non_xai_path_does_not_inject_native_web_search)
  • Preflight validation: _RESPONSES_BUILTIN_TOOL_TYPES allows built-in tool types through preflight without forcing them through function-tool validation (tested in test_preflight_passes_native_web_search_tool_through + test_preflight_still_rejects_unknown_tool_type)
  • Lambda capture correctness: In build_kwargs, the filtered list comprehension and append happen before any async dispatch, so no late-binding risk

The _SERVER_SIDE_TOOL_CALL_TYPES set includes mcp_call — this is safe because MCP tool calls from xAI's server side would also have the stale in_progress status issue. Client-side MCP function calls use type="function" and are not affected.

No issues found. LGTM.

teknium1 added a commit that referenced this pull request Jun 18, 2026
…tx to 200k

Salvage corrections on top of @XVVH's #44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in #47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for #44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #48108 — your commit was cherry-picked onto current main with your authorship preserved, plus two review-driven corrections:

  1. Native web_search injection is now a 1:1 swap for an already-present client web_search, not an additive grant. The original appended {"type":"web_search"} on every is_xai_responses turn with any tools, which force-enabled Grok server-side search even when the user never enabled the web toolset (silently bypassing the configured web provider + tool-trace/citation plumbing). Now gated on a client web_search actually being present, with a no-web-toolset guard test.
  2. grok-composer context reconciled to 200000 (xAI's published usable window for Composer 2.5; 262144 is the /v1/responses input+output budget). This also avoided a duplicate-key conflict with feat(xai): surface Composer 2.5 in the xAI OAuth model picker #47908 which already merged 200000.

The incomplete-guard (server-side *_call items at in_progress no longer flipping the incomplete verdict) and the preflight built-in-tool allowlist — the real heart of the fix — went in as-is. Solid root-causing on the stalled-search-loop bug. Thanks! #48108

@teknium1 teknium1 closed this Jun 18, 2026
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…tx to 200k

Salvage corrections on top of @XVVH's NousResearch#44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in NousResearch#47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for NousResearch#44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…tx to 200k

Salvage corrections on top of @XVVH's NousResearch#44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in NousResearch#47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for NousResearch#44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…tx to 200k

Salvage corrections on top of @XVVH's NousResearch#44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in NousResearch#47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for NousResearch#44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…tx to 200k

Salvage corrections on top of @XVVH's NousResearch#44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in NousResearch#47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for NousResearch#44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…tx to 200k

Salvage corrections on top of @XVVH's NousResearch#44341:
- Make native web_search injection a 1:1 swap for an already-present client
  web_search function, NOT an additive grant. The original unconditionally
  appended {"type":"web_search"} on every is_xai_responses turn with any
  tools, force-enabling Grok server-side search even when the user never
  enabled the web toolset (bypassing Hermes web-provider config + tool-trace
  plumbing). Now gated on a client web_search actually being present.
- Reconcile grok-composer context to 200000 (merged in NousResearch#47908) rather than
  262144; 200k is xAI's published usable context window for Composer 2.5,
  262144 is the /v1/responses input+output budget.
- Update tests to match scoped behavior + add a no-web-toolset guard test.
- AUTHOR_MAP entry for NousResearch#44341 salvage.

Incomplete-guard (server-side *_call items at in_progress no longer flip
has_incomplete_items) and preflight built-in-tool allowlist kept as-is.
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 P3 Low — cosmetic, nice to have provider/xai xAI (Grok) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants