Skip to content

feat(deepseek): add reasoning_effort and thinking toggle support#24225

Closed
Booklight12 wants to merge 1 commit into
NousResearch:mainfrom
Booklight12:feat/deepseek-reasoning-effort
Closed

feat(deepseek): add reasoning_effort and thinking toggle support#24225
Booklight12 wants to merge 1 commit into
NousResearch:mainfrom
Booklight12:feat/deepseek-reasoning-effort

Conversation

@Booklight12

Copy link
Copy Markdown

What does this PR do?

Add reasoning_effort (intensity control) and thinking toggle support for the native DeepSeek provider (api.deepseek.com).

DeepSeek V4 models (Flash / Pro) expose two independent thinking controls through their OpenAI-compatible API:

  • Thinking toggle: {"thinking": {"type": "enabled/disabled"}} in extra_body
  • Effort control: "reasoning_effort": "high" / "max" at top level

The server maps low / mediumhigh and xhighmax for compatibility with OpenRouter-style effort levels. This PR mirrors that mapping client-side.

Previously, the deepseek provider profile was a bare ProviderProfile that emitted neither parameter — the native API path had no way to toggle thinking or control reasoning intensity. The OpenRouter path sent a generic extra_body.reasoning block that does not match DeepSeek's native format.

This PR introduces a DeepSeekProfile subclass implementing build_api_kwargs_extras() that emits both parameters, following the same pattern already used by KimiProfile for Kimi / Moonshot.

Related Issue

Fixes #

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • plugins/model-providers/deepseek/__init__.py — Replace bare ProviderProfile with DeepSeekProfile subclass that implements build_api_kwargs_extras(), emitting extra_body.thinking (toggle) and top-level reasoning_effort (intensity). Effort mapping: low/medium/minimalhigh, xhighmax, highhigh, maxmax, unknown → high.
  • tests/providers/test_provider_profiles.py — Add TestDeepSeekProfile class with 12 test cases covering all effort mappings (none, minimal, low, medium, high, xhigh, max, unknown, missing), alias lookup, profile registration, and thinking toggle behavior.

How to Test

  1. Run pytest tests/providers/test_provider_profiles.py -v -n 0 — all 53 tests should pass (41 existing + 12 new).
  2. Start a Hermes session with provider: deepseek and a DeepSeek V4 model.
  3. Use /reasoning none to disable thinking — the API request should include extra_body.thinking = {"type": "disabled"} with no reasoning_effort.
  4. Use /reasoning xhigh — the API request should include reasoning_effort: "max" and extra_body.thinking = {"type": "enabled"}.
  5. Verify default behavior (no /reasoning set) sends thinking: enabled + reasoning_effort: high.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: WSL (Ubuntu) / Windows 11

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A (docstring on build_api_kwargs_extras updated)
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (provider profile is platform-agnostic)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

tests/providers/test_provider_profiles.py ................................
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_profile_registered PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_alias_lookup PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_no_config_defaults PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_thinking_disabled PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_high PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_max PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_xhigh_maps_to_max PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_medium_maps_to_high PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_low_maps_to_high PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_effort_minimal_maps_to_high PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_unknown_effort_falls_back_to_high PASSED
tests/providers/test_provider_profiles.py::TestDeepSeekProfile::test_missing_effort_defaults_to_high PASSED

============================== 53 passed in 1.10s ==============================

Ref: https://api-docs.deepseek.com/guides/thinking_mode

DeepSeek V4 models support two independent thinking controls via the
native API (api.deepseek.com):

  - Thinking toggle: {"thinking": {"type": "enabled/disabled"}}
    in extra_body
  - Effort control: "reasoning_effort": "high"|"max" at top level
    (low/medium → high, xhigh → max per DeepSeek API docs)

Previously the deepseek provider profile was a bare ProviderProfile
that emitted neither parameter — the native API path had no way to
toggle thinking or control reasoning intensity.  The OpenRouter path
sent a generic extra_body.reasoning block that does not match
DeepSeek's native format.

This adds a DeepSeekProfile subclass implementing
build_api_kwargs_extras() that emits both parameters, following the
same pattern already used by KimiProfile for Kimi / Moonshot.

Tests: 12 new test cases covering all effort mappings (none, minimal,
low, medium, high, xhigh, max, unknown, missing) plus alias lookup
and profile registration.

Ref: https://api-docs.deepseek.com/guides/thinking_mode
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins provider/deepseek DeepSeek API labels May 12, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #22218 — same approach (DeepSeekProfile subclass with build_api_kwargs_extras() for thinking toggle + reasoning_effort mapping). Multiple competing PRs exist: #16448, #21052, #22218.

@Booklight12

Copy link
Copy Markdown
Author

Thanks for the heads-up. Closing this in favor of #22218 since the approaches overlap.

This PR includes 12 test cases covering all effort mappings (none/minimal/low/medium/high/xhigh/max + edge cases) — none of the competing PRs have tests. Happy to contribute those tests to whichever PR the maintainers prefer.

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

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have provider/deepseek DeepSeek API type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants