Skip to content

fix(responses): capability-gate external_web_access in the canonical-only table - #2262

Merged
lidge-jun merged 1 commit into
devfrom
codex/capability-gated-ewa
Aug 21, 2026
Merged

fix(responses): capability-gate external_web_access in the canonical-only table#2262
lidge-jun merged 1 commit into
devfrom
codex/capability-gated-ewa

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

Post-merge reconciliation between #2238 and #2258: the consolidated series' unconditional CANONICAL_ONLY_TOOL_FIELDS strip removed external_web_access from official OpenAI API-key traffic, breaking #2238's capability contract (caught by the lidge full-suite lagging gate: 1 fail / 14025).

  • external_web_access in the declarative table is now capabilityGated: true: stripped only when the provider declares supportsOpenAiWebSearchToolFields: false (the xAI registry entry does), matching stripOpenAiOnlyWebSearchFields ownership.
  • defer_loading stays unconditional (private on any tool for every noncanonical gateway).
  • The two passthrough tests using bare xAI configs now declare the registry capability explicitly — the strip is capability-driven, not hostname-driven.

Verification

  • 387/0 across six suites: routed web-search fields (incl. the OpenAI retain regression), namespace compat, passthrough sanitization, redact, fastwire policy, chat reasoning-streaming E2E.
  • bun x tsc --noEmit clean.

Checklist

  • Targets dev
  • Regression that caught this stays red-provable

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility when sending web-search tool settings to providers with different capability support.
    • Preserved supported web-search fields while removing unsupported settings to prevent request errors.
  • Tests
    • Updated coverage to verify correct handling of provider-specific web-search capabilities.

…only table

The #2258 series unconditional strip collided with the #2238 capability contract: official OpenAI API-key traffic lost external_web_access (lidge full suite 1/14025 fail). The table row is now capabilityGated, active only when supportsOpenAiWebSearchToolFields === false; defer_loading stays unconditional. 387/0 across six suites.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 21, 2026 04:29
@lidge-jun lidge-jun added the bug Something isn't working label Aug 21, 2026
@lidge-jun
lidge-jun merged commit 2b988b3 into dev Aug 21, 2026
5 of 6 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9b42a8d9-da89-4376-a8bc-fca22562f06a

📥 Commits

Reviewing files that changed from the base of the PR and between 6c928aa and 097b126.

📒 Files selected for processing (2)
  • src/adapters/openai-responses.ts
  • tests/openai-responses-passthrough.test.ts

📝 Walkthrough

Walkthrough

The request sanitizer now preserves external_web_access when supported and removes it when unsupported. It always removes defer_loading. The request builder passes the provider capability flag to the sanitizer, and xAI passthrough tests cover both fields.

Changes

Tool field sanitization

Layer / File(s) Summary
Sanitizer capability gating
src/adapters/openai-responses.ts
At lines 169–191, canonical-only tool fields include capability metadata. The sanitizer removes gated fields only when includeCapabilityGated is enabled.
Request pipeline integration and passthrough tests
src/adapters/openai-responses.ts, tests/openai-responses-passthrough.test.ts
At line 1730, the request pipeline enables gated stripping only when supportsOpenAiWebSearchToolFields is explicitly false. Tests at lines 979–988 and 1039–1046 configure xAI with that capability disabled.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: ingwannu

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/capability-gated-ewa

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

olddonkey pushed a commit to olddonkey/opencodex that referenced this pull request Aug 21, 2026
…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 lidge-jun#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant