From 8136c96284485f7460d2a490608c7efdadc4f6ed Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 16:46:31 +0000 Subject: [PATCH] test(anthropic): cover usage-shape detection for cache token pricing --- .../test_anthropic_chat_transformation.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py index 94a4a3fc945..34fbea95e5b 100644 --- a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -23,7 +23,7 @@ from litellm.llms.anthropic.experimental_pass_through.messages.transformation im AnthropicMessagesConfig, ) from litellm.types.llms.anthropic import ANTHROPIC_BETA_HEADER_VALUES -from litellm.types.utils import ServerToolUse +from litellm.types.utils import ServerToolUse, Usage def test_response_format_transformation_unit_test(): @@ -5845,3 +5845,25 @@ def test_top_k_forwarded_at_transform_on_models_that_accept_it(): ) assert result["top_k"] == 40 + + +def test_is_anthropic_usage_object_distinguishes_chat_usage(): + """Chat-shaped Usage mirrors cache_read_input_tokens alongside prompt_tokens that already + include the cache tokens, so treating it as Anthropic usage would re-add them and + double-count the prompt. Only the Anthropic shape, where input_tokens excludes cache + tokens, may take the Anthropic mapping.""" + assert AnthropicConfig.is_anthropic_usage_object( + {"input_tokens": 3, "output_tokens": 5, "cache_read_input_tokens": 4014} + ) + assert AnthropicConfig.is_anthropic_usage_object( + {"input_tokens": 3, "output_tokens": 5, "cache_creation_input_tokens": 10} + ) + assert not AnthropicConfig.is_anthropic_usage_object( + Usage( + prompt_tokens=4017, + completion_tokens=5, + total_tokens=4022, + cache_read_input_tokens=4014, + ).model_dump() + ) + assert not AnthropicConfig.is_anthropic_usage_object({"input_tokens": 3, "output_tokens": 5})