diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 63441d14c6c..dcd9b905c9b 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -42,6 +42,8 @@ from litellm.litellm_core_utils.llm_cost_calc.utils import ( generic_cost_per_token, get_batch_cost_rates, get_billable_input_tokens, + get_cost_per_unit, + get_modality_token_cost_key, get_regional_uplift_multiplier, get_service_tier_cost_key, get_token_type_cost_breakdown, @@ -2837,8 +2839,12 @@ def _batch_rate( "input_cost_per_video_token_batches", ], fallback: float, + *, + prompt_tokens: int = 0, ) -> float: - rate: Final = model_info.get(key) + context_key: Final = get_modality_token_cost_key(model_info, key, prompt_tokens) + context_rate: Final = get_cost_per_unit(model_info, context_key, None) + rate: Final = model_info.get(key) if context_rate is None else context_rate return fallback if rate is None else rate @@ -2978,7 +2984,8 @@ def _batch_prompt_cost( ) return ( text_tokens * input_rate - + audio_tokens * _batch_rate(model_info, "input_cost_per_audio_token_batches", input_rate) + + audio_tokens + * _batch_rate(model_info, "input_cost_per_audio_token_batches", input_rate, prompt_tokens=usage.prompt_tokens) + image_tokens * _batch_rate(model_info, "input_cost_per_image_token_batches", input_rate) + video_tokens * _batch_rate(model_info, "input_cost_per_video_token_batches", input_rate) + (cached_tokens - cached_audio_tokens) * (cache_read_rate or 0.0) diff --git a/litellm/litellm_core_utils/llm_cost_calc/utils.py b/litellm/litellm_core_utils/llm_cost_calc/utils.py index 6664d54a744..2aa6142b3c5 100644 --- a/litellm/litellm_core_utils/llm_cost_calc/utils.py +++ b/litellm/litellm_core_utils/llm_cost_calc/utils.py @@ -1088,21 +1088,55 @@ def parse_completion_tokens_details(usage: Usage) -> CompletionTokensDetailsResu ) +def get_modality_token_cost_key( + model_info: ModelInfo, + cost_key: str, + prompt_tokens: int, + *, + threshold_is_inclusive: bool = False, +) -> str: + suffix: Final = next((suffix for suffix in _NON_STANDARD_THRESHOLD_SUFFIXES if cost_key.endswith(suffix)), "") + base_key: Final = cost_key.removesuffix(suffix) + threshold_key: Final = max( + ( + key + for key in model_info + if key.startswith(f"{base_key}_above_") + and key.endswith(("_tokens", f"_tokens{suffix}")) + and model_info.get(key) is not None + and _prompt_exceeds_threshold(prompt_tokens, _parse_above_token_threshold(key), threshold_is_inclusive) + ), + key=_parse_above_token_threshold, + default=None, + ) + if threshold_key is None: + return cost_key + return f"{threshold_key.removesuffix(suffix)}{suffix}" + + def _modality_token_cost( model_info: ModelInfo, modality_cost_key: str, tokens: int, prompt_base_cost: float, service_tier: str | None, + *, + prompt_tokens: int = 0, + threshold_is_inclusive: bool = False, ) -> float: """ Audio, image and video prompt tokens bill at their modality rate when the model has one. Without one they are ordinary prompt tokens, so they bill at `prompt_base_cost`, which `_get_token_base_cost` has already resolved for the service tier and long-context tier. """ - tiered_key: Final = get_service_tier_cost_key(modality_cost_key, service_tier) - cost_key: Final = tiered_key if model_info.get(tiered_key) is not None else modality_cost_key - if model_info.get(cost_key) is None: + cost_key: Final = get_modality_token_cost_key( + model_info, + get_service_tier_cost_key(modality_cost_key, service_tier), + prompt_tokens, + threshold_is_inclusive=threshold_is_inclusive, + ) + standard_key: Final = cost_key.removesuffix(get_service_tier_cost_key("", service_tier)) + if model_info.get(cost_key) is None and model_info.get(standard_key) is None: return float(tokens) * prompt_base_cost return calculate_cost_component(model_info, cost_key, tokens) @@ -1115,6 +1149,9 @@ def _calculate_input_cost( cache_creation_cost: float, cache_creation_cost_above_1hr: float, service_tier: str | None = None, + *, + prompt_tokens: int = 0, + threshold_is_inclusive: bool = False, ) -> float: """ Calculates the input cost for a given model, prompt tokens, and completion tokens. @@ -1149,6 +1186,8 @@ def _calculate_input_cost( prompt_tokens_details["audio_tokens"], prompt_base_cost, service_tier, + prompt_tokens=prompt_tokens, + threshold_is_inclusive=threshold_is_inclusive, ) ### IMAGE TOKEN COST @@ -1467,6 +1506,8 @@ def generic_cost_per_token( cache_creation_cost=cache_creation_cost, cache_creation_cost_above_1hr=cache_creation_cost_above_1hr, service_tier=service_tier, + prompt_tokens=usage.prompt_tokens, + threshold_is_inclusive=_uses_inclusive_token_thresholds(custom_llm_provider), ) ## CALCULATE OUTPUT COST @@ -1524,11 +1565,9 @@ def generic_cost_per_token( ## IMAGE COST if not is_text_tokens_total and image_tokens and image_tokens > 0: - _output_cost_per_image_token = get_cost_per_unit(resolved_model_info, "output_cost_per_image_token", None) - _output_cost_per_image_token = ( - _output_cost_per_image_token if _output_cost_per_image_token is not None else completion_base_cost - ) - completion_cost += float(image_tokens) * _output_cost_per_image_token + image_cost_key: Final = get_service_tier_cost_key("output_cost_per_image_token", service_tier) + image_rate: Final = get_cost_per_unit(resolved_model_info, image_cost_key, None) + completion_cost += float(image_tokens) * (completion_base_cost if image_rate is None else image_rate) ## VIDEO COST if not is_text_tokens_total and video_tokens and video_tokens > 0: diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index e4c902b9504..2c183527ce8 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -28999,7 +28999,13 @@ "output_cost_per_token_batches": 1.25e-06, "output_cost_per_token_flex": 1.25e-06, "output_cost_per_token_priority": 4.5e-06, - "supports_image_size": false + "supports_image_size": false, + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 3e-07, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "gemini-2.5-flash-image": { "deprecation_date": "2027-03-15", @@ -29109,7 +29115,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000216 }, "gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -29166,7 +29173,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000216 }, "gemini-3.1-flash-image": { "cache_read_input_token_cost": 5e-08, @@ -29221,7 +29229,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000108 }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -29269,14 +29278,14 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000108 }, "gemini-3.1-flash-lite-image": { "cache_read_input_token_cost": 2.5e-08, "cache_read_input_token_cost_batches": 1.25e-08, "cache_read_input_token_cost_flex": 1.25e-08, "cache_read_input_token_cost_priority": 4.5e-08, - "deprecation_date": "2027-06-28", "input_cost_per_image": 0.00028, "input_cost_per_token": 2.5e-07, "input_cost_per_token_batches": 1.25e-07, @@ -29316,7 +29325,8 @@ "supports_response_schema": false, "supports_system_messages": true, "supports_video_input": true, - "supports_vision": true + "supports_vision": true, + "output_cost_per_image_token_priority": 5.4e-05 }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -29437,7 +29447,15 @@ }, "web_search_billing_unit": "per_query", "google_maps_grounding_cost_per_query": 0.014, - "input_cost_per_audio_token_batches": 2.5e-07 + "input_cost_per_audio_token_batches": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens_priority": 9e-07, + "cache_read_input_audio_token_cost_flex": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_flex": 2.5e-07, + "cache_read_input_audio_token_cost_priority": 9e-08, + "input_cost_per_audio_token_flex": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens": 5e-07, + "cache_read_input_audio_token_cost_batches": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_batches": 2.5e-07 }, "gemini-3.5-flash-lite": { "deprecation_date": "2027-07-21", @@ -29600,7 +29618,13 @@ "output_cost_per_token_batches": 2e-07, "output_cost_per_token_flex": 2e-07, "output_cost_per_token_priority": 7.2e-07, - "supports_image_size": false + "supports_image_size": false, + "input_cost_per_audio_token_above_200k_tokens_priority": 5.4e-07, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-08, + "cache_read_input_audio_token_cost_priority": 5.4e-08, + "input_cost_per_audio_token_flex": 5e-08, + "input_cost_per_audio_token_above_200k_tokens": 3e-07, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-08 }, "gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -29901,7 +29925,9 @@ "output_cost_per_token_above_200k_tokens_priority": 2.7e-05, "output_cost_per_token_batches": 5e-06, "output_cost_per_token_flex": 5e-06, - "output_cost_per_token_priority": 1.8e-05 + "output_cost_per_token_priority": 1.8e-05, + "input_cost_per_token_above_200k_tokens_flex": 1.25e-06, + "output_cost_per_token_above_200k_tokens_flex": 7.5e-06 }, "gemini-3.1-pro-preview": { "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -29967,7 +29993,9 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_token_above_200k_tokens_flex": 2e-06, + "output_cost_per_token_above_200k_tokens_flex": 9e-06 }, "gemini-3.1-pro-preview-customtools": { "prompt_cache_min_tokens": 4096, @@ -30145,7 +30173,13 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 1e-06, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "vertex_ai/gemini-3.5-flash": { "prompt_cache_min_tokens": 4096, @@ -30560,7 +30594,9 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_token_above_200k_tokens_flex": 2e-06, + "output_cost_per_token_above_200k_tokens_flex": 9e-06 }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "prompt_cache_min_tokens": 4096, @@ -32535,7 +32571,13 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 1e-06, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "gemini-omni-flash-preview": { "input_cost_per_audio_token": 1.5e-06, @@ -52581,7 +52623,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000216 }, "vertex_ai/gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -52614,7 +52657,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000216 }, "vertex_ai/gemini-3.1-flash-image": { "cache_read_input_token_cost": 5e-08, @@ -52646,7 +52690,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000108 }, "vertex_ai/gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -52670,14 +52715,14 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000108 }, "vertex_ai/gemini-3.1-flash-lite-image": { "cache_read_input_token_cost": 2.5e-08, "cache_read_input_token_cost_batches": 1.25e-08, "cache_read_input_token_cost_flex": 1.25e-08, "cache_read_input_token_cost_priority": 4.5e-08, - "deprecation_date": "2027-06-28", "input_cost_per_image": 0.00028, "input_cost_per_token": 2.5e-07, "input_cost_per_token_batches": 1.25e-07, @@ -52717,7 +52762,8 @@ "supports_response_schema": false, "supports_system_messages": true, "supports_video_input": true, - "supports_vision": true + "supports_vision": true, + "output_cost_per_image_token_priority": 5.4e-05 }, "vertex_ai/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -52839,7 +52885,15 @@ }, "web_search_billing_unit": "per_query", "google_maps_grounding_cost_per_query": 0.014, - "input_cost_per_audio_token_batches": 2.5e-07 + "input_cost_per_audio_token_batches": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens_priority": 9e-07, + "cache_read_input_audio_token_cost_flex": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_flex": 2.5e-07, + "cache_read_input_audio_token_cost_priority": 9e-08, + "input_cost_per_audio_token_flex": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens": 5e-07, + "cache_read_input_audio_token_cost_batches": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_batches": 2.5e-07 }, "vertex_ai/gemini-3.5-flash-lite": { "deprecation_date": "2027-07-21", @@ -75557,7 +75611,8 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 5.4e-05 }, "vertex_ai/gemini-nano-banana-2.1": { "cache_read_input_token_cost": 1.5e-07, @@ -75607,7 +75662,8 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 5.4e-05 }, "azure_ai/grok-4.7": { "cache_read_input_token_cost": 5e-07, diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 376579ec372..104ab9d928d 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -352,6 +352,10 @@ class ModelInfoBase(ProviderSpecificModelInfo, total=False): input_cost_per_character: float | None # only for vertex ai models input_cost_per_audio_token: float | None input_cost_per_audio_token_flex: ReadOnly[float | None] + input_cost_per_audio_token_above_200k_tokens: ReadOnly[float | None] + input_cost_per_audio_token_above_200k_tokens_flex: ReadOnly[float | None] + input_cost_per_audio_token_above_200k_tokens_priority: ReadOnly[float | None] + input_cost_per_audio_token_above_200k_tokens_batches: ReadOnly[float | None] input_cost_per_audio_token_priority: ReadOnly[float | None] input_cost_per_token_above_128k_tokens: float | None # only for vertex ai models input_cost_per_token_above_200k_tokens: float | None # only for vertex ai gemini-2.5-pro models @@ -377,10 +381,12 @@ class ModelInfoBase(ProviderSpecificModelInfo, total=False): input_cost_per_token_batches: float | None input_cost_per_video_token_batches: ReadOnly[float | None] input_cost_per_token_above_200k_tokens_batches: ReadOnly[float | None] + input_cost_per_token_above_200k_tokens_flex: ReadOnly[float | None] input_cost_per_token_above_100k_tokens_batches: ReadOnly[float | None] input_cost_per_token_above_272k_tokens_batches: ReadOnly[float | None] output_cost_per_token_batches: float | None output_cost_per_token_above_200k_tokens_batches: ReadOnly[float | None] + output_cost_per_token_above_200k_tokens_flex: ReadOnly[float | None] output_cost_per_token_above_100k_tokens_batches: ReadOnly[float | None] output_cost_per_token_above_272k_tokens_batches: ReadOnly[float | None] output_cost_per_token: Required[float | None] @@ -413,6 +419,7 @@ class ModelInfoBase(ProviderSpecificModelInfo, total=False): output_cost_per_pixel: ReadOnly[float | None] output_cost_per_image_token: float | None output_cost_per_image_token_batches: ReadOnly[float | None] + output_cost_per_image_token_priority: ReadOnly[float | None] output_cost_per_video_token: float | None # for gemini omni models with video output output_vector_size: int | None output_cost_per_reasoning_token: float | None @@ -3981,6 +3988,10 @@ class CustomPricingLiteLLMParams(MirroredPricingParams): input_cost_per_character_above_128k_tokens: float | None = None input_cost_per_audio_token: float | None = None input_cost_per_audio_token_flex: float | None = None + input_cost_per_audio_token_above_200k_tokens: float | None = None + input_cost_per_audio_token_above_200k_tokens_flex: float | None = None + input_cost_per_audio_token_above_200k_tokens_priority: float | None = None + input_cost_per_audio_token_above_200k_tokens_batches: float | None = None input_cost_per_audio_token_priority: float | None = None input_cost_per_token_cache_hit: float | None = None input_cost_per_token_above_128k_tokens: float | None = None @@ -3991,6 +4002,7 @@ class CustomPricingLiteLLMParams(MirroredPricingParams): input_cost_per_token_above_272k_tokens_flex: float | None = None input_cost_per_token_above_272k_tokens_ultrafast: float | None = None input_cost_per_token_above_200k_tokens_batches: float | None = None + input_cost_per_token_above_200k_tokens_flex: float | None = None input_cost_per_token_above_100k_tokens_batches: float | None = None input_cost_per_token_above_272k_tokens_batches: float | None = None input_cost_per_query: float | None = None @@ -4020,12 +4032,14 @@ class CustomPricingLiteLLMParams(MirroredPricingParams): output_cost_per_token_above_272k_tokens_flex: float | None = None output_cost_per_token_above_272k_tokens_ultrafast: float | None = None output_cost_per_token_above_200k_tokens_batches: float | None = None + output_cost_per_token_above_200k_tokens_flex: float | None = None output_cost_per_token_above_100k_tokens_batches: float | None = None output_cost_per_token_above_272k_tokens_batches: float | None = None output_cost_per_character_above_128k_tokens: float | None = None output_cost_per_image: float | None = None output_cost_per_image_token: float | None = None output_cost_per_image_token_batches: float | None = None + output_cost_per_image_token_priority: float | None = None output_cost_per_video_token: float | None = None output_cost_per_reasoning_token: float | None = None output_cost_per_reasoning_token_flex: float | None = None diff --git a/litellm/utils.py b/litellm/utils.py index e570d6c1198..c4a51de1560 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -6616,6 +6616,18 @@ def get_model_info_helper( input_cost_per_text_message=_model_info.get("input_cost_per_text_message", None), input_cost_per_audio_token=_model_info.get("input_cost_per_audio_token", None), input_cost_per_audio_token_flex=_model_info.get("input_cost_per_audio_token_flex", None), + input_cost_per_audio_token_above_200k_tokens=_model_info.get( + "input_cost_per_audio_token_above_200k_tokens", None + ), + input_cost_per_audio_token_above_200k_tokens_flex=_model_info.get( + "input_cost_per_audio_token_above_200k_tokens_flex", None + ), + input_cost_per_audio_token_above_200k_tokens_priority=_model_info.get( + "input_cost_per_audio_token_above_200k_tokens_priority", None + ), + input_cost_per_audio_token_above_200k_tokens_batches=_model_info.get( + "input_cost_per_audio_token_above_200k_tokens_batches", None + ), input_cost_per_audio_token_priority=_model_info.get("input_cost_per_audio_token_priority", None), input_cost_per_image_token=_model_info.get("input_cost_per_image_token", None), input_cost_per_video_token=_model_info.get("input_cost_per_video_token", None), @@ -6629,6 +6641,9 @@ def get_model_info_helper( input_cost_per_token_above_200k_tokens_batches=_model_info.get( "input_cost_per_token_above_200k_tokens_batches" ), + input_cost_per_token_above_200k_tokens_flex=_model_info.get( + "input_cost_per_token_above_200k_tokens_flex", None + ), input_cost_per_token_above_272k_tokens_batches=_model_info.get( "input_cost_per_token_above_272k_tokens_batches" ), @@ -6636,6 +6651,9 @@ def get_model_info_helper( output_cost_per_token_above_200k_tokens_batches=_model_info.get( "output_cost_per_token_above_200k_tokens_batches" ), + output_cost_per_token_above_200k_tokens_flex=_model_info.get( + "output_cost_per_token_above_200k_tokens_flex", None + ), output_cost_per_token_above_272k_tokens_batches=_model_info.get( "output_cost_per_token_above_272k_tokens_batches" ), @@ -6697,6 +6715,7 @@ def get_model_info_helper( output_cost_per_pixel=_model_info.get("output_cost_per_pixel", None), output_cost_per_image_token=_model_info.get("output_cost_per_image_token", None), output_cost_per_image_token_batches=_model_info.get("output_cost_per_image_token_batches", None), + output_cost_per_image_token_priority=_model_info.get("output_cost_per_image_token_priority", None), output_cost_per_video_token=_model_info.get("output_cost_per_video_token", None), output_vector_size=_model_info.get("output_vector_size", None), citation_cost_per_token=_model_info.get("citation_cost_per_token", None), diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index e4c902b9504..2c183527ce8 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -28999,7 +28999,13 @@ "output_cost_per_token_batches": 1.25e-06, "output_cost_per_token_flex": 1.25e-06, "output_cost_per_token_priority": 4.5e-06, - "supports_image_size": false + "supports_image_size": false, + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 3e-07, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "gemini-2.5-flash-image": { "deprecation_date": "2027-03-15", @@ -29109,7 +29115,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000216 }, "gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -29166,7 +29173,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000216 }, "gemini-3.1-flash-image": { "cache_read_input_token_cost": 5e-08, @@ -29221,7 +29229,8 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000108 }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -29269,14 +29278,14 @@ "period": "month", "shared_group": "gemini-3" }, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 0.000108 }, "gemini-3.1-flash-lite-image": { "cache_read_input_token_cost": 2.5e-08, "cache_read_input_token_cost_batches": 1.25e-08, "cache_read_input_token_cost_flex": 1.25e-08, "cache_read_input_token_cost_priority": 4.5e-08, - "deprecation_date": "2027-06-28", "input_cost_per_image": 0.00028, "input_cost_per_token": 2.5e-07, "input_cost_per_token_batches": 1.25e-07, @@ -29316,7 +29325,8 @@ "supports_response_schema": false, "supports_system_messages": true, "supports_video_input": true, - "supports_vision": true + "supports_vision": true, + "output_cost_per_image_token_priority": 5.4e-05 }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -29437,7 +29447,15 @@ }, "web_search_billing_unit": "per_query", "google_maps_grounding_cost_per_query": 0.014, - "input_cost_per_audio_token_batches": 2.5e-07 + "input_cost_per_audio_token_batches": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens_priority": 9e-07, + "cache_read_input_audio_token_cost_flex": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_flex": 2.5e-07, + "cache_read_input_audio_token_cost_priority": 9e-08, + "input_cost_per_audio_token_flex": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens": 5e-07, + "cache_read_input_audio_token_cost_batches": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_batches": 2.5e-07 }, "gemini-3.5-flash-lite": { "deprecation_date": "2027-07-21", @@ -29600,7 +29618,13 @@ "output_cost_per_token_batches": 2e-07, "output_cost_per_token_flex": 2e-07, "output_cost_per_token_priority": 7.2e-07, - "supports_image_size": false + "supports_image_size": false, + "input_cost_per_audio_token_above_200k_tokens_priority": 5.4e-07, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-08, + "cache_read_input_audio_token_cost_priority": 5.4e-08, + "input_cost_per_audio_token_flex": 5e-08, + "input_cost_per_audio_token_above_200k_tokens": 3e-07, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-08 }, "gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -29901,7 +29925,9 @@ "output_cost_per_token_above_200k_tokens_priority": 2.7e-05, "output_cost_per_token_batches": 5e-06, "output_cost_per_token_flex": 5e-06, - "output_cost_per_token_priority": 1.8e-05 + "output_cost_per_token_priority": 1.8e-05, + "input_cost_per_token_above_200k_tokens_flex": 1.25e-06, + "output_cost_per_token_above_200k_tokens_flex": 7.5e-06 }, "gemini-3.1-pro-preview": { "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -29967,7 +29993,9 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_token_above_200k_tokens_flex": 2e-06, + "output_cost_per_token_above_200k_tokens_flex": 9e-06 }, "gemini-3.1-pro-preview-customtools": { "prompt_cache_min_tokens": 4096, @@ -30145,7 +30173,13 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 1e-06, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "vertex_ai/gemini-3.5-flash": { "prompt_cache_min_tokens": 4096, @@ -30560,7 +30594,9 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_token_above_200k_tokens_flex": 2e-06, + "output_cost_per_token_above_200k_tokens_flex": 9e-06 }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "prompt_cache_min_tokens": 4096, @@ -32535,7 +32571,13 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "input_cost_per_audio_token_above_200k_tokens_priority": 1.8e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 5e-07, + "cache_read_input_audio_token_cost_priority": 1.8e-07, + "input_cost_per_audio_token_flex": 5e-07, + "input_cost_per_audio_token_above_200k_tokens": 1e-06, + "input_cost_per_audio_token_above_200k_tokens_batches": 5e-07 }, "gemini-omni-flash-preview": { "input_cost_per_audio_token": 1.5e-06, @@ -52581,7 +52623,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000216 }, "vertex_ai/gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -52614,7 +52657,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000216 }, "vertex_ai/gemini-3.1-flash-image": { "cache_read_input_token_cost": 5e-08, @@ -52646,7 +52690,8 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000108 }, "vertex_ai/gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -52670,14 +52715,14 @@ "/v1/images/generations", "/v1/images/edits", "/v1/batch" - ] + ], + "output_cost_per_image_token_priority": 0.000108 }, "vertex_ai/gemini-3.1-flash-lite-image": { "cache_read_input_token_cost": 2.5e-08, "cache_read_input_token_cost_batches": 1.25e-08, "cache_read_input_token_cost_flex": 1.25e-08, "cache_read_input_token_cost_priority": 4.5e-08, - "deprecation_date": "2027-06-28", "input_cost_per_image": 0.00028, "input_cost_per_token": 2.5e-07, "input_cost_per_token_batches": 1.25e-07, @@ -52717,7 +52762,8 @@ "supports_response_schema": false, "supports_system_messages": true, "supports_video_input": true, - "supports_vision": true + "supports_vision": true, + "output_cost_per_image_token_priority": 5.4e-05 }, "vertex_ai/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -52839,7 +52885,15 @@ }, "web_search_billing_unit": "per_query", "google_maps_grounding_cost_per_query": 0.014, - "input_cost_per_audio_token_batches": 2.5e-07 + "input_cost_per_audio_token_batches": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens_priority": 9e-07, + "cache_read_input_audio_token_cost_flex": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_flex": 2.5e-07, + "cache_read_input_audio_token_cost_priority": 9e-08, + "input_cost_per_audio_token_flex": 2.5e-07, + "input_cost_per_audio_token_above_200k_tokens": 5e-07, + "cache_read_input_audio_token_cost_batches": 2.5e-08, + "input_cost_per_audio_token_above_200k_tokens_batches": 2.5e-07 }, "vertex_ai/gemini-3.5-flash-lite": { "deprecation_date": "2027-07-21", @@ -75557,7 +75611,8 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 5.4e-05 }, "vertex_ai/gemini-nano-banana-2.1": { "cache_read_input_token_cost": 1.5e-07, @@ -75607,7 +75662,8 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "web_search_billing_unit": "per_query" + "web_search_billing_unit": "per_query", + "output_cost_per_image_token_priority": 5.4e-05 }, "azure_ai/grok-4.7": { "cache_read_input_token_cost": 5e-07, diff --git a/tests/unit/litellm_core_utils/llm_cost_calc/test_utils.py b/tests/unit/litellm_core_utils/llm_cost_calc/test_utils.py index b6c18e0da86..1d2a5e4cc9b 100644 --- a/tests/unit/litellm_core_utils/llm_cost_calc/test_utils.py +++ b/tests/unit/litellm_core_utils/llm_cost_calc/test_utils.py @@ -12,7 +12,7 @@ import litellm from litellm.integrations.custom_logger import CustomLogger from litellm.litellm_core_utils.logging_worker import GLOBAL_LOGGING_WORKER from litellm.types.llms.base import CachedTokensDetails -from litellm.types.utils import ModelResponse, PromptTokensDetailsWrapper, Usage +from litellm.types.utils import CompletionTokensDetailsWrapper, ModelResponse, PromptTokensDetailsWrapper, Usage TIER_MODEL: Final = "tier-priced-test-model" TIER_ROW: Final[Mapping[str, float]] = MappingProxyType( @@ -48,6 +48,190 @@ AUDIO_TIER_ROW: Final[Mapping[str, float]] = MappingProxyType( ) +@pytest.mark.parametrize("image_tokens", (60, 100)) +@pytest.mark.parametrize( + ("service_tier", "priority_rate", "image_rate"), + ((None, 11e-06, 7e-06), ("priority", 11e-06, 11e-06), ("flex", 11e-06, 7e-06), ("priority", 0.0, 0.0)), +) +def test_completion_cost_uses_priority_image_output_rate( + local_model_cost_map: None, service_tier: str | None, priority_rate: float, image_rate: float, image_tokens: int +) -> None: + model: Final = "gemini-synthetic-image-priority" + litellm.register_model( + { + model: { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 5e-06, + "output_cost_per_image_token": 7e-06, + "output_cost_per_image_token_priority": priority_rate, + } + } + ) + response: Final = ModelResponse( + model=model, + usage=Usage( + prompt_tokens=20, + completion_tokens=100, + total_tokens=120, + completion_tokens_details=CompletionTokensDetailsWrapper(image_tokens=image_tokens), + ), + ) + cost: Final = litellm.completion_cost( + completion_response=response, model=model, custom_llm_provider="vertex_ai", service_tier=service_tier + ) + assert cost == pytest.approx(20 * 3e-06 + (100 - image_tokens) * 5e-06 + image_tokens * image_rate) + + +@pytest.mark.parametrize("prompt_tokens", (199_999, 200_000, 200_001)) +@pytest.mark.parametrize( + ("service_tier", "flat_rate", "context_rate"), + ((None, 7e-06, 11e-06), ("priority", 13e-06, 17e-06), ("flex", 19e-06, 23e-06)), +) +def test_completion_cost_uses_total_prompt_for_audio_context_tiers( + local_model_cost_map: None, prompt_tokens: int, service_tier: str | None, flat_rate: float, context_rate: float +) -> None: + model: Final = "gemini-synthetic-audio-context" + litellm.register_model( + { + model: { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 5e-06, + "input_cost_per_audio_token": 7e-06, + "input_cost_per_audio_token_above_200k_tokens": 11e-06, + "input_cost_per_audio_token_priority": 13e-06, + "input_cost_per_audio_token_above_200k_tokens_priority": 17e-06, + "input_cost_per_audio_token_flex": 19e-06, + "input_cost_per_audio_token_above_200k_tokens_flex": 23e-06, + } + } + ) + response: Final = ModelResponse( + model=model, + usage=Usage( + prompt_tokens=prompt_tokens, + completion_tokens=10, + total_tokens=prompt_tokens + 10, + prompt_tokens_details=PromptTokensDetailsWrapper(audio_tokens=100), + ), + ) + cost: Final = litellm.completion_cost( + completion_response=response, model=model, custom_llm_provider="vertex_ai", service_tier=service_tier + ) + audio_rate: Final = context_rate if prompt_tokens > 200_000 else flat_rate + assert cost == pytest.approx((prompt_tokens - 100) * 3e-06 + 100 * audio_rate + 10 * 5e-06) + + +@pytest.mark.parametrize("prompt_tokens", (200_000, 200_001)) +def test_batch_cost_uses_audio_context_and_image_output_tiers(local_model_cost_map: None, prompt_tokens: int) -> None: + from litellm.cost_calculator import batch_cost_calculator + + model: Final = "gemini-synthetic-batch-audio-context" + litellm.register_model( + { + model: { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 6e-06, + "output_cost_per_token": 10e-06, + "input_cost_per_token_batches": 3e-06, + "output_cost_per_token_batches": 5e-06, + "input_cost_per_token_above_200k_tokens_batches": 13e-06, + "output_cost_per_token_above_200k_tokens_batches": 17e-06, + "output_cost_per_image_token_batches": 19e-06, + "input_cost_per_audio_token_batches": 7e-06, + "input_cost_per_audio_token_above_200k_tokens_batches": 11e-06, + } + } + ) + usage: Final = Usage( + prompt_tokens=prompt_tokens, + completion_tokens=20, + total_tokens=prompt_tokens + 20, + prompt_tokens_details=PromptTokensDetailsWrapper(audio_tokens=100), + completion_tokens_details=CompletionTokensDetailsWrapper(image_tokens=10), + ) + cost: Final = batch_cost_calculator(model=model, custom_llm_provider="vertex_ai", usage=usage) + audio_rate: Final = 11e-06 if prompt_tokens > 200_000 else 7e-06 + input_rate: Final = 13e-06 if prompt_tokens > 200_000 else 3e-06 + output_rate: Final = 17e-06 if prompt_tokens > 200_000 else 5e-06 + assert sum(cost) == pytest.approx( + (prompt_tokens - 100) * input_rate + 100 * audio_rate + 10 * output_rate + 10 * 19e-06 + ) + + +@pytest.mark.parametrize("prompt_tokens", (200_000, 200_001)) +def test_completion_cost_uses_flex_context_input_and_output_rates( + local_model_cost_map: None, prompt_tokens: int +) -> None: + model: Final = "gemini-synthetic-flex-context" + litellm.register_model( + { + model: { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 6e-06, + "output_cost_per_token": 10e-06, + "input_cost_per_token_flex": 3e-06, + "output_cost_per_token_flex": 5e-06, + "input_cost_per_token_above_200k_tokens_flex": 7e-06, + "output_cost_per_token_above_200k_tokens_flex": 11e-06, + } + } + ) + response: Final = ModelResponse( + model=model, usage=Usage(prompt_tokens=prompt_tokens, completion_tokens=10, total_tokens=prompt_tokens + 10) + ) + cost: Final = litellm.completion_cost( + completion_response=response, model=model, custom_llm_provider="vertex_ai", service_tier="flex" + ) + input_rate: Final = 7e-06 if prompt_tokens > 200_000 else 3e-06 + output_rate: Final = 11e-06 if prompt_tokens > 200_000 else 5e-06 + assert cost == pytest.approx(prompt_tokens * input_rate + 10 * output_rate) + + +@pytest.mark.parametrize( + ("audio_fields", "audio_rate"), + ( + ({}, 3e-06), + ({"input_cost_per_audio_token": 7e-06}, 7e-06), + ({"input_cost_per_audio_token_above_200k_tokens": 11e-06}, 11e-06), + ({"input_cost_per_audio_token_above_200k_tokens_priority": 0.0}, 0.0), + ), +) +def test_audio_context_rates_preserve_fallbacks_and_explicit_zero( + local_model_cost_map: None, audio_fields: Mapping[str, float], audio_rate: float +) -> None: + model: Final = "gemini-synthetic-audio-fallback" + litellm.register_model( + { + model: { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 5e-06, + **audio_fields, + } + } + ) + response: Final = ModelResponse( + model=model, + usage=Usage( + prompt_tokens=200_001, + completion_tokens=10, + total_tokens=200_011, + prompt_tokens_details=PromptTokensDetailsWrapper(audio_tokens=100), + ), + ) + cost: Final = litellm.completion_cost( + completion_response=response, model=model, custom_llm_provider="vertex_ai", service_tier="priority" + ) + assert cost == pytest.approx(199_901 * 3e-06 + 100 * audio_rate + 10 * 5e-06) + + def _cost_at(prices: Mapping[str, float], column_suffix: str) -> float: return ( (PROMPT_TOKENS - CACHED_TOKENS) * prices[f"input_cost_per_token{column_suffix}"] diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 80e04dbb0ce..4ccfb886be3 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -972,6 +972,13 @@ def test_aaamodel_prices_and_context_window_json_is_valid(): "cache_read_input_audio_token_cost_batches": {"type": "number"}, "cache_read_input_audio_token_cost_flex": {"type": "number"}, "cache_read_input_audio_token_cost_priority": {"type": "number"}, + "input_cost_per_audio_token_above_200k_tokens": {"type": "number"}, + "input_cost_per_audio_token_above_200k_tokens_batches": {"type": "number"}, + "input_cost_per_audio_token_above_200k_tokens_flex": {"type": "number"}, + "input_cost_per_audio_token_above_200k_tokens_priority": {"type": "number"}, + "input_cost_per_token_above_200k_tokens_flex": {"type": "number"}, + "output_cost_per_image_token_priority": {"type": "number"}, + "output_cost_per_token_above_200k_tokens_flex": {"type": "number"}, "cache_read_input_image_token_cost": {"type": "number"}, "audio_transcription_config": {"type": "string"}, "deprecation_date": {"type": "string"}, @@ -1375,6 +1382,27 @@ def test_aaamodel_prices_and_context_window_json_is_valid(): raise AssertionError(error_message) +def test_cost_map_schema_accepts_vertex_modality_and_context_tiers() -> None: + row: Final = { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 1e-6, + "output_cost_per_token": 2e-6, + "input_cost_per_token_above_200k_tokens_flex": 3e-6, + "output_cost_per_token_above_200k_tokens_flex": 4e-6, + "input_cost_per_token_above_200k_tokens_batches": 3e-6, + "output_cost_per_token_above_200k_tokens_batches": 4e-6, + "input_cost_per_audio_token_above_200k_tokens": 5e-6, + "input_cost_per_audio_token_above_200k_tokens_flex": 6e-6, + "input_cost_per_audio_token_above_200k_tokens_priority": 7e-6, + "input_cost_per_audio_token_above_200k_tokens_batches": 8e-6, + "output_cost_per_image_token_priority": 9e-6, + "output_cost_per_image_token_batches": 10e-6, + } + + assert Draft7Validator(_COST_MAP_ROW_SCHEMA).is_valid({"synthetic-vertex-tier-model": row}) + + def test_max_tokens_consistency(): """ Test that max_tokens == max_output_tokens for all models. @@ -10014,3 +10042,24 @@ def test_get_optional_params_forwards_a_tool_config_cache_point_to_a_downstream_ ) assert optional_params["extra_body"] == {"kept": True, "cache_control_injection_points": [point]} + + +def test_cost_map_schema_accepts_vertex_modality_and_context_tiers() -> None: + row: Final = { + "litellm_provider": "vertex_ai", + "mode": "chat", + "input_cost_per_token": 1e-6, + "output_cost_per_token": 2e-6, + "input_cost_per_token_above_200k_tokens_flex": 3e-6, + "output_cost_per_token_above_200k_tokens_flex": 4e-6, + "input_cost_per_token_above_200k_tokens_batches": 3e-6, + "output_cost_per_token_above_200k_tokens_batches": 4e-6, + "input_cost_per_audio_token_above_200k_tokens": 5e-6, + "input_cost_per_audio_token_above_200k_tokens_flex": 6e-6, + "input_cost_per_audio_token_above_200k_tokens_priority": 7e-6, + "input_cost_per_audio_token_above_200k_tokens_batches": 8e-6, + "output_cost_per_image_token_priority": 9e-6, + "output_cost_per_image_token_batches": 10e-6, + } + + assert Draft7Validator(_COST_MAP_ROW_SCHEMA).is_valid({"synthetic-vertex-tier-model": row}) diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index 5341035992b..89cc9157359 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -35129,6 +35129,14 @@ export interface components { input_cost_per_audio_per_second_above_128k_tokens?: number | null; /** Input Cost Per Audio Token */ input_cost_per_audio_token?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens */ + input_cost_per_audio_token_above_200k_tokens?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Batches */ + input_cost_per_audio_token_above_200k_tokens_batches?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Flex */ + input_cost_per_audio_token_above_200k_tokens_flex?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Priority */ + input_cost_per_audio_token_above_200k_tokens_priority?: number | null; /** Input Cost Per Audio Token Batches */ input_cost_per_audio_token_batches?: number | null; /** Input Cost Per Audio Token Flex */ @@ -35167,6 +35175,8 @@ export interface components { input_cost_per_token_above_200k_tokens?: number | null; /** Input Cost Per Token Above 200K Tokens Batches */ input_cost_per_token_above_200k_tokens_batches?: number | null; + /** Input Cost Per Token Above 200K Tokens Flex */ + input_cost_per_token_above_200k_tokens_flex?: number | null; /** Input Cost Per Token Above 200K Tokens Priority */ input_cost_per_token_above_200k_tokens_priority?: number | null; /** Input Cost Per Token Above 272K Tokens */ @@ -35274,6 +35284,8 @@ export interface components { output_cost_per_image_token?: number | null; /** Output Cost Per Image Token Batches */ output_cost_per_image_token_batches?: number | null; + /** Output Cost Per Image Token Priority */ + output_cost_per_image_token_priority?: number | null; /** Output Cost Per Pixel */ output_cost_per_pixel?: number | null; /** Output Cost Per Reasoning Token */ @@ -35308,6 +35320,8 @@ export interface components { output_cost_per_token_above_200k_tokens?: number | null; /** Output Cost Per Token Above 200K Tokens Batches */ output_cost_per_token_above_200k_tokens_batches?: number | null; + /** Output Cost Per Token Above 200K Tokens Flex */ + output_cost_per_token_above_200k_tokens_flex?: number | null; /** Output Cost Per Token Above 200K Tokens Priority */ output_cost_per_token_above_200k_tokens_priority?: number | null; /** Output Cost Per Token Above 272K Tokens */ @@ -50374,6 +50388,14 @@ export interface components { input_cost_per_audio_per_second_above_128k_tokens?: number | null; /** Input Cost Per Audio Token */ input_cost_per_audio_token?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens */ + input_cost_per_audio_token_above_200k_tokens?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Batches */ + input_cost_per_audio_token_above_200k_tokens_batches?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Flex */ + input_cost_per_audio_token_above_200k_tokens_flex?: number | null; + /** Input Cost Per Audio Token Above 200K Tokens Priority */ + input_cost_per_audio_token_above_200k_tokens_priority?: number | null; /** Input Cost Per Audio Token Batches */ input_cost_per_audio_token_batches?: number | null; /** Input Cost Per Audio Token Flex */ @@ -50412,6 +50434,8 @@ export interface components { input_cost_per_token_above_200k_tokens?: number | null; /** Input Cost Per Token Above 200K Tokens Batches */ input_cost_per_token_above_200k_tokens_batches?: number | null; + /** Input Cost Per Token Above 200K Tokens Flex */ + input_cost_per_token_above_200k_tokens_flex?: number | null; /** Input Cost Per Token Above 200K Tokens Priority */ input_cost_per_token_above_200k_tokens_priority?: number | null; /** Input Cost Per Token Above 272K Tokens */ @@ -50519,6 +50543,8 @@ export interface components { output_cost_per_image_token?: number | null; /** Output Cost Per Image Token Batches */ output_cost_per_image_token_batches?: number | null; + /** Output Cost Per Image Token Priority */ + output_cost_per_image_token_priority?: number | null; /** Output Cost Per Pixel */ output_cost_per_pixel?: number | null; /** Output Cost Per Reasoning Token */ @@ -50553,6 +50579,8 @@ export interface components { output_cost_per_token_above_200k_tokens?: number | null; /** Output Cost Per Token Above 200K Tokens Batches */ output_cost_per_token_above_200k_tokens_batches?: number | null; + /** Output Cost Per Token Above 200K Tokens Flex */ + output_cost_per_token_above_200k_tokens_flex?: number | null; /** Output Cost Per Token Above 200K Tokens Priority */ output_cost_per_token_above_200k_tokens_priority?: number | null; /** Output Cost Per Token Above 272K Tokens */