From eeed4a3851be9e02fcdaddcb7ae7dd7ebec3fd10 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Fri, 29 May 2026 15:42:30 -0700 Subject: [PATCH] Make anthropic's Usage input_tokens include cache_read_tokens This matches what gateway and openai do. --- src/ai/providers/anthropic/protocol.py | 11 +++++++---- src/ai/types/usage.py | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ai/providers/anthropic/protocol.py b/src/ai/providers/anthropic/protocol.py index 6d8ed528..c1f98c2c 100644 --- a/src/ai/providers/anthropic/protocol.py +++ b/src/ai/providers/anthropic/protocol.py @@ -861,12 +861,15 @@ async def stream( snapshot = sdk_stream.current_message_snapshot sdk_usage = snapshot.usage + cache_read = getattr(sdk_usage, "cache_read_input_tokens", None) usage = types.usage.Usage( - input_tokens=sdk_usage.input_tokens or 0, - output_tokens=sdk_usage.output_tokens or 0, - cache_read_tokens=getattr( - sdk_usage, "cache_read_input_tokens", None + # We combine input_tokens and cache_read_input_tokens, + # to match the behavior of other providers. + input_tokens=( + (sdk_usage.input_tokens or 0) + (cache_read or 0) ), + output_tokens=sdk_usage.output_tokens or 0, + cache_read_tokens=cache_read, cache_write_tokens=getattr( sdk_usage, "cache_creation_input_tokens", None ), diff --git a/src/ai/types/usage.py b/src/ai/types/usage.py index d33b3fcd..8d926a42 100644 --- a/src/ai/types/usage.py +++ b/src/ai/types/usage.py @@ -15,6 +15,7 @@ class Usage(pydantic.BaseModel): model_config = pydantic.ConfigDict(frozen=True) + # input_tokens includes both cached and uncached input tokens. input_tokens: int = 0 output_tokens: int = 0