@@ -195,30 +195,33 @@ describe("lookupContextTokens", () => {
195195 expect ( result ) . toBe ( 200_000 ) ;
196196 } ) ;
197197
198- it ( "resolveContextTokensForModel: bare key wins over qualified; OpenRouter raw entry not shadowed by Google config" , async ( ) => {
199- // applyConfiguredContextWindows writes "gemini-2.5-pro" → 2M (bare key, Google config).
200- // Discovery writes "google/gemini-2.5-pro" → 999k (OpenRouter raw qualified entry).
201- // Lookup order: bare first → finds 2M immediately, never reaching the
202- // OpenRouter raw "google/gemini-2.5-pro" qualified key.
203- mockDiscoveryDeps ( [ { id : "google/gemini-2.5-pro" , contextWindow : 999_000 } ] , {
204- google : {
205- models : [ { id : "gemini-2.5-pro" , contextWindow : 2_000_000 } ] ,
198+ it ( "resolveContextTokensForModel: config direct scan prevents OpenRouter qualified key collision for Google provider" , async ( ) => {
199+ // When provider is explicitly "google" and cfg has a Google contextWindow
200+ // override, the config direct scan returns it before any cache lookup —
201+ // so the OpenRouter raw "google/gemini-2.5-pro" qualified entry is never hit.
202+ // Real callers (status.summary.ts) always pass cfg when provider is explicit.
203+ mockDiscoveryDeps ( [ { id : "google/gemini-2.5-pro" , contextWindow : 999_000 } ] ) ;
204+
205+ const cfg = {
206+ models : {
207+ providers : {
208+ google : { models : [ { id : "gemini-2.5-pro" , contextWindow : 2_000_000 } ] } ,
209+ } ,
206210 } ,
207- } ) ;
211+ } ;
208212
209213 const { resolveContextTokensForModel } = await import ( "./context.js" ) ;
210214 await new Promise ( ( r ) => setTimeout ( r , 0 ) ) ;
211215
212- // Google provider: bare key "gemini-2.5-pro" → 2M (config-written) is found
213- // first; OpenRouter's "google/gemini-2.5-pro" qualified entry is never hit.
216+ // Google with explicit cfg: config direct scan wins before any cache lookup.
214217 const googleResult = resolveContextTokensForModel ( {
218+ cfg : cfg as never ,
215219 provider : "google" ,
216220 model : "gemini-2.5-pro" ,
217221 } ) ;
218222 expect ( googleResult ) . toBe ( 2_000_000 ) ;
219223
220- // OpenRouter provider with slash model id: bare lookup "google/gemini-2.5-pro"
221- // → 999k (OpenRouter raw discovery entry, still intact).
224+ // OpenRouter provider with slash model id: bare lookup finds the raw entry.
222225 const openrouterResult = resolveContextTokensForModel ( {
223226 provider : "openrouter" ,
224227 model : "google/gemini-2.5-pro" ,
@@ -297,4 +300,27 @@ describe("lookupContextTokens", () => {
297300 } ) ;
298301 expect ( explicitResult ) . toBe ( 2_000_000 ) ;
299302 } ) ;
303+
304+ it ( "resolveContextTokensForModel: qualified key beats bare min when provider is explicit (original #35976 fix)" , async ( ) => {
305+ // Regression: when both "gemini-3.1-pro-preview" (bare, min=128k) AND
306+ // "google-gemini-cli/gemini-3.1-pro-preview" (qualified, 1M) are in cache,
307+ // an explicit-provider call must return the provider-specific qualified value,
308+ // not the collided bare minimum.
309+ mockDiscoveryDeps ( [
310+ { id : "github-copilot/gemini-3.1-pro-preview" , contextWindow : 128_000 } ,
311+ { id : "gemini-3.1-pro-preview" , contextWindow : 128_000 } ,
312+ { id : "google-gemini-cli/gemini-3.1-pro-preview" , contextWindow : 1_048_576 } ,
313+ ] ) ;
314+
315+ const { resolveContextTokensForModel } = await import ( "./context.js" ) ;
316+ await new Promise ( ( r ) => setTimeout ( r , 0 ) ) ;
317+
318+ // Qualified "google-gemini-cli/gemini-3.1-pro-preview" → 1M wins over
319+ // bare "gemini-3.1-pro-preview" → 128k (cross-provider minimum).
320+ const result = resolveContextTokensForModel ( {
321+ provider : "google-gemini-cli" ,
322+ model : "gemini-3.1-pro-preview" ,
323+ } ) ;
324+ expect ( result ) . toBe ( 1_048_576 ) ;
325+ } ) ;
300326} ) ;
0 commit comments