fix(ai): preserve input token counts from message_start in Anthropic provider

Proxies like Portkey omit input_tokens in message_delta events (it's nullable
per the SDK). The previous code unconditionally overwrote usage fields, causing
input token counts to reset to 0.

Now only updates usage fields when they are present (not null), preserving
the correct input_tokens value captured from message_start.

Fixes #1045
This commit is contained in:
Mario Zechner 2026-01-29 00:06:51 +01:00
parent 4f9deddd47
commit 8b5c81f21f
2 changed files with 15 additions and 4 deletions

View file

@ -304,10 +304,20 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
if (event.delta.stop_reason) {
output.stopReason = mapStopReason(event.delta.stop_reason);
}
output.usage.input = event.usage.input_tokens || 0;
output.usage.output = event.usage.output_tokens || 0;
output.usage.cacheRead = event.usage.cache_read_input_tokens || 0;
output.usage.cacheWrite = event.usage.cache_creation_input_tokens || 0;
// Only update usage fields if present (not null).
// Preserves input_tokens from message_start when proxies omit it in message_delta.
if (event.usage.input_tokens != null) {
output.usage.input = event.usage.input_tokens;
}
if (event.usage.output_tokens != null) {
output.usage.output = event.usage.output_tokens;
}
if (event.usage.cache_read_input_tokens != null) {
output.usage.cacheRead = event.usage.cache_read_input_tokens;
}
if (event.usage.cache_creation_input_tokens != null) {
output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
}
// Anthropic doesn't provide total_tokens, compute from components
output.usage.totalTokens =
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;