From 32ffcb00c65f8dc55fc82a99ab42121b8a3d18e8 Mon Sep 17 00:00:00 2001 From: Chesars Date: Mon, 24 Nov 2025 11:28:53 -0300 Subject: [PATCH 1/3] fix(gemini): exclude image models from automatic thinking_level parameter (#17013) - gemini-3-pro-image-preview does not support thinking_level parameter - Added check to skip adding thinkingConfig for models containing "image" - Fixes BadRequestError: "Thinking level is not supported for this model" - Only affects automatic default behavior, user can still pass reasoning_effort explicitly Fixes #17013 --- .../gemini/vertex_and_google_ai_studio_gemini.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 ab594c79ef42..5fef8c1ec493 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 @@ -904,13 +904,15 @@ def map_openai_params( # noqa: PLR0915 if VertexGeminiConfig._is_gemini_3_or_newer(model): if "temperature" not in optional_params: optional_params["temperature"] = 1.0 - thinking_config = optional_params.get("thinkingConfig", {}) - if ( - "thinkingLevel" not in thinking_config - and "thinkingBudget" not in thinking_config - ): - thinking_config["thinkingLevel"] = "low" - optional_params["thinkingConfig"] = thinking_config + # Only add thinkingLevel if model supports it (exclude image models) + if "image" not in model.lower(): + thinking_config = optional_params.get("thinkingConfig", {}) + if ( + "thinkingLevel" not in thinking_config + and "thinkingBudget" not in thinking_config + ): + thinking_config["thinkingLevel"] = "low" + optional_params["thinkingConfig"] = thinking_config return optional_params From 2480ff76546dc46a5fd357b40f8df6e877400d52 Mon Sep 17 00:00:00 2001 From: Chesars Date: Mon, 24 Nov 2025 11:32:37 -0300 Subject: [PATCH 2/3] test: add tests for gemini-3 image models thinking_level exclusion --- ...test_vertex_and_google_ai_studio_gemini.py | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py index 8942239bb21f..2b305dbade17 100644 --- a/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py +++ b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py @@ -1967,3 +1967,98 @@ def test_media_resolution_per_part(): assert "inline_data" in image2_part assert image2_part["inline_data"]["mediaResolution"] == "high" + +def test_gemini_3_image_models_no_thinking_config(): + """ + Test that Gemini 3 image models do NOT receive automatic thinkingConfig. + + Related issue: https://github.com/BerriAI/litellm/issues/17013 + gemini-3-pro-image-preview does not support thinking_level parameter + and returns BadRequestError: "Thinking level is not supported for this model" + """ + from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import ( + VertexGeminiConfig, + ) + + v = VertexGeminiConfig() + + # Test gemini-3-pro-image-preview (the specific model from the bug report) + model = "gemini-3-pro-image-preview" + optional_params = {} + non_default_params = {} + + result = v.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False, + ) + + # Should NOT have thinkingConfig automatically added + assert "thinkingConfig" not in result + # But should still get temperature=1.0 for Gemini 3 + assert result["temperature"] == 1.0 + + +def test_gemini_3_text_models_get_thinking_config(): + """ + Test that Gemini 3 text models DO receive automatic thinkingConfig. + This ensures we didn't break the existing behavior for non-image models. + """ + from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import ( + VertexGeminiConfig, + ) + + v = VertexGeminiConfig() + + # Test gemini-3-pro-preview (text model, should get thinking) + model = "gemini-3-pro-preview" + optional_params = {} + non_default_params = {} + + result = v.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False, + ) + + # Should have thinkingConfig automatically added + assert "thinkingConfig" in result + assert result["thinkingConfig"]["thinkingLevel"] == "low" + assert result["temperature"] == 1.0 + + +def test_gemini_image_models_excluded_from_thinking(): + """ + Test that any Gemini model with 'image' in the name is excluded from thinking config. + This covers current and future image models. + """ + from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import ( + VertexGeminiConfig, + ) + + v = VertexGeminiConfig() + + # Test various image model patterns + image_models = [ + "gemini-3-pro-image-preview", + "gemini-3-pro-image-generation", + "gemini-3-flash-image-preview", + "gemini/gemini-3-image-edit", + ] + + for model in image_models: + optional_params = {} + non_default_params = {} + + result = v.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False, + ) + + # None of these should have thinkingConfig + assert "thinkingConfig" not in result, f"Model {model} should not have thinkingConfig" + From a4c079069995eaef39ceed8e7845b82de4130ca4 Mon Sep 17 00:00:00 2001 From: Chesars Date: Mon, 24 Nov 2025 11:54:15 -0300 Subject: [PATCH 3/3] update docs --- docs/my-website/docs/providers/gemini.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/my-website/docs/providers/gemini.md b/docs/my-website/docs/providers/gemini.md index e04225e1f856..1b21ed8d03c0 100644 --- a/docs/my-website/docs/providers/gemini.md +++ b/docs/my-website/docs/providers/gemini.md @@ -74,6 +74,10 @@ Note: Reasoning cannot be turned off on Gemini 2.5 Pro models. For **Gemini 3+ models** (e.g., `gemini-3-pro-preview`), LiteLLM automatically maps `reasoning_effort` to the new `thinking_level` parameter instead of `thinking_budget`. The `thinking_level` parameter uses `"low"` or `"high"` values for better control over reasoning depth. ::: +:::warning Image Models +**Gemini image models** (e.g., `gemini-3-pro-image-preview`, `gemini-2.0-flash-exp-image-generation`) do **not** support the `thinking_level` parameter. LiteLLM automatically excludes image models from receiving thinking configuration to prevent API errors. +::: + **Mapping for Gemini 2.5 and earlier models** | reasoning_effort | thinking | Notes |