mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-28 11:32:22 +00:00
fix(agent): close tool-call sequence on interrupt to prevent role alternation violation (#48879)
This commit is contained in:
parent
53f8386587
commit
81d2dc5d0f
1 changed files with 23 additions and 0 deletions
|
|
@ -166,6 +166,29 @@ def finalize_turn(
|
|||
# same empty-response loop again.
|
||||
try:
|
||||
agent._drop_trailing_empty_response_scaffolding(messages)
|
||||
|
||||
# When the turn was interrupted and the last message is a tool
|
||||
# result, append a synthetic assistant message to close the
|
||||
# tool-call sequence. Without this, the session persists a
|
||||
# ``tool → user`` alternation that strict providers (Gemini,
|
||||
# Claude) reject, causing them to hallucinate a continuation of
|
||||
# the user's message on the next turn (#48879).
|
||||
#
|
||||
# ``_drop_trailing_empty_response_scaffolding`` only rewinds the
|
||||
# tool tail when an empty-response scaffolding flag is present; a
|
||||
# clean ``/stop`` interrupt after a successful tool sets no such
|
||||
# flag, so the tool result survives as the tail and we close it
|
||||
# here instead. On an interrupt ``final_response`` is typically
|
||||
# empty, so fall back to an explicit placeholder rather than
|
||||
# persisting an empty-content assistant turn.
|
||||
if interrupted and messages and messages[-1].get("role") == "tool":
|
||||
messages.append(
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": (final_response or "").strip() or "Operation interrupted.",
|
||||
}
|
||||
)
|
||||
|
||||
agent._persist_session(messages, conversation_history)
|
||||
except Exception as _persist_err:
|
||||
_cleanup_errors.append(f"persist_session: {_persist_err}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue