fix(router): backfill the xAI web-search capability into routed provider config - #2283
Conversation
…der config Routed Grok turns on the Responses lane died with `400 Argument not supported: external_web_access` before inference. routedProviderConfig() backfills every other registry-only scalar (supportsServiceTier, preserveResponsesReasoningContent, fastWire) but not supportsOpenAiWebSearchToolFields. enrichProviderFromRegistry() does fill it, and the request path never calls that function -- so a saved xai row reached the Responses adapter with the flag undefined. The #2262 capability gate reads undefined as "unclassified upstream, keep the fields", so Codex's OpenAI-only web_search config went to the wire and xAI rejected the whole request. Live probe against the OAuth Grok endpoint (2026-08-21) isolates the cause: bare {type:"web_search"} returns 200, +external_web_access returns 400, and +search_context_size returns 400 -- individually, before inference. Verified end-to-end on a remote macOS host running this dev head: with the GUI Responses opt-in on and NO hand-written capability in config.json, a multi-step codex exec tool-use turn now completes over adapter "openai-responses" with status 200, where the same turn 400'd before. The existing tests could not catch this: they hand-build a provider with the flag already set, or call enrichProviderFromRegistry() directly, so both start downstream of the break. The new tests assert on routedProviderConfig() output and were driven red against the unfixed router.
|
✅ Deterministic PR hygiene checks passed. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesWeb-search capability routing
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change prevents unsupported web-search fields from being sent to routed xAI Responses requests while preserving explicit saved settings; the focused tests and verification pass, so no actionable merge-blocking risk remains. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Ingwannu
left a comment
There was a problem hiding this comment.
Approved exact head d5ea14a2d522b428ff5b13d011bdf9e376b41358.
I independently verified the request-path gap and the fix. routedProviderConfig() was the missing registry-enrichment boundary: a saved xAI row could reach the Responses adapter with supportsOpenAiWebSearchToolFields unset even though the registry declares false. The new fill-only backfill matches the established enrichProviderFromRegistry() contract, applies only to registry-owned transport rows, and preserves an explicit saved override.
The focused request/router and passthrough suites pass locally (105/105), as do bun run typecheck and bun run privacy:scan. The new tests cover the saved-row path that the older adapter-only tests missed, including actual field stripping and explicit-value precedence.
No blocking issue found. Merge should wait for the remaining exact-head macOS job to finish green.
Summary
Routed Grok turns on the Responses lane died with
400 Argument not supported: external_web_accessbefore inference, so every tool-use turn failed.routedProviderConfig()backfills every other registry-only scalar (supportsServiceTier,preserveResponsesReasoningContent,fastWire) but notsupportsOpenAiWebSearchToolFields.enrichProviderFromRegistry()does fill it — and the request path never calls that function. So a savedxairow reached the Responses adapter with the flagundefined, the #2262 capability gate read that as "unclassified upstream, keep the fields", and Codex's OpenAI-onlyweb_searchconfig went to the wire.A live probe against the OAuth Grok endpoint (2026-08-21) isolates the cause: bare
{type:"web_search"}returns 200,+external_web_accessreturns 400,+search_context_sizereturns 400 — each individually, before inference.The fix is one backfill entry next to the existing registry-only scalars. An explicit saved user value still wins, and only providers whose registry entry declares the capability are affected (today:
xai).Verification
bun run typecheck— exit 0bun run test— 14090 pass / 0 fail across 887 filesbun run privacy:scan— passedbun test --isolate tests/responses-routed-web-search-fields.test.ts— 7 pass / 0 failconfig.json, a multi-stepcodex exectool-use turn (mkdir, write, cat, uname) completed over adapter"openai-responses"withstatus: 200inusage.jsonl. The same turn 400'd on the same host before the fix.The existing tests could not catch this: they hand-build a provider with the flag already set, or call
enrichProviderFromRegistry()directly, so both start downstream of the break. The new tests assert onroutedProviderConfig()output.Checklist
Summary by CodeRabbit
Bug Fixes
Tests