Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions docs-site/src/content/docs/guides/model-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ Routing and catalog visibility are separate controls:
deliberately inert for them.
- `provider.disabled: true` removes that provider from catalog discovery. Explicit
`provider/model` requests fail, and `defaultModel` / `models[]` scans skip it.
- Routed catalog rows are cloned from the Codex-native template, so native-only delivery flags are
stripped during normalization: `supports_websockets`, `supports_reasoning_summaries`, and
`supports_experimental_context`. A routed provider never inherits the experimental-context
contract; inheriting it made Codex compact after nearly every step on long routed threads.
- `providerContextCaps` applies per-provider Codex-visible context caps. `contextCapValue` is the
dashboard default (350,000 by default), but it does nothing by itself until a provider is
present in `providerContextCaps`. Changing the dashboard value updates every enabled cap
Expand Down
7 changes: 7 additions & 0 deletions src/codex/catalog/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,13 @@ export function normalizeRoutedCatalogEntry(
delete entry.multi_agent_reasoning_effort;
delete entry.use_responses_lite;
delete entry.supports_websockets;
// Routed rows cloned from native templates must not inherit OpenAI-only experimental context
// delivery. Codex reads the flag as "this model accepts experimental context history" and drives
// its context-management cadence from it, so a third-party provider that never negotiated it gets
// a compact-after-every-step loop instead (observed on a routed DeepSeek row: 1,600+ compactions
// in a single thread). Nothing re-applies the field from provider metadata during this step, so
// the row leaves this normalization without it.
delete entry.supports_experimental_context;
Comment thread
Mpayro marked this conversation as resolved.
/*
* Tier metadata is stripped from routed rows because a row cloned from a native template
* would otherwise hand a third-party provider OpenAI's tiers.
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e-style/phase100-native-parity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function nativeTemplate(): Record<string, unknown> {
multi_agent_version: "v2",
use_responses_lite: true,
supports_websockets: true,
supports_experimental_context: true,
web_search_tool_type: "text_and_image",
supports_search_tool: true,
supported_reasoning_levels: [
Expand Down Expand Up @@ -88,6 +89,7 @@ describe("Phase 100 Codex-native parity smoke", () => {
expect(routed).not.toHaveProperty("model_messages");
expect(routed).not.toHaveProperty("use_responses_lite");
expect(routed).not.toHaveProperty("supports_websockets");
expect(routed).not.toHaveProperty("supports_experimental_context");

const parsed = parseRequest({
model: "opencode-go/deepseek-v4-flash",
Expand Down
Loading