@@ -23,10 +23,26 @@ export function contextTokensFromUsage(usage: TokenUsage | undefined): number {
2323// Exact model-id match wins over the family heuristics below.
2424let contextWindowRegistry : Record < string , number > = { } ;
2525
26+ // Provider-level overrides for local models set via /context-size.
27+ // Takes precedence over the model registry and heuristics.
28+ let providerContextOverrides : Record < string , number | undefined > = { } ;
29+
2630export function setModelContextWindows ( windows : Record < string , number > | undefined ) : void {
2731 contextWindowRegistry = windows ?? { } ;
2832}
2933
34+ export function setProviderContextOverrides ( overrides : Record < string , number > | undefined ) : void {
35+ providerContextOverrides = overrides ?? { } ;
36+ }
37+
38+ export function setProviderContextWindow ( provider : string , tokens ?: number ) : void {
39+ if ( tokens === undefined ) {
40+ providerContextOverrides [ provider ] = undefined ;
41+ } else {
42+ providerContextOverrides [ provider ] = tokens ;
43+ }
44+ }
45+
3046function heuristicWindow ( model : string ) : number {
3147 const m = model . toLowerCase ( ) ;
3248 if ( m . includes ( "gpt-5" ) || m . includes ( "codex" ) ) return 400_000 ;
@@ -45,6 +61,12 @@ function heuristicWindow(model: string): number {
4561// full identity as given, the bare model id, and `canonicalProvider/model` —
4662// so a custom-named provider still exact-matches the registry instead of
4763// silently missing and falling through to the heuristic.
64+ function providerFromModel ( model : string ) : string | undefined {
65+ const colonIndex = model . indexOf ( ":" ) ;
66+ if ( colonIndex === - 1 ) return undefined ;
67+ return model . slice ( 0 , colonIndex ) ;
68+ }
69+
4870function lookupCandidates ( model : string ) : string [ ] {
4971 const colonIndex = model . indexOf ( ":" ) ;
5072 if ( colonIndex === - 1 ) return [ model ] ;
@@ -59,12 +81,20 @@ function lookupCandidates(model: string): string[] {
5981/** True when the registry has an entry for `model` under any known form, so a
6082 * caller can distinguish a confident lookup from the heuristic fallback. */
6183export function hasContextWindowFor ( model : string ) : boolean {
84+ const provider = providerFromModel ( model ) ;
85+ if ( provider !== undefined && providerContextOverrides [ provider ] !== undefined ) {
86+ return true ;
87+ }
6288 return lookupCandidates ( model ) . some (
6389 ( candidate ) => contextWindowRegistry [ candidate ] !== undefined ,
6490 ) ;
6591}
6692
6793export function contextWindowFor ( model : string ) : number {
94+ const provider = providerFromModel ( model ) ;
95+ if ( provider !== undefined && providerContextOverrides [ provider ] !== undefined ) {
96+ return providerContextOverrides [ provider ] ;
97+ }
6898 for ( const candidate of lookupCandidates ( model ) ) {
6999 const exact = contextWindowRegistry [ candidate ] ;
70100 if ( exact !== undefined ) return exact ;
0 commit comments