From 040c6fe92057739c9605a4871f1ecd4ba3aaa6a6 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:00:13 -0300 Subject: [PATCH 1/7] fix(gemini): read web search cost from model_info instead of hardcode The Gemini web search cost calculator hardcoded $0.035 per request, which is only correct for Gemini 2.x models. Gemini 3.x models charge $0.014 per request. Read from search_context_cost_per_query in model_info (same field used by Anthropic, OpenAI, and Perplexity) with fallback to the legacy $0.035 for models not yet updated in the JSON. Also add search_context_cost_per_query to all 25 Gemini models that support web search in model_prices_and_context_window.json. Fixes #24369 --- litellm/llms/gemini/cost_calculator.py | 14 +- model_prices_and_context_window.json | 198 ++++++++++++++---- tests/litellm/llms/gemini/__init__.py | 0 .../llms/gemini/test_cost_calculator.py | 61 ++++++ 4 files changed, 225 insertions(+), 48 deletions(-) create mode 100644 tests/litellm/llms/gemini/__init__.py create mode 100644 tests/litellm/llms/gemini/test_cost_calculator.py diff --git a/litellm/llms/gemini/cost_calculator.py b/litellm/llms/gemini/cost_calculator.py index 45850e0d66..5de6eedfbe 100644 --- a/litellm/llms/gemini/cost_calculator.py +++ b/litellm/llms/gemini/cost_calculator.py @@ -31,11 +31,17 @@ def cost_per_token( def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> float: """ Calculates the cost per web search request for a given model, prompt tokens, and completion tokens. + + Uses ``search_context_cost_per_query`` from ``model_info`` when available + (keyed by ``search_context_size_medium`` as the default tier). Falls back + to the legacy $0.035 hardcode for models that haven't been updated yet. """ from litellm.types.utils import PromptTokensDetailsWrapper - # cost per web search request - cost_per_web_search_request = 35e-3 + # Resolve per-request cost from model_info, fallback to legacy default + _DEFAULT_COST = 35e-3 + search_costs = model_info.get("search_context_cost_per_query") or {} + _cost = search_costs.get("search_context_size_medium", _DEFAULT_COST) number_of_web_search_requests = 0 # Get number of web search requests @@ -47,10 +53,8 @@ def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> floa and usage.prompt_tokens_details.web_search_requests is not None ): number_of_web_search_requests = usage.prompt_tokens_details.web_search_requests - else: - number_of_web_search_requests = 0 # Calculate total cost - total_cost = cost_per_web_search_request * number_of_web_search_requests + total_cost = _cost * number_of_web_search_requests return total_cost diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index c53ee943c5..31c1289b0b 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -13963,7 +13963,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-lite-preview-06-17": { "deprecation_date": "2025-11-18", @@ -14552,7 +14557,12 @@ "supports_vision": true, "supports_web_search": true, "tpm": 250000, - "rpm": 10 + "rpm": 10, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, @@ -14604,17 +14614,14 @@ "uses_embed_content": true }, "vertex_ai/gemini-embedding-2-preview": { - "input_cost_per_audio_per_second": 0.00016, - "input_cost_per_image": 0.00012, - "input_cost_per_token": 2e-07, - "input_cost_per_video_per_second": 0.00079, + "input_cost_per_token": 1.5e-07, "litellm_provider": "vertex_ai", "max_input_tokens": 8192, "max_tokens": 8192, "mode": "embedding", "output_cost_per_token": 0, "output_vector_size": 3072, - "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing", + "source": "https://ai.google.dev/gemini-api/docs/embeddings#multimodal", "supports_multimodal": true, "uses_embed_content": true }, @@ -14631,18 +14638,6 @@ "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing", "uses_embed_content": true }, - "vertex_ai/gemini-embedding-2-preview": { - "input_cost_per_token": 1.5e-07, - "litellm_provider": "vertex_ai", - "max_input_tokens": 8192, - "max_tokens": 8192, - "mode": "embedding", - "output_cost_per_token": 0, - "output_vector_size": 3072, - "source": "https://ai.google.dev/gemini-api/docs/embeddings#multimodal", - "supports_multimodal": true, - "uses_embed_content": true - }, "gemini/gemini-embedding-001": { "input_cost_per_token": 1.5e-07, "litellm_provider": "gemini", @@ -14725,7 +14720,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.0-flash-001": { "cache_read_input_token_cost": 2.5e-08, @@ -14764,7 +14764,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, @@ -14801,7 +14806,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 4000000 + "tpm": 4000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash": { "cache_read_input_token_cost": 3e-08, @@ -14848,7 +14858,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-image": { "cache_read_input_token_cost": 3e-08, @@ -14898,7 +14913,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -14934,7 +14954,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-flash-image-preview": { "input_cost_per_token": 2.5e-07, @@ -14970,7 +14995,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -15006,7 +15036,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite": { "cache_read_input_token_cost": 1e-08, @@ -15053,7 +15088,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -15100,7 +15140,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-preview-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -15147,7 +15192,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-flash-latest": { "cache_read_input_token_cost": 7.5e-08, @@ -15194,7 +15244,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-flash-lite-latest": { "cache_read_input_token_cost": 2.5e-08, @@ -15241,7 +15296,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite-preview-06-17": { "deprecation_date": "2025-11-18", @@ -15289,7 +15349,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-preview-tts": { "input_cost_per_token": 3e-07, @@ -15352,7 +15417,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, @@ -15440,7 +15510,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -15493,7 +15568,12 @@ "supports_vision": true, "supports_web_search": true, "supports_native_streaming": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15546,7 +15626,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -15604,7 +15689,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -15662,7 +15752,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15750,7 +15845,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-exp-1114": { "input_cost_per_token": 0, @@ -31147,7 +31247,9 @@ "mode": "chat", "output_cost_per_token": 3.2e-06, "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing#glm-models", - "supported_regions": ["global"], + "supported_regions": [ + "global" + ], "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, @@ -36756,7 +36858,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 4000000 + "tpm": 4000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-native-audio-latest": { "input_cost_per_audio_token": 1e-06, @@ -37102,7 +37209,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-exp-1206": { "cache_read_input_token_cost": 3e-08, diff --git a/tests/litellm/llms/gemini/__init__.py b/tests/litellm/llms/gemini/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/litellm/llms/gemini/test_cost_calculator.py b/tests/litellm/llms/gemini/test_cost_calculator.py new file mode 100644 index 0000000000..19a7a83968 --- /dev/null +++ b/tests/litellm/llms/gemini/test_cost_calculator.py @@ -0,0 +1,61 @@ +import os +import sys + +import pytest + +sys.path.insert(0, os.path.abspath("../../../..")) + +from litellm.llms.gemini.cost_calculator import cost_per_web_search_request +from litellm.types.utils import PromptTokensDetailsWrapper, Usage + + +def _make_usage(web_search_requests: int) -> Usage: + return Usage( + prompt_tokens=100, + completion_tokens=50, + total_tokens=150, + prompt_tokens_details=PromptTokensDetailsWrapper( + web_search_requests=web_search_requests, + ), + ) + + +def test_web_search_cost_from_model_info(): + """Cost should come from model_info when search_context_cost_per_query is set.""" + model_info = { + "key": "gemini/gemini-3-flash-preview", + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014, + }, + } + cost = cost_per_web_search_request(usage=_make_usage(3), model_info=model_info) + assert cost == pytest.approx(0.014 * 3) + + +def test_web_search_cost_legacy_fallback(): + """Without search_context_cost_per_query, should fallback to $0.035.""" + model_info = {"key": "gemini/gemini-2.0-flash"} + cost = cost_per_web_search_request(usage=_make_usage(2), model_info=model_info) + assert cost == pytest.approx(0.035 * 2) + + +def test_web_search_cost_zero_requests(): + """Zero web search requests should return zero cost.""" + model_info = { + "key": "gemini/gemini-3-flash-preview", + "search_context_cost_per_query": { + "search_context_size_medium": 0.014, + }, + } + cost = cost_per_web_search_request(usage=_make_usage(0), model_info=model_info) + assert cost == 0.0 + + +def test_web_search_cost_no_usage_details(): + """Missing prompt_tokens_details should return zero cost.""" + model_info = {"key": "gemini/gemini-3-flash-preview"} + usage = Usage(prompt_tokens=100, completion_tokens=50, total_tokens=150) + cost = cost_per_web_search_request(usage=usage, model_info=model_info) + assert cost == 0.0 From 4c99f3ddd89b4b53ab25e55fdc45144b0cb30a45 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:20:00 -0300 Subject: [PATCH 2/7] fix(gemini): differentiate billing model and extract web search requests - Gemini 2.x charges per grounded prompt (flat $0.035), clamped to 1 regardless of internal query count - Gemini 3.x charges per search query ($0.014 each) - Extract web_search_requests from groundingMetadata in non-streaming responses (parity with streaming path) - Add search_context_cost_per_query to vertex_ai and base Gemini entries - Move tests to tests/test_litellm/ (CI directory) --- litellm/llms/gemini/cost_calculator.py | 28 +- .../vertex_and_google_ai_studio_gemini.py | 9 + ...odel_prices_and_context_window_backup.json | 394 ++++++++++++++---- model_prices_and_context_window.json | 196 +++++++-- tests/litellm/llms/gemini/__init__.py | 0 .../llms/gemini/test_cost_calculator.py | 52 ++- 6 files changed, 551 insertions(+), 128 deletions(-) delete mode 100644 tests/litellm/llms/gemini/__init__.py rename tests/{litellm => test_litellm}/llms/gemini/test_cost_calculator.py (58%) diff --git a/litellm/llms/gemini/cost_calculator.py b/litellm/llms/gemini/cost_calculator.py index 5de6eedfbe..23ec6ad7c1 100644 --- a/litellm/llms/gemini/cost_calculator.py +++ b/litellm/llms/gemini/cost_calculator.py @@ -28,23 +28,32 @@ def cost_per_token( ) +def _is_gemini_3_model(model_info: "ModelInfo") -> bool: + """Check if the model is a Gemini 3.x variant based on its key.""" + key = model_info.get("key", "") + return "gemini-3" in key + + def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> float: """ - Calculates the cost per web search request for a given model, prompt tokens, and completion tokens. + Calculates the cost of web search (grounding with Google Search). - Uses ``search_context_cost_per_query`` from ``model_info`` when available - (keyed by ``search_context_size_medium`` as the default tier). Falls back - to the legacy $0.035 hardcode for models that haven't been updated yet. + Billing differs by model family: + - Gemini 3.x: charged per individual search query ($0.014 default). + - Gemini 2.x and older: charged per grounded prompt ($0.035 default), + regardless of how many queries were executed internally. + + Reads the per-request cost from ``search_context_cost_per_query`` in + ``model_info`` when available, falling back to $0.035 for models not + yet updated in the pricing JSON. """ from litellm.types.utils import PromptTokensDetailsWrapper - # Resolve per-request cost from model_info, fallback to legacy default _DEFAULT_COST = 35e-3 search_costs = model_info.get("search_context_cost_per_query") or {} _cost = search_costs.get("search_context_size_medium", _DEFAULT_COST) number_of_web_search_requests = 0 - # Get number of web search requests if ( usage is not None and usage.prompt_tokens_details is not None @@ -54,7 +63,8 @@ def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> floa ): number_of_web_search_requests = usage.prompt_tokens_details.web_search_requests - # Calculate total cost - total_cost = _cost * number_of_web_search_requests + # Gemini 2.x charges per grounded prompt (flat 1), not per query + if number_of_web_search_requests > 0 and not _is_gemini_3_model(model_info): + number_of_web_search_requests = 1 - return total_cost + return _cost * number_of_web_search_requests diff --git a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py index 36f51c5b2f..3013d476ff 100644 --- a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py +++ b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py @@ -2378,6 +2378,15 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): usage = VertexGeminiConfig._calculate_usage( completion_response=completion_response ) + + web_search_requests = VertexGeminiConfig._calculate_web_search_requests( + grounding_metadata + ) + if web_search_requests is not None: + cast( + PromptTokensDetailsWrapper, usage.prompt_tokens_details + ).web_search_requests = web_search_requests + setattr(model_response, "usage", usage) ## ADD METADATA TO RESPONSE ## diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index c53ee943c5..540ec03476 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -13383,7 +13383,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-001": { "cache_read_input_token_cost": 3.75e-08, @@ -13421,7 +13426,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, @@ -13457,7 +13467,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-lite-001": { "cache_read_input_token_cost": 1.875e-08, @@ -13493,7 +13508,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash": { "cache_read_input_token_cost": 3e-08, @@ -13538,7 +13558,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-image": { "cache_read_input_token_cost": 3e-08, @@ -13621,7 +13646,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -13653,7 +13683,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -13704,7 +13739,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -13783,7 +13823,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -13828,7 +13873,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-preview-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -13873,7 +13923,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-live-2.5-flash-preview-native-audio-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -13917,7 +13972,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-live-2.5-flash-preview-native-audio-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -13963,7 +14023,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-lite-preview-06-17": { "deprecation_date": "2025-11-18", @@ -14009,7 +14074,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-pro": { "cache_read_input_token_cost": 1.25e-07, @@ -14054,7 +14124,12 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-3-pro-preview": { "deprecation_date": "2026-03-26", @@ -14111,7 +14186,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14169,7 +14249,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14220,7 +14305,12 @@ "supports_vision": true, "supports_web_search": true, "supports_url_context": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14276,7 +14366,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -14325,7 +14420,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14383,7 +14483,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14441,7 +14546,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -14477,7 +14587,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-robotics-er-1.5-preview": { "cache_read_input_token_cost": 0, @@ -14552,7 +14667,12 @@ "supports_vision": true, "supports_web_search": true, "tpm": 250000, - "rpm": 10 + "rpm": 10, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, @@ -14604,17 +14724,14 @@ "uses_embed_content": true }, "vertex_ai/gemini-embedding-2-preview": { - "input_cost_per_audio_per_second": 0.00016, - "input_cost_per_image": 0.00012, - "input_cost_per_token": 2e-07, - "input_cost_per_video_per_second": 0.00079, + "input_cost_per_token": 1.5e-07, "litellm_provider": "vertex_ai", "max_input_tokens": 8192, "max_tokens": 8192, "mode": "embedding", "output_cost_per_token": 0, "output_vector_size": 3072, - "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing", + "source": "https://ai.google.dev/gemini-api/docs/embeddings#multimodal", "supports_multimodal": true, "uses_embed_content": true }, @@ -14631,18 +14748,6 @@ "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing", "uses_embed_content": true }, - "vertex_ai/gemini-embedding-2-preview": { - "input_cost_per_token": 1.5e-07, - "litellm_provider": "vertex_ai", - "max_input_tokens": 8192, - "max_tokens": 8192, - "mode": "embedding", - "output_cost_per_token": 0, - "output_vector_size": 3072, - "source": "https://ai.google.dev/gemini-api/docs/embeddings#multimodal", - "supports_multimodal": true, - "uses_embed_content": true - }, "gemini/gemini-embedding-001": { "input_cost_per_token": 1.5e-07, "litellm_provider": "gemini", @@ -14725,7 +14830,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.0-flash-001": { "cache_read_input_token_cost": 2.5e-08, @@ -14764,7 +14874,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, @@ -14801,7 +14916,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 4000000 + "tpm": 4000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash": { "cache_read_input_token_cost": 3e-08, @@ -14848,7 +14968,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-image": { "cache_read_input_token_cost": 3e-08, @@ -14898,7 +15023,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-3-pro-image-preview": { "input_cost_per_image": 0.0011, @@ -14934,7 +15064,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-flash-image-preview": { "input_cost_per_token": 2.5e-07, @@ -14970,7 +15105,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -15006,7 +15146,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite": { "cache_read_input_token_cost": 1e-08, @@ -15053,7 +15198,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -15100,7 +15250,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-preview-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -15147,7 +15302,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-flash-latest": { "cache_read_input_token_cost": 7.5e-08, @@ -15194,7 +15354,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-flash-lite-latest": { "cache_read_input_token_cost": 2.5e-08, @@ -15241,7 +15406,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-lite-preview-06-17": { "deprecation_date": "2025-11-18", @@ -15289,7 +15459,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-flash-preview-tts": { "input_cost_per_token": 3e-07, @@ -15352,7 +15527,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, @@ -15440,7 +15620,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -15493,7 +15678,12 @@ "supports_vision": true, "supports_web_search": true, "supports_native_streaming": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15546,7 +15736,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -15604,7 +15799,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -15662,7 +15862,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15713,7 +15918,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -15750,7 +15960,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 10000000 + "tpm": 10000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-exp-1114": { "input_cost_per_token": 0, @@ -30809,7 +31024,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -31147,7 +31367,9 @@ "mode": "chat", "output_cost_per_token": 3.2e-06, "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing#glm-models", - "supported_regions": ["global"], + "supported_regions": [ + "global" + ], "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, @@ -36756,7 +36978,12 @@ "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true, - "tpm": 4000000 + "tpm": 4000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-native-audio-latest": { "input_cost_per_audio_token": 1e-06, @@ -36963,7 +37190,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-flash-lite-latest": { "cache_read_input_token_cost": 1e-08, @@ -37010,7 +37242,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-pro-latest": { "cache_read_input_token_cost": 1.25e-07, @@ -37056,7 +37293,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-pro-latest": { "cache_read_input_token_cost": 1.25e-07, @@ -37102,7 +37344,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-exp-1206": { "cache_read_input_token_cost": 3e-08, @@ -37149,7 +37396,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "vertex_ai/claude-sonnet-4-6@default": { "cache_creation_input_token_cost": 3.75e-06, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 31c1289b0b..540ec03476 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -13383,7 +13383,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-001": { "cache_read_input_token_cost": 3.75e-08, @@ -13421,7 +13426,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, @@ -13457,7 +13467,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.0-flash-lite-001": { "cache_read_input_token_cost": 1.875e-08, @@ -13493,7 +13508,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash": { "cache_read_input_token_cost": 3e-08, @@ -13538,7 +13558,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-image": { "cache_read_input_token_cost": 3e-08, @@ -13621,7 +13646,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -13653,7 +13683,12 @@ "supports_response_schema": true, "supports_system_messages": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -13704,7 +13739,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -13783,7 +13823,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-lite-preview-09-2025": { "cache_read_input_token_cost": 1e-08, @@ -13828,7 +13873,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-flash-preview-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -13873,7 +13923,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-live-2.5-flash-preview-native-audio-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -13917,7 +13972,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-live-2.5-flash-preview-native-audio-09-2025": { "cache_read_input_token_cost": 7.5e-08, @@ -14014,7 +14074,12 @@ "supports_tool_choice": true, "supports_url_context": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-2.5-pro": { "cache_read_input_token_cost": 1.25e-07, @@ -14059,7 +14124,12 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-3-pro-preview": { "deprecation_date": "2026-03-26", @@ -14116,7 +14186,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14174,7 +14249,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14225,7 +14305,12 @@ "supports_vision": true, "supports_web_search": true, "supports_url_context": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14281,7 +14366,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -14330,7 +14420,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14388,7 +14483,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14446,7 +14546,12 @@ "output_cost_per_token_above_200k_tokens_priority": 3.24e-05, "cache_read_input_token_cost_priority": 3.6e-07, "cache_read_input_token_cost_above_200k_tokens_priority": 7.2e-07, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -14482,7 +14587,12 @@ "supports_system_messages": true, "supports_tool_choice": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-robotics-er-1.5-preview": { "cache_read_input_token_cost": 0, @@ -15808,7 +15918,12 @@ "input_cost_per_audio_token_priority": 1.8e-06, "output_cost_per_token_priority": 5.4e-06, "cache_read_input_token_cost_priority": 9e-08, - "supports_service_tier": true + "supports_service_tier": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "gemini/gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -30909,7 +31024,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "supports_native_streaming": true + "supports_native_streaming": true, + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } }, "vertex_ai/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -37070,7 +37190,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-flash-lite-latest": { "cache_read_input_token_cost": 1e-08, @@ -37117,7 +37242,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 250000 + "tpm": 250000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini-pro-latest": { "cache_read_input_token_cost": 1.25e-07, @@ -37163,7 +37293,12 @@ "supports_video_input": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "gemini/gemini-pro-latest": { "cache_read_input_token_cost": 1.25e-07, @@ -37261,7 +37396,12 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 8000000 + "tpm": 8000000, + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } }, "vertex_ai/claude-sonnet-4-6@default": { "cache_creation_input_token_cost": 3.75e-06, diff --git a/tests/litellm/llms/gemini/__init__.py b/tests/litellm/llms/gemini/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/litellm/llms/gemini/test_cost_calculator.py b/tests/test_litellm/llms/gemini/test_cost_calculator.py similarity index 58% rename from tests/litellm/llms/gemini/test_cost_calculator.py rename to tests/test_litellm/llms/gemini/test_cost_calculator.py index 19a7a83968..baa3aab318 100644 --- a/tests/litellm/llms/gemini/test_cost_calculator.py +++ b/tests/test_litellm/llms/gemini/test_cost_calculator.py @@ -1,11 +1,9 @@ -import os -import sys - import pytest -sys.path.insert(0, os.path.abspath("../../../..")) - -from litellm.llms.gemini.cost_calculator import cost_per_web_search_request +from litellm.llms.gemini.cost_calculator import ( + _is_gemini_3_model, + cost_per_web_search_request, +) from litellm.types.utils import PromptTokensDetailsWrapper, Usage @@ -20,8 +18,8 @@ def _make_usage(web_search_requests: int) -> Usage: ) -def test_web_search_cost_from_model_info(): - """Cost should come from model_info when search_context_cost_per_query is set.""" +def test_gemini3_charged_per_query(): + """Gemini 3.x should charge per search query at $0.014.""" model_info = { "key": "gemini/gemini-3-flash-preview", "search_context_cost_per_query": { @@ -34,28 +32,42 @@ def test_web_search_cost_from_model_info(): assert cost == pytest.approx(0.014 * 3) -def test_web_search_cost_legacy_fallback(): - """Without search_context_cost_per_query, should fallback to $0.035.""" - model_info = {"key": "gemini/gemini-2.0-flash"} - cost = cost_per_web_search_request(usage=_make_usage(2), model_info=model_info) - assert cost == pytest.approx(0.035 * 2) - - -def test_web_search_cost_zero_requests(): - """Zero web search requests should return zero cost.""" +def test_gemini2_charged_per_prompt(): + """Gemini 2.x should charge 1 grounded prompt regardless of query count.""" model_info = { - "key": "gemini/gemini-3-flash-preview", + "key": "gemini/gemini-2.5-flash", "search_context_cost_per_query": { - "search_context_size_medium": 0.014, + "search_context_size_medium": 0.035, }, } + cost = cost_per_web_search_request(usage=_make_usage(3), model_info=model_info) + assert cost == pytest.approx(0.035 * 1) + + +def test_legacy_fallback(): + """Without search_context_cost_per_query, should fallback to $0.035 × 1.""" + model_info = {"key": "gemini/gemini-2.0-flash"} + cost = cost_per_web_search_request(usage=_make_usage(2), model_info=model_info) + assert cost == pytest.approx(0.035 * 1) + + +def test_zero_requests(): + """Zero web search requests should return zero cost.""" + model_info = {"key": "gemini/gemini-3-flash-preview"} cost = cost_per_web_search_request(usage=_make_usage(0), model_info=model_info) assert cost == 0.0 -def test_web_search_cost_no_usage_details(): +def test_no_usage_details(): """Missing prompt_tokens_details should return zero cost.""" model_info = {"key": "gemini/gemini-3-flash-preview"} usage = Usage(prompt_tokens=100, completion_tokens=50, total_tokens=150) cost = cost_per_web_search_request(usage=usage, model_info=model_info) assert cost == 0.0 + + +def test_is_gemini_3_model(): + assert _is_gemini_3_model({"key": "gemini/gemini-3-flash-preview"}) + assert _is_gemini_3_model({"key": "gemini/gemini-3.1-pro-preview"}) + assert not _is_gemini_3_model({"key": "gemini/gemini-2.5-flash"}) + assert not _is_gemini_3_model({"key": "gemini/gemini-2.0-flash"}) From a0d1d22bcfa53f52de5f76ebdafbcde9cfad35c5 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:25:01 -0300 Subject: [PATCH 3/7] docs: add Web Search Cost Tracking section Document how each provider bills for web search, the search_context_cost_per_query field in model_prices JSON, how to override pricing via proxy config, and how LiteLLM extracts web_search_requests from each provider's response. --- docs/my-website/docs/completion/web_search.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/docs/my-website/docs/completion/web_search.md b/docs/my-website/docs/completion/web_search.md index 1f5ba2dee4..375e9a6375 100644 --- a/docs/my-website/docs/completion/web_search.md +++ b/docs/my-website/docs/completion/web_search.md @@ -596,3 +596,78 @@ Expected Response + +## Web Search Cost Tracking + +LiteLLM tracks web search costs automatically based on provider-specific billing models. The cost is added on top of the standard token-based pricing. + +### How providers charge for web search + +| Provider | Billing Unit | How it works | +|----------|-------------|--------------| +| **Gemini 3.x** (3-flash, 3-pro, 3.1-*) | Per search query | Each internal search query is billed individually. One prompt may trigger multiple queries. | +| **Gemini 2.x** (2.0-flash, 2.5-flash, 2.5-pro) | Per grounded prompt | Flat fee per API call that uses grounding, regardless of how many queries are executed internally. | +| **OpenAI** (gpt-4o-search, gpt-5-search) | Per search context size | Cost varies by `search_context_size` (`low`, `medium`, `high`). | +| **Anthropic** (Claude with web search) | Per search request | Fixed cost per web search tool invocation. | +| **Perplexity** (sonar, sonar-pro) | Per search context size | Cost varies by `search_context_size`. | + +### Pricing configuration + +Web search costs are defined in `model_prices_and_context_window.json` using the `search_context_cost_per_query` field: + +```json +{ + "gemini/gemini-3-flash-preview": { + "search_context_cost_per_query": { + "search_context_size_low": 0.014, + "search_context_size_medium": 0.014, + "search_context_size_high": 0.014 + } + }, + "gemini/gemini-2.5-flash": { + "search_context_cost_per_query": { + "search_context_size_low": 0.035, + "search_context_size_medium": 0.035, + "search_context_size_high": 0.035 + } + } +} +``` + +You can override these costs in your proxy config using `model_info`: + +```yaml +model_list: + - model_name: gemini-3-flash + litellm_params: + model: gemini/gemini-3-flash-preview + model_info: + search_context_cost_per_query: + search_context_size_low: 0.014 + search_context_size_medium: 0.014 + search_context_size_high: 0.014 +``` + +### How LiteLLM tracks search usage + +The number of web search requests is stored in `usage.prompt_tokens_details.web_search_requests`. LiteLLM extracts this from each provider's response: + +- **Gemini**: Extracted from `groundingMetadata.webSearchQueries` in the response. For Gemini 2.x, clamped to 1 (per-prompt billing). +- **OpenAI**: Reported directly in the usage metadata. +- **Anthropic**: Reported via `server_tool_use.web_search_requests`. +- **xAI**: Mapped from `num_sources_used` in the response. + +```python +response = litellm.completion( + model="gemini/gemini-3-flash-preview", + messages=[{"role": "user", "content": "Latest tech news?"}], + web_search_options={"search_context_size": "medium"}, +) + +# Check web search usage +print(response.usage.prompt_tokens_details.web_search_requests) # e.g., 3 + +# Get total cost (includes token cost + web search cost) +cost = litellm.completion_cost(completion_response=response) +print(f"Total cost: ${cost}") +``` From e82d3f6d2e54941193600cdb0ed993234a5cfb86 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:29:38 -0300 Subject: [PATCH 4/7] refactor(gemini): use web_search_billing_unit field instead of hardcoded model name check Replace _is_gemini_3_model() substring check with a web_search_billing_unit field in model_prices JSON: - "per_query": each search query billed individually (Gemini 3.x) - "per_prompt" (default): flat fee per grounded API call (Gemini 2.x) Add web_search_billing_unit to 23 Gemini 3.x model entries. Update docs and tests accordingly. --- docs/my-website/docs/completion/web_search.md | 13 +++- litellm/llms/gemini/cost_calculator.py | 17 ++--- ...odel_prices_and_context_window_backup.json | 69 ++++++++++++------- model_prices_and_context_window.json | 69 ++++++++++++------- .../llms/gemini/test_cost_calculator.py | 32 ++++----- 5 files changed, 121 insertions(+), 79 deletions(-) diff --git a/docs/my-website/docs/completion/web_search.md b/docs/my-website/docs/completion/web_search.md index 375e9a6375..dc8f72025f 100644 --- a/docs/my-website/docs/completion/web_search.md +++ b/docs/my-website/docs/completion/web_search.md @@ -613,11 +613,15 @@ LiteLLM tracks web search costs automatically based on provider-specific billing ### Pricing configuration -Web search costs are defined in `model_prices_and_context_window.json` using the `search_context_cost_per_query` field: +Web search costs are defined in `model_prices_and_context_window.json` using two fields: + +- **`search_context_cost_per_query`**: the cost per billable unit (per search context size tier). +- **`web_search_billing_unit`**: `"per_query"` (each search query is billed individually) or `"per_prompt"` (default — flat fee per API call that uses search). ```json { "gemini/gemini-3-flash-preview": { + "web_search_billing_unit": "per_query", "search_context_cost_per_query": { "search_context_size_low": 0.014, "search_context_size_medium": 0.014, @@ -634,7 +638,11 @@ Web search costs are defined in `model_prices_and_context_window.json` using the } ``` -You can override these costs in your proxy config using `model_info`: +:::info +Models without `web_search_billing_unit` default to `"per_prompt"` — one flat charge per API call that uses web search, regardless of how many internal queries the model executes. +::: + +You can override these in your proxy config using `model_info`: ```yaml model_list: @@ -642,6 +650,7 @@ model_list: litellm_params: model: gemini/gemini-3-flash-preview model_info: + web_search_billing_unit: per_query search_context_cost_per_query: search_context_size_low: 0.014 search_context_size_medium: 0.014 diff --git a/litellm/llms/gemini/cost_calculator.py b/litellm/llms/gemini/cost_calculator.py index 23ec6ad7c1..cd536b8bd3 100644 --- a/litellm/llms/gemini/cost_calculator.py +++ b/litellm/llms/gemini/cost_calculator.py @@ -28,19 +28,13 @@ def cost_per_token( ) -def _is_gemini_3_model(model_info: "ModelInfo") -> bool: - """Check if the model is a Gemini 3.x variant based on its key.""" - key = model_info.get("key", "") - return "gemini-3" in key - - def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> float: """ Calculates the cost of web search (grounding with Google Search). - Billing differs by model family: - - Gemini 3.x: charged per individual search query ($0.014 default). - - Gemini 2.x and older: charged per grounded prompt ($0.035 default), + Billing mode is determined by ``web_search_billing_unit`` in model_info: + - ``"per_query"``: charged per individual search query (Gemini 3.x). + - ``"per_prompt"`` (default): charged per grounded prompt (Gemini 2.x), regardless of how many queries were executed internally. Reads the per-request cost from ``search_context_cost_per_query`` in @@ -63,8 +57,9 @@ def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> floa ): number_of_web_search_requests = usage.prompt_tokens_details.web_search_requests - # Gemini 2.x charges per grounded prompt (flat 1), not per query - if number_of_web_search_requests > 0 and not _is_gemini_3_model(model_info): + # per_prompt billing: clamp to 1 (flat fee per grounded API call) + billing_mode = model_info.get("web_search_billing_unit", "per_prompt") + if number_of_web_search_requests > 0 and billing_mode == "per_prompt": number_of_web_search_requests = 1 return _cost * number_of_web_search_requests diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 540ec03476..e0f5658106 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -13651,7 +13651,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -13688,7 +13689,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -13744,7 +13746,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -14191,7 +14194,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14254,7 +14258,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14310,7 +14315,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14371,7 +14377,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -14425,7 +14432,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14488,7 +14496,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14551,7 +14560,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -15069,7 +15079,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-flash-image-preview": { "input_cost_per_token": 2.5e-07, @@ -15110,7 +15121,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -15625,7 +15637,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -15683,7 +15696,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15741,7 +15755,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -15804,7 +15819,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -15867,7 +15883,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15923,7 +15940,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -24692,7 +24710,8 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "web_search_billing_unit": "per_query" }, "openrouter/google/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -24739,7 +24758,8 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "web_search_billing_unit": "per_query" }, "openrouter/google/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -26286,14 +26306,16 @@ "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "web_search_billing_unit": "per_query" }, "perplexity/google/gemini-3-flash-preview": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "web_search_billing_unit": "per_query" }, "perplexity/google/gemini-2.5-pro": { "litellm_provider": "perplexity", @@ -31029,7 +31051,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 540ec03476..e0f5658106 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -13651,7 +13651,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-flash-image-preview": { "input_cost_per_image": 0.00056, @@ -13688,7 +13689,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -13744,7 +13746,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -14191,7 +14194,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14254,7 +14258,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14310,7 +14315,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14371,7 +14377,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -14425,7 +14432,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -14488,7 +14496,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -14551,7 +14560,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -15069,7 +15079,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-flash-image-preview": { "input_cost_per_token": 2.5e-07, @@ -15110,7 +15121,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, @@ -15625,7 +15637,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-flash-lite-preview": { "cache_read_input_token_cost": 2.5e-08, @@ -15683,7 +15696,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15741,7 +15755,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -15804,7 +15819,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-3.1-pro-preview-customtools": { "cache_read_input_token_cost": 2e-07, @@ -15867,7 +15883,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -15923,7 +15940,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "gemini/gemini-2.5-pro-preview-tts": { "cache_read_input_token_cost": 1.25e-07, @@ -24692,7 +24710,8 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true + "supports_web_search": true, + "web_search_billing_unit": "per_query" }, "openrouter/google/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -24739,7 +24758,8 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000 + "tpm": 800000, + "web_search_billing_unit": "per_query" }, "openrouter/google/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -26286,14 +26306,16 @@ "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "web_search_billing_unit": "per_query" }, "perplexity/google/gemini-3-flash-preview": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "web_search_billing_unit": "per_query" }, "perplexity/google/gemini-2.5-pro": { "litellm_provider": "perplexity", @@ -31029,7 +31051,8 @@ "search_context_size_low": 0.014, "search_context_size_medium": 0.014, "search_context_size_high": 0.014 - } + }, + "web_search_billing_unit": "per_query" }, "vertex_ai/deep-research-pro-preview-12-2025": { "input_cost_per_image": 0.0011, diff --git a/tests/test_litellm/llms/gemini/test_cost_calculator.py b/tests/test_litellm/llms/gemini/test_cost_calculator.py index baa3aab318..9bb83aa7cf 100644 --- a/tests/test_litellm/llms/gemini/test_cost_calculator.py +++ b/tests/test_litellm/llms/gemini/test_cost_calculator.py @@ -1,9 +1,6 @@ import pytest -from litellm.llms.gemini.cost_calculator import ( - _is_gemini_3_model, - cost_per_web_search_request, -) +from litellm.llms.gemini.cost_calculator import cost_per_web_search_request from litellm.types.utils import PromptTokensDetailsWrapper, Usage @@ -18,22 +15,21 @@ def _make_usage(web_search_requests: int) -> Usage: ) -def test_gemini3_charged_per_query(): - """Gemini 3.x should charge per search query at $0.014.""" +def test_per_query_billing(): + """web_search_billing_unit=per_query charges per search query.""" model_info = { "key": "gemini/gemini-3-flash-preview", + "web_search_billing_unit": "per_query", "search_context_cost_per_query": { - "search_context_size_low": 0.014, "search_context_size_medium": 0.014, - "search_context_size_high": 0.014, }, } cost = cost_per_web_search_request(usage=_make_usage(3), model_info=model_info) assert cost == pytest.approx(0.014 * 3) -def test_gemini2_charged_per_prompt(): - """Gemini 2.x should charge 1 grounded prompt regardless of query count.""" +def test_per_prompt_billing(): + """web_search_billing_unit=per_prompt (default) clamps to 1.""" model_info = { "key": "gemini/gemini-2.5-flash", "search_context_cost_per_query": { @@ -44,8 +40,8 @@ def test_gemini2_charged_per_prompt(): assert cost == pytest.approx(0.035 * 1) -def test_legacy_fallback(): - """Without search_context_cost_per_query, should fallback to $0.035 × 1.""" +def test_default_billing_unit_is_per_prompt(): + """Without web_search_billing_unit, defaults to per_prompt (clamp to 1).""" model_info = {"key": "gemini/gemini-2.0-flash"} cost = cost_per_web_search_request(usage=_make_usage(2), model_info=model_info) assert cost == pytest.approx(0.035 * 1) @@ -53,7 +49,10 @@ def test_legacy_fallback(): def test_zero_requests(): """Zero web search requests should return zero cost.""" - model_info = {"key": "gemini/gemini-3-flash-preview"} + model_info = { + "key": "gemini/gemini-3-flash-preview", + "web_search_billing_unit": "per_query", + } cost = cost_per_web_search_request(usage=_make_usage(0), model_info=model_info) assert cost == 0.0 @@ -64,10 +63,3 @@ def test_no_usage_details(): usage = Usage(prompt_tokens=100, completion_tokens=50, total_tokens=150) cost = cost_per_web_search_request(usage=usage, model_info=model_info) assert cost == 0.0 - - -def test_is_gemini_3_model(): - assert _is_gemini_3_model({"key": "gemini/gemini-3-flash-preview"}) - assert _is_gemini_3_model({"key": "gemini/gemini-3.1-pro-preview"}) - assert not _is_gemini_3_model({"key": "gemini/gemini-2.5-flash"}) - assert not _is_gemini_3_model({"key": "gemini/gemini-2.0-flash"}) From b6079018cdb5105bf4859befac5b97326404bbb7 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:32:03 -0300 Subject: [PATCH 5/7] docs: clarify web_search_billing_unit applies to Gemini models only --- docs/my-website/docs/completion/web_search.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/my-website/docs/completion/web_search.md b/docs/my-website/docs/completion/web_search.md index dc8f72025f..86a9677861 100644 --- a/docs/my-website/docs/completion/web_search.md +++ b/docs/my-website/docs/completion/web_search.md @@ -616,7 +616,7 @@ LiteLLM tracks web search costs automatically based on provider-specific billing Web search costs are defined in `model_prices_and_context_window.json` using two fields: - **`search_context_cost_per_query`**: the cost per billable unit (per search context size tier). -- **`web_search_billing_unit`**: `"per_query"` (each search query is billed individually) or `"per_prompt"` (default — flat fee per API call that uses search). +- **`web_search_billing_unit`** *(on Gemini models)*: `"per_query"` (each search query is billed individually) or `"per_prompt"` (default — flat fee per API call that uses search). ```json { From 996d27b156f9ae4a368933011ed88875cc4887d3 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:39:12 -0300 Subject: [PATCH 6/7] fix(vertex_ai): delegate web search cost to shared Gemini calculator The vertex_ai cost calculator hardcoded $0.035 and charged for every call with a PromptTokensDetailsWrapper (not just web search calls). Delegate to the shared Gemini calculator which reads pricing and billing unit from model_info, fixing both issues for vertex_ai models. --- .../llms/vertex_ai/gemini/cost_calculator.py | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/litellm/llms/vertex_ai/gemini/cost_calculator.py b/litellm/llms/vertex_ai/gemini/cost_calculator.py index 23977bc917..69a29c16af 100644 --- a/litellm/llms/vertex_ai/gemini/cost_calculator.py +++ b/litellm/llms/vertex_ai/gemini/cost_calculator.py @@ -1,7 +1,8 @@ """ Cost calculator for Vertex AI Gemini. -Used because there are differences in how Google AI Studio and Vertex AI Gemini handle web search requests. +Delegates to the shared Gemini cost calculator which reads pricing and +billing unit from model_info. """ from typing import TYPE_CHECKING @@ -14,32 +15,14 @@ def cost_per_web_search_request(usage: "Usage", model_info: "ModelInfo") -> floa """ Calculate the cost of a web search request for Vertex AI Gemini. - Vertex AI charges $35/1000 prompts, independent of the number of web search requests. + Billing differs by ``web_search_billing_unit`` in ``model_info``: + - ``"per_query"``: charged per individual search query (Gemini 3.x). + - ``"per_prompt"`` (default): charged per grounded prompt (Gemini 2.x). - For a single call, this is $35e-3 USD. - - Args: - usage: The usage object for the web search request. - model_info: The model info for the web search request. - - Returns: - The cost of the web search request. + Delegates to the shared Gemini cost calculator. """ - from litellm.types.utils import PromptTokensDetailsWrapper + from litellm.llms.gemini.cost_calculator import ( + cost_per_web_search_request as _gemini_cost, + ) - # check if usage object has web search requests - cost_per_llm_call_with_web_search = 35e-3 - - makes_web_search_request = False - if ( - usage is not None - and usage.prompt_tokens_details is not None - and isinstance(usage.prompt_tokens_details, PromptTokensDetailsWrapper) - ): - makes_web_search_request = True - - # Calculate total cost - if makes_web_search_request: - return cost_per_llm_call_with_web_search - else: - return 0.0 + return _gemini_cost(usage=usage, model_info=model_info) From 21b9c68d42101e912d860db643610f1a322f0b96 Mon Sep 17 00:00:00 2001 From: Chesars Date: Sun, 22 Mar 2026 18:46:39 -0300 Subject: [PATCH 7/7] fix: remove web_search_billing_unit from OpenRouter/Perplexity entries These providers have their own web search systems and pricing, independent of Google's grounding billing model. --- litellm/model_prices_and_context_window_backup.json | 12 ++++-------- model_prices_and_context_window.json | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index e0f5658106..32ef8b5c26 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -24710,8 +24710,7 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true, - "web_search_billing_unit": "per_query" + "supports_web_search": true }, "openrouter/google/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -24758,8 +24757,7 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000, - "web_search_billing_unit": "per_query" + "tpm": 800000 }, "openrouter/google/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -26306,16 +26304,14 @@ "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true, - "web_search_billing_unit": "per_query" + "supports_function_calling": true }, "perplexity/google/gemini-3-flash-preview": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true, - "web_search_billing_unit": "per_query" + "supports_function_calling": true }, "perplexity/google/gemini-2.5-pro": { "litellm_provider": "perplexity", diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index e0f5658106..32ef8b5c26 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -24710,8 +24710,7 @@ "supports_tool_choice": true, "supports_video_input": true, "supports_vision": true, - "supports_web_search": true, - "web_search_billing_unit": "per_query" + "supports_web_search": true }, "openrouter/google/gemini-3-flash-preview": { "cache_read_input_token_cost": 5e-08, @@ -24758,8 +24757,7 @@ "supports_url_context": true, "supports_vision": true, "supports_web_search": true, - "tpm": 800000, - "web_search_billing_unit": "per_query" + "tpm": 800000 }, "openrouter/google/gemini-3.1-pro-preview": { "cache_read_input_token_cost": 2e-07, @@ -26306,16 +26304,14 @@ "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true, - "web_search_billing_unit": "per_query" + "supports_function_calling": true }, "perplexity/google/gemini-3-flash-preview": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true, - "web_search_billing_unit": "per_query" + "supports_function_calling": true }, "perplexity/google/gemini-2.5-pro": { "litellm_provider": "perplexity",