From 4c0495f76a79d965c39bad11879666b03b3bc48e Mon Sep 17 00:00:00 2001 From: chelsealong Date: Wed, 30 Sep 2026 13:03:01 +0000 Subject: [PATCH] fix(litellm): forward thinking_config to litellm reasoning params --- src/google/adk/models/lite_llm.py | 13 +++++++++ tests/unittests/models/test_litellm.py | 38 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/google/adk/models/lite_llm.py b/src/google/adk/models/lite_llm.py index 1630c3c983..4b106d58ee 100644 --- a/src/google/adk/models/lite_llm.py +++ b/src/google/adk/models/lite_llm.py @@ -3039,6 +3039,19 @@ async def _get_completion_inputs( mapped_key = param_mapping.get(key, key) generation_params[mapped_key] = config_dict[key] + thinking_config = config_dict.get("thinking_config") or {} + thinking_level = thinking_config.get("thinking_level") + thinking_budget = thinking_config.get("thinking_budget") + if thinking_level and thinking_level != "THINKING_LEVEL_UNSPECIFIED": + generation_params["reasoning_effort"] = str( + getattr(thinking_level, "value", thinking_level) + ).lower() + elif thinking_budget and thinking_budget > 0: + generation_params["thinking"] = { + "type": "enabled", + "budget_tokens": thinking_budget, + } + if not generation_params: generation_params = None diff --git a/tests/unittests/models/test_litellm.py b/tests/unittests/models/test_litellm.py index caf2ceeb97..b27452f463 100644 --- a/tests/unittests/models/test_litellm.py +++ b/tests/unittests/models/test_litellm.py @@ -6407,6 +6407,44 @@ async def test_get_completion_inputs_generation_params(): assert "stop_sequences" not in generation_params +@pytest.mark.asyncio +async def test_get_completion_inputs_maps_thinking_level_to_reasoning_effort(): + req = LlmRequest( + contents=[ + types.Content(role="user", parts=[types.Part.from_text(text="hi")]), + ], + config=types.GenerateContentConfig( + thinking_config=types.ThinkingConfig( + thinking_level=types.ThinkingLevel.LOW + ), + ), + ) + + _, _, _, generation_params, _ = await _get_completion_inputs( + req, model="gpt-4o-mini" + ) + assert generation_params == {"reasoning_effort": "low"} + + +@pytest.mark.asyncio +async def test_get_completion_inputs_maps_thinking_budget(): + req = LlmRequest( + contents=[ + types.Content(role="user", parts=[types.Part.from_text(text="hi")]), + ], + config=types.GenerateContentConfig( + thinking_config=types.ThinkingConfig(thinking_budget=2048), + ), + ) + + _, _, _, generation_params, _ = await _get_completion_inputs( + req, model="gpt-4o-mini" + ) + assert generation_params == { + "thinking": {"type": "enabled", "budget_tokens": 2048} + } + + @pytest.mark.asyncio async def test_get_completion_inputs_empty_generation_params(): # Test that generation_params is None when no generation parameters are set