Skip to content

feat: add DeepSeek-V4 thinking mode via unified thinking_mode parameter - #15577

Closed
heming-gmh wants to merge 1 commit into
NousResearch:mainfrom
heming-gmh:feat/deepseek-thinking-mode
Closed

feat: add DeepSeek-V4 thinking mode via unified thinking_mode parameter#15577
heming-gmh wants to merge 1 commit into
NousResearch:mainfrom
heming-gmh:feat/deepseek-thinking-mode

Conversation

@heming-gmh

Copy link
Copy Markdown

Summary

Add support for DeepSeek V4-Pro / V4-Flash thinking mode when using the DeepSeek direct API (api.deepseek.com).

Design Intent

Introduce a single string-valued thinking_mode parameter to replace the pattern of adding one boolean flag per provider. Each provider uses exactly one branch in the transport's build_kwargs:

thinking_mode Behavior
kimi Top-level reasoning_effort + extra_body.thinking (low/medium/high)
deepseek Top-level reasoning_effort + extra_body.thinking (high/max)
None Falls back to is_kimi / supports_reasoning for backward compatibility

Adding a new thinking-capable provider requires only one elif in run_agent.py + one elif in chat_completions.py -- no flag proliferation.

DeepSeek-specific behavior

  • Sets reasoning_effort: max (default) or high
  • Sets extra_body: {thinking: {type: enabled}}
  • Automatically removes temperature when thinking is active (DeepSeek docs: temperature/top_p unsupported with thinking)
  • Can be disabled via reasoning_config: {enabled: false}

Files changed

  • agent/transports/chat_completions.py -- Unified thinking_mode branch for Kimi + DeepSeek, backward compat with is_kimi/supports_reasoning
  • run_agent.py -- New _thinking_provider() method replacing scattered boolean detection
  • tests/agent/transports/test_chat_completions.py -- 8 new tests

Testing

  • All 49 chat_completions tests pass (41 existing + 8 new)
  • Full test suite: 4282 passed, 2 pre-existing failures unrelated
  • Real API call verified against api.deepseek.com with deepseek-v4-pro

Add support for DeepSeek V4-Pro/V4-Flash thinking mode when using
api.deepseek.com directly.

Design intent:
  Introduce a single string-valued  parameter to replace
  the pattern of adding one boolean flag per provider.  Each provider
  uses exactly one branch in the transport's build_kwargs:

    thinking_mode='kimi'     → reasoning_effort + extra_body.thinking
    thinking_mode='deepseek' → reasoning_effort + extra_body.thinking
                               (different effort values: high/max)
    thinking_mode=None       → falls back to is_kimi / supports_reasoning
                               for backward compatibility

  For DeepSeek:
    - Sets top-level reasoning_effort: "max" (default) or "high"
    - Sets extra_body: {thinking: {type: "enabled"}}
    - Automatically removes temperature when thinking is active
      (DeepSeek docs: temperature/top_p unsupported with thinking)
    - Can be disabled via reasoning_config: {enabled: false}

  Testing:
    - 49 tests pass (41 existing + 8 new for DeepSeek + unified mode)
    - Real API call verified against api.deepseek.com with
      deepseek-v4-pro model, confirmed reasoning_content returned
@heming-gmh

Copy link
Copy Markdown
Author

Timing note: DeepSeek V4-Pro and V4-Flash were released on April 24/25, 2026 — just yesterday. This PR adds first-class thinking mode support for the DeepSeek direct API (api.deepseek.com), which requires the reasoning_effort + extra_body.thinking parameters to unlock the model's chain-of-thought reasoning.

Without this change, users of deepseek-v4-pro / deepseek-v4-flash on the direct API get plain responses. With it, they get structured reasoning content streamed back through assistant_msg["reasoning"] — the same way Kimi's thinking mode works today.

Tests verified against the live API ✅ (4282 tests passed, 2 pre-existing failures unrelated).

Happy to make any adjustments the maintainers suggest!

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/deepseek DeepSeek API labels Apr 25, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #15446 (comprehensive DeepSeek V4 support), #15251, and #14958 — overlapping DeepSeek thinking mode implementations. This PR introduces a unified thinking_mode parameter which is a cleaner design than per-provider boolean flags.

@heming-gmh heming-gmh changed the title feat: add DeepSeek thinking mode via unified thinking_mode parameter feat: add DeepSeek-V4 thinking mode via unified thinking_mode parameter Apr 25, 2026
@heming-gmh

heming-gmh commented Apr 25, 2026

Copy link
Copy Markdown
Author

Thanks for the overview, @alt-glitch! I'd be happy to collaborate with @Tranquil-Flow and the others to merge these overlapping implementations into a cohesive solution.

My PR introduces a unified thinking_mode parameter ("deepseek" / "kimi" / None) that replaces per-provider boolean flags — a design I believe keeps build_kwargs() cleaner as more providers add thinking/reasoning support.

I see that #15446 has additional valuable coverage (1M context windows, reasoning replay fixes, max-iterations path, more extensive tests) that mine doesn't address yet. I'd love to work with Tranquil-Flow to integrate the unified thinking_mode approach into a comprehensive PR that combines the best of both.

@heming-gmh

Copy link
Copy Markdown
Author

@alt-glitch Thanks for the review and for flagging the competing PRs. I see #16448 takes the minimal approach — it's clean and solves the immediate problem. My PR (#15577) aims for the same functional goal but introduces a unified thinking_mode string parameter to prevent future provider-specific boolean flag proliferation. Each new thinking-capable provider (Kimi, DeepSeek, and any future ones) requires exactly one elif branch — no new boolean flags, no scattered detection. The two approaches are complementary: if #16448 lands first as the hotfix, I'm happy to rebase mine on top of it as the long-term architectural abstraction. Let me know which direction you'd prefer.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the DeepSeek thinking-mode work. This is an automated hermes-sweeper review; current main already provides the requested direct-API behavior through the provider-profile path.

  • plugins/model-providers/deepseek/__init__.py:47-82 emits extra_body.thinking and maps reasoning_config to top-level reasoning_effort for DeepSeek V4 models.
  • agent/transports/chat_completions.py:316-325,562-594 routes registered providers through DeepSeekProfile.build_api_kwargs_extras() rather than the legacy flag-based transport path.
  • tests/plugins/model_providers/test_deepseek_profile.py:155-169 verifies the complete V4-Pro request wire shape.
  • This shipped in cd9470f41638bd515db096cd934c463205790110 (fix(deepseek): wire thinking-mode via DeepSeekProfile, not legacy fallback), included in v2026.5.16.

The overlapping-implementation discussion was useful: main adopted the provider-profile implementation so provider-specific behavior executes on the live request path.

@teknium1 teknium1 closed this Jul 12, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 12, 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:implemented-on-main Sweeper: behavior already present on current main type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants