fix(agent): preserve recent turns during compression - #39170
Closed
konsisumer wants to merge 1 commit into
Closed
Conversation
Contributor
Author
|
Rebased onto origin/main and resolved the context-compressor merge conflict. Scoped verification passed ( |
konsisumer
force-pushed
the
fix/context-compression-tail-preservation
branch
from
June 12, 2026 07:28
be30691 to
436caf1
Compare
Contributor
teknium1
pushed a commit
that referenced
this pull request
Jul 1, 2026
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.
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
Jasper6439
pushed a commit
to Jasper6439/hermes-agent
that referenced
this pull request
Jul 5, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
habarmc1223-sudo
pushed a commit
to habarmc1223-sudo/hermes-agent-fluxmem
that referenced
this pull request
Jul 8, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
waym0reom3ga
pushed a commit
to waym0reom3ga/autolycus-agent
that referenced
this pull request
Jul 23, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
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 (NousResearch#10896/NousResearch#22523). Reuse the existing _is_context_summary_content helper to skip summary banners when locating the last real user message. Salvaged from NousResearch#36626 by Frank Song (issue NousResearch#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 (NousResearch#39170), the no-op compression counting (NousResearch#40803), and the existing 413/disabled terminal-error paths.
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.
What does this PR do?
Fixes context compression tail selection so token-exhausted compactions keep a bounded run of recent messages verbatim instead of preserving only the latest user anchor plus a tiny tail. This prevents recent assistant/tool context immediately before the latest ask from being folded into the summary, while capping the message floor so large tool-output tails can still be compacted.
Related Issue
Fixes #9413
Type of Change
Changes Made
agent/context_compressor.py: replace the hard-coded 3-message protected tail floor with a boundedprotect_last_n-aware floor, capped at 8 messages and constrained to leave a real middle window to summarize.tests/agent/test_context_compressor.py: add a regression test for tiny-budget compression preserving recent turns before the latest user ask.How to Test
HERMES_HOME=/private/tmp/hermes-agent-test-home-issue-new-5b851828 PATH="$VIRTUAL_ENV/bin:$PATH" /opt/homebrew/bin/timeout -k 30 480 sh -c 'pytest tests/ -q -x --timeout=60 "$@"' sh/opt/homebrew/bin/timeout -k 30 480 pytest tests/agent/test_context_compressor.py -q/opt/homebrew/bin/timeout -k 30 480 pytest -q -x --timeout=60 tests/agent/test_context_compressor.py tests/run_agent/test_compression_boundary.py tests/agent/test_compressor_image_tokens.py tests/agent/test_compressor_historical_media.py tests/agent/test_context_compressor_summary_continuity.py tests/run_agent/test_compressor_fallback_update.pyruff check agent/context_compressor.py tests/agent/test_context_compressor.pypython scripts/check-windows-footguns.py agent/context_compressor.py tests/agent/test_context_compressor.pygit diff --checkChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AFor New Skills
hermes --toolsets skills -q "Use the X skill to do Y"Screenshots / Logs
tests/agent/test_context_compressor.py -q: 92 passed in 40.64s.ruff check agent/context_compressor.py tests/agent/test_context_compressor.pypassed.python scripts/check-windows-footguns.py agent/context_compressor.py tests/agent/test_context_compressor.pypassed.git diff --checkpassed.HERMES_HOME; it stopped early in unrelatedtests/acp/test_edit_approval.py::test_write_file_approval_mutates_and_request_includes_diffbecause this sandbox treats pytest's/private/var/.../Ttemp path as a sensitive system path, sowrite_filerefused the test write before the suite reached compressor coverage.