Skip to content

fix(subagent): preserve reasoning_content in assistant messages#1848

Merged
Re-bin merged 1 commit intoHKUDS:mainfrom
lailoo:fix/subagent-reasoning-content
Mar 11, 2026
Merged

fix(subagent): preserve reasoning_content in assistant messages#1848
Re-bin merged 1 commit intoHKUDS:mainfrom
lailoo:fix/subagent-reasoning-content

Conversation

@lailoo
Copy link
Copy Markdown
Contributor

@lailoo lailoo commented Mar 10, 2026

Summary

  • Subagent's _run_subagent() was silently dropping reasoning_content and thinking_blocks when building assistant messages for the conversation history
  • Providers like Deepseek Reasoner mandate reasoning_content on every assistant message when thinking mode is active, causing a 400 BadRequestError on the second LLM round-trip
  • The main AgentLoop already preserves these fields correctly via ContextBuilder.add_assistant_message() — this fix aligns the subagent loop with that behavior

Root Cause

In subagent.py, the assistant message was built as a plain dict without reasoning_content:

# Before (broken)
messages.append({
    "role": "assistant",
    "content": response.content or "",
    "tool_calls": tool_call_dicts,
})

Deepseek's API returns 400 with:

Missing `reasoning_content` field in the assistant message at message index 2

Fix

Conditionally include reasoning_content and thinking_blocks when the provider returns them, matching how ContextBuilder.add_assistant_message() handles this in the main agent loop:

# After (fixed)
assistant_msg: dict[str, Any] = {
    "role": "assistant",
    "content": response.content or "",
    "tool_calls": tool_call_dicts,
}
if response.reasoning_content is not None:
    assistant_msg["reasoning_content"] = response.reasoning_content
if response.thinking_blocks:
    assistant_msg["thinking_blocks"] = response.thinking_blocks
messages.append(assistant_msg)

Verification

Bug reproduced and fix verified by calling Deepseek Reasoner API (deepseek-reasoner) directly:

STEP 1: First LLM call → tool_calls + reasoning_content returned ✅
STEP 2: ❌ BUG — send assistant message WITHOUT reasoning_content
  → DeepseekException: Missing `reasoning_content` field in the assistant message at message index 2
STEP 3: ✅ FIX — send assistant message WITH reasoning_content
  → API success, normal response returned

Full test output:

======================================================================
STEP 2: BUG -- assistant message WITHOUT reasoning_content
======================================================================
  Message keys: ['role', 'content', 'tool_calls']
  Calling Deepseek API with buggy messages...

  BUG REPRODUCED!
  Error: Error calling LLM: litellm.BadRequestError: DeepseekException -
  {"error":{"message":"Missing `reasoning_content` field in the assistant
  message at message index 2."}}

======================================================================
STEP 3: FIX -- assistant message WITH reasoning_content
======================================================================
  Message keys: ['role', 'content', 'tool_calls', 'reasoning_content']
  Calling Deepseek API with fixed messages...

  SUCCESS!

======================================================================
SUMMARY
======================================================================
  BUG:  Without reasoning_content -> API error
  FIX:  With reasoning_content -> API success

  Issue #1834 confirmed and fix is correct!

Test plan

  • Reproduced bug with real Deepseek Reasoner API (missing reasoning_content → 400 error)
  • Verified fix with real Deepseek Reasoner API (with reasoning_content → success)
  • Non-reasoning providers (Claude, GPT) unaffected — fields only added when present

Closes #1834

🤖 Generated with Claude Code

Subagent's _run_subagent() was dropping reasoning_content and
thinking_blocks when building assistant messages for the conversation
history. Providers like Deepseek Reasoner require reasoning_content on
every assistant message when thinking mode is active, causing a 400
BadRequestError on the second LLM round-trip.

Align with the main AgentLoop which already preserves these fields via
ContextBuilder.add_assistant_message().

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Spawn/subagent 工具在 Deepseek Reasoner 下报错:缺少 reasoning_content 字段

2 participants