fix: preserve Anthropic cache_control and cache_creation on /v1/responses - #38
Closed
lukesorvikDO wants to merge 4 commits into
Conversation
_transform_responses_api_content_to_chat_completion_content rebuilt content blocks with only type+text, dropping cache_control. The Anthropic adapter (add_cache_control_to_content) never sees it, so cache is never seeded for /v1/responses. Fix: copy cache_control from the source item when present (mirrors the existing pattern for tools). Co-authored-by: Cursor <cursoragent@cursor.com>
The _transform_chat_completion_usage_to_responses_usage method drops Anthropic cache creation fields (cache_creation_input_tokens, cache_read_input_tokens, cache_creation.ephemeral_5m/1h_input_tokens) when converting chat-completion Usage to ResponseAPIUsage. This causes the inference proxy to see zero cache creation tokens, resulting in unbilled cache creation on /v1/responses. Fix: use setattr to add these fields as extras on ResponseAPIUsage (which supports extra fields via BaseLiteLLMOpenAIResponseObject's extra="allow" config), so they survive serialization and can be extracted downstream. Co-authored-by: Cursor <cursoragent@cursor.com>
lukesorvikDO
force-pushed
the
lsorvik/anthropic-responses-cache-control-and-creation
branch
from
July 21, 2026 02:22
1713f65 to
9921f9d
Compare
…opic adapters Bug 3: streaming_iterator.py assigned input_tokens_details (an object) to cache_creation_tokens, and output_tokens_details (wrong field) to cache_read_tokens. Remove the dead assignments, read the correct integer fields directly, and add an OpenAI-style fallback to input_tokens_details.cached_tokens. Bug 4: responses_adapters/transformation.py never populated cache_creation_input_tokens or cache_read_input_tokens on AnthropicUsage. Read both from ResponseAPIUsage extras with the same cached_tokens fallback.
2 tasks
Collaborator
Author
|
Most up to date one here #55 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related
cache_controldropped on/v1/responsescontent blocks (bug 1)Summary
Fixes the 3 LiteLLM-side bugs causing Anthropic prompt caching to silently produce
cache_created_input_tokens: 0/cache_read_input_tokens: 0onPOST /v1/responses. All 3 bugs share the same symptom (zero cache tokens reported) but are independently reproducible.Bug 1:
cache_controldropped on request content blocksFile:
litellm/responses/litellm_completion_transformation/transformation.py_transform_responses_api_content_to_chat_completion_contentrebuilt each content block with onlytype+text, silently dropping anycache_controlfield the caller supplied. The downstream Anthropic adapter never sees a caching directive, so the prompt cache is never seeded.Fix: Copy
cache_controlfrom the source item onto the rebuilt content block when present.Bug 2:
cache_creationfields dropped in usage transformFile:
litellm/responses/litellm_completion_transformation/transformation.py_transform_chat_completion_usage_to_responses_usagedroppedcache_creation_input_tokens,cache_read_input_tokens, andcache_creation.ephemeral_5m/1h_input_tokenswhen converting internalUsagetoResponseAPIUsage. The inference proxy sees zero cache-creation tokens.Fix: Use
setattrto preserve these as extras onResponseAPIUsage(which hasextra="allow"viaBaseLiteLLMOpenAIResponseObject), so they survive serialization and can be extracted by the inference proxy before the lossyapi.Usageunmarshal.Bug 3: Wrong variable assignments in streaming usage
File:
litellm/llms/anthropic/experimental_pass_through/responses_adapters/streaming_iterator.pycache_creation_tokenswas assigned the entireinput_tokens_detailsobject (not a count), andcache_read_tokenswas assignedoutput_tokens_details(completely the wrong field). Streaming responses always reported zero cache tokens.Fix: Remove the dead/wrong assignments. Read
cache_creation_input_tokensandcache_read_input_tokensdirectly as integers. Add fallback toinput_tokens_details.cached_tokens(OpenAI-style field) when the Anthropic-nativecache_read_input_tokensis absent.Bug 4 (not in this PR): inference-proxy lossy unmarshal
response_conversions.go ConvertExecutorResponseToAPIResponsedoes a plainjson.Unmarshalof the executor's raw response, which is lossy for these Anthropic-specific extra fields. Even with bugs 1-3 fixed, the inference-proxy needs its own fix (INF-936) to reliably read these fields off the raw executor JSON.Expected behavior after this PR lands (+ INF-936)
Request:
Before (bug):
After (first request — cache write):
After (follow-up identical request — cache read):
Sequencing
Pre-Submission checklist
Type
🐛 Bug Fix