Agno's OpenAIChat fills MessageMetrics.cache_write_tokens from usage.prompt_tokens_details.cache_write_tokens, and OpenAIResponses from usage.input_tokens_details.cache_write_tokens. Both already read cached_tokens from the same object into cache_read_tokens, so a run now shows both sides of the prompt cache.
The LiteLLM model reads prompt_tokens_details.cache_write_tokens and falls back to cache_creation_tokens, the mirror LiteLLM also fills. That covers Claude and any other cache-writing provider behind LiteLLM, whether the usage arrives as a dict or as LiteLLM's Usage object. A missing or null field still counts as zero, and the value adds up into run and session metrics like every other token count.
We passed each parser a usage payload built with the provider SDK's own types: 3,000 written tokens for the two OpenAI APIs, and LiteLLM's Usage with cache_creation_tokens=4000.
# Before (real output)
OpenAIChat cache_read_tokens=12000 cache_write_tokens=0
OpenAIResponses cache_read_tokens=12000 cache_write_tokens=0
LiteLLM cache_read_tokens=8000 cache_write_tokens=0
# Now (real output)
OpenAIChat cache_read_tokens=12000 cache_write_tokens=3000
OpenAIResponses cache_read_tokens=12000 cache_write_tokens=3000
LiteLLM cache_read_tokens=8000 cache_write_tokens=4000Learn more about cache and reasoning token metrics and LiteLLM in the documentation.
Frequently asked questions
OpenAIChat reads usage.prompt_tokens_details.cache_write_tokens from Chat Completions, and OpenAIResponses reads usage.input_tokens_details.cache_write_tokens from the Responses API.
Yes. The LiteLLM model reads prompt_tokens_details.cache_write_tokens, LiteLLM's own name for the cache write, and uses cache_creation_tokens when only that mirror is set.
Zero. A missing or null field, from an older SDK or an OpenAI-compatible server, produces cache_write_tokens=0 without an error.





