diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 5774e699ad7..d053300e299 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -37504,7 +37504,6 @@ "input_cost_per_token": 5e-08, "input_cost_per_token_batches": 2.5e-08, "input_cost_per_token_flex": 2.5e-08, - "input_cost_per_token_priority": 2.5e-06, "litellm_provider": "openai", "max_input_tokens": 272000, "max_output_tokens": 128000, @@ -37552,7 +37551,6 @@ "deprecation_date": "2026-12-11", "input_cost_per_token": 5e-08, "input_cost_per_token_batches": 2.5e-08, - "input_cost_per_token_priority": 2.5e-06, "input_cost_per_token_flex": 2.5e-08, "litellm_provider": "openai", "max_input_tokens": 272000, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 5774e699ad7..d053300e299 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -37504,7 +37504,6 @@ "input_cost_per_token": 5e-08, "input_cost_per_token_batches": 2.5e-08, "input_cost_per_token_flex": 2.5e-08, - "input_cost_per_token_priority": 2.5e-06, "litellm_provider": "openai", "max_input_tokens": 272000, "max_output_tokens": 128000, @@ -37552,7 +37551,6 @@ "deprecation_date": "2026-12-11", "input_cost_per_token": 5e-08, "input_cost_per_token_batches": 2.5e-08, - "input_cost_per_token_priority": 2.5e-06, "input_cost_per_token_flex": 2.5e-08, "litellm_provider": "openai", "max_input_tokens": 272000, diff --git a/tests/unit/test_model_prices_and_context_window.py b/tests/unit/test_model_prices_and_context_window.py index 1f84be7710f..08a39b94c12 100644 --- a/tests/unit/test_model_prices_and_context_window.py +++ b/tests/unit/test_model_prices_and_context_window.py @@ -2,7 +2,7 @@ from __future__ import annotations import json import re -from collections.abc import Mapping +from collections.abc import Iterator, Mapping from pathlib import Path from types import MappingProxyType from typing import Final @@ -224,6 +224,50 @@ def test_dated_variants_carry_base_alias_service_tier_pricing(prices: dict): ) +PRIORITY_SUFFIX: Final = "_priority" +MIN_PRIORITY_MARKUP: Final = 1.0 +MAX_PRIORITY_MARKUP: Final = 5.0 + + +def _rate(value: JsonValue | None) -> float | None: + return float(value) if isinstance(value, (int, float)) and not isinstance(value, bool) else None + + +def _priority_markup(entry: Mapping[str, JsonValue], key: str) -> float | None: + if not key.endswith(PRIORITY_SUFFIX): + return None + priority: Final = _rate(entry[key]) + standard: Final = _rate(entry.get(key.removesuffix(PRIORITY_SUFFIX))) + if priority is None or standard is None or standard <= 0: + return None + return priority / standard + + +def priority_markups(prices: Mapping[str, JsonValue]) -> Iterator[tuple[str, str, float]]: + for name, entry in prices.items(): + if not isinstance(entry, dict): + continue + for key in entry: + if (markup := _priority_markup(entry, key)) is not None: + yield name, key, markup + + +@pytest.mark.parametrize("path", (PRICES_PATH, BACKUP_PRICES_PATH), ids=("main", "backup")) +def test_priority_rates_stay_within_a_premium_of_their_standard_rate(path: Path) -> None: + prices: Final = TypeAdapter(dict[str, JsonValue]).validate_json(path.read_bytes()) + markups: Final = tuple(priority_markups(prices)) + assert markups + overpriced: Final = tuple( + f"{name}.{key} is {markup:.1f}x its standard rate" + for name, key, markup in markups + if not MIN_PRIORITY_MARKUP <= markup <= MAX_PRIORITY_MARKUP + ) + assert overpriced == (), ( + "a priority rate is a premium on the standard rate, so one below it or far above it was likely copied from " + "another model; drop the key when the provider sells no priority tier for the model:\n" + "\n".join(overpriced) + ) + + # Azure Foundry GPT-6.1 Sol announcement, 2026-09-29: https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/introducing-gpt-6-1-sol-in-microsoft-foundry-advanced-intelligence-optimized-for/4560811 AZURE_GPT_6_1_SOL_REGIONAL_PREMIUM: Final = MappingProxyType({"us": 1.1, "eu": 1.2, "apac": 1.2})