From 58d113083a0193446d12042d89d046f02f3b41b2 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Wed, 14 Jan 2026 17:27:22 -0800 Subject: [PATCH] translate_anthropic_messages_to_openai wiht cache control --- .../adapters/transformation.py | 31 +++++++++++++--- litellm/proxy/proxy_config.yaml | 35 ++++++++++++++++++- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py index cb2110aee9a..e43cc2169b1 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py @@ -204,6 +204,10 @@ class LiteLLMAnthropicMessagesAdapter: text_obj = ChatCompletionTextObject( type="text", text=content.get("text", "") ) + # Preserve cache_control if present (for prompt caching) + cache_control = content.get("cache_control") + if cache_control: + text_obj["cache_control"] = cache_control # type: ignore new_user_content_list.append(text_obj) elif content.get("type") == "image": # Convert Anthropic image format to OpenAI format @@ -219,6 +223,10 @@ class LiteLLMAnthropicMessagesAdapter: image_obj = ChatCompletionImageObject( type="image_url", image_url=image_url_obj ) + # Preserve cache_control if present (for prompt caching) + cache_control = content.get("cache_control") + if cache_control: + image_obj["cache_control"] = cache_control # type: ignore new_user_content_list.append(image_obj) elif content.get("type") == "tool_result": if "content" not in content: @@ -529,7 +537,7 @@ class LiteLLMAnthropicMessagesAdapter: self, tools: List[AllAnthropicToolsValues] ) -> List[ChatCompletionToolParam]: new_tools: List[ChatCompletionToolParam] = [] - mapped_tool_params = ["name", "input_schema", "description"] + mapped_tool_params = ["name", "input_schema", "description", "cache_control"] for tool in tools: function_chunk = ChatCompletionToolParamFunctionChunk( name=tool["name"], @@ -542,9 +550,13 @@ class LiteLLMAnthropicMessagesAdapter: for k, v in tool.items(): if k not in mapped_tool_params: # pass additional computer kwargs function_chunk.setdefault("parameters", {}).update({k: v}) - new_tools.append( - ChatCompletionToolParam(type="function", function=function_chunk) - ) + + tool_param = ChatCompletionToolParam(type="function", function=function_chunk) + # Preserve cache_control if present (for prompt caching) + cache_control = tool.get("cache_control") + if cache_control: + tool_param["cache_control"] = cache_control # type: ignore + new_tools.append(tool_param) return new_tools @@ -778,6 +790,12 @@ class LiteLLMAnthropicMessagesAdapter: input_tokens=usage.prompt_tokens or 0, output_tokens=usage.completion_tokens or 0, ) + # Add cache tokens if available (for prompt caching support) + if hasattr(usage, "_cache_creation_input_tokens") and usage._cache_creation_input_tokens > 0: + anthropic_usage["cache_creation_input_tokens"] = usage._cache_creation_input_tokens + if hasattr(usage, "_cache_read_input_tokens") and usage._cache_read_input_tokens > 0: + anthropic_usage["cache_read_input_tokens"] = usage._cache_read_input_tokens + translated_obj = AnthropicMessagesResponse( id=response.id, type="message", @@ -925,6 +943,11 @@ class LiteLLMAnthropicMessagesAdapter: input_tokens=litellm_usage_chunk.prompt_tokens or 0, output_tokens=litellm_usage_chunk.completion_tokens or 0, ) + # Add cache tokens if available (for prompt caching support) + if hasattr(litellm_usage_chunk, "_cache_creation_input_tokens") and litellm_usage_chunk._cache_creation_input_tokens > 0: + usage_delta["cache_creation_input_tokens"] = litellm_usage_chunk._cache_creation_input_tokens + if hasattr(litellm_usage_chunk, "_cache_read_input_tokens") and litellm_usage_chunk._cache_read_input_tokens > 0: + usage_delta["cache_read_input_tokens"] = litellm_usage_chunk._cache_read_input_tokens else: usage_delta = UsageDelta(input_tokens=0, output_tokens=0) return MessageBlockDelta( diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index 54a923e3bbb..3ab0b9b69bd 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -1,4 +1,36 @@ model_list: + - model_name: claude-sonnet-4-5-20250929 + litellm_params: + model: bedrock/invoke/us.anthropic.claude-sonnet-4-5-20250929-v1:0 + model_info: + cache_creation_input_token_cost: 3.75e-06 + cache_read_input_token_cost: 3e-07 + input_cost_per_token: 3e-06 + input_cost_per_token_above_200k_tokens: 6e-06 + output_cost_per_token_above_200k_tokens: 2.25e-05 + cache_creation_input_token_cost_above_200k_tokens: 7.5e-06 + cache_read_input_token_cost_above_200k_tokens: 6e-07 + litellm_provider: bedrock_converse + max_input_tokens: 200000 + max_output_tokens: 64000 + max_tokens: 200000 + mode: chat + output_cost_per_token: 1.5e-05 + search_context_cost_per_query: + search_context_size_high: 0.01 + search_context_size_low: 0.01 + search_context_size_medium: 0.01 + supports_assistant_prefill: true + supports_computer_use: true + supports_function_calling: true + supports_pdf_input: true + supports_prompt_caching: true + supports_reasoning: true + supports_response_schema: true + supports_tool_choice: true + supports_vision: true + tool_use_system_prompt_tokens: 346 + - model_name: us.anthropic.claude-sonnet-4-20250514-v1:0 litellm_params: model: bedrock/converse/us.anthropic.claude-sonnet-4-20250514-v1:0 @@ -7,4 +39,5 @@ model_list: mode: chat general_settings: - store_prompts_in_spend_logs: true \ No newline at end of file + store_prompts_in_spend_logs: true + forward_client_headers_to_llm_api: true \ No newline at end of file