mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
fix(vertex_ai): handle reasoning_effort as dict from OpenAI Agents SDK (#19419)
The OpenAI Agents SDK (v0.6.9+) now passes reasoning_effort as a dict
when summary is specified: {"effort": "high", "summary": "auto"}
This change extracts the "effort" value from the dict for Vertex AI,
which only supports thinkingLevel (not summary).
Before: reasoning_effort={"effort": "high"} was silently ignored
After: reasoning_effort={"effort": "high"} correctly maps to thinkingLevel
Fixes #19411
This commit is contained in:
parent
b36e704e06
commit
b4ed387d24
2 changed files with 91 additions and 17 deletions
|
|
@ -988,25 +988,34 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
optional_params["parallel_tool_calls"] = value
|
||||
elif param == "seed":
|
||||
optional_params["seed"] = value
|
||||
elif param == "reasoning_effort" and isinstance(value, str):
|
||||
# Validate no conflict with thinking_level
|
||||
VertexGeminiConfig._validate_thinking_config_conflicts(
|
||||
optional_params=optional_params,
|
||||
param_name="reasoning_effort",
|
||||
param_description="thinking_budget",
|
||||
)
|
||||
if VertexGeminiConfig._is_gemini_3_or_newer(model):
|
||||
optional_params["thinkingConfig"] = (
|
||||
VertexGeminiConfig._map_reasoning_effort_to_thinking_level(
|
||||
value, model
|
||||
)
|
||||
elif param == "reasoning_effort":
|
||||
# Extract effort value - handle both string and dict formats
|
||||
# Dict format comes from OpenAI Agents SDK: {"effort": "high", "summary": "auto"}
|
||||
effort_value: Optional[str] = None
|
||||
if isinstance(value, str):
|
||||
effort_value = value
|
||||
elif isinstance(value, dict):
|
||||
effort_value = value.get("effort")
|
||||
|
||||
if effort_value is not None:
|
||||
# Validate no conflict with thinking_level
|
||||
VertexGeminiConfig._validate_thinking_config_conflicts(
|
||||
optional_params=optional_params,
|
||||
param_name="reasoning_effort",
|
||||
param_description="thinking_budget",
|
||||
)
|
||||
else:
|
||||
optional_params["thinkingConfig"] = (
|
||||
VertexGeminiConfig._map_reasoning_effort_to_thinking_budget(
|
||||
value, model
|
||||
if VertexGeminiConfig._is_gemini_3_or_newer(model):
|
||||
optional_params["thinkingConfig"] = (
|
||||
VertexGeminiConfig._map_reasoning_effort_to_thinking_level(
|
||||
effort_value, model
|
||||
)
|
||||
)
|
||||
else:
|
||||
optional_params["thinkingConfig"] = (
|
||||
VertexGeminiConfig._map_reasoning_effort_to_thinking_budget(
|
||||
effort_value, model
|
||||
)
|
||||
)
|
||||
)
|
||||
elif param == "thinking":
|
||||
# Validate no conflict with thinking_level
|
||||
VertexGeminiConfig._validate_thinking_config_conflicts(
|
||||
|
|
|
|||
|
|
@ -1887,6 +1887,71 @@ def test_reasoning_effort_maps_to_thinking_level_gemini_3():
|
|||
assert result["thinkingConfig"]["includeThoughts"] is False
|
||||
|
||||
|
||||
def test_reasoning_effort_dict_format_gemini_3():
|
||||
"""
|
||||
Test that reasoning_effort works when passed as dict format from OpenAI Agents SDK.
|
||||
|
||||
The OpenAI Agents SDK passes reasoning_effort as {"effort": "high", "summary": "auto"}
|
||||
instead of just a string. This test verifies that we correctly extract the effort value.
|
||||
|
||||
Related issue: https://github.com/BerriAI/litellm/issues/19411
|
||||
"""
|
||||
from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import (
|
||||
VertexGeminiConfig,
|
||||
)
|
||||
|
||||
v = VertexGeminiConfig()
|
||||
model = "gemini-3-pro-preview"
|
||||
|
||||
# Test dict format with effort="high" (OpenAI Agents SDK format)
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": {"effort": "high", "summary": "auto"}}
|
||||
result = v.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model=model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinkingConfig"]["thinkingLevel"] == "high"
|
||||
assert result["thinkingConfig"]["includeThoughts"] is True
|
||||
|
||||
# Test dict format with effort="low"
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": {"effort": "low"}}
|
||||
result = v.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model=model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinkingConfig"]["thinkingLevel"] == "low"
|
||||
assert result["thinkingConfig"]["includeThoughts"] is True
|
||||
|
||||
# Test dict format with effort="medium"
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": {"effort": "medium"}}
|
||||
result = v.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model=model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinkingConfig"]["thinkingLevel"] == "high"
|
||||
assert result["thinkingConfig"]["includeThoughts"] is True
|
||||
|
||||
# Test dict format without effort key - should fall back to Gemini 3 default (low)
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": {"summary": "auto"}}
|
||||
result = v.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model=model,
|
||||
drop_params=False,
|
||||
)
|
||||
# Gemini 3 defaults to thinkingLevel="low" when no explicit effort is set
|
||||
assert result["thinkingConfig"]["thinkingLevel"] == "low"
|
||||
|
||||
|
||||
def test_temperature_default_for_gemini_3():
|
||||
"""Test that temperature defaults to 1.0 for Gemini 3+ models when not specified"""
|
||||
from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import (
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue