fix(agent): pad reasoning_content on DeepSeek/Kimi tool-call turns#17489
Closed
season179 wants to merge 1 commit into
Closed
fix(agent): pad reasoning_content on DeepSeek/Kimi tool-call turns#17489season179 wants to merge 1 commit into
season179 wants to merge 1 commit into
Conversation
The defensive elif at _build_assistant_message was gated on
msg.get("tool_calls") but tool_calls only lands on msg ~60 lines later,
so the branch never fired. DeepSeek tool-call turns with no streamed
reasoning got persisted without reasoning_content and the next replay
400'd. Same defect reachable on Kimi/Moonshot thinking.
Drops the dead branch; adds a single post-tool_calls pad gated on
assistant_message.tool_calls (the source of truth) for both providers.
Extracts _needs_thinking_reasoning_pad() so _copy_reasoning_content_for_api
shares the predicate.
Contributor
|
Merged via PR #18045. Your Kimi/Moonshot extension was salvaged on top of @lsdsjy's #16855 — the shared Stash-and-rerun confirmed 2/5 parametrized cases fail without your extension ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
The defensive branch in
_build_assistant_messagethat was supposed to pinreasoning_content=""on DeepSeek thinking-mode tool-call turns never actually fired. It was gated onmsg.get("tool_calls")— buttool_callsdoesn't get added tomsguntil ~60 lines later in the same method, so the check was always falsy. Whenever DeepSeek returnedreasoning_content=Noneon a tool-call turn (which happens intermittently in long sessions) and streaming captured no reasoning text, the message got persisted bare. The next replay 400'd:The same defect is reachable on Kimi/Moonshot thinking — same enforcement, no separate ticket but the shape's identical.
The fix replaces the dead
elifwith a single post-tool_callspad that fires when:assistant_message.tool_callsis truthy (reading the SDK source of truth, not a not-yet-populated dict key, which is what caused the original bug); andreasoning_contentisn't already set by an earlier branch (so we never clobber legitimate reasoning); andPulled the predicate into a new
_needs_thinking_reasoning_pad()helper so_copy_reasoning_content_for_apishares it instead of re-inliningkimi or deepseek.Related Issue
Fixes #17400
Type of Change
Changes Made
run_agent.py: removed the dead pad branch in_build_assistant_message; added the unified post-tool_callspad covering DeepSeek and Kimi/Moonshot; extracted_needs_thinking_reasoning_pad()and reused it in_copy_reasoning_content_for_api.tests/run_agent/test_deepseek_reasoning_content_echo.py: newTestBuildAssistantMessagePadsStrictProvidersclass — one parametrized test covering five provider/attribute combos (deepseek withreasoning_content=None, deepseek without the attribute at all, kimi-coding, custom-provider viaapi.moonshot.ai, plus an openrouter case to confirm we don't pad needlessly), and three standalone tests for "real reasoning preserved", "text-only turn untouched", "streamed reasoning wins over the empty pad". Folded the new helper's defaults into the existing_make_agentso the file doesn't end up with two parallel agent factories.How to Test
pytest tests/run_agent/test_deepseek_reasoning_content_echo.py -q— 31 pass.git stashthe change torun_agent.py, re-run the file, and 4 of the 8 new cases fail (the four that hit the previously-dead pad). Pop the stash; they pass again.pytest tests/run_agent/ -q— 1164 passed, 7 unrelated skips.Checklist
Code
tests/run_agent/) and all tests pass — 1164 passed, 7 unrelated skips. Skipped the fulltests/suite as the change is contained.Documentation & Housekeeping
cli-config.yaml.example— N/ACONTRIBUTING.md/AGENTS.md— N/A