diff --git a/litellm/llms/deepseek/chat/transformation.py b/litellm/llms/deepseek/chat/transformation.py index 5cd8d119542..7df1c89d989 100644 --- a/litellm/llms/deepseek/chat/transformation.py +++ b/litellm/llms/deepseek/chat/transformation.py @@ -56,9 +56,17 @@ class DeepSeekChatConfig(OpenAIGPTConfig): # DeepSeek only accepts {"type": "enabled"}, ignore budget_tokens optional_params["thinking"] = {"type": "enabled"} - # Handle reasoning_effort - map to thinking enabled + # Handle reasoning_effort - enable thinking and pass effort level + # DeepSeek V4 Pro/Flash support reasoning_effort as a native param + # with values "high" and "max". Older models ignore it gracefully. elif reasoning_effort is not None and reasoning_effort != "none": optional_params["thinking"] = {"type": "enabled"} + # Normalize per DeepSeek V4 compatibility mappings + if reasoning_effort in ("low", "medium"): + reasoning_effort = "high" + elif reasoning_effort == "xhigh": + reasoning_effort = "max" + optional_params["reasoning_effort"] = reasoning_effort return optional_params diff --git a/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py b/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py index a2f45e7188b..d13ae62d93f 100644 --- a/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py +++ b/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py @@ -52,7 +52,7 @@ class TestDeepSeekThinkingParams: assert "budget_tokens" not in result.get("thinking", {}) def test_map_reasoning_effort_medium(self): - """Test that reasoning_effort='medium' maps to thinking enabled.""" + """Test that reasoning_effort='medium' enables thinking and normalizes to 'high'.""" non_default_params = {"reasoning_effort": "medium"} optional_params = {} @@ -64,9 +64,10 @@ class TestDeepSeekThinkingParams: ) assert result["thinking"] == {"type": "enabled"} + assert result["reasoning_effort"] == "high" def test_map_reasoning_effort_low(self): - """Test that reasoning_effort='low' maps to thinking enabled.""" + """Test that reasoning_effort='low' enables thinking and normalizes to 'high'.""" non_default_params = {"reasoning_effort": "low"} optional_params = {} @@ -78,9 +79,10 @@ class TestDeepSeekThinkingParams: ) assert result["thinking"] == {"type": "enabled"} + assert result["reasoning_effort"] == "high" def test_map_reasoning_effort_high(self): - """Test that reasoning_effort='high' maps to thinking enabled.""" + """Test that reasoning_effort='high' is passed through to DeepSeek V4.""" non_default_params = {"reasoning_effort": "high"} optional_params = {} @@ -92,6 +94,37 @@ class TestDeepSeekThinkingParams: ) assert result["thinking"] == {"type": "enabled"} + assert result["reasoning_effort"] == "high" + + def test_map_reasoning_effort_max(self): + """Test that reasoning_effort='max' is passed through to DeepSeek V4.""" + non_default_params = {"reasoning_effort": "max"} + optional_params = {} + + result = self.config.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=self.model, + drop_params=False, + ) + + assert result["thinking"] == {"type": "enabled"} + assert result["reasoning_effort"] == "max" + + def test_map_reasoning_effort_xhigh_normalizes_to_max(self): + """Test that reasoning_effort='xhigh' normalizes to 'max' per DeepSeek V4 compat.""" + non_default_params = {"reasoning_effort": "xhigh"} + optional_params = {} + + result = self.config.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=self.model, + drop_params=False, + ) + + assert result["thinking"] == {"type": "enabled"} + assert result["reasoning_effort"] == "max" def test_map_reasoning_effort_none_does_not_enable_thinking(self): """Test that reasoning_effort='none' does not enable thinking."""