mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(deepseek): forward graded reasoning_effort instead of discarding it
map_openai_params collapsed every non-"none" reasoning_effort into a bare
thinking: {"type": "enabled"} and dropped the level, so low, high and max
were all indistinguishable from the default and callers could not ask for
reduced reasoning at all
DeepSeek accepts reasoning_effort directly in thinking mode and grades it
server-side, so the value is forwarded rather than remapped here
Fixes #27439
This commit is contained in:
parent
9a715df212
commit
ee779d4259
2 changed files with 45 additions and 2 deletions
|
|
@ -39,7 +39,8 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
Handles `thinking` and `reasoning_effort` parameters for DeepSeek reasoner models.
|
||||
DeepSeek supports `{"type": "enabled"}` and `{"type": "disabled"}` - no budget_tokens
|
||||
like Anthropic. `reasoning_effort="none"` is the OpenAI-style way to ask for thinking
|
||||
off, so it maps to `{"type": "disabled"}`; any other effort keeps thinking on.
|
||||
off, so it maps to `{"type": "disabled"}`; any other effort keeps thinking on and
|
||||
is forwarded, since DeepSeek grades effort itself server-side.
|
||||
|
||||
Reference: https://api-docs.deepseek.com/guides/thinking_mode
|
||||
"""
|
||||
|
|
@ -57,7 +58,10 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
|
||||
# Otherwise fall back to reasoning_effort: "none" disables, anything else enables
|
||||
elif reasoning_effort is not None:
|
||||
optional_params["thinking"] = {"type": "disabled" if reasoning_effort == "none" else "enabled"}
|
||||
thinking_enabled: Final = reasoning_effort != "none"
|
||||
optional_params["thinking"] = {"type": "enabled" if thinking_enabled else "disabled"}
|
||||
if thinking_enabled:
|
||||
optional_params["reasoning_effort"] = reasoning_effort
|
||||
|
||||
return optional_params
|
||||
|
||||
|
|
|
|||
|
|
@ -443,6 +443,7 @@ class TestDeepSeekThinkingParams:
|
|||
)
|
||||
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
assert result["reasoning_effort"] == "medium"
|
||||
|
||||
def test_map_reasoning_effort_low(self):
|
||||
"""Test that reasoning_effort='low' maps to thinking enabled."""
|
||||
|
|
@ -457,6 +458,7 @@ class TestDeepSeekThinkingParams:
|
|||
)
|
||||
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
assert result["reasoning_effort"] == "low"
|
||||
|
||||
def test_map_reasoning_effort_high(self):
|
||||
"""Test that reasoning_effort='high' maps to thinking enabled."""
|
||||
|
|
@ -471,6 +473,43 @@ class TestDeepSeekThinkingParams:
|
|||
)
|
||||
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
assert result["reasoning_effort"] == "high"
|
||||
|
||||
def test_map_graded_effort_is_forwarded_not_collapsed(self):
|
||||
"""Every effort value reaches DeepSeek, which grades it server-side."""
|
||||
for effort in ("minimal", "low", "medium", "default", "high", "xhigh", "max", "ultra"):
|
||||
result = self.config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": effort},
|
||||
optional_params={},
|
||||
model=self.model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
assert result["reasoning_effort"] == effort
|
||||
|
||||
def test_explicit_thinking_is_honoured_exactly_as_given(self):
|
||||
"""An explicit toggle decides thinking, and no effort is merged into it."""
|
||||
result = self.config.map_openai_params(
|
||||
non_default_params={"thinking": {"type": "enabled"}, "reasoning_effort": "low"},
|
||||
optional_params={},
|
||||
model=self.model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "enabled"}
|
||||
assert "reasoning_effort" not in result
|
||||
|
||||
def test_disabled_thinking_carries_no_effort(self):
|
||||
"""Nothing is thinking, so an effort value would be meaningless."""
|
||||
for params in ({"reasoning_effort": "none"},
|
||||
{"thinking": {"type": "disabled"}}):
|
||||
result = self.config.map_openai_params(
|
||||
non_default_params=params,
|
||||
optional_params={},
|
||||
model=self.model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinking"] == {"type": "disabled"}
|
||||
assert "reasoning_effort" not in result
|
||||
|
||||
def test_map_reasoning_effort_none_does_not_enable_thinking(self):
|
||||
"""Test that reasoning_effort='none' does not enable thinking."""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue