Skip to content

feat(web-search): inert backend union + routed web_search field fix (#2188 L6) - #2238

Merged
lidge-jun merged 5 commits into
devfrom
codex/sidecar-backend-union
Aug 21, 2026
Merged

feat(web-search): inert backend union + routed web_search field fix (#2188 L6)#2238
lidge-jun merged 5 commits into
devfrom
codex/sidecar-backend-union

Conversation

@lidge-jun

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

Copy link
Copy Markdown
Owner

Summary

Layer 6 of the #2188 follow-up chain (parent: #2211). Widens the web-search backend union INERTLY and fixes the routed-Grok dispatch killer found while probing:

  • OcxWebSearchSidecarConfig.backend union gains "xai" | "gemini" | "exa" — explicit-only, and planWebSearch fails closed (no plan → normal routed path) for each until its executor layer lands. resolveSidecarBackend stays pure with the unset→openai pin; shouldResolveOpenAiWebSearchSidecar is false for the new ids.
  • exaApiKey config field: PUT set/clear only, never echoed by GET or the PUT response, and redact.ts strips it from logged structures (canary-tested).
  • Claude-code override union widened for web-search only — vision keeps its two-member contract (review-caught: a wider vision id would read as unset and silently activate a backend the operator never chose).
  • fix(responses): Codex attaches external_web_access/search_context_size to its default hosted web_search config; xAI's /v1/responses 400s the whole request on either ("Argument not supported"), killing every routed Grok dispatch with tools enabled. The routed sanitize chain now strips exactly those two proven-fatal fields (live probe: each 400s individually; user_location/filters accepted and kept). Canonical ChatGPT-forward traffic untouched. Wire-level proof: identical body BEFORE 400 → AFTER 200.
  • structure/04 + 05 updated to the new contract.

Design doc: devlog/_plan/260820_sidecar_selection_unification/060_layer6_backend_union.md (rev 2) + 003 research.

Verification

  • bun x tsc --noEmit clean; focused suites green (union 12, routed-fields 2, claude-management 28).
  • Full remote gate on the exact head (lidge): 13779 pass / 15 skip / 0 fail across 872 files (488s).
  • Live probes: xAI reasoning+tools 200, both hosted tools in one request 200, handles+dates 200; BEFORE/AFTER fix 400→200.
  • Independent read-only review: roadmap audited across 3 rounds (7 findings folded); implementation review (terra) found the vision-union High — fixed and re-verified to pass.

Checklist

Summary by CodeRabbit

  • New Features
    • Added support for xAI, Gemini, and Exa web-search backends.
    • Added optional Exa API key configuration with secure write-only handling.
    • Expanded management and CLI settings to accept the new backends.
  • Improvements
    • Web search now defaults explicitly to OpenAI.
    • Vision backend selection behavior is documented more clearly.
    • Requests routed to providers that do not support OpenAI-only search options are adjusted automatically.
  • Documentation
    • Updated configuration and sidecar documentation across supported languages.

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 21, 2026 01:27
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@lidge-jun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f6ecaea7-5052-482b-a4e8-f73a4a71d8b2

📥 Commits

Reviewing files that changed from the base of the PR and between 1e7c45b and 7d015ba.

📒 Files selected for processing (25)
  • docs-site/src/content/docs/fr/reference/configuration/server.md
  • docs-site/src/content/docs/ja/reference/configuration/server.md
  • docs-site/src/content/docs/ko/reference/configuration/server.md
  • docs-site/src/content/docs/reference/configuration/server.md
  • docs-site/src/content/docs/ru/reference/configuration/server.md
  • docs-site/src/content/docs/tr/reference/configuration/server.md
  • docs-site/src/content/docs/zh-cn/reference/configuration/server.md
  • docs-site/src/content/docs/zh-tw/reference/configuration/server.md
  • src/adapters/openai-responses.ts
  • src/cli/agent.ts
  • src/cli/integrations.ts
  • src/lib/redact.ts
  • src/providers/derive.ts
  • src/providers/registry.ts
  • src/server/management/agent-settings-routes.ts
  • src/server/management/config-routes.ts
  • src/types/config.ts
  • src/types/provider.ts
  • src/web-search/index.ts
  • src/web-search/loop.ts
  • structure/04_transports-and-sidecars.md
  • structure/05_gui-and-management-api.md
  • tests/redact.test.ts
  • tests/responses-routed-web-search-fields.test.ts
  • tests/web-search-backend-union.test.ts
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c2c192f1-8080-4469-8d96-f5d35774be0d

📥 Commits

Reviewing files that changed from the base of the PR and between 1e7c45b and 7d015ba.

📒 Files selected for processing (25)
  • docs-site/src/content/docs/fr/reference/configuration/server.md
  • docs-site/src/content/docs/ja/reference/configuration/server.md
  • docs-site/src/content/docs/ko/reference/configuration/server.md
  • docs-site/src/content/docs/reference/configuration/server.md
  • docs-site/src/content/docs/ru/reference/configuration/server.md
  • docs-site/src/content/docs/tr/reference/configuration/server.md
  • docs-site/src/content/docs/zh-cn/reference/configuration/server.md
  • docs-site/src/content/docs/zh-tw/reference/configuration/server.md
  • src/adapters/openai-responses.ts
  • src/cli/agent.ts
  • src/cli/integrations.ts
  • src/lib/redact.ts
  • src/providers/derive.ts
  • src/providers/registry.ts
  • src/server/management/agent-settings-routes.ts
  • src/server/management/config-routes.ts
  • src/types/config.ts
  • src/types/provider.ts
  • src/web-search/index.ts
  • src/web-search/loop.ts
  • structure/04_transports-and-sidecars.md
  • structure/05_gui-and-management-api.md
  • tests/redact.test.ts
  • tests/responses-routed-web-search-fields.test.ts
  • tests/web-search-backend-union.test.ts

📝 Walkthrough

Walkthrough

The change adds xAI, Gemini, and Exa web-search backend identifiers, defaults unset selection to OpenAI, adds Exa API key management, and removes unsupported OpenAI-only search fields from routed xAI requests.

Changes

Web-search backend expansion

Layer / File(s) Summary
Backend contracts and planning
src/types/config.ts, src/web-search/..., src/server/management/..., src/cli/...
The backend union now includes xai, gemini, and exa. Unset selection resolves to openai. Unsupported backends produce no sidecar plan.
Provider capability and request sanitization
src/types/provider.ts, src/providers/..., src/adapters/openai-responses.ts, tests/responses-routed-web-search-fields.test.ts
Provider metadata identifies unsupported OpenAI web-search fields. Routed requests remove those fields for xAI while preserving them for OpenAI.
Management API and secret handling
src/server/management/config-routes.ts, src/lib/redact.ts, tests/redact.test.ts, tests/web-search-backend-union.test.ts
The management API accepts, stores, clears, and omits exaApiKey. Exa key variants are redacted.
Configuration and sidecar documentation
docs-site/src/content/docs/*/reference/configuration/server.md, structure/*.md
Documentation describes the expanded backend set, explicit-only selection, vision backend precedence, and write-only Exa credentials.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant ManagementAPI
  participant Configuration
  participant RoutedProvider
  Operator->>ManagementAPI: Set webSearchSidecar.backend and exaApiKey
  ManagementAPI->>Configuration: Validate and persist settings
  ManagementAPI-->>Operator: Response without exaApiKey
  Configuration->>RoutedProvider: Build selected backend request
  RoutedProvider-->>Configuration: Remove unsupported OpenAI-only fields when required
Loading

Possibly related PRs

  • lidge-jun/opencodex#1890: Both changes expand web-search sidecar backend handling across configuration, validation, planning, and loop types.

Suggested reviewers: luvs01, wibias

✨ 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/sidecar-backend-union

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.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a05f23fa93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/adapters/openai-responses.ts Outdated
Comment thread src/types/config.ts
@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 64 / 80

#2188 L6임. 베이스가 지금 dev가 아니라 codex/sidecar-cli (#2211). L1부터 안 들어가면 리베이스 지옥임. 유니온을 xai|gemini|exa로 넓히되 planWebSearch가 새 id면 무조건 undefined. fail-closed. 지금 dev resolveSidecarBackend (src/web-search/index.ts:104-108)가 이미 unset→openai임. 근데 src/types/config.ts:793-794 주석은 자격 있으면 anthropic이라고 아직 거짓말함. 이 PR이 주석이랑 유니온을 맞춤. 비전 오버라이드는 두 멤버 유지한 거 맞음. 넓은 id를 비전이 unset으로 읽으면 오퍼레이터가 안 고른 백엔드가 켜짐.

exaApiKey는 PUT set/clear. GET은 안 울림. 지금 dev GET /api/sidecar-settings (src/server/management/config-routes.ts:511-522)가 model/backend/streamRoutedModelOutput만 찍는 화이트리스트임. 그 목록에 키 넣지 말 것. redact.ts:3 패턴에 exa[-_]?api[-_]?key 넣은 거 맞음. PUT 응답도 GET이랑 같은 공개 셰이프 유지.

같이 들어 있는 라우티드 web_search 필드 스트립이 더 급함. Codex 기본 툴 설정 external_web_access / search_context_size가 xAI에서 요청 전체 400. 지금 dev 패스스루 체인 (src/adapters/openai-responses.ts:1568-1575)에 그 스트립 없음. user_location/filters는 살림. 캐논 ChatGPT는 안 탐. 방향 맞음. 근데 이 스트립은 #2217이랑 겹침. 저 PR이 이미 external_web_access를 뜯음. L6 스택 기다리면 기본 Grok 첫 턴이 더 죽음. 이 헬퍼는 dev 핫픽스(#2217)로 빼는 게 맞음. 사이드카 유니온이랑 한 PR로 묶지 말 것.

L7 플랜 070_layer7_xai_executor.md가 사이드카에 x_search를 넣으려고 함. #2190 불변식이 호스트 툴은 기존 xAI OAuth 페이지만, #2188이랑 안 섞음. L6 이너트 유니온은 괜찮음. L7에서 x_search를 사이드카 실행기에 넣지 말 것. GUI 셀렉터는 후속. 새 백엔드는 컨피그/CLI 명시만.

src/types/config.ts를 직접 넓힘. 스플릿 캠페인이 이 파일을 삼키면 리베이스하지 말고 닫고 다시 짜라. 지금은 사이드카 스택이 그 파일을 이미 만지고 있어서 L1→L6 순서가 우선임. 닫을 중복 아님. #2217/#2227 modelWireDefaults.wire 안 건드림. 지금 HEAD 78f1942a0 위에 바로 머지하지 말 것. 부모 #2211 먼저.

해결방안: L1-L5 먼저 dev 머지 후 리타깃. web_search 필드 스트립은 #2217 쪽으로 옮기거나 dev 단독 PR로 빼라. 새 id는 실행기 전까지 plan 없음 유지. 비전 유니온 넓히지 말 것. GET에 exaApiKey 넣지 말 것. L7 x_search#2190 페이지에만.

이 댓글은 grok-bot이 작성했습니다

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes on exact head a05f23fa93e434c5a4ddee15b8a4bc976ddeb6d4.

The stacked direction is sound, but three blockers remain before this layer can be accepted:

  1. stripOpenAiOnlyWebSearchFields is called for every non-ChatGPT-forward Responses provider, not specifically xAI. I reproduced this with an official OpenAI API-key provider at https://api.openai.com/v1: an input tool carrying external_web_access: false and search_context_size: "low" reached the final wire body with both fields removed. Gate this rewrite on an xAI-specific provider identity/capability and add a buildRequest regression proving official OpenAI API-key traffic retains both fields.

  2. The public contract now accepts xai, gemini, and exa, plus the write-only exaApiKey, but the English configuration reference and CLI help still advertise only the old backend pair and do not explain that the new arms are explicit-only/inert. Update the canonical docs/help and keep translated accepted-value lists consistent.

  3. exaApiKey was added only to SENSITIVE_KEY_PATTERN. The shared string redactor still leaves all of these unchanged:

  • {"exaApiKey":"exa-canary-1234567890"}
  • exaApiKey: exa-canary-1234567890
  • exaApiKey=exa-canary-1234567890&model=x

Add the label to the shared colon/query/JSON string-redaction grammar and cover all three canaries in tests/redact.test.ts. The structured redactSecrets test is useful but does not exercise the error/log string path.

The focused exact-head suites pass 55/55, which confirms the current tests do not catch these boundaries. Please keep this PR stacked on codex/sidecar-cli; it should not be merged directly to dev.

lidge-jun added a commit that referenced this pull request Aug 21, 2026
Split the opt-in DTO into a write boolean vs read tri-state; record the concrete #2238 (3) and #2242 (5) review blockers in doc 120; recast doc 150 as the final aggregate gate with the full GUI/i18n/docs chain; replace temporal API-key rows with exact wire+tier assertions; state the explicit wp9->wp8->wp11->wp10 execution sequence.
@lidge-jun

Copy link
Copy Markdown
Owner Author

All three blockers addressed in 19376f7: (1) the strip now activates only on an explicit provider capability denial — supportsOpenAiWebSearchToolFields: false, declared by the xAI registry entry — so official OpenAI API-key traffic and unclassified gateways retain external_web_access/search_context_size (buildRequest regression covers both directions, observed red before the fix); (2) English configuration reference + CLI help document the widened backend union (openai|anthropic|xai|gemini|exa, explicit-only arms, write-only exaApiKey) with fr/ja/ko/ru/tr/zh-cn/zh-tw kept consistent; (3) exaApiKey added to the shared colon/query/JSON string-redaction grammar with all three canaries in tests/redact.test.ts (JSON canary also observed red pre-fix). Fresh local: 46/46 on the two changed suites, adapter suites 80/0, tsc clean, privacy:scan pass, docs build 393 pages. Ready for re-review.

@lidge-jun
lidge-jun requested a review from Ingwannu August 21, 2026 03:15

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on exact head 19376f73732578abd9fdc29305c9c91f9bf47698.

The reviewed blockers are resolved. Stripping of external_web_access and search_context_size now requires explicit provider capability denial, so official OpenAI API-key and unclassified Responses routes retain the caller fields while xAI removes the two proven-incompatible fields. The widened backend union and write-only exaApiKey contract are documented across locales and CLI help, and exaApiKey is covered by string redaction as well as structural redaction.

Independent local verification: 67 focused tests passed, bun run typecheck and bun run privacy:scan passed, and the docs site built all 393 pages. Exact-head required CI and React Doctor are green. This remains a stacked PR; merge it only in the intended stack order after its base layer is integrated.

The config union admits the three probed backends so settings can carry
them, but planWebSearch fails closed for each until its executor layer
lands — no plan means the request takes the normal routed path.
resolveSidecarBackend stays explicit-only with the unset->openai pin.
Both management routes validate the widened union; exaApiKey persists
write/clear-only, never echoed, and redact.ts strips it from logged
structures. Structure docs updated to the new contract.
The shared validation loop admitted all five ids for the vision override
too; the vision resolver reads a wide id as unset and silently activates
a backend the operator never chose. Vision keeps its two-member
contract, the web-search override type widens honestly, and regressions
pin both directions.
Codex attaches its default hosted web_search config to subagent turns;
xAI's /v1/responses rejects the whole request on external_web_access
and search_context_size (Argument not supported), killing every routed
Grok dispatch with tools enabled. The routed sanitize chain now drops
exactly those two proven-fatal fields — user_location and filters pass
through, and canonical ChatGPT-forward traffic is untouched.
Gate xAI-only Responses web_search field stripping through registry-enriched capability metadata so official OpenAI API-key requests preserve external_web_access and search_context_size. Add buildRequest regressions for both providers.\n\nAdvertise the five-value web-search backend union in agent and Claude CLI usage, document explicit-only xAI/Gemini/Exa behavior and write-only exaApiKey, and synchronize localized accepted-value tables.\n\nExtend shared string-framing redaction for exaApiKey and cover JSON, colon, and query canaries.\n\nEvidence: 80 adapter tests, 42 redaction tests, 37 registry tests, 47 CLI tests; tsc, privacy scan, and 393-page docs build green.
@lidge-jun
lidge-jun force-pushed the codex/sidecar-backend-union branch from d9a1fbc to 7d015ba Compare August 21, 2026 03:32
@lidge-jun
lidge-jun changed the base branch from codex/sidecar-cli to dev August 21, 2026 03:32
@lidge-jun
lidge-jun merged commit 29ce3da into dev Aug 21, 2026
4 of 5 checks passed
lidge-jun added a commit that referenced this pull request Aug 21, 2026
…er rebase

Cross-layer reconciliation: #2209 introduced the (backend, model) pair contract typed as openai|anthropic; #2238 widened the configured union to five backends. The options module now re-exports WebSearchBackendId and passes config into isActive, so inert arms simply never produce rows. tsc clean; 48/0 across the three web-search suites.
lidge-jun added a commit that referenced this pull request Aug 21, 2026
…2242)

* feat(web-search): xai executor with opt-in x_search (#2188 L7)

runXaiWebSearch POSTs the pinned api.x.ai Responses endpoint with the
stored Grok OAuth credential, hosted web_search (+ opt-in x_search with
doc-validated handle/date limits), and reduces the SSE stream to
text + deduped sources from url_citation annotations unioned with
web_search_call action.sources. custom_tool_call items and skeleton
action are tolerated per live captures. planWebSearch's xai arm goes
live fail-closed; the loop dispatches it without touching forward
headers; the registry activates the backend on OAuth presence; PUT
validates the xSearch block before persisting.

* fix(web-search): pin the xai origin exactly, fail the loop arm closed, round-trip xSearch

Origin pinning by prefix admitted https://api.x.ai.evil — parse and
compare url.origin, falling back to the canonical endpoint (Critical).
A missing xaiSidecar on the xai loop arm now yields an error outcome
instead of falling through to the forward-header OpenAI executor
(High). GET and the PUT response now carry the persisted xSearch block
so a dashboard reload cannot lose visible configuration (High). Tests:
lookalike-origin bearer containment, xSearch 400/round-trip/clear.

* test(web-search): loop-level regression for the xai fail-closed arm

* fix(web-search): close xai executor review blockers

Attach abort-driven body cancellation immediately after the xAI fetch, cancel oversized SSE readers upstream, and cover transport release.

Stage and validate complete web-search management candidates before commit; reject malformed xSearch types without partial mutation or broadened searches.

Document the live Grok OAuth/x_search backend across canonical docs, locales, type comments, and structure sources. Evidence: 47 focused tests pass; bun x tsc --noEmit; docs Astro build 393 pages.

* fix(web-search): reject unknown xSearch fields

* fix(web-search): unify WebSearchBackend with the five-value union after rebase

Cross-layer reconciliation: #2209 introduced the (backend, model) pair contract typed as openai|anthropic; #2238 widened the configured union to five backends. The options module now re-exports WebSearchBackendId and passes config into isActive, so inert arms simply never produce rows. tsc clean; 48/0 across the three web-search suites.
lidge-jun added a commit that referenced this pull request Aug 21, 2026
Split the opt-in DTO into a write boolean vs read tri-state; record the concrete #2238 (3) and #2242 (5) review blockers in doc 120; recast doc 150 as the final aggregate gate with the full GUI/i18n/docs chain; replace temporal API-key rows with exact wire+tier assertions; state the explicit wp9->wp8->wp11->wp10 execution sequence.
lidge-jun added a commit that referenced this pull request Aug 21, 2026
…#2245)

* feat(web-search): exa executor and the non-LLM search lane (#2188 L9)

runExaWebSearch POSTs api.exa.ai/search with the operator key and maps
ranked results to a digest the routed model synthesizes from. The key
never rides the SidecarPlan — core.ts reads it from config at unpack
time — and the executor scrubs the literal key from every error string
(pattern-based redaction cannot know an arbitrary operator key;
canary-tested). Plan, loop, and registry arms fail closed without the
key. docs-site gains the explicit-only backend table.

* fix(web-search): scrub the exa key before truncating error bodies

Reviewer blocker (L9 round 2): error(t.slice(0,200)) truncated before the literal-key scrub, so a key straddling the 200-char boundary left an unscrubbable prefix in the returned tool error. Scrub first, then slice. Adds truncation-boundary and fetch-rejection canaries; 9/9 focused tests, tsc and privacy:scan green.

* docs(devlog): integration merge-train roadmap 100-150 (chat default, global order, opt-in switch)

Amends the 260820 unit with the audited (3-round sol-medium, round-3 PASS) roadmap: 100 chat-default regression as an atomic #2227+tier-policy unit with a 5-row regression matrix and the E2E reasoning-streaming proof; 110 global cross-train merge order and 21-PR triage matrix (#2072 deferred, #2217 RESHAPE); 120 sidecar L1-L9 merge execution with the fresh blocker inventory; 130 atomic xai Responses opt-in switch (single provider id, auth-mode-scoped sections, virtual PATCH field); 140 release prep; 150 blocking lidge final gate. DeepSeek explicitly out of scope per user decision.

* docs(devlog): fold C-gate blockers into roadmap 100-150

Split the opt-in DTO into a write boolean vs read tri-state; record the concrete #2238 (3) and #2242 (5) review blockers in doc 120; recast doc 150 as the final aggregate gate with the full GUI/i18n/docs chain; replace temporal API-key rows with exact wire+tier assertions; state the explicit wp9->wp8->wp11->wp10 execution sequence.

* docs(devlog): doc 100 API-key opt-in row preserves current tier forwarding

C-gate round 2: current dev forwards caller service_tier verbatim on the API-key + explicit openai-responses route (fastPolicyForModel proof). The tier drop is an OAuth-route policy only; the API-key row now states preserve-current semantics, consistent with doc 130.

* docs(devlog): wp9 execution record — all six chain blockers resolved and pushed
lidge-jun added a commit that referenced this pull request Aug 21, 2026
…only table (#2262)

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants