diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 9dd0382a185..aa33e0d5010 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -49829,14 +49829,14 @@ "supports_tool_choice": true }, "bedrock_mantle/openai.gpt-5.6-sol": { - "input_cost_per_token": 4.4e-06, - "input_cost_per_token_above_272k_tokens": 8.8e-06, - "cache_creation_input_token_cost": 5.5e-06, - "cache_creation_input_token_cost_above_272k_tokens": 1.1e-05, - "cache_read_input_token_cost": 4.4e-07, - "cache_read_input_token_cost_above_272k_tokens": 8.8e-07, - "output_cost_per_token": 2.2e-05, - "output_cost_per_token_above_272k_tokens": 3.3e-05, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "cache_creation_input_token_cost": 6.875e-06, + "cache_creation_input_token_cost_above_272k_tokens": 1.375e-05, + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -50113,8 +50113,11 @@ }, "bedrock_mantle/openai.gpt-5.5": { "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -50140,8 +50143,11 @@ }, "bedrock_mantle/openai.gpt-5.4": { "input_cost_per_token": 2.75e-06, + "input_cost_per_token_above_272k_tokens": 5.5e-06, "cache_read_input_token_cost": 2.75e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.5e-07, "output_cost_per_token": 1.65e-05, + "output_cost_per_token_above_272k_tokens": 2.475e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 9dd0382a185..aa33e0d5010 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -49829,14 +49829,14 @@ "supports_tool_choice": true }, "bedrock_mantle/openai.gpt-5.6-sol": { - "input_cost_per_token": 4.4e-06, - "input_cost_per_token_above_272k_tokens": 8.8e-06, - "cache_creation_input_token_cost": 5.5e-06, - "cache_creation_input_token_cost_above_272k_tokens": 1.1e-05, - "cache_read_input_token_cost": 4.4e-07, - "cache_read_input_token_cost_above_272k_tokens": 8.8e-07, - "output_cost_per_token": 2.2e-05, - "output_cost_per_token_above_272k_tokens": 3.3e-05, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "cache_creation_input_token_cost": 6.875e-06, + "cache_creation_input_token_cost_above_272k_tokens": 1.375e-05, + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -50113,8 +50113,11 @@ }, "bedrock_mantle/openai.gpt-5.5": { "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -50140,8 +50143,11 @@ }, "bedrock_mantle/openai.gpt-5.4": { "input_cost_per_token": 2.75e-06, + "input_cost_per_token_above_272k_tokens": 5.5e-06, "cache_read_input_token_cost": 2.75e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.5e-07, "output_cost_per_token": 1.65e-05, + "output_cost_per_token_above_272k_tokens": 2.475e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 1050000, "max_output_tokens": 128000, diff --git a/tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py b/tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py index ce90719789a..8ccd8235739 100644 --- a/tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py +++ b/tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py @@ -532,40 +532,71 @@ def test_generic_cost_per_token_bedrock_mantle_gpt56_long_context(_local_model_c @pytest.mark.parametrize( - "model", + "model,input_rate,cache_read_rate,output_rate,long_input_rate,long_cache_read_rate,long_output_rate", [ - "bedrock_mantle/openai.gpt-5.5", - "bedrock_mantle/openai.gpt-5.4", + ("bedrock_mantle/openai.gpt-5.5", 5.5e-06, 5.5e-07, 3.3e-05, 1.1e-05, 1.1e-06, 4.95e-05), + ("bedrock_mantle/openai.gpt-5.4", 2.75e-06, 2.75e-07, 1.65e-05, 5.5e-06, 5.5e-07, 2.475e-05), + ("bedrock_mantle/openai.gpt-5.6-sol", 5.5e-06, 5.5e-07, 3.3e-05, 1.1e-05, 1.1e-06, 4.95e-05), ], ) -def test_generic_cost_per_token_bedrock_mantle_gpt55_gpt54_long_context_flat_rate(_local_model_cost_map, model): - """Bedrock serves gpt-5.5 and gpt-5.4 up to its enforced 1,050,000-token prompt maximum and documents - no long-context tier for them, so a prompt past 272K is billed at the flat per-token rates.""" +def test_generic_cost_per_token_bedrock_mantle_gpt5_matches_aws_invoiced_rates( + _local_model_cost_map, + model, + input_rate, + cache_read_rate, + output_rate, + long_input_rate, + long_cache_read_rate, + long_output_rate, +): + """AWS bills a Bedrock GPT-5.x prompt past 272K under its long-context usage types, the whole prompt at + 2x input, 2x cache read, and 1.5x output. The flat rates undercounted a 300K gpt-5.5 prompt by half and + sol's base rates sat 20% under the invoice.""" - model_cost_map = litellm.model_cost[model] - assert model_cost_map["max_input_tokens"] == 1050000 - assert [key for key in model_cost_map if "above_272k" in key] == [] - - served_prompt_tokens = 1030590 cached_tokens = 100000 completion_tokens = 1000 - usage = Usage( - prompt_tokens=served_prompt_tokens, + + invoiced_prompt_tokens = 300238 + long_usage = Usage( + prompt_tokens=invoiced_prompt_tokens, completion_tokens=completion_tokens, - total_tokens=served_prompt_tokens + completion_tokens, + total_tokens=invoiced_prompt_tokens + completion_tokens, prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=cached_tokens), ) - prompt_cost, completion_cost = generic_cost_per_token( + long_prompt_cost, long_completion_cost = generic_cost_per_token( model=model, - usage=usage, + usage=long_usage, custom_llm_provider="bedrock_mantle", ) - assert round(prompt_cost, 10) == round( - model_cost_map["input_cost_per_token"] * (served_prompt_tokens - cached_tokens) - + model_cost_map["cache_read_input_token_cost"] * cached_tokens, - 10, + assert long_prompt_cost == pytest.approx( + long_input_rate * (invoiced_prompt_tokens - cached_tokens) + long_cache_read_rate * cached_tokens ) - assert round(completion_cost, 10) == round(model_cost_map["output_cost_per_token"] * completion_tokens, 10) + assert long_completion_cost == pytest.approx(long_output_rate * completion_tokens) + + threshold_prompt_tokens = 272000 + short_usage = Usage( + prompt_tokens=threshold_prompt_tokens, + completion_tokens=completion_tokens, + total_tokens=threshold_prompt_tokens + completion_tokens, + prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=cached_tokens), + ) + short_prompt_cost, short_completion_cost = generic_cost_per_token( + model=model, + usage=short_usage, + custom_llm_provider="bedrock_mantle", + ) + assert short_prompt_cost == pytest.approx( + input_rate * (threshold_prompt_tokens - cached_tokens) + cache_read_rate * cached_tokens + ) + assert short_completion_cost == pytest.approx(output_rate * completion_tokens) + + +def test_bedrock_mantle_gpt56_sol_cache_write_matches_aws_invoiced_rate(_local_model_cost_map): + """The invoice bills sol 30-minute cache writes at $6.88 per million tokens, 1.25x the $5.50 input rate.""" + + sol = litellm.model_cost["bedrock_mantle/openai.gpt-5.6-sol"] + assert sol["cache_creation_input_token_cost"] == pytest.approx(6.875e-06) + assert sol["cache_creation_input_token_cost_above_272k_tokens"] == pytest.approx(1.375e-05) def test_generic_cost_per_token_honors_non_standard_above_threshold(): diff --git a/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py b/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py index a8a20670d4e..0033f4467bb 100644 --- a/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py +++ b/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py @@ -1695,7 +1695,7 @@ class TestBedrockMantleResponsesPricing: @pytest.mark.parametrize( "model, input_cost, cache_creation_cost, cache_read_cost, output_cost", [ - ("openai.gpt-5.6-sol", 4.4e-06, 5.5e-06, 4.4e-07, 2.2e-05), + ("openai.gpt-5.6-sol", 5.5e-06, 6.875e-06, 5.5e-07, 3.3e-05), ("openai.gpt-5.6-terra", 2.2e-06, 2.75e-06, 2.2e-07, 1.32e-05), ("openai.gpt-5.6-luna", 2.2e-07, 2.75e-07, 2.2e-08, 1.32e-06), ], @@ -1718,7 +1718,7 @@ class TestBedrockMantleResponsesPricing: @pytest.mark.parametrize( "model, input_cost, output_cost", [ - ("openai.gpt-5.6-sol", 4.4e-06, 2.2e-05), + ("openai.gpt-5.6-sol", 5.5e-06, 3.3e-05), ("openai.gpt-5.6-terra", 2.2e-06, 1.32e-05), ("openai.gpt-5.6-luna", 2.2e-07, 1.32e-06), ],