fix(context_compressor): always keep last user message in tail to prevent active-task loss (#10896)#10969
Closed
sontianye wants to merge 1 commit into
Closed
Conversation
…vent task loss (NousResearch#10896) When `_align_boundary_backward` tried to keep tool_call/result groups intact it could inadvertently slide the tail boundary past the most recent user message, pushing it into the compressed (middle) region. The summariser would then record that user message in "Pending User Asks", but SUMMARY_PREFIX tells the receiving model to respond only to user messages *after* the summary — so the active task silently disappeared, causing the agent to stall, repeat completed work, or re-execute an already-finished Task A instead of continuing Task B. Fix: - Add `_find_last_user_message_idx()` helper. - Add `_ensure_last_user_message_in_tail()`: if the last user message ended up in the compressed middle, pull `cut_idx` back to that index. A user message is a clean boundary (no tool-pair splitting risk) so we set `cut_idx = last_user_idx` directly rather than calling `_align_boundary_backward` again, which would over-correct. - Call `_ensure_last_user_message_in_tail()` at the end of `_find_tail_cut_by_tokens()`, after the existing `_align_boundary_backward` call, as a final safety pass. Summary-template improvements (defence-in-depth): - Add `## Active Task` section at the top of the structured template with explicit instruction to copy the user's latest unfulfilled request verbatim — giving the next model a clear, prominent anchor. - Update SUMMARY_PREFIX to point readers to the `## Active Task` section so they know exactly where to find their current objective. - Add "CRITICAL: Update '## Active Task'" reminder to the iterative (re-compression) update prompt. Fixes NousResearch#10896
kshitijk4poor
pushed a commit
that referenced
this pull request
Apr 16, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from #10969 by @sontianye. Fixes #10896.
Collaborator
|
Salvaged into #11052. Cherry-picked with authorship preserved onto current main. All 44 compressor tests pass. Thanks @sontianye! |
kshitijk4poor
pushed a commit
that referenced
this pull request
Apr 16, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from #10969 by @sontianye. Fixes #10896.
kshitijk4poor
pushed a commit
that referenced
this pull request
Apr 16, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from #10969 by @sontianye. Fixes #10896.
ulasbilgen
pushed a commit
to ulasbilgen/hermes-adhd-agent
that referenced
this pull request
May 1, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from NousResearch#10969 by @sontianye. Fixes NousResearch#10896.
aj-nt
pushed a commit
to aj-nt/hermes-agent
that referenced
this pull request
May 1, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from NousResearch#10969 by @sontianye. Fixes NousResearch#10896.
02356abc
pushed a commit
to 02356abc/hermes-agent
that referenced
this pull request
May 14, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from NousResearch#10969 by @sontianye. Fixes NousResearch#10896.
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from NousResearch#10969 by @sontianye. Fixes NousResearch#10896.
Egavasyug
pushed a commit
to Egavasyug/hermes-agent
that referenced
this pull request
Jun 10, 2026
…vent active-task loss Ensure _align_boundary_backward never pushes the last user message into the compressed region. Without this, compression could delete the user active task instruction mid-session. Cherry-picked from NousResearch#10969 by @sontianye. Fixes NousResearch#10896.
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.
Problem
Fixes #10896.
When context compression fires mid-task, the agent can silently drop the user's current request and either stall or re-execute a previously completed task.
Root cause
_find_tail_cut_by_tokensfinishes with a call to_align_boundary_backward, which walks the cut boundary backward to avoid splitting atool_call/tool_resultgroup. In pathological cases this slidescut_idxpast the most recent user message, pushing it into the compressed (middle) region.The LLM summariser faithfully records that user message in
## Pending User Asks, butSUMMARY_PREFIXinstructs the receiving model:With the user message now inside the summary rather than in the live tail, the model has no post-summary user message to act on. It either stalls or — worse — interprets the summary's
## Completed Actionsas still-pending work and re-executes it.Reproduction (from issue):
_align_boundary_backwardpullscut_idxbeforeuser: "Task B".Fix
1. Structural fix —
_find_tail_cut_by_tokensAdded two new private methods:
_find_last_user_message_idx(messages, head_end)Scans backward from the end to find the last user-role message index.
_ensure_last_user_message_in_tail(messages, cut_idx, head_end)If the last user message is already in the tail (
>= cut_idx), does nothing. If it fell into the middle region, setscut_idx = last_user_idxdirectly — a user message is a clean exchange boundary with notool_call/tool_resultpair straddling it, so calling_align_boundary_backwardagain would over-correct.Called as the final step of
_find_tail_cut_by_tokens, after the existing_align_boundary_backwardcall:2. Summary-template defence-in-depth
Even with the structural fix in place, iterative re-compressions over very long sessions could still lose task context. Three template-level changes add a second layer of protection:
New
## Active Tasksection (top of template, highest priority):Updated
SUMMARY_PREFIX— explicitly points the receiving model to## Active Taskso it knows where to find its current objective.Updated iterative-update prompt — adds
CRITICAL: Update "## Active Task"to the list of things to maintain across re-compressions.Impact
_ensure_last_user_message_in_tailreturns immediately)._align_boundary_backwardover-corrects by anchoringcut_idxto the last user message.