fix(formatter): preserve reasoning content on surviving assistant turns#1538
fix(formatter): preserve reasoning content on surviving assistant turns#1538Alexxigang wants to merge 1 commit intoagentscope-ai:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses an issue where 'reasoning_content' was not being correctly injected into assistant messages due to a strict message count comparison after formatting. Previously, if AgentScope's formatter dropped assistant turns containing only thinking blocks, it caused a mismatch, leading to 'reasoning_content' being skipped and warnings logged. The changes introduce a more robust mechanism to identify and align 'reasoning_content' only with assistant messages that genuinely survive the formatting process, ensuring proper payload injection and eliminating erroneous warnings. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request effectively addresses an issue where reasoning_content was being dropped from assistant messages. The introduction of _assistant_message_survives_format to predict which messages persist after formatting is a smart solution to correctly align reasoning content and prevent erroneous warnings. The accompanying unit tests are well-written and cover the key scenarios. I have a couple of suggestions to enhance the robustness and readability of the implementation.
| in_assistant = [ | ||
| m for m in msgs if _assistant_message_survives_format(m) | ||
| ] | ||
| out_assistant = [ | ||
| m for m in messages if m.get("role") == "assistant" | ||
| ] | ||
| if len(in_assistant) != len(out_assistant): | ||
| logger.warning( | ||
| "Assistant message count mismatch after formatting " | ||
| "(%d before, %d after). " | ||
| "Skipping reasoning_content injection.", | ||
| len(in_assistant), | ||
| len(out_assistant), | ||
| ) | ||
| else: | ||
| for in_msg, out_msg in zip( | ||
| in_assistant, | ||
| out_assistant, | ||
| ): | ||
| reasoning = reasoning_contents.get(id(in_msg)) | ||
| if reasoning: | ||
| out_msg["reasoning_content"] = reasoning | ||
| for in_msg, out_msg in zip( | ||
| in_assistant, | ||
| out_assistant, | ||
| ): | ||
| reasoning = reasoning_contents.get(id(in_msg)) | ||
| if reasoning: | ||
| out_msg["reasoning_content"] = reasoning |
There was a problem hiding this comment.
Removing the length check between the predicted surviving messages and the actual formatted messages could hide future bugs. Since _assistant_message_survives_format is a 'best-effort' check, if the underlying formatter's logic changes, this could lead to silent misalignment or dropping of reasoning_content. It would be safer to reintroduce a warning log if a mismatch occurs. This would provide a valuable signal for debugging if the prediction logic becomes inaccurate over time.
in_assistant = [
m for m in msgs if _assistant_message_survives_format(m)
]
out_assistant = [
m for m in messages if m.get("role") == "assistant"
]
if len(in_assistant) != len(out_assistant):
logger.warning(
"Assistant message count mismatch after formatting "
"(%d predicted, %d actual). "
"Reasoning content may be misaligned.",
len(in_assistant),
len(out_assistant),
)
for in_msg, out_msg in zip(
in_assistant,
out_assistant,
):
reasoning = reasoning_contents.get(id(in_msg))
if reasoning:
out_msg["reasoning_content"] = reasoning| if block_type == "thinking": | ||
| continue | ||
| if block_type == "text": | ||
| if block.get("text"): | ||
| return True | ||
| continue | ||
| return True |
There was a problem hiding this comment.
The logic within this for loop can be simplified for improved readability and maintainability. By restructuring the conditions, you can make the code more concise while preserving the existing functionality.
| if block_type == "thinking": | |
| continue | |
| if block_type == "text": | |
| if block.get("text"): | |
| return True | |
| continue | |
| return True | |
| if block_type == "thinking": | |
| continue | |
| if block_type == "text" and not block.get("text"): | |
| continue | |
| # Any other block type, or a text block with content, survives. | |
| return True | |
Summary
reasoning_contentfor assistant messages that are still present after the base formatter runsWhy this fix
FileBlockSupportFormattercollected reasoning blocks before calling the base formatter, but then required the input and output assistant counts to match exactly. AgentScope drops assistant turns that only contain thinking blocks, so the counts diverged and CoPaw skipped everyreasoning_contentinjection while logging a warning on every request.This change aligns reasoning injection only against assistant messages that actually survive formatting, which preserves valid reasoning payloads without spamming mismatch warnings.
Fixes #1532.
Validation
Result:
2 passed