mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix: prevent stale reasoning from being reused across turns
The reasoning-box extraction loop in run_conversation() walked backwards through the entire message history looking for any assistant message with a non-empty 'reasoning' field. When the current turn produced no reasoning (e.g. the provider returned reasoning_content=null for a trivial response), the loop walked past the current turn and showed reasoning from a prior turn — stale text from minutes or hours ago displayed as if it belonged to the current reply. Fix: stop the walk at the user message that started the current turn. That picks the most recent reasoning WITHIN the turn (correct for tool-calling turns where reasoning lands on the tool-call step and the final-answer step has reasoning=None — common on Claude thinking, DeepSeek v4, Codex Responses), and returns None cleanly when the current turn genuinely had no reasoning. Co-authored-by: happy5318 <happy5318@users.noreply.github.com>
This commit is contained in:
parent
4577f392f9
commit
efe1cb00c8
1 changed files with 11 additions and 1 deletions
12
run_agent.py
12
run_agent.py
|
|
@ -13952,9 +13952,19 @@ class AIAgent:
|
|||
except Exception as exc:
|
||||
logger.warning("post_llm_call hook failed: %s", exc)
|
||||
|
||||
# Extract reasoning from the last assistant message (if any)
|
||||
# Extract reasoning from the CURRENT turn only. Walk backwards
|
||||
# but stop at the user message that started this turn — anything
|
||||
# earlier is from a prior turn and must not leak into the reasoning
|
||||
# box (confusing stale display; #17055). Within the current turn
|
||||
# we still want the *most recent* non-empty reasoning: many
|
||||
# providers (Claude thinking, DeepSeek v4, Codex Responses) emit
|
||||
# reasoning on the tool-call step and leave the final-answer step
|
||||
# with reasoning=None, so picking only the last assistant would
|
||||
# silently drop legitimate same-turn reasoning.
|
||||
last_reasoning = None
|
||||
for msg in reversed(messages):
|
||||
if msg.get("role") == "user":
|
||||
break # turn boundary — don't cross into prior turns
|
||||
if msg.get("role") == "assistant" and msg.get("reasoning"):
|
||||
last_reasoning = msg["reasoning"]
|
||||
break
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue