Skip to content

fix: extract Anthropic cache_creation_input_tokens without TTL breakdown#5606

Open
colegottdank wants to merge 1 commit intomainfrom
fix/anthropic-cache-creation-tokens
Open

fix: extract Anthropic cache_creation_input_tokens without TTL breakdown#5606
colegottdank wants to merge 1 commit intomainfrom
fix/anthropic-cache-creation-tokens

Conversation

@colegottdank
Copy link
Collaborator

Summary

Fixes Anthropic prompt caching issue where cache write tokens were not being extracted when the TTL breakdown was not provided.

Root cause: The AnthropicUsageProcessor was only looking at cache_creation.ephemeral_5m_input_tokens and cache_creation.ephemeral_1h_input_tokens, completely ignoring the main cache_creation_input_tokens field. When Anthropic's API returns the total without the TTL breakdown (older API responses, certain scenarios), the cache write tokens were lost.

Impact:

  • Incorrect cost calculations (undercharging for cache writes)
  • Missing cache write data in the dashboard
  • "cache read without cache creation" display issues reported by customers

Changes

  1. packages/cost/usage/anthropicUsageProcessor.ts: Now extracts cache_creation_input_tokens and uses it as fallback when TTL breakdown is not available

  2. packages/llm-mapper/transform/providers/anthropic/response/toOpenai.ts: Fixed fallback from cachedTokens (read) to cacheWriteTokens (write) in non-streaming transformation

  3. Added 2 new test cases to verify the fix

Test plan

  • All 585 existing tests pass
  • New test case: extracts cache_creation_input_tokens when TTL breakdown is missing
  • New test case: prefers TTL breakdown over total when both are provided

🤖 Generated with Claude Code

The AnthropicUsageProcessor was only extracting cache write tokens from the
TTL breakdown (ephemeral_5m_input_tokens, ephemeral_1h_input_tokens) but
completely ignoring the overall cache_creation_input_tokens field.

When Anthropic's API returns cache_creation_input_tokens without the TTL
breakdown (older API versions, certain response types), the cache write
tokens were lost, causing:
- Incorrect cost calculations (undercharging)
- Missing cache write data in the dashboard
- "cache read without cache creation" display issues

Fixes:
1. AnthropicUsageProcessor now extracts cache_creation_input_tokens and uses
   it as fallback when TTL breakdown is not available
2. Fixed toOpenai.ts non-streaming transformation that incorrectly fell back
   to cachedTokens (read) instead of cacheWriteTokens (write)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
helicone Error Error Feb 24, 2026 6:36pm
helicone-bifrost Ready Ready Preview, Comment Feb 24, 2026 6:36pm
helicone-eu Error Error Feb 24, 2026 6:36pm

Request Review

@supabase
Copy link

supabase bot commented Feb 24, 2026

This pull request has been ignored for the connected project bolqqmqbrciybnypvklh because there are no changes detected in supbase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@supabase
Copy link

supabase bot commented Feb 24, 2026

This pull request has been ignored for the connected project lmahfbbnchpworytrrqk because there are no changes detected in .supabase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@claude
Copy link
Contributor

claude bot commented Feb 24, 2026

Claude finished @colegottdank's task —— View job


Code Review Complete

Score: 8/10 - Good implementation with solid test coverage. Minor suggestions for improvement, ready to merge.

Todo List:

  • Read repository guidelines (CLAUDE.md)
  • Analyze the 3 changed files
  • Review AnthropicUsageProcessor changes
  • Review toOpenai transformer changes
  • Review test coverage and quality
  • Check for potential bugs or edge cases
  • Provide comprehensive feedback with confidence score

Detailed Review Analysis

✅ Strengths

  1. Correct Problem Identification: The issue is accurately described - cache_creation_input_tokens was being ignored when TTL breakdown wasn't provided.

  2. Sound Implementation Logic: The fallback logic in anthropicUsageProcessor.ts:134-141 correctly:

    • Checks if TTL breakdown exists (ttlBreakdownTotal === 0)
    • Falls back to total cache creation tokens
    • Defaults to 5m TTL (reasonable assumption)
  3. Comprehensive Test Coverage: Added excellent test cases covering both edge cases:

    • Cache creation without TTL breakdown (lines 301-335)
    • Priority of TTL breakdown over total (lines 337-374)
  4. Consistent API Handling: The fix in toOpenai.ts:72 maintains backward compatibility while providing the correct fallback.

🔧 Minor Suggestions

  1. Documentation Enhancement (anthropicUsageProcessor.ts:132-141):

    // Consider adding a comment explaining the 5m default choice:
    // Default to 5m TTL as it's the most common cache duration in Anthropic responses
    if (ephemeral5mTokens > 0) {
      modelUsage.cacheDetails.write5m = ephemeral5mTokens;
    } else if (cacheCreationInputTokens > 0 && ttlBreakdownTotal === 0) {
      // No TTL breakdown provided, use total as 5m (default TTL)
      modelUsage.cacheDetails.write5m = cacheCreationInputTokens;
    }
  2. Edge Case Consideration: What happens if cache_creation_input_tokens exists but TTL breakdown partially exists (e.g., only ephemeral_1h_input_tokens)? The current logic may not handle this optimally.

  3. Type Safety: Consider adding TypeScript interface validation for the cache_creation object structure.

🔍 Technical Analysis

AnthropicUsageProcessor Changes:

  • Lines 107-108: ✅ Correctly extracts the main cache_creation_input_tokens
  • Lines 134-141: ✅ Solid fallback logic with appropriate conditions
  • Logic Flow: ✅ Prioritizes TTL breakdown, falls back to total when needed

toOpenai.ts Changes:

  • Line 72: ✅ Fixes the variable reference from cachedTokens to cacheWriteTokens
  • Context: This was a bug - using cache read tokens as fallback for cache write tokens

Test Coverage:

  • Mock Data: ✅ Well-structured test scenarios covering the exact issue
  • Assertions: ✅ Verifies both the fix and existing functionality
  • Edge Cases: ✅ Tests both missing TTL breakdown and preference behavior

🚫 No Critical Issues Found

  • Security: ✅ No sensitive data exposure or injection risks
  • Performance: ✅ Minimal computational overhead, efficient conditionals
  • Breaking Changes: ✅ Backward compatible, maintains existing API contracts
  • Error Handling: ✅ Leverages existing error handling patterns

💡 Suggestions Summary

  1. Add explanatory comments for the 5m default TTL choice
  2. Consider edge cases where TTL breakdown is partially provided
  3. Validate the fix with real Anthropic API responses that exhibit this issue

Overall Assessment: This is a well-implemented fix that addresses a real customer issue with appropriate testing. The code follows repository patterns and maintains backward compatibility while fixing the underlying problem.


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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant