From 837bcba32d0093a5f6263c27d0dc32a29e7c0c7b Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 27 Aug 2026 19:31:45 -0700 Subject: [PATCH] fix(model_prices): add bedrock_mantle gpt-5.5/5.4 272K tiers, align sol with AWS invoice AWS bills a Bedrock GPT-5.5 or GPT-5.4 prompt past 272K tokens under the long-context usage types for the whole prompt, at 2x input, 2x cache read, and 1.5x output, and the cost map only had the flat rates, so a 300K prompt was logged at half of what the invoice charges. The map's promo rates for gpt-5.6-sol are 20% under the $5.50 input, $33.00 output, $0.55 cache read, and $6.88 cache write per million the invoice bills. Adds the *_above_272k_tokens fields to gpt-5.5 and gpt-5.4, moves sol's base and tier rates to the invoiced ones, replaces the test that pinned the flat behaviour with one that pins the invoiced numbers, and updates the sol pins in the mantle transformation tests --- ...odel_prices_and_context_window_backup.json | 22 ++++-- model_prices_and_context_window.json | 22 ++++-- .../llm_cost_calc/test_llm_cost_calc_utils.py | 73 +++++++++++++------ ...bedrock_mantle_responses_transformation.py | 4 +- 4 files changed, 82 insertions(+), 39 deletions(-) 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), ],