mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(deepseek): map reasoning_effort=none to thinking disabled
DeepSeek V4 defaults to thinking mode when no thinking parameter is
set. When a user passes reasoning_effort="none", LiteLLM should
explicitly send thinking={"type": "disabled"} to turn off reasoning.
Previously, reasoning_effort="none" was silently ignored, leaving
the model in its default thinking-enabled state.
Also passes through thinking={"type": "disabled"} when set directly,
which was previously dropped by the enabled-only filter.
Fixes #27453
This commit is contained in:
parent
0af33fbe70
commit
0827eb1011
3 changed files with 101 additions and 9 deletions
|
|
@ -47,18 +47,20 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
thinking_value = optional_params.pop("thinking", None)
|
||||
reasoning_effort = optional_params.pop("reasoning_effort", None)
|
||||
|
||||
# Handle thinking parameter - only accept {"type": "enabled"}
|
||||
# Handle thinking parameter
|
||||
if thinking_value is not None:
|
||||
if (
|
||||
isinstance(thinking_value, dict)
|
||||
and thinking_value.get("type") == "enabled"
|
||||
if isinstance(thinking_value, dict) and thinking_value.get("type") in (
|
||||
"enabled",
|
||||
"disabled",
|
||||
):
|
||||
# DeepSeek only accepts {"type": "enabled"}, ignore budget_tokens
|
||||
optional_params["thinking"] = {"type": "enabled"}
|
||||
optional_params["thinking"] = {"type": thinking_value["type"]}
|
||||
|
||||
# Handle reasoning_effort - map to thinking enabled
|
||||
elif reasoning_effort is not None and reasoning_effort != "none":
|
||||
optional_params["thinking"] = {"type": "enabled"}
|
||||
# Handle reasoning_effort - map to thinking enabled/disabled
|
||||
elif reasoning_effort is not None:
|
||||
if reasoning_effort == "none":
|
||||
optional_params["thinking"] = {"type": "disabled"}
|
||||
else:
|
||||
optional_params["thinking"] = {"type": "enabled"}
|
||||
|
||||
return optional_params
|
||||
|
||||
|
|
|
|||
0
tests/test_litellm/llms/deepseek/__init__.py
Normal file
0
tests/test_litellm/llms/deepseek/__init__.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
"""
|
||||
Tests for DeepSeekChatConfig.map_openai_params thinking/reasoning_effort handling.
|
||||
|
||||
Regression tests for https://github.com/BerriAI/litellm/issues/27453
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../../.."))
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.llms.deepseek.chat.transformation import DeepSeekChatConfig
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config():
|
||||
return DeepSeekChatConfig()
|
||||
|
||||
|
||||
class TestReasoningEffortNone:
|
||||
"""reasoning_effort='none' should disable thinking."""
|
||||
|
||||
def test_reasoning_effort_none_disables_thinking(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "none"},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "disabled"}
|
||||
|
||||
def test_reasoning_effort_high_enables_thinking(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "high"},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
|
||||
def test_reasoning_effort_low_enables_thinking(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "low"},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
|
||||
|
||||
class TestThinkingParam:
|
||||
"""Direct thinking parameter should be passed through."""
|
||||
|
||||
def test_thinking_enabled(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"thinking": {"type": "enabled", "budget_tokens": 5000}},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
|
||||
def test_thinking_disabled(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"thinking": {"type": "disabled"}},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "disabled"}
|
||||
|
||||
def test_thinking_strips_budget_tokens(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"thinking": {"type": "enabled", "budget_tokens": 5000}},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert "budget_tokens" not in result["thinking"]
|
||||
|
||||
def test_no_thinking_params_leaves_thinking_unset(self, config):
|
||||
result = config.map_openai_params(
|
||||
non_default_params={"temperature": 0.5},
|
||||
optional_params={},
|
||||
model="deepseek-v4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert "thinking" not in result
|
||||
Loading…
Add table
Reference in a new issue