diff --git a/src/agents/context.test.ts b/src/agents/context.test.ts index ab2381e7555..5e762683ec8 100644 --- a/src/agents/context.test.ts +++ b/src/agents/context.test.ts @@ -57,6 +57,30 @@ describe("applyConfiguredContextWindows", () => { expect(cache.get("anthropic/claude-opus-4-6")).toBe(200_000); }); + it("stores provider-qualified key so config overrides beat qualified discovery entries", () => { + // Scenario from reviewer: discovery emits provider-qualified IDs but config + // uses bare IDs — without the qualified key in cache, resolveContextTokensForModel + // would return the discovered value and bypass the explicit config override. + const cache = new Map(); + // Simulate discovery storing a qualified entry. + cache.set("google-gemini-cli/gemini-3.1-pro-preview", 1_048_576); + // Config override stored under bare key AND qualified key. + applyConfiguredContextWindows({ + cache, + modelsConfig: { + providers: { + "google-gemini-cli": { + models: [{ id: "gemini-3.1-pro-preview", contextWindow: 200_000 }], + }, + }, + }, + }); + + // Both bare and qualified keys must reflect the configured override. + expect(cache.get("gemini-3.1-pro-preview")).toBe(200_000); + expect(cache.get("google-gemini-cli/gemini-3.1-pro-preview")).toBe(200_000); + }); + it("adds config-only model context windows and ignores invalid entries", () => { const cache = new Map(); applyConfiguredContextWindows({ diff --git a/src/agents/context.ts b/src/agents/context.ts index 710a33ecdfe..d05eebb85da 100644 --- a/src/agents/context.ts +++ b/src/agents/context.ts @@ -61,7 +61,7 @@ export function applyConfiguredContextWindows(params: { if (!providers || typeof providers !== "object") { return; } - for (const provider of Object.values(providers)) { + for (const [providerId, provider] of Object.entries(providers)) { if (!Array.isArray(provider?.models)) { continue; } @@ -73,6 +73,12 @@ export function applyConfiguredContextWindows(params: { continue; } params.cache.set(modelId, contextWindow); + // When the model id is bare (no provider prefix), also store under the + // provider-qualified key so that qualified lookups in resolveContextTokensForModel + // respect explicit config overrides over discovered values. + if (!modelId.includes("/")) { + params.cache.set(`${providerId}/${modelId}`, contextWindow); + } } } }