(params: {
messages: TokenCountRequest['messages']
system: string | undefined
model: string | undefined
tools: TokenCountRequest['tools']
fetch: typeof globalThis.fetch
logger: Logger
})
| 291 | } |
| 292 | |
| 293 | async function countTokensViaAnthropic(params: { |
| 294 | messages: TokenCountRequest['messages'] |
| 295 | system: string | undefined |
| 296 | model: string | undefined |
| 297 | tools: TokenCountRequest['tools'] |
| 298 | fetch: typeof globalThis.fetch |
| 299 | logger: Logger |
| 300 | }): Promise<number> { |
| 301 | const { messages, system, model, tools, fetch, logger } = params |
| 302 | |
| 303 | // Convert messages to Anthropic format |
| 304 | const anthropicMessages = convertToAnthropicMessages(messages) |
| 305 | |
| 306 | // Convert model from OpenRouter format (e.g. "anthropic/claude-opus-4.5") to Anthropic format (e.g. "claude-opus-4-5-20251101") |
| 307 | // For non-Anthropic models, use the default Anthropic model for token counting |
| 308 | const isNonAnthropicModel = !model || !isClaudeModel(model) |
| 309 | const anthropicModelId = isNonAnthropicModel |
| 310 | ? DEFAULT_ANTHROPIC_MODEL |
| 311 | : toAnthropicModelId(model) |
| 312 | |
| 313 | // Use the count_tokens endpoint (beta) or make a minimal request |
| 314 | const response = await fetch( |
| 315 | 'https://api.anthropic.com/v1/messages/count_tokens', |
| 316 | { |
| 317 | method: 'POST', |
| 318 | headers: { |
| 319 | 'x-api-key': env.ANTHROPIC_API_KEY, |
| 320 | 'anthropic-version': '2023-06-01', |
| 321 | 'anthropic-beta': 'token-counting-2024-11-01', |
| 322 | 'content-type': 'application/json', |
| 323 | }, |
| 324 | body: JSON.stringify({ |
| 325 | model: anthropicModelId, |
| 326 | messages: anthropicMessages, |
| 327 | ...(system && { system }), |
| 328 | ...(tools && { tools }), |
| 329 | }), |
| 330 | }, |
| 331 | ) |
| 332 | |
| 333 | if (!response.ok) { |
| 334 | const errorText = await response.text() |
| 335 | logger.error( |
| 336 | { |
| 337 | status: response.status, |
| 338 | errorText, |
| 339 | messages: anthropicMessages, |
| 340 | system, |
| 341 | model, |
| 342 | }, |
| 343 | 'Anthropic token count API error', |
| 344 | ) |
| 345 | throw new Error(`Anthropic API error: ${response.status} - ${errorText}`) |
| 346 | } |
| 347 | |
| 348 | const data = await response.json() |
| 349 | const baseTokens = data.input_tokens |
| 350 |
no test coverage detected