diff --git a/src/providers/registry.ts b/src/providers/registry.ts index 2380699acb4..bbd74a80b0b 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -1814,6 +1814,9 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ }, modelContextWindows: { "kimi-k3": KIMI_K3_STANDARD_CONTEXT_WINDOW, + // Zen Go discovers only the gateway id, so carry DeepSeek's official 1M V4.1 + // window here or Codex falls back to its conservative 128k routed-model default. + "deepseek-v4.1-flash": 1_048_576, // The DeepSeek vision preview id is metadata-only here: the Go roster is // discovered live, so it applies the moment the gateway serves the id. [DEEPSEEK_VISION_PREVIEW_MODEL]: 1_048_576, diff --git a/structure/providers/xai-grok.md b/structure/providers/xai-grok.md index 5f4217b0934..5f707078432 100644 --- a/structure/providers/xai-grok.md +++ b/structure/providers/xai-grok.md @@ -68,4 +68,8 @@ privately to final dispatch; preliminary route selection does not inject Go-only Devin CLI credential path composition in `src/oauth/devin-cli.ts` follows the selected platform: Windows uses Win32 APPDATA paths, other platforms use POSIX XDG-data paths. The explicit absolute override remains verbatim; credential parsing and login behavior are unchanged. +Provider-scoped catalog hints remain isolated by provider in `src/providers/registry.ts`. The +OpenCode Go `deepseek-v4.1-flash` 1,048,576-token context hint does not change xAI model metadata or +transport behavior. + Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](../catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary. diff --git a/structure/runtime.md b/structure/runtime.md index ae3cc34bbbd..4a69aca17da 100644 --- a/structure/runtime.md +++ b/structure/runtime.md @@ -173,6 +173,11 @@ OAuth presets resolve discovery against the same canonical registry transport as before any adapter-specific transport override, so a stale configured `baseUrl` cannot receive an OAuth bearer token. +Provider-scoped capability hints remain authoritative when discovery returns an id without +capabilities. In particular, `src/providers/registry.ts` assigns OpenCode Go's live +`deepseek-v4.1-flash` route the official 1,048,576-token window instead of the conservative 128k +routed-model fallback. + The BigModel Coding Plan Responses preset uses the separately documented `https://open.bigmodel.cn/api/v1` transport and a static catalog. Its provider row disables live discovery: a local Codex `models.json` example does not establish an diff --git a/structure/subagents.md b/structure/subagents.md index 24d37af883f..03f82135357 100644 --- a/structure/subagents.md +++ b/structure/subagents.md @@ -89,8 +89,9 @@ ordering behavior. This does not change the separate `opencodex_spawn_priority` Retained rows recompute their natural ranks from the current featured roster and account-selector stride before display order is applied, so a discovery outage cannot preserve an obsolete featured or picker rank. Canonical `opencode-go` rows retain their configured reasoning ladder -both when generated and when merged from retained catalog state; synthetic max/ultra choices -are not added to that provider's declared ladder. +and provider-scoped context metadata both when generated and when merged from retained catalog +state; `deepseek-v4.1-flash` therefore keeps its 1,048,576-token window, while synthetic max/ultra +choices are not added to that provider's declared ladder. Full derivation with per-line citations: `devlog/_plan/260816_codexrs_multiagent_v2_and_history_perf/013_five_cap_v1_vs_v2.md`. diff --git a/structure/transports/inventory.md b/structure/transports/inventory.md index 7a7d2f9b4d5..1b183dcebd9 100644 --- a/structure/transports/inventory.md +++ b/structure/transports/inventory.md @@ -23,7 +23,7 @@ surface is listed here so a maintainer can find the owner without grepping: | OAuth account failover | `src/oauth/generic-account-failover.ts`, `src/oauth/anthropic-routing.ts` | Reactive pre-output 429 recovery is presence-driven with 2+ eligible accounts. Pool and `oauthAccountFailover` flags govern proactive routing, not the reactive retry: a disabled Anthropic pool recovers through quota ordering rather than its dormant strategy, and a per-provider `enabled` beats the global default in either direction. | | OAuth login callback (inbound) | `src/oauth/callback-server.ts` | Every response, including non-callback 404s, closes its connection so a pooled socket cannot deliver a later login to a retired flow on the same callback port. | | Alibaba regions | `src/providers/alibaba-region-backup.ts`, `src/providers/alibaba-region-migration.ts`, `src/providers/alibaba-region-startup.ts` | Region migration backs up before rewriting and is idempotent across restarts. | -| Discovery and quota | `src/providers/model-discovery.ts`, `src/providers/quota.ts` | Discovery rejects a response over 4 MiB or past 2,000 raw rows before caching it. | +| Discovery and quota | `src/providers/model-discovery.ts`, `src/providers/quota.ts`, `src/providers/registry.ts` | Discovery rejects a response over 4 MiB or past 2,000 raw rows before caching it. Provider-scoped hints fill capabilities omitted by live rosters; OpenCode Go's `deepseek-v4.1-flash` keeps its 1,048,576-token context window. | > Decision record: [ADR-0072](../decisions/ADR-0072-transport-inventory.md) diff --git a/tests/codex-integration/codex-catalog.test.ts b/tests/codex-integration/codex-catalog.test.ts index 794a92bd50b..907531c47de 100644 --- a/tests/codex-integration/codex-catalog.test.ts +++ b/tests/codex-integration/codex-catalog.test.ts @@ -5662,6 +5662,21 @@ describe("Codex catalog routed normalization", () => { } }); + test("opencode-go DeepSeek V4.1 live rows inherit the official 1M context window", () => { + const provider = providerConfigSeed(PROVIDER_REGISTRY.find(entry => entry.id === "opencode-go")!); + const model = applyProviderConfigHints( + "opencode-go", + provider, + { provider: "opencode-go", id: "deepseek-v4.1-flash" }, + ); + const entries = buildCatalogEntries(nativeTemplate(), [], [model]); + const routed = entries.find(entry => entry.slug === "opencode-go/deepseek-v4.1-flash"); + + expect(routed?.context_window).toBe(1_048_576); + expect(routed?.max_context_window).toBe(1_048_576); + expect(routed?.auto_compact_token_limit).toBe(943_718); + }); + test("opencode-go catalog sync appends official rows missing from /v1/models", () => { const models = augmentRoutedModelsWithMetadata( [{ provider: "opencode-go", id: "glm-5.2" }], diff --git a/tests/providers/provider-registry-parity.test.ts b/tests/providers/provider-registry-parity.test.ts index bfe4532edb0..d33d10f4c54 100644 --- a/tests/providers/provider-registry-parity.test.ts +++ b/tests/providers/provider-registry-parity.test.ts @@ -120,6 +120,7 @@ describe("provider registry parity", () => { expect(zenGo?.preserveReasoningContentModels).toContain("deepseek-v4.1-flash"); expect(zenGo?.noVisionModels).toContain("deepseek-v4.1-flash"); expect(Object.keys(zenGo?.modelReasoningEfforts ?? {})).toContain("deepseek-v4.1-flash"); + expect(zenGo?.modelContextWindows?.["deepseek-v4.1-flash"]).toBe(1_048_576); // Negatives: neither spelling crosses into the other side. expect(JSON.stringify(nativeDeepseek)).not.toContain("deepseek-v4.1-flash");