From c9c9a4f3a241a9d03eeb96befea8a7a7737ae8fe Mon Sep 17 00:00:00 2001 From: shivam Date: Fri, 24 Jul 2026 00:28:04 +0000 Subject: [PATCH] fix(pricing): correct gpt-5.4-mini/nano max_input_tokens to 272000 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- ...odel_prices_and_context_window_backup.json | 16 ++--- model_prices_and_context_window.json | 24 +++---- .../test_gpt_5_4_model_metadata.py | 66 +++++++++++++++++++ 3 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 tests/test_litellm/test_gpt_5_4_model_metadata.py diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index d3917886060..fa152cc28aa 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -3214,7 +3214,7 @@ "input_cost_per_token_priority": 1.5e-06, "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3260,7 +3260,7 @@ "input_cost_per_token_priority": 1.5e-06, "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3306,7 +3306,7 @@ "input_cost_per_token_priority": 4e-07, "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3352,7 +3352,7 @@ "input_cost_per_token_priority": 4e-07, "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -6953,7 +6953,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -6988,7 +6988,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7023,7 +7023,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7058,7 +7058,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index c9d871fc41d..4d728c71919 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -3214,7 +3214,7 @@ "input_cost_per_token_priority": 1.5e-06, "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3260,7 +3260,7 @@ "input_cost_per_token_priority": 1.5e-06, "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3306,7 +3306,7 @@ "input_cost_per_token_priority": 4e-07, "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3352,7 +3352,7 @@ "input_cost_per_token_priority": 4e-07, "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -6953,7 +6953,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -6988,7 +6988,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7023,7 +7023,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7058,7 +7058,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -24028,7 +24028,7 @@ "input_cost_per_token_batches": 3.75e-07, "input_cost_per_token_priority": 1.5e-06, "litellm_provider": "openai", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -24074,7 +24074,7 @@ "input_cost_per_token_batches": 3.75e-07, "input_cost_per_token_priority": 1.5e-06, "litellm_provider": "openai", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -24118,7 +24118,7 @@ "input_cost_per_token_flex": 1e-07, "input_cost_per_token_batches": 1e-07, "litellm_provider": "openai", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -24161,7 +24161,7 @@ "input_cost_per_token_flex": 1e-07, "input_cost_per_token_batches": 1e-07, "litellm_provider": "openai", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", diff --git a/tests/test_litellm/test_gpt_5_4_model_metadata.py b/tests/test_litellm/test_gpt_5_4_model_metadata.py new file mode 100644 index 00000000000..388cb4b0a45 --- /dev/null +++ b/tests/test_litellm/test_gpt_5_4_model_metadata.py @@ -0,0 +1,66 @@ +import json +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).parents[2] +MAIN_PATH = REPO_ROOT / "model_prices_and_context_window.json" +BACKUP_PATH = REPO_ROOT / "litellm" / "model_prices_and_context_window_backup.json" + +MINI_NANO_MODELS = ( + "gpt-5.4-mini", + "gpt-5.4-mini-2026-03-17", + "gpt-5.4-nano", + "gpt-5.4-nano-2026-03-17", + "azure/gpt-5.4-mini", + "azure/gpt-5.4-mini-2026-03-17", + "azure/gpt-5.4-nano", + "azure/gpt-5.4-nano-2026-03-17", + "azure_ai/gpt-5.4-mini", + "azure_ai/gpt-5.4-mini-2026-03-17", + "azure_ai/gpt-5.4-nano", + "azure_ai/gpt-5.4-nano-2026-03-17", +) + +LONG_CONTEXT_MODELS = ( + "gpt-5.4", + "gpt-5.4-pro", + "azure/gpt-5.4", + "azure_ai/gpt-5.4", +) + + +def _load(path): + with open(path) as f: + return json.load(f) + + +@pytest.mark.parametrize("model", MINI_NANO_MODELS) +def test_gpt_5_4_mini_nano_max_input_tokens(model): + """gpt-5.4-mini/nano share the 400k context window, so max input is 272k. + + Regression for azure/azure_ai variants that had leaked the base gpt-5.4 + 1,050,000 window (and the raw 400,000 context window) into max_input_tokens. + """ + info = _load(MAIN_PATH).get(model) + assert info is not None, f"{model} missing from model_prices_and_context_window.json" + assert info["max_input_tokens"] == 272000 + assert info["max_output_tokens"] == 128000 + assert info["max_tokens"] == 128000 + + +@pytest.mark.parametrize("model", LONG_CONTEXT_MODELS) +def test_gpt_5_4_base_keeps_long_context_window(model): + """Base gpt-5.4 and gpt-5.4-pro keep the full 1,050,000 token input window.""" + info = _load(MAIN_PATH).get(model) + assert info is not None, f"{model} missing from model_prices_and_context_window.json" + assert info["max_input_tokens"] == 1050000 + assert info["max_output_tokens"] == 128000 + + +@pytest.mark.parametrize("model", MINI_NANO_MODELS + LONG_CONTEXT_MODELS) +def test_gpt_5_4_backup_matches_main(model): + """The bundled cost map must stay in sync with the canonical file.""" + assert _load(BACKUP_PATH).get(model) == _load(MAIN_PATH).get( + model + ), f"{model} differs between main and backup model cost maps"