mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-01 02:02:20 +00:00
fix(deepseek): use model-name check for always-on reasoner instead of supports_reasoning()
supports_reasoning() returns True for V3.x opt-in models (e.g. deepseek-v3.2) as well as always-on models (deepseek-reasoner, R1 variants), so using it as the always-on guard was incorrectly injecting reasoning_content on V3.x requests that never enabled thinking. Replace with _is_always_on_reasoner() which checks for "reasoner" or "-r1"/"/r1" in the model name, precisely targeting only the always-on thinking models.
This commit is contained in:
parent
903b09c7ef
commit
2d05765955
1 changed files with 13 additions and 6 deletions
|
|
@ -10,7 +10,6 @@ from litellm.litellm_core_utils.prompt_templates.common_utils import (
|
|||
)
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
from litellm.utils import supports_reasoning
|
||||
|
||||
from ...openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
|
||||
|
|
@ -50,9 +49,7 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
thinking_value = optional_params.pop("thinking", None)
|
||||
reasoning_effort = optional_params.pop("reasoning_effort", None)
|
||||
|
||||
is_always_on_reasoner = supports_reasoning(
|
||||
model=model, custom_llm_provider="deepseek"
|
||||
)
|
||||
is_always_on_reasoner = self._is_always_on_reasoner(model=model)
|
||||
|
||||
# Handle thinking parameter - accepts {"type": "enabled"} or {"type": "disabled"}.
|
||||
# Guard: deepseek-reasoner has always-on thinking and rejects {"type": "disabled"}.
|
||||
|
|
@ -79,7 +76,7 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
normalized = "max" if reasoning_effort in ("max", "xhigh") else "high"
|
||||
optional_params["thinking"] = {"type": "enabled"}
|
||||
# Only forward reasoning_effort on V4 opt-in models.
|
||||
# deepseek-reasoner/R1 have supports_reasoning=True but don't accept reasoning_effort field.
|
||||
# deepseek-reasoner/R1 have always-on thinking and don't accept the reasoning_effort field.
|
||||
if not is_always_on_reasoner:
|
||||
optional_params["reasoning_effort"] = normalized
|
||||
|
||||
|
|
@ -140,6 +137,16 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
result.append(msg)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _is_always_on_reasoner(model: str) -> bool:
|
||||
"""
|
||||
Returns True for models with always-on thinking (deepseek-reasoner, R1 variants).
|
||||
These models reject reasoning_effort, thinking: {"type": "disabled"}, and
|
||||
require reasoning_content on every assistant message unconditionally.
|
||||
"""
|
||||
m = model.lower()
|
||||
return "reasoner" in m or "-r1" in m or "/r1" in m
|
||||
|
||||
@overload
|
||||
def _transform_messages(
|
||||
self, messages: List[AllMessageValues], model: str, is_async: Literal[True]
|
||||
|
|
@ -175,7 +182,7 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
- deepseek-reasoner/R1: always-on thinking, no explicit param needed
|
||||
- V4 opt-in models: only when user explicitly passed thinking={"type": "enabled"}
|
||||
"""
|
||||
if supports_reasoning(model=model, custom_llm_provider="deepseek"):
|
||||
if self._is_always_on_reasoner(model=model):
|
||||
return True # deepseek-reasoner always has thinking on
|
||||
return (optional_params.get("thinking") or {}).get("type") == "enabled"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue