Skip to content

fix(run_agent): prevent reasoning_content regression in DeepSeek/Kimi tool-call replay (#15812)#15883

Closed
yes999zc wants to merge 1 commit into
NousResearch:mainfrom
yes999zc:fix-reasoning-regression-15749
Closed

fix(run_agent): prevent reasoning_content regression in DeepSeek/Kimi tool-call replay (#15812)#15883
yes999zc wants to merge 1 commit into
NousResearch:mainfrom
yes999zc:fix-reasoning-regression-15749

Conversation

@yes999zc

Copy link
Copy Markdown
Contributor

Problem

PR #15478 fixed missing reasoning_content for DeepSeek API calls, but introduced a regression in the logic order of _copy_reasoning_content_for_api.

Regression Detail

When a message contains:

  • role: assistant
  • tool_calls (non-empty)
  • reasoning: "some genuine reasoning" (from a prior provider that uses the internal reasoning key)
  • No reasoning_content

The old (buggy) order was:

  1. Preserve explicit reasoning_content → skip (not present)
  2. DeepSeek/Kimi tool-call check → inject ""returnreasoning never promoted
  3. Promote reasoning field → never reached

Result: genuine reasoning content is lost, replaced by empty string.

Fix

Swap steps 2 and 3 so promotion happens before the empty-string fallback:

1. Preserve explicit reasoning_content
2. Promote 'reasoning' field (MOVED UP) ← fix
3. DeepSeek/Kimi tool-call empty-string fallback (MOVED DOWN)
4. Non-thinking provider cleanup

Verification

pytest tests/run_agent/test_deepseek_reasoning_content_echo.py -v: 21/21 passed

Key regression test: test_deepseek_reasoning_field_promoted → PASSED

References

Checklist

  • Bug fix (non-breaking change)
  • Tests pass (21/21)
  • Only run_agent.py modified (single-file change)
  • Comments updated to explain ordering rationale

… tool-call replay

PR #15478 fixed missing reasoning_content for DeepSeek API but introduced
a regression: tool-call messages with genuine 'reasoning' field were
overwritten by empty-string fallback before promotion.

Re-order _copy_reasoning_content_for_api steps:
  1. Preserve explicit reasoning_content
  2. Promote 'reasoning' field (MOVED UP)
  3. DeepSeek/Kimi tool-call empty-string fallback (MOVED DOWN)
  4. Non-thinking provider cleanup

Fixes #15812, relates #15749, #15478.
@OutThisLife

Copy link
Copy Markdown
Collaborator

This regresses #15749 and reintroduces #15250.

The current ordering — step 2 (DeepSeek/Kimi tool-call empty-string guard) before step 3 (reasoningreasoning_content promotion) — is intentional, set by #15749 (commits 9daa0620 + 5ae60815). The comment on step 2 spells out the design:

DeepSeek returns HTTP 400 if reasoning_content is absent on replay; inject "" to satisfy the provider's requirement without forwarding any cross-provider reasoning content.

That's the whole point: when the active provider is DeepSeek/Kimi and the source message has tool_calls but no native reasoning_content, the reasoning field is presumed to be cross-provider (MiniMax, etc.) and must not be promoted. Swapping step 2 and step 3 — which is what this PR does — restores exactly the bug #15749 fixed.

A few other smell tests:

  1. Misattributed history. Body says "fix: DeepSeek/Kimi thinking mode requires reasoning_content on ALL assistant messages #15478 … introduced a regression." The merged ordering change came from fix(agent): ordering fix in _copy_reasoning_content_for_api — cross-provider reasoning isolation #15749 (Zjianru, 2026-04-25). Issue regression: #15749 breaks reasoning field promotion for DeepSeek/Kimi tool-call messages #15812 itself names fix(agent): ordering fix in _copy_reasoning_content_for_api — cross-provider reasoning isolation #15749, not fix: DeepSeek/Kimi thinking mode requires reasoning_content on ALL assistant messages #15478.
  2. No regression test. Diff is run_agent.py only. The 21/21 figure is the pre-existing suite; there's no test for the "genuine reasoning lost" scenario this PR claims to fix, and no test that pins the cross-provider isolation fix(agent): ordering fix in _copy_reasoning_content_for_api — cross-provider reasoning isolation #15749 was protecting.
  3. Scenario plausibility. The "lost reasoning" case requires a DeepSeek/Kimi session whose own assistant tool-call message has reasoning set but no reasoning_content. Native DeepSeek/Kimi turns write reasoning_content directly — the only way to land in that state is exactly the cross-provider migration fix(agent): ordering fix in _copy_reasoning_content_for_api — cross-provider reasoning isolation #15749 is isolating.

If #15812 is a real failure mode, the fix needs to be provider-of-origin-aware (e.g. only promote reasoning when the message was authored by the current provider), not an order swap. As-is this is a revert wrapped in a misattributed changelog.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder provider/deepseek DeepSeek API labels Apr 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #15830 — same fix for #15812 (reorder reasoning field promotion before empty-pad in _copy_reasoning_content_for_api).

teknium1 added a commit that referenced this pull request Apr 26, 2026
Salvage PR #15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #16097 (commit 63bf7a2 on main). Your commit was cherry-picked onto current main with your authorship preserved in git log. Thanks for the fix — clean single-file swap with the regression test already in place from #15478 made this easy to land.

#16097

@teknium1 teknium1 closed this Apr 26, 2026
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
donald131 pushed a commit to donald131/hermes-agent that referenced this pull request May 2, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
dannyJ848 pushed a commit to dannyJ848/hermes-agent that referenced this pull request May 17, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
Salvage PR NousResearch#15883 cherry-picked FocusFlow Dev's commit; release-notes
CI needs the AUTHOR_MAP entry to attribute to the PR author's GitHub
login rather than a placeholder.
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 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.

regression: #15749 breaks reasoning field promotion for DeepSeek/Kimi tool-call messages

4 participants