Skip to content

Conversation

@daniel7an
Copy link

Summary

Update the DeepSeek model implementation to support the latest DeepSeek V3.2 reasoner features, including tool call support in thinking mode.

Changes

Bug Fix

  • Fixed config filtering bug: copy.deepcopy(self.model_config_dict) was overwriting the filtered config for reasoner models, making the parameter filtering completely ineffective.

Feature Updates

  • Enabled tool calls for reasoner model: Removed 'tools' from REASONER_UNSUPPORTED_PARAMS since DeepSeek V3.2 reasoner now supports tool calls with thinking mode (docs).
  • Added reasoning_content injection/extraction: For multi-turn tool calls in thinking mode, the DeepSeek API requires reasoning_content from the model response to be passed back in subsequent requests. This follows the same pattern already used by VolcanoModel.

Minor

  • Fixed typo in constant name (REASONSERREASONER)
  • Updated documentation URL to point to the current thinking_mode guide

Tests

Added tests for:

  • Reasoner param filtering works correctly
  • Reasoner allows tools in request config
  • Chat model keeps all params
  • reasoning_content injection into assistant messages with tool calls
  • No injection when no reasoning_content is stored

Closes #3811

- Remove 'tools' from reasoner unsupported params since DeepSeek V3.2
  reasoner now supports tool calls with thinking mode
- Fix bug where copy.deepcopy overwrote the filtered config for
  reasoner models, making param filtering ineffective
- Add reasoning_content injection/extraction for tool call
  continuations (required by DeepSeek API for multi-turn tool calls
  in thinking mode)
- Fix typo in constant name (REASONSER -> REASONER)
- Update documentation URL to point to current thinking_mode guide

Closes camel-ai#3811
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Collaborator

@bytecii bytecii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, left some comments

# Store the last reasoning_content from model response.
# For DeepSeek reasoner models with tool calls, the
# reasoning_content must be passed back in subsequent requests.
self._last_reasoning_content: Optional[str] = None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also add a TODO to improve the reasoning content storage
also nit:

Suggested change
self._last_reasoning_content: Optional[str] = None
self._last_reasoning_content: str | None = None


def _inject_reasoning_content(
self,
messages: List[OpenAIMessage],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
messages: List[OpenAIMessage],
messages: list[OpenAIMessage],

in subsequent requests for proper context management.

Args:
messages: The original messages list.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
messages: The original messages list.
messages (OpenAIMessage): The original messages list.

if (
not reasoning_injected
and isinstance(msg, dict)
and msg.get("role") == "assistant"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any enum for the assistant we can use here?

reasoning_injected = False

for msg in reversed(messages):
if (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can separate these checkings to make it clearer?
is_reasoning = (not reasoning_injected) and ("reasoning_content" not in msg)
is_tool_call = msg.get("tool_calls") is not None
is_assistant = msg.get("role") == "assistant"
if is_reasoning and is_tool_call and is_assistant:
...

and "reasoning_content" not in msg
):
new_msg = dict(msg)
new_msg["reasoning_content"] = self._last_reasoning_content
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be not None?

processed.append(msg)

if reasoning_injected:
self._last_reasoning_content = None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move it below the reasoning_injected = True?

r"""Extract reasoning_content from the model response.

Args:
response: The model response.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
response: The model response.
response (ChatCompletion): The model response.


def _extract_reasoning_content(
self, response: ChatCompletion
) -> Optional[str]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) -> Optional[str]:
) -> str | None:

tools: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
request_config = self.model_config_dict.copy()
import copy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to the top

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Update deepseek model feature

2 participants