From 00dc34fcf61a5eaa9c907792e5646c7a7dcdfd70 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Mon, 11 Aug 2025 21:46:31 -0500 Subject: [PATCH] Wire through token cache statistics --- src/anthropic-api-types.ts | 2 ++ src/anthropic-proxy.ts | 7 +++++++ src/convert-to-anthropic-stream.ts | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/anthropic-api-types.ts b/src/anthropic-api-types.ts index 061b616..9faefa4 100644 --- a/src/anthropic-api-types.ts +++ b/src/anthropic-api-types.ts @@ -118,6 +118,8 @@ export type AnthropicToolChoice = export type AnthropicStreamUsage = { input_tokens: number; output_tokens: number; + cache_creation_input_tokens?: number; + cache_read_input_tokens?: number; }; export type AnthropicStreamChunk = diff --git a/src/anthropic-proxy.ts b/src/anthropic-proxy.ts index 2860120..2e06b71 100644 --- a/src/anthropic-proxy.ts +++ b/src/anthropic-proxy.ts @@ -325,6 +325,13 @@ export const createAnthropicProxy = ({ usage: { input_tokens: usage.inputTokens, output_tokens: usage.outputTokens, + // OpenAI provides cached tokens via cachedInputTokens or in experimental_providerMetadata + // Map to Anthropic's cache_read_input_tokens + cache_creation_input_tokens: 0, // OpenAI doesn't report cache creation separately + cache_read_input_tokens: usage.cachedInputTokens ?? + (typeof (response as any).experimental_providerMetadata?.openai?.cached_tokens === 'number' + ? (response as any).experimental_providerMetadata.openai.cached_tokens + : 0), }, }) ); diff --git a/src/convert-to-anthropic-stream.ts b/src/convert-to-anthropic-stream.ts index 73e15cc..ffa0bac 100644 --- a/src/convert-to-anthropic-stream.ts +++ b/src/convert-to-anthropic-stream.ts @@ -27,7 +27,12 @@ export function convertToAnthropicStream( model: "claude-4-sonnet-20250514", stop_reason: null, stop_sequence: null, - usage: { input_tokens: 0, output_tokens: 0 }, + usage: { + input_tokens: 0, + output_tokens: 0, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + }, }, }); break; @@ -42,6 +47,14 @@ export function convertToAnthropicStream( usage: { input_tokens: chunk.usage.inputTokens ?? 0, output_tokens: chunk.usage.outputTokens ?? 0, + // OpenAI provides cached tokens via cachedInputTokens or in providerMetadata + cache_creation_input_tokens: 0, // OpenAI doesn't report cache creation separately + cache_read_input_tokens: + chunk.usage.cachedInputTokens ?? + (typeof chunk.providerMetadata?.openai?.cached_tokens === + "number" + ? chunk.providerMetadata.openai.cached_tokens + : 0), }, }); break;