diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index a8055a25ff3..b2b32782067 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -19527,6 +19527,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19584,6 +19585,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19738,6 +19740,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "deprecation_date": "2027-05-19", "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 1.5e-06, @@ -19790,6 +19793,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -19844,6 +19848,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -19898,6 +19903,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19955,6 +19961,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -21464,6 +21471,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 1.5e-07, "input_cost_per_audio_token": 1e-06, "input_cost_per_token": 1.5e-06, @@ -21518,6 +21526,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21575,6 +21584,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21665,6 +21675,7 @@ "tpm": 800000 }, "gemini/gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "input_cost_per_token": 2e-06, @@ -21722,6 +21733,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "input_cost_per_token": 2e-06, @@ -21860,6 +21872,7 @@ "supports_vision": true }, "gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "deprecation_date": "2027-05-19", "cache_read_input_token_cost": 1.5e-07, "input_cost_per_audio_token": 1e-06, @@ -21913,6 +21926,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21968,6 +21982,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index a8055a25ff3..b2b32782067 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -19527,6 +19527,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19584,6 +19585,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19738,6 +19740,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "deprecation_date": "2027-05-19", "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 1.5e-06, @@ -19790,6 +19793,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -19844,6 +19848,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -19898,6 +19903,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -19955,6 +19961,7 @@ "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "cache_creation_input_token_cost_above_200k_tokens": 2.5e-07, @@ -21464,6 +21471,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 1.5e-07, "input_cost_per_audio_token": 1e-06, "input_cost_per_token": 1.5e-06, @@ -21518,6 +21526,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21575,6 +21584,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21665,6 +21675,7 @@ "tpm": 800000 }, "gemini/gemini-3.1-pro-preview": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "input_cost_per_token": 2e-06, @@ -21722,6 +21733,7 @@ "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview-customtools": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 2e-07, "cache_read_input_token_cost_above_200k_tokens": 4e-07, "input_cost_per_token": 2e-06, @@ -21860,6 +21872,7 @@ "supports_vision": true }, "gemini-3.5-flash": { + "prompt_cache_min_tokens": 4096, "deprecation_date": "2027-05-19", "cache_read_input_token_cost": 1.5e-07, "input_cost_per_audio_token": 1e-06, @@ -21913,6 +21926,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.6-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, @@ -21968,6 +21982,7 @@ "web_search_billing_unit": "per_query" }, "gemini-3.7-flash": { + "prompt_cache_min_tokens": 4096, "cache_read_input_token_cost": 7.5e-08, "cache_read_input_token_cost_flex": 3.75e-08, "input_cost_per_token": 7.5e-07, diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index 0218f8f6219..1d9477432ee 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -2,6 +2,7 @@ import json import logging import os import sys +from typing import Final from unittest.mock import AsyncMock, MagicMock, patch import pytest @@ -4384,6 +4385,45 @@ def test_get_prompt_cache_min_tokens_differs_per_platform_for_same_model(local_m ) +GEMINI_4096_CACHE_MIN_MODELS: Final = tuple( + prefix + base + for base in ( + "gemini-3.5-flash", + "gemini-3.6-flash", + "gemini-3.7-flash", + "gemini-3.1-pro-preview", + "gemini-3.1-pro-preview-customtools", + ) + for prefix in ("", "gemini/", "vertex_ai/") +) + + +def test_gemini_3_flash_and_31_pro_preview_resolve_4096_cache_minimum(local_model_cost_map: None) -> None: + """Regression for the cost map missing prompt_cache_min_tokens on these models: Google rejects + explicit caching below 4,096 tokens for them (https://ai.google.dev/gemini-api/docs/caching), so + the 1024 default sent cachedContents creates Vertex answered with a hard 400.""" + wrong: Final = { + model: get_prompt_cache_min_tokens(model=model) + for model in GEMINI_4096_CACHE_MIN_MODELS + if get_prompt_cache_min_tokens(model=model) != 4096 + } + assert not wrong, f"prompt_cache_min_tokens must be 4096: {wrong}" + + +def test_gemini_4096_cache_minimum_present_in_root_cost_map() -> None: + """The root map ships to the CDN independently of the bundled backup, so both must carry the + minimum or proxies reading one of them regress to the 1024 default.""" + root_map_path: Final = os.path.join(os.path.dirname(__file__), "..", "..", "model_prices_and_context_window.json") + with open(root_map_path) as f: + root_map: Final = json.load(f) + wrong: Final = { + model: root_map[model].get("prompt_cache_min_tokens") + for model in GEMINI_4096_CACHE_MIN_MODELS + if root_map[model].get("prompt_cache_min_tokens") != 4096 + } + assert not wrong, f"prompt_cache_min_tokens must be 4096: {wrong}" + + def test_get_prompt_cache_min_tokens_unmapped_model_falls_back_to_default(local_model_cost_map: None) -> None: """get_model_info raises for a model it has no entry for. The resolver must swallow that and fall back to the default, otherwise the raise reaches callers that would read it as