Skip to content

fix: ensure reasoning_content on all assistant messages for DeepSeek/Kimi thinking mode - #15996

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

highland0971 wants to merge 1 commit into
NousResearch:mainfrom
highland0971:fix/deepseek-reasoning-content-400

Conversation

@highland0971

Copy link
Copy Markdown

Problem

DeepSeek and Volc Ark thinking mode requires every assistant message (including plain text replies) to carry a reasoning_content field. When this field is missing, the API returns HTTP 400:

{"error":{"message":"The reasoning_content in the thinking mode must be passed back to the API.","type":"invalid_request_error"}}

Root Cause

Three places where reasoning_content could be dropped:

  1. agent_loop.py: conditionally added reasoning_content only when non-empty (if reasoning:)
  2. run_agent.py: _copy_reasoning_content_for_api only covered tool-call assistant turns
  3. chat_completions.py: convert_messages returned messages as-is when no Codex sanitization was needed — no field normalization

Fix (3 changes)

  • environments/agent_loop.py L323 & L494: changed if reasoning: msg_dict["reasoning_content"] = reasoningmsg_dict["reasoning_content"] = reasoning or "" (unconditional)
  • run_agent.py _copy_reasoning_content_for_api: expanded scope from tool-call-only to all assistant turns for DeepSeek/Kimi providers
  • agent/transports/chat_completions.py convert_messages: added defense-in-depth normalization — ensures every role=="assistant" message has reasoning_content

Testing

Verified in production (Feishu bot with DeepSeek V4 Pro thinking mode). Previously failing conversations now work correctly. Three-layer defense ensures future changes won't re-introduce the issue.

…Kimi thinking mode

DeepSeek V4 and Volc Ark Coding Plan's thinking mode requires every assistant
message in the conversation history to have 'reasoning_content' field (even
if empty string). Missing this field on text-only (non-tool-call) responses
causes HTTP 400: 'The reasoning_content in the thinking mode must be passed
back to the API.'

Three changes:
1. agent_loop.py: Always set reasoning_content (not conditional on reasoning)
2. run_agent.py: _copy_reasoning_content_for_api applies to all assistant
   turns for DeepSeek/Kimi providers, not just tool-call turns
3. chat_completions.py: convert_messages() ensures reasoning_content is
   present on all assistant messages before API call (defense-in-depth)
@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
Contributor

Likely duplicate of #15478 (merged) — same fix ensuring reasoning_content on all assistant messages for DeepSeek/Kimi thinking mode. Also overlaps with #15792 and #15982.

@teknium1

Copy link
Copy Markdown
Collaborator

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