Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6f6ef58
docs: define foreign web-search compatibility contract
AviBackToBlack Sep 14, 2026
d409b1b
docs: record foreign web-search source evidence
AviBackToBlack Sep 14, 2026
63011d7
docs: link foreign web-search research
AviBackToBlack Sep 14, 2026
6033904
docs: summarize v0.3 foreign web-search disposition
AviBackToBlack Sep 14, 2026
6fc3466
docs: keep web-search design gate focused
AviBackToBlack Sep 14, 2026
ac70919
docs: remove duplicate web-search decision summary
AviBackToBlack Sep 14, 2026
ae03c36
docs: temporary web-search gate marker
AviBackToBlack Sep 14, 2026
eeffc5d
docs: remove temporary gate marker
AviBackToBlack Sep 14, 2026
b85c711
docs: preserve web-search gate branch state
AviBackToBlack Sep 14, 2026
232c50b
docs: remove temporary gate marker
AviBackToBlack Sep 14, 2026
4fd1fac
docs: record contract research date
AviBackToBlack Sep 14, 2026
0cb433b
docs: keep web-search gate to contract files
AviBackToBlack Sep 14, 2026
c03c586
chore: keep docs directory
AviBackToBlack Sep 14, 2026
930e53b
chore: temporary marker
AviBackToBlack Sep 14, 2026
e236cfc
chore: remove temporary docs marker
AviBackToBlack Sep 14, 2026
00336b0
chore: remove temporary PR marker
AviBackToBlack Sep 14, 2026
f1aa09f
docs: anchor web-search research to stable Codex ref
AviBackToBlack Sep 14, 2026
f7b15fc
docs: make web-search contract version-aware
AviBackToBlack Sep 14, 2026
a672a32
docs: correct hosted web-search guidance
AviBackToBlack Sep 14, 2026
4d8ef2d
docs: align overrides with web-search contract
AviBackToBlack Sep 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Existing `models = ["..."]` entries are always exact strings; wildcard character

`model_overrides` is keyed by an exact user-facing `model_name`; override keys are never globs. The target must be covered by either `models` or `model_globs`. Overrides operate on aggregated compatibility evidence, not on individual deployments and not on arbitrary Codex catalog fields. Supported fields are the six capability booleans (`supports_vision`, `supports_audio_input`, `supports_function_calling`, `supports_parallel_function_calling`, `supports_web_search`, `supports_reasoning`), `max_input_tokens`, `max_output_tokens`, `supported_openai_params`, and `reasoning_effort_levels`. `max_output_tokens` is currently evidence/audit-only because the generated Codex model schema has no independent output-token-limit field that consumes it; it is retained for explainability and future fields that may depend on that evidence.

An override is an explicit trusted assertion and can replace aggregate `guaranteed`, `denied`, or `unknown` evidence. `explain` keeps the original aggregate state/value beside the configured value and effective state/value. Dependency closure still applies: disabling reasoning disables reasoning transport/efforts, and disabling function calling prevents parallel tool calls. Overrides cannot force exact-template identity or enable foreign-model Codex web search.
An override is an explicit trusted assertion and can replace aggregate `guaranteed`, `denied`, or `unknown` evidence. `explain` keeps the original aggregate state/value beside the configured value and effective state/value. Dependency closure still applies: disabling reasoning disables reasoning transport/efforts, and disabling function calling prevents parallel tool calls. `supports_web_search` overrides remain evidence-only for hosted-search compatibility: they do not control Codex `supports_search_tool`, and the generated model catalog alone does not guarantee hosted web-search enablement or suppression. See [docs/foreign-web-search.md](docs/foreign-web-search.md).

`version = "auto"` runs `codex --version` and fetches the catalog from the corresponding `rust-v<version>` tag in `openai/codex`. This avoids using a `main` catalog whose schema may not match the installed Codex binary.

Expand Down Expand Up @@ -175,11 +175,11 @@ Rows with the same exact raw `model_name` are treated as one LiteLLM routing gro

For an **exact Codex template group**, every deployment must independently resolve unambiguously to the same version-matched Codex template. The Codex entry remains authoritative, while explicit deployment denials can conservatively downgrade capabilities. Unknown evidence alone does not narrow exact-template behavior. A configured override may replace the aggregate compatibility evidence used for those downgrade decisions, but cannot change the proven exact identity or invent Codex-owned fields.

For a **foreign group**, the generated catalog entry describes what is safe for an arbitrary routed request: boolean capabilities require a group guarantee, supported parameter and reasoning sets are intersected, and context/output limits use the safe minimum only when every deployment provides a valid value. Explicit overrides may replace those aggregate evidence values. Foreign web search remains disabled even when the effective web-search evidence is true.
For a **foreign group**, the generated catalog entry describes what is safe for an arbitrary routed request: boolean capabilities require a group guarantee, supported parameter and reasoning sets are intersected, and context/output limits use the safe minimum only when every deployment provides a valid value. Explicit overrides may replace those aggregate evidence values. Web-search evidence is retained for audit/explain but is not mapped to Codex `supports_search_tool` or treated as sufficient proof for hosted-search compatibility; hosted web search also depends on Codex provider/runtime behavior.

## Context-window policy

For an **exact Codex template match**, `context_window` and `max_context_window` remain the Codex values. LiteLLM `max_input_tokens` is treated as validation evidence because the two fields do not have identical semantics. A `max_input_tokens` override likewise changes validation evidence only; it does not replace exact-template Codex context fields.
For an **exact Codex template match**, `context_window` and `max_context_window` remain the Codex values. LiteLLM `max_input_tokens` is treated as validation evidence because the two fields do not have identical semantics. A `max_input_tokens` override likewise changes the LiteLLM validation evidence only; it does not replace the exact template's Codex context fields.

For a **foreign model group**, the generator uses the minimum known LiteLLM `max_input_tokens` across every deployment as the best safe approximation for both context fields. A multi-deployment foreign group with missing or invalid context evidence fails closed rather than advertising a guessed window. An explicit `max_input_tokens` override can supply the trusted effective evidence needed to synthesize that group. A single foreign deployment preserves the v0.2 fallback behavior.

Expand All @@ -196,7 +196,7 @@ For a **foreign model group**, the generator uses the minimum known LiteLLM `max

## Current limitations

- Foreign-model web search remains disabled even when LiteLLM or a configured override advertises web search; Codex search-tool wire semantics need an explicit compatibility rule.
- Foreign hosted web-search compatibility is not inferred from LiteLLM `supports_web_search`. Current Codex hosted search is provider/runtime controlled, while `supports_search_tool` has separate tool-discovery semantics; see [docs/foreign-web-search.md](docs/foreign-web-search.md). The generated model catalog alone does not guarantee hosted-search enablement or suppression.
- Foreign-model context-window mapping is an approximation, as described above.
- `model_overrides` are trusted user assertions; they can deliberately replace conservative aggregate evidence, so incorrect overrides can over-advertise gateway compatibility even though Codex-owned template identity/fields remain protected.
- Hand-authored offline bundle manifests provide digest integrity and one declared Codex identity, but are not signed provenance attestations that the files came from the named Git ref.
Expand Down
60 changes: 60 additions & 0 deletions docs/foreign-web-search-sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Foreign web-search research source index

This companion page records the upstream evidence used by `foreign-web-search.md` so the contract can be revalidated against future Codex/LiteLLM versions without redoing discovery from scratch.

## Evidence scope

The Codex behavior used for the v0.3 decision was verified against **`rust-v0.154.0`**, the latest stable Codex release on 2026-09-14, and then cross-checked against upstream `main` for drift. The contract does not assume that every historical or future Codex ref has identical semantics.

For any generated catalog, the version-matched Codex ref remains authoritative. If a future matched ref changes these semantics, the generator must re-evaluate the mapping rather than inherit this snapshot blindly.

## Codex — version-matched stable evidence (`rust-v0.154.0`)

- Hosted web-search construction and `WebSearchToolType` consumption:
- https://github.com/openai/codex/blob/rust-v0.154.0/codex-rs/core/src/tools/hosted_spec.rs
- Hosted web-search provider/config gating and separate `search_tool_enabled()` path:
- https://github.com/openai/codex/blob/rust-v0.154.0/codex-rs/core/src/tools/spec_plan.rs
- `WebSearchToolType` schema (`text`, `text_and_image`; no disabled variant):
- https://github.com/openai/codex/blob/rust-v0.154.0/codex-rs/protocol/src/openai_models.rs
- Configured-provider capability defaults (`web_search=true` via `ProviderCapabilities::default()`):
- https://github.com/openai/codex/blob/rust-v0.154.0/codex-rs/model-provider/src/provider.rs

The same semantics were still present on upstream `main` when researched on 2026-09-14:

- https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/hosted_spec.rs
- https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/spec_plan.rs
- https://github.com/openai/codex/blob/main/codex-rs/protocol/src/openai_models.rs
- https://github.com/openai/codex/blob/main/codex-rs/model-provider/src/provider.rs
- https://github.com/openai/codex/blob/main/codex-rs/core/tests/suite/web_search.rs

Additional behavioral evidence:

- Custom catalog/tool-search failure showing `supports_search_tool` is about deferred tool discovery, while hosted web search is independent:
- https://github.com/openai/codex/issues/36382
- Provider capability/config limitations relevant to suppression/opt-in:
- https://github.com/openai/codex/issues/21952
- https://github.com/openai/codex/issues/24465
- LiteLLM/custom-provider model discovery context:
- https://github.com/openai/codex/issues/30760
- https://github.com/openai/codex/issues/37122

## LiteLLM

- Mixed-provider routing bug demonstrating that `supports_web_search` metadata does not by itself prove deterministic compatibility for every native search request shape:
- https://github.com/BerriAI/litellm/issues/38982
- Responses/web-search integration gaps and response-shape translation context:
- https://github.com/BerriAI/litellm/issues/26073
- Provider-specific Responses bridge interaction for search:
- https://github.com/BerriAI/litellm/issues/37127

## Revalidation rule

Before changing or applying the contract to a new Codex version, re-check the **version-matched** source used by the generator, not only `main`. In particular verify:

1. whether `WebSearchToolType` gained a disabled/off variant;
2. whether provider capabilities became user-configurable;
3. whether `supports_search_tool` changed meaning;
4. whether hosted search is still gated by provider capability + runtime mode;
5. whether LiteLLM routing guarantees the exact OpenAI Responses hosted-search wire shape across every deployment in the selected model group.

The v0.3 rule is intentionally conservative: without a version-matched proof of semantic equivalence, LiteLLM `supports_web_search` must not be mapped to Codex `supports_search_tool` or treated as sufficient proof for hosted-search enablement.
Loading