Skip to content

Conversation

@wong2
Copy link
Contributor

@wong2 wong2 commented Nov 28, 2025

Background

Now AI SDK only read input_tokens from message_start, but in our experience, many Anthropic compatible providers only return the actual input_tokens in message_delta

Summary

Read input_tokens from message_delta as a fallback

Manual Verification

Checklist

  • Tests have been added / updated (for bug fixes / features)
  • Documentation has been added / updated (for bug fixes / features)
  • A patch changeset for relevant packages has been added (for bug fixes / features - run pnpm changeset in the project root)
  • I have reviewed this pull request (self-review)

Future Work

Related Issues

}

case 'message_delta': {
if (!usage.inputTokens) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!usage.inputTokens) {
if (usage.inputTokens === undefined) {

The condition if (!usage.inputTokens) uses truthiness check which incorrectly treats a valid value of 0 tokens as "not set", causing it to overwrite correct values from message_start with fallback values from message_delta.

View Details

Analysis

Falsy check on usage.inputTokens causes overwriting valid zero value

What fails: In anthropic-messages-language-model.ts:1488, the condition if (!usage.inputTokens) uses a truthiness check that incorrectly treats input_tokens: 0 (a valid Anthropic API value) as "not set", causing it to overwrite the correct zero value with a fallback value from message_delta.

How to reproduce:

  1. Call the Anthropic Messages API with a prompt that results in message_start event containing usage.input_tokens: 0 (e.g., when using cache hits or other edge cases)
  2. The stream handler receives the message_start event and sets usage.inputTokens = 0
  3. When message_delta arrives with usage: { output_tokens: X, input_tokens: Y, ... }, the falsy check on line 1488 evaluates to true (since 0 && true is falsy in JavaScript)
  4. The code executes usage.inputTokens = value.usage.input_tokens ?? 0, overwriting the correct 0 with the message_delta value

Result: The final reported inputTokens is incorrect - it uses the value from message_delta instead of the value from message_start

Expected: According to Anthropic API documentation, input_tokens has a minimum value of 0, meaning zero is a valid and legitimate value. The fallback should only trigger when inputTokens hasn't been set (is undefined), not when it's legitimately set to 0.

Fix: Change the condition from if (!usage.inputTokens) to if (usage.inputTokens === undefined) to explicitly check for undefined rather than relying on truthiness. This properly distinguishes between "not set" (undefined) and "set to zero" (0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant