Skip to content

feat: add DeepSeek V4 reasoning support - #28945

Open
andrew-manger wants to merge 1 commit into
NousResearch:mainfrom
andrew-manger:hermes/deepseek-v4-reasoning
Open

feat: add DeepSeek V4 reasoning support#28945
andrew-manger wants to merge 1 commit into
NousResearch:mainfrom
andrew-manger:hermes/deepseek-v4-reasoning

Conversation

@andrew-manger

Copy link
Copy Markdown

Summary

DeepSeek V4 (deepseek-v4-flash / deepseek-v4-pro) added thinking mode with client-controllable reasoning effort. Hermes previously had no DeepSeek-specific reasoning handling, so reasoning config was silently dropped when using the direct DeepSeek API.

What DeepSeek V4 supports

Per DeepSeek API docs:

  • reasoning_effort top-level parameter: "high" or "max"
  • extra_body.thinking.type: "enabled" or "disabled"
  • Effort mapping: low/mediumhigh, xhighmax
  • Default: thinking enabled at high effort

Changes

agent/transports/chat_completions.py

  • Detect DeepSeek via is_deepseek flag
  • Emit top-level reasoning_effort mapped to DeepSeek's levels
  • Emit extra_body.thinking toggle (enabled/disabled)

agent/chat_completion_helpers.py

  • Add _is_deepseek detection
  • Pass is_deepseek through to transport
  • Handle DeepSeek reasoning in summary/compression path (previously only handled extra_body.reasoning for OpenRouter/Anthropic, and reasoning_effort for LM Studio)

Before / After

Config Before After
/reasoning high + DeepSeek direct API No-op (silently ignored) reasoning_effort: high + thinking: enabled
/reasoning xhigh + DeepSeek direct API No-op reasoning_effort: max + thinking: enabled
/reasoning none + DeepSeek direct API No-op thinking: disabled

Test plan

  1. Set provider to deepseek with model deepseek-v4-pro
  2. Run /reasoning high → verify reasoning_effort: high sent
  3. Run /reasoning xhigh → verify reasoning_effort: max sent
  4. Run /reasoning none → verify thinking: disabled sent

Related

DeepSeek V4 (deepseek-v4-flash/pro) supports thinking mode via:
- top-level reasoning_effort parameter (high/max)
- extra_body.thinking {type: enabled/disabled}

Per DeepSeek docs:
- low/medium/high map to 'high'
- xhigh maps to 'max'
- thinking defaults to enabled

This adds DeepSeek-specific handling in both:
1. ChatCompletionsTransport.build_kwargs() — main chat path
2. chat_completion_helpers summary path — compression/summary path

Hermes previously only supported reasoning for:
- Kimi (reasoning_effort + extra_body.thinking)
- TokenHub (reasoning_effort)
- LM Studio (reasoning_effort)
- OpenRouter Anthropic/Claude/OpenAI (extra_body.reasoning)

DeepSeek via direct API was silently dropping reasoning config.

Fixes: reasoning config now properly forwarded to DeepSeek V4 models.
@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/deepseek DeepSeek API P2 Medium — degraded but workaround exists labels May 19, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the DeepSeek V4 reasoning work. The premise still has value, but current main has moved the active DeepSeek request-shaping path since this PR was opened.

Problems

  • The main chat-path part is now wired to the wrong layer. Current main resolves registered providers at agent/chat_completion_helpers.py:725-764 and passes provider_profile into the transport; agent/transports/chat_completions.py:526-538 then delegates provider-specific kwargs to profile.build_api_kwargs_extras(). For provider: deepseek, the new legacy is_deepseek flag path in this PR would be bypassed.
  • The effort mapping requested here is not fully present on current main: plugins/model-providers/deepseek/__init__.py:72-80 still forwards low and medium unchanged, while this PR maps them to DeepSeek's high.
  • The summary-path addition appears to re-enable thinking for /reasoning none: in the PR diff, agent/chat_completion_helpers.py:1018 always sends summary_extra_body["thinking"] = {"type": "enabled"} when the DeepSeek summary effort branch runs.

Suggested changes

  • Salvage the mapping into plugins/model-providers/deepseek/__init__.py::DeepSeekProfile.build_api_kwargs_extras().
  • Add targeted tests for high, xhigh, low/medium, and disabled reasoning, plus a summary-path kwargs test if summary support is retained.

Automated hermes-sweeper review.

@@ -283,6 +284,25 @@ def build_kwargs(
_kimi_effort = _e

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

On current main this lives in the bypassed legacy flag path for registered providers. provider: deepseek now routes through ProviderProfile, so this mapping should move into plugins/model-providers/deepseek/__init__.py::DeepSeekProfile.build_api_kwargs_extras().

@@ -1009,6 +1016,9 @@ def handle_max_iterations(agent, messages: list, api_call_count: int) -> str:
summary_kwargs.update(agent._max_tokens_param(agent.max_tokens))
if _lm_reasoning_effort is not None:
summary_kwargs["reasoning_effort"] = _lm_reasoning_effort

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This re-enables DeepSeek thinking during summaries even for /reasoning none: the branch is entered for a truthy reasoning_config, then always sends thinking.type=enabled. The disabled case needs to mirror the main request path.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/deepseek DeepSeek API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants