From 1c855385c9ae5e8c2bad767e167248ddfd39dbfb Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 16 Sep 2025 18:43:57 -0700 Subject: [PATCH] build(model_cost): add cache_creation_input_token_cost_above_1hr pricing --- litellm/llms/anthropic/chat/transformation.py | 8 ++- ...odel_prices_and_context_window_backup.json | 1 + model_prices_and_context_window.json | 1 + .../test_anthropic_prompt_caching.py | 70 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index ce874bfde9..b3b5f5107b 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -200,8 +200,12 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): ) _allowed_properties = set(AnthropicInputSchema.__annotations__.keys()) - input_schema_filtered = {k: v for k, v in _input_schema.items() if k in _allowed_properties} - input_anthropic_schema: AnthropicInputSchema = AnthropicInputSchema(**input_schema_filtered) + input_schema_filtered = { + k: v for k, v in _input_schema.items() if k in _allowed_properties + } + input_anthropic_schema: AnthropicInputSchema = AnthropicInputSchema( + **input_schema_filtered + ) _tool = AnthropicMessagesTool( name=tool["function"]["name"], diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 96e19d022c..4394cef383 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -6228,6 +6228,7 @@ "input_cost_per_token": 8e-07, "output_cost_per_token": 4e-06, "cache_creation_input_token_cost": 1e-06, + "cache_creation_input_token_cost_above_1hr": 1.6e-06, "cache_read_input_token_cost": 8e-08, "search_context_cost_per_query": { "search_context_size_low": 0.01, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 96e19d022c..4394cef383 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -6228,6 +6228,7 @@ "input_cost_per_token": 8e-07, "output_cost_per_token": 4e-06, "cache_creation_input_token_cost": 1e-06, + "cache_creation_input_token_cost_above_1hr": 1.6e-06, "cache_read_input_token_cost": 8e-08, "search_context_cost_per_query": { "search_context_size_low": 0.01, diff --git a/tests/local_testing/test_anthropic_prompt_caching.py b/tests/local_testing/test_anthropic_prompt_caching.py index 4c2b66879e..f2c194a36e 100644 --- a/tests/local_testing/test_anthropic_prompt_caching.py +++ b/tests/local_testing/test_anthropic_prompt_caching.py @@ -300,6 +300,76 @@ async def test_anthropic_api_prompt_caching_basic(): ) +@pytest.mark.asyncio() +async def test_anthropic_api_prompt_caching_basic_with_cache_creation(): + from uuid import uuid4 + + random_id = uuid4() + + litellm.set_verbose = True + response = await litellm.acompletion( + model="anthropic/claude-3-5-sonnet-20240620", + messages=[ + # System Message + { + "role": "system", + "content": [ + { + "type": "text", + "text": "Here is the full text of a complex legal agreement {}".format( + random_id + ) + * 400, + "cache_control": {"type": "ephemeral"}, + } + ], + }, + # marked for caching with the cache_control parameter, so that this checkpoint can read from the previous cache. + { + "role": "user", + "content": [ + { + "type": "text", + "text": "What are the key terms and conditions in this agreement?", + "cache_control": {"type": "ephemeral"}, + } + ], + }, + { + "role": "assistant", + "content": "Certainly! the key terms and conditions are the following: the contract is 1 year long for $10/mo", + }, + # The final turn is marked with cache-control, for continuing in followups. + { + "role": "user", + "content": [ + { + "type": "text", + "text": "What are the key terms and conditions in this agreement?", + "cache_control": {"type": "ephemeral"}, + } + ], + }, + ], + temperature=0.2, + max_tokens=10, + extra_headers={ + "anthropic-version": "2023-06-01", + "anthropic-beta": "prompt-caching-2024-07-31", + }, + ) + + print("response=", response) + + assert "cache_read_input_tokens" in response.usage + assert "cache_creation_input_tokens" in response.usage + + # Assert either a cache entry was created or cache was read - changes depending on the anthropic api ttl + assert (response.usage.cache_read_input_tokens > 0) or ( + response.usage.cache_creation_input_tokens > 0 + ) + + @pytest.mark.asyncio() async def test_anthropic_api_prompt_caching_with_content_str(): system_message = [