Skip to content

fix: add DeepSeek reasoning_content echo for tool-call messages (fixes #15353)#15354

Closed
chen1749144759 wants to merge 1 commit into
NousResearch:mainfrom
chen1749144759:fix/deepseek-reasoning-content-15250
Closed

fix: add DeepSeek reasoning_content echo for tool-call messages (fixes #15353)#15354
chen1749144759 wants to merge 1 commit into
NousResearch:mainfrom
chen1749144759:fix/deepseek-reasoning-content-15250

Conversation

@chen1749144759

Copy link
Copy Markdown
Contributor

Summary

DeepSeek V4 thinking mode requires reasoning_content on every assistant message that includes tool_calls. When missing, replay causes HTTP 400.

Closes #15353
Related: #14938 #14933 #15213

Changes

1. Merge DeepSeek into needs_tool_reasoning_echo check

In _copy_reasoning_content_for_api(), replaced the Kimi-only detection with a combined check covering:

  • provider == "deepseek"
  • "deepseek" in model (case-insensitive)
  • api.deepseek.com base URL (custom provider)

This handles already-poisoned persisted sessions by injecting empty reasoning_content on replay.

2. Store reasoning_content on new tool-call messages

Added _needs_deepseek_tool_reasoning() helper method, wired into _build_assistant_message(). When a DeepSeek tool-call message is created without reasoning text (common for streaming tool-only turns), stores reasoning_content="" instead of omitting the field. Prevents future session poisoning at the source.

3. Fix _handle_max_iterations path

Added missing call to _copy_reasoning_content_for_api() in the max-iterations flush path. Previously only the main loop and flush_memories() had this call.

Test Plan

  • Verified in state.db: new tool-call messages store reasoning_content
  • Previously poisoned messages handled by replay fix
  • Tested on Rocky Linux 9.7 with deepseek-v4-pro via custom provider

Diff

1 file changed: run_agent.py (+30, -3)

DeepSeek V4 thinking mode requires reasoning_content on every
assistant message that includes tool_calls. When this field is
missing from persisted history, replaying the session causes
HTTP 400: 'The reasoning_content in the thinking mode must be
passed back to the API.'

Two-part fix (refs NousResearch#15250):

1. _copy_reasoning_content_for_api: Merge the Kimi-only and
   DeepSeek detection into a single needs_tool_reasoning_echo
   check. This handles already-poisoned persisted sessions by
   injecting an empty reasoning_content on replay.

2. _build_assistant_message: Store reasoning_content='' on new
   DeepSeek tool-call messages at creation time, preventing
   future session poisoning at the source.

Additional fix:
3. _handle_max_iterations: Add missing call to
   _copy_reasoning_content_for_api in the max-iterations flush
   path (previously only main loop and flush_memories had it).

Detection covers:
- provider == 'deepseek'
- model name containing 'deepseek' (case-insensitive)
- base URL matching api.deepseek.com (for custom provider)
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent loop, run_agent.py, prompt builder provider/deepseek DeepSeek API labels Apr 24, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #15407 — your commit 93a2d6b30 is on main with your authorship preserved via rebase-merge. Thanks @chen1749144759!

We added a small refactor on top (extracted _needs_kimi_tool_reasoning() for symmetry with _needs_deepseek_tool_reasoning(), so both the creation and replay paths share the same detection logic) plus a regression test suite (tests/run_agent/test_deepseek_reasoning_content_echo.py, 21 tests covering all 3 DeepSeek signals + existing Kimi behavior).

Closes #15250 + #15353.

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

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround provider/deepseek DeepSeek API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DeepSeek V4 thinking mode: missing reasoning_content on tool-call messages causes 400

3 participants