fix(vertex-ai): sync tier prices and retirement floors (#49964)

Backport of #49964 to lts/1.108.x.
Cherry-picked from 62f85afacf (main). The cost-map schema keys and the schema test were re-applied by hand onto the line's test_utils.py, and the priority-markup test the line does not have was left out.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-11-04 23:54:32 +00:00 • committed by kerry
parent 4f6bc3c507
commit 8fa525c90d
9 changed files with 509 additions and 57 deletions

View file

@ -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)

View file

@ -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:

View file

@ -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,

View file

@ -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

View file

@ -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),

View file

@ -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,

View file

@ -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}"]

View file

@ -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})

View file

@ -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 */