Skip to content

fix: extend DeepSeek reasoning_content fallback to text-only assistant messages - #16247

Closed
brian-doherty wants to merge 1 commit into
NousResearch:mainfrom
brian-doherty:fix/deepseek-reasoning-content-creation-path
Closed

fix: extend DeepSeek reasoning_content fallback to text-only assistant messages#16247
brian-doherty wants to merge 1 commit into
NousResearch:mainfrom
brian-doherty:fix/deepseek-reasoning-content-creation-path

Conversation

@brian-doherty

Copy link
Copy Markdown
Contributor

Bug

When using DeepSeek in thinking mode (reasoning_effort: medium), text-only assistant responses (the final reply after a tool loop) could be persisted to the session DB without a reasoning_content field. On session resume, replaying that message to DeepSeek's API produces:

HTTP 400: The reasoning_content in the thinking mode must be passed back to the API.

This forced users to start a new session to recover.

Root Cause

_build_assistant_message (the creation path at run_agent.py:7763) only guaranteed the reasoning_content="" fallback for tool-call messages under DeepSeek thinking mode. Text-only responses fell through without setting reasoning_content at all, because:

  1. The API response object may not have reasoning_content on every turn
  2. The fallback only fired when msg["tool_calls"] was truthy AND _needs_deepseek_tool_reasoning() was True

Fix

Separates the Kimi (tool-call-only) and DeepSeek (all messages) fallback logic:

  • Kimi: unchanged — reasoning_content="" only on tool-call messages
  • DeepSeek: reasoning_content set on every assistant message, falling back to the content of the reasoning field or empty string

The replay safety net in _copy_reasoning_content_for_api (step 4) already catches this edge case, but storing correct data from creation time is cleaner and avoids relying on the replay-time catch-all.

Related

Refs #15250 (original DeepSeek tool-call reasoning_content fix), #15998 (this bug).

Test Plan

  • Existing tests pass: pytest tests/run_agent/ -x -q
  • Manual: DeepSeek thinking mode session with tool calls followed by text-only response, then session resume

…t messages

DeepSeek thinking mode requires reasoning_content on EVERY assistant
message replayed to the API, not just tool-call ones. The previous
code only set the empty-string fallback for tool-call messages, so
text-only responses (e.g. the final response after a tool loop) could
be persisted without reasoning_content. On session resume, replaying
such a message to DeepSeek's API produces HTTP 400:

  The reasoning_content in the thinking mode must be passed back
  to the API.

The replay safety net in _copy_reasoning_content_for_api (step 4)
already handles this on replay, but storing correct data from creation
time is cleaner and avoids relying on the replay catch-all.

Separates Kimi (tool-call-only empty-string) from DeepSeek (all
assistant messages) so each provider's contract is met precisely.

Refs NousResearch#15250, NousResearch#15998
@alt-glitch alt-glitch added type/bug Something isn't working 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 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Part of the reasoning_content fix cluster — related to #15792, #15527, #15982, #16023. Verify this is not already addressed by one of the merged fixes.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Part of the reasoning_content fix cluster.

@teknium1

Copy link
Copy Markdown
Contributor

Closing as redundant — the DeepSeek reasoning_content thinking-mode 400 and cross-provider leak chain of issues is now fully covered on main:

21 regression tests in tests/run_agent/test_deepseek_reasoning_content_echo.py + 2 new tests for the cross-provider scenario exercise every known path. Thanks for the submission — appreciate the digging on this area.

@teknium1 teknium1 closed this Apr 27, 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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants