This commit is contained in:
misinierijon4-debug 2026-08-27 22:51:22 -04:00 committed by GitHub
commit c3f06c5189
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 79 additions and 12 deletions

View file

@ -931,10 +931,12 @@ class AmazonConverseConfig(BaseConfig):
litellm.verbose_logger.warning(DROP_UNSUPPORTED_ADAPTIVE_THINKING_WARNING, model)
else:
optional_params["thinking"] = value
elif param == "reasoning_effort" and isinstance(value, str):
self._handle_reasoning_effort_parameter(
model=model, reasoning_effort=value, optional_params=optional_params
)
elif param == "reasoning_effort":
effort_value = value.get("effort") if isinstance(value, dict) else value
if isinstance(effort_value, str):
self._handle_reasoning_effort_parameter(
model=model, reasoning_effort=effort_value, optional_params=optional_params
)
elif param == "output_config" and isinstance(value, dict):
mapped_output_config = dict(value)
normalize_bedrock_opus_output_config_effort(model=model, output_config=mapped_output_config)

View file

@ -170,10 +170,12 @@ class OllamaChatConfig(BaseConfig):
if value.get("json_schema") and value["json_schema"].get("schema"):
optional_params["format"] = value["json_schema"]["schema"]
if param == "reasoning_effort" and value is not None:
if model.startswith("gpt-oss"):
optional_params["think"] = value
else:
optional_params["think"] = value in {"low", "medium", "high"}
effort_value = value.get("effort") if isinstance(value, dict) else value
if effort_value is not None:
if model.startswith("gpt-oss"):
optional_params["think"] = effort_value
else:
optional_params["think"] = effort_value in {"low", "medium", "high"}
### FUNCTION CALLING LOGIC ###
# Ollama 0.4+ supports native tool calling - pass tools directly
# and let Ollama handle model capability detection

View file

@ -178,10 +178,12 @@ class OllamaConfig(BaseConfig):
elif param == "stop":
optional_params["stop"] = value
elif param == "reasoning_effort" and value is not None:
if model.startswith("gpt-oss"):
optional_params["think"] = value
else:
optional_params["think"] = value in {"low", "medium", "high"}
effort_value = value.get("effort") if isinstance(value, dict) else value
if effort_value is not None:
if model.startswith("gpt-oss"):
optional_params["think"] = effort_value
else:
optional_params["think"] = effort_value in {"low", "medium", "high"}
elif param == "response_format" and isinstance(value, dict):
if value["type"] == "json_object":
optional_params["format"] = "json"

View file

@ -904,3 +904,40 @@ class TestOllamaToolCallTransformation:
assert tool_msg["content"] == "Sunny, 72°F"
assert "tool_call_id" in tool_msg, "tool_call_id must be forwarded to Ollama"
assert tool_msg["tool_call_id"] == "call_abc123"
class TestOllamaReasoningEffortMapping:
"""
Test reasoning_effort mapping with string and dict formats (Responses API bridge).
Regression: https://github.com/BerriAI/litellm/issues/37452
"""
def test_map_openai_params_reasoning_effort_string(self):
config = OllamaChatConfig()
assert config.map_openai_params({"reasoning_effort": "low"}, {}, "qwen3", False) == {"think": True}
assert config.map_openai_params({"reasoning_effort": "medium"}, {}, "qwen3", False) == {"think": True}
assert config.map_openai_params({"reasoning_effort": "high"}, {}, "qwen3", False) == {"think": True}
assert config.map_openai_params({"reasoning_effort": "none"}, {}, "qwen3", False) == {"think": False}
def test_map_openai_params_reasoning_effort_dict_with_effort(self):
config = OllamaChatConfig()
result = config.map_openai_params(
{"reasoning_effort": {"effort": "medium", "summary": "auto"}}, {}, "qwen3", False
)
assert result == {"think": True}
result_low = config.map_openai_params({"reasoning_effort": {"effort": "low"}}, {}, "qwen3", False)
assert result_low == {"think": True}
result_none = config.map_openai_params({"reasoning_effort": {"effort": "none"}}, {}, "qwen3", False)
assert result_none == {"think": False}
def test_map_openai_params_reasoning_effort_dict_summary_only(self):
config = OllamaChatConfig()
result = config.map_openai_params({"reasoning_effort": {"summary": "auto"}}, {}, "qwen3", False)
assert "think" not in result
def test_map_openai_params_reasoning_effort_gpt_oss(self):
config = OllamaChatConfig()
result = config.map_openai_params({"reasoning_effort": {"effort": "medium"}}, {}, "gpt-oss-123", False)
assert result == {"think": "medium"}

View file

@ -502,3 +502,27 @@ class TestOllamaTextCompletionResponseIterator:
assert result["usage"]["prompt_tokens"] == 10
assert result["usage"]["completion_tokens"] == 5
assert result["usage"]["total_tokens"] == 15
class TestOllamaCompletionReasoningEffortMapping:
@pytest.mark.parametrize(
("reasoning_effort", "model", "expected"),
[
("medium", "qwen3", {"think": True}),
("none", "qwen3", {"think": False}),
({"effort": "medium", "summary": "auto"}, "qwen3", {"think": True}),
({"effort": "medium"}, "gpt-oss-123", {"think": "medium"}),
({"summary": "auto"}, "qwen3", {}),
],
)
def test_map_openai_params_reasoning_effort(self, reasoning_effort, model, expected):
config = OllamaConfig()
result = config.map_openai_params(
{"reasoning_effort": reasoning_effort},
{},
model,
False,
)
assert result == expected