diff --git a/docs/my-website/docs/providers/deepseek.md b/docs/my-website/docs/providers/deepseek.md
index 31efb36c21f..1214431386d 100644
--- a/docs/my-website/docs/providers/deepseek.md
+++ b/docs/my-website/docs/providers/deepseek.md
@@ -58,9 +58,56 @@ We support ALL Deepseek models, just set `deepseek/` as a prefix when sending co
## Reasoning Models
| Model Name | Function Call |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| deepseek-reasoner | `completion(model="deepseek/deepseek-reasoner", messages)` |
+| deepseek-reasoner | `completion(model="deepseek/deepseek-reasoner", messages)` |
+### Thinking / Reasoning Mode
+Enable thinking mode for DeepSeek reasoner models using `thinking` or `reasoning_effort` parameters:
+
+
+
+
+```python
+from litellm import completion
+import os
+
+os.environ['DEEPSEEK_API_KEY'] = ""
+
+resp = completion(
+ model="deepseek/deepseek-reasoner",
+ messages=[{"role": "user", "content": "What is 2+2?"}],
+ thinking={"type": "enabled"},
+)
+print(resp.choices[0].message.reasoning_content) # Model's reasoning
+print(resp.choices[0].message.content) # Final answer
+```
+
+
+
+
+```python
+from litellm import completion
+import os
+
+os.environ['DEEPSEEK_API_KEY'] = ""
+
+resp = completion(
+ model="deepseek/deepseek-reasoner",
+ messages=[{"role": "user", "content": "What is 2+2?"}],
+ reasoning_effort="medium", # low, medium, high all map to thinking enabled
+)
+print(resp.choices[0].message.reasoning_content) # Model's reasoning
+print(resp.choices[0].message.content) # Final answer
+```
+
+
+
+
+:::note
+DeepSeek only supports `{"type": "enabled"}` - unlike Anthropic, it doesn't support `budget_tokens`. Any `reasoning_effort` value other than `"none"` enables thinking mode.
+:::
+
+### Basic Usage
diff --git a/litellm/llms/deepseek/chat/transformation.py b/litellm/llms/deepseek/chat/transformation.py
index a7defa886b5..d38ec4d67dd 100644
--- a/litellm/llms/deepseek/chat/transformation.py
+++ b/litellm/llms/deepseek/chat/transformation.py
@@ -14,6 +14,54 @@ from ...openai.chat.gpt_transformation import OpenAIGPTConfig
class DeepSeekChatConfig(OpenAIGPTConfig):
+ def get_supported_openai_params(self, model: str) -> list:
+ """
+ DeepSeek reasoner models support thinking parameter.
+ """
+ params = super().get_supported_openai_params(model)
+ params.extend(["thinking", "reasoning_effort"])
+ return params
+
+ def map_openai_params(
+ self,
+ non_default_params: dict,
+ optional_params: dict,
+ model: str,
+ drop_params: bool,
+ ) -> dict:
+ """
+ Map OpenAI params to DeepSeek params.
+
+ Handles `thinking` and `reasoning_effort` parameters for DeepSeek reasoner models.
+ DeepSeek only supports `{"type": "enabled"}` - no budget_tokens like Anthropic.
+
+ Reference: https://api-docs.deepseek.com/guides/thinking_mode
+ """
+ # Let parent handle standard params first
+ optional_params = super().map_openai_params(
+ non_default_params, optional_params, model, drop_params
+ )
+
+ # Pop thinking/reasoning_effort from optional_params first (parent may have added them)
+ # Then re-add only if valid for DeepSeek
+ thinking_value = optional_params.pop("thinking", None)
+ reasoning_effort = optional_params.pop("reasoning_effort", None)
+
+ # Handle thinking parameter - only accept {"type": "enabled"}
+ if thinking_value is not None:
+ if (
+ isinstance(thinking_value, dict)
+ and thinking_value.get("type") == "enabled"
+ ):
+ # DeepSeek only accepts {"type": "enabled"}, ignore budget_tokens
+ optional_params["thinking"] = {"type": "enabled"}
+
+ # Handle reasoning_effort - map to thinking enabled
+ elif reasoning_effort is not None and reasoning_effort != "none":
+ optional_params["thinking"] = {"type": "enabled"}
+
+ return optional_params
+
@overload
def _transform_messages(
self, messages: List[AllMessageValues], model: str, is_async: Literal[True]
diff --git a/tests/litellm/llms/deepseek/__init__.py b/tests/litellm/llms/deepseek/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/litellm/llms/deepseek/chat/__init__.py b/tests/litellm/llms/deepseek/chat/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py b/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py
new file mode 100644
index 00000000000..a2f45e7188b
--- /dev/null
+++ b/tests/litellm/llms/deepseek/chat/test_deepseek_chat_transformation.py
@@ -0,0 +1,168 @@
+"""
+Unit tests for DeepSeek chat transformation.
+
+Tests the thinking and reasoning_effort parameter handling for DeepSeek models.
+"""
+
+import pytest
+from litellm.llms.deepseek.chat.transformation import DeepSeekChatConfig
+
+
+class TestDeepSeekThinkingParams:
+ """Test thinking and reasoning_effort parameter handling for DeepSeek."""
+
+ def setup_method(self):
+ self.config = DeepSeekChatConfig()
+ self.model = "deepseek-reasoner"
+
+ def test_get_supported_openai_params_includes_thinking(self):
+ """Test that thinking and reasoning_effort are in supported params."""
+ params = self.config.get_supported_openai_params(self.model)
+ assert "thinking" in params
+ assert "reasoning_effort" in params
+
+ def test_map_thinking_enabled(self):
+ """Test that thinking={"type": "enabled"} is passed through correctly."""
+ non_default_params = {"thinking": {"type": "enabled"}}
+ 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"}
+
+ def test_map_thinking_with_budget_tokens_strips_budget(self):
+ """Test that budget_tokens is stripped from thinking param (DeepSeek doesn't support it)."""
+ non_default_params = {"thinking": {"type": "enabled", "budget_tokens": 2048}}
+ optional_params = {}
+
+ result = self.config.map_openai_params(
+ non_default_params=non_default_params,
+ optional_params=optional_params,
+ model=self.model,
+ drop_params=False,
+ )
+
+ # Should strip budget_tokens, only pass type
+ assert result["thinking"] == {"type": "enabled"}
+ assert "budget_tokens" not in result.get("thinking", {})
+
+ def test_map_reasoning_effort_medium(self):
+ """Test that reasoning_effort='medium' maps to thinking enabled."""
+ non_default_params = {"reasoning_effort": "medium"}
+ 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"}
+
+ def test_map_reasoning_effort_low(self):
+ """Test that reasoning_effort='low' maps to thinking enabled."""
+ non_default_params = {"reasoning_effort": "low"}
+ 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"}
+
+ def test_map_reasoning_effort_high(self):
+ """Test that reasoning_effort='high' maps to thinking enabled."""
+ non_default_params = {"reasoning_effort": "high"}
+ 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"}
+
+ def test_map_reasoning_effort_none_does_not_enable_thinking(self):
+ """Test that reasoning_effort='none' does not enable thinking."""
+ non_default_params = {"reasoning_effort": "none"}
+ 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 "thinking" not in result
+
+ def test_map_reasoning_effort_null_does_not_enable_thinking(self):
+ """Test that reasoning_effort=None does not enable thinking."""
+ non_default_params = {"reasoning_effort": None}
+ 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 "thinking" not in result
+
+ def test_thinking_takes_precedence_over_reasoning_effort(self):
+ """Test that thinking param takes precedence when both are provided."""
+ non_default_params = {
+ "thinking": {"type": "enabled"},
+ "reasoning_effort": "high",
+ }
+ optional_params = {}
+
+ result = self.config.map_openai_params(
+ non_default_params=non_default_params,
+ optional_params=optional_params,
+ model=self.model,
+ drop_params=False,
+ )
+
+ # thinking should be set, reasoning_effort should not override
+ assert result["thinking"] == {"type": "enabled"}
+
+ def test_invalid_thinking_type_ignored(self):
+ """Test that invalid thinking type values are ignored."""
+ non_default_params = {"thinking": {"type": "invalid"}}
+ 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 "thinking" not in result
+
+ def test_thinking_none_value_ignored(self):
+ """Test that thinking=None is ignored."""
+ non_default_params = {"thinking": None}
+ 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 "thinking" not in result