mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-14 14:12:44 +00:00
fix(compressor): skip context-summary markers as last-user tail anchor
A context-compaction handoff banner is inserted with role="user" when the protected head ends in an assistant/tool message. On a resumed or multi-compaction session, _find_last_user_message_idx would return that banner as the latest user turn, so _ensure_last_user_message_in_tail anchored the tail to the summary and rolled the genuine last user message into the next compaction — the exact active-task loss the anchor exists to prevent (#10896/#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from #36626 by Frank Song (issue #36624). The PR's other two changes (demoting completed tool results inside the protected tail; a preflight compression_exhausted result) are superseded on current main by the min_tail floor (#39170), the no-op compression counting (#40803), and the existing 413/disabled terminal-error paths.
This commit is contained in:
parent
500c2b1e46
commit
ee710db135
2 changed files with 59 additions and 2 deletions
|
|
@ -2224,9 +2224,21 @@ This compaction should PRIORITISE preserving all information related to the focu
|
|||
def _find_last_user_message_idx(
|
||||
self, messages: List[Dict[str, Any]], head_end: int
|
||||
) -> int:
|
||||
"""Return the index of the last user-role message at or after *head_end*, or -1."""
|
||||
"""Return the index of the last user-role message at or after *head_end*, or -1.
|
||||
|
||||
A context-compaction handoff banner can be inserted as a ``role="user"``
|
||||
message (see the summary-role selection in ``compress``). It is internal
|
||||
continuity state, not a real user turn, so it must not be picked as the
|
||||
tail anchor — otherwise ``_ensure_last_user_message_in_tail`` protects
|
||||
the summary and rolls the genuine last user message into the next
|
||||
compaction, re-triggering the active-task loss the anchor exists to
|
||||
prevent.
|
||||
"""
|
||||
for i in range(len(messages) - 1, head_end - 1, -1):
|
||||
if messages[i].get("role") == "user":
|
||||
msg = messages[i]
|
||||
if msg.get("role") == "user" and not self._is_context_summary_content(
|
||||
msg.get("content")
|
||||
):
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue