@@ -12,8 +12,9 @@ import {
1212 ProviderOptions ,
1313} from '../types.js' ;
1414
15- // Define model context window sizes for Anthropic models
16- const ANTHROPIC_MODEL_LIMITS : Record < string , number > = {
15+ // Fallback model context window sizes for Anthropic models
16+ // Used only if models.list() call fails or returns incomplete data
17+ const ANTHROPIC_MODEL_LIMITS_FALLBACK : Record < string , number > = {
1718 default : 200000 ,
1819 'claude-3-7-sonnet-20250219' : 200000 ,
1920 'claude-3-7-sonnet-latest' : 200000 ,
@@ -96,15 +97,27 @@ function addCacheControlToMessages(
9697 } ) ;
9798}
9899
99- function tokenUsageFromMessage ( message : Anthropic . Message , model : string ) {
100+ // Cache for model context window sizes
101+ const modelContextWindowCache : Record < string , number > = { } ;
102+
103+ function tokenUsageFromMessage (
104+ message : Anthropic . Message ,
105+ model : string ,
106+ contextWindow ?: number ,
107+ ) {
100108 const usage = new TokenUsage ( ) ;
101109 usage . input = message . usage . input_tokens ;
102110 usage . cacheWrites = message . usage . cache_creation_input_tokens ?? 0 ;
103111 usage . cacheReads = message . usage . cache_read_input_tokens ?? 0 ;
104112 usage . output = message . usage . output_tokens ;
105113
106114 const totalTokens = usage . input + usage . output ;
107- const maxTokens = ANTHROPIC_MODEL_LIMITS [ model ] || 100000 ; // Default fallback
115+ // Use provided context window, or fallback to cached value, or use hardcoded fallback
116+ const maxTokens =
117+ contextWindow ||
118+ modelContextWindowCache [ model ] ||
119+ ANTHROPIC_MODEL_LIMITS_FALLBACK [ model ] ||
120+ ANTHROPIC_MODEL_LIMITS_FALLBACK . default ;
108121
109122 return {
110123 usage,
@@ -123,6 +136,7 @@ export class AnthropicProvider implements LLMProvider {
123136 private client : Anthropic ;
124137 private apiKey : string ;
125138 private baseUrl ?: string ;
139+ private modelContextWindow ?: number ;
126140
127141 constructor ( model : string , options : AnthropicOptions = { } ) {
128142 this . model = model ;
@@ -138,6 +152,32 @@ export class AnthropicProvider implements LLMProvider {
138152 apiKey : this . apiKey ,
139153 ...( this . baseUrl && { baseURL : this . baseUrl } ) ,
140154 } ) ;
155+
156+ // Initialize model context window detection
157+ this . initializeModelContextWindow ( ) ;
158+ }
159+
160+ /**
161+ * Fetches the model context window size from the Anthropic API
162+ */
163+ private async initializeModelContextWindow ( ) : Promise < void > {
164+ try {
165+ const response = await this . client . models . list ( ) ;
166+ const model = response . data . find ( ( m ) => m . id === this . model ) ;
167+
168+ // Using type assertion to access context_window property
169+ // The Anthropic API returns context_window but it may not be in the TypeScript definitions
170+ if ( model && 'context_window' in model ) {
171+ this . modelContextWindow = ( model as any ) . context_window ;
172+ // Cache the result for future use
173+ modelContextWindowCache [ this . model ] = ( model as any ) . context_window ;
174+ }
175+ } catch ( error ) {
176+ console . warn (
177+ `Failed to fetch model context window for ${ this . model } : ${ ( error as Error ) . message } ` ,
178+ ) ;
179+ // Will fall back to hardcoded limits
180+ }
141181 }
142182
143183 /**
@@ -198,7 +238,11 @@ export class AnthropicProvider implements LLMProvider {
198238 } ;
199239 } ) ;
200240
201- const tokenInfo = tokenUsageFromMessage ( response , this . model ) ;
241+ const tokenInfo = tokenUsageFromMessage (
242+ response ,
243+ this . model ,
244+ this . modelContextWindow ,
245+ ) ;
202246
203247 return {
204248 text : content ,
0 commit comments