hermes - 💡(How to fix) Fix [Bug] Context Compaction + Session Split: compressed summary injected as valid history into new session [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#20293Fetched 2026-05-06 06:37:34
View on GitHub
Comments
2
Participants
2
Timeline
5
Reactions
0
Author
Participants
Timeline (top)
labeled ×3commented ×2

Root Cause

Root Cause Hypothesis

Code Example

[0] USER: "hello"
[1] ASSISTANT: "Hi! How can I help you?"
[2] USER: "help me with X"
[3] ASSISTANT: "[CONTEXT COMPACTION — REFERENCE ONLY] Summary of [0]-[2]..."

---

if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        entry.session_id = agent.session_id  # ← Problem: messages already written to old session
        self.session_store._save()
RAW_BUFFERClick to expand / collapse

Describe the bug

When a conversation triggers Context Compaction followed by a Session Split, the compressed summary and its referenced original messages are incorrectly injected as valid conversation history into the newly created session, instead of being treated as background-only reference material.

Reproduction Steps

  1. Start a conversation in Session A — the model responds normally
  2. Continue the conversation until Context Compaction fires (after ~10+ messages depending on context limits)
    • The compressor generates a [CONTEXT COMPACTION — REFERENCE ONLY] summary message
    • Original messages are demoted below the --- END OF CONTEXT SUMMARY — respond to the message below, not the summary above --- separator
  3. Send another message to continue the conversation
  4. This second message triggers a Session Split (the agent decides to start a new session for the fresh topic)
  5. Bug: The new session contains the compressed summary AND the original pre-compression messages as if they were valid user/assistant exchanges — not as background reference

Actual Behavior

The new session's transcript looks like:

[0] USER: "hello"
[1] ASSISTANT: "Hi! How can I help you?"
[2] USER: "help me with X"
[3] ASSISTANT: "[CONTEXT COMPACTION — REFERENCE ONLY] Summary of [0]-[2]..."

Messages [0]–[2] are the compressed first-round exchanges. They appear as live conversation rather than historical context that was summarized.

Expected Behavior

When a Session Split occurs after Context Compaction, the new session should start clean — it should not inherit the compressed summary's referenced original messages as valid history.

Root Cause Hypothesis

Code Path

  1. gateway/run.py message handling (~line 12800): loads history from session transcript into agent_history
  2. agent/context_compressor.py SummarizerCompressor._compress():
    • Extracts leading messages → generates a [CONTEXT COMPACTION — REFERENCE ONLY] summary
    • Appends --- END OF CONTEXT SUMMARY — respond to the message below, not the summary above ---
    • Appends original messages after the separator
    • Rewrites the session transcript with the compressed version
  3. When the next message triggers a session split, gateway/run.py lines ~13157–13166 handle it:
if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        entry.session_id = agent.session_id  # ← Problem: messages already written to old session
        self.session_store._save()

The entry.session_id update happens AFTER messages are persisted to the transcript. When context compression creates a split during the same turn:

  1. Compressed messages are written to the current entry.session_id (old session file)
  2. entry.session_id is updated only after the response is sent
  3. The new session thus inherits the compressed message chain as if it were valid history

Alternatively, the split logic may be inheriting a message range from the parent that includes the compressed block, without filtering out the REFERENCE ONLY region.

Environment

  • Hermes Agent: latest
  • OS: Ubuntu 24.04 (WSL)

Additional context

Session timeline from the triggering case:

  • Session B: first round (10:10 AM)
  • Session A: later same day, second round in same session
    • Messages [0]–[3]: first round (compressed)
    • Messages [N]–[M]: second round (triggered split)
  • Session C: split from Session A
    • Messages [0]–[3]: injected from Session A's first round as live history ← BUG

Key Code Locations

  • gateway/run.py line ~13157–13175: session split detection and history_offset handling
  • gateway/run.py line ~12800–12850: agent_history built from transcript
  • agent/context_compressor.py _compress(): summary generation logic

extent analysis

TL;DR

Update the session split logic to filter out the REFERENCE ONLY region when inheriting messages from the parent session.

Guidance

  • Review the session split detection logic in gateway/run.py lines ~13157–13166 to ensure it correctly handles the entry.session_id update and message inheritance.
  • Modify the agent_history building process in gateway/run.py lines ~12800–12850 to exclude messages marked as REFERENCE ONLY when creating a new session.
  • Investigate the SummarizerCompressor._compress() method in agent/context_compressor.py to ensure it correctly appends the original messages after the separator and rewrites the session transcript.
  • Verify that the session_store._save() method is called after the entry.session_id update to ensure the new session ID is persisted.

Example

# gateway/run.py, lines ~13157–13166
if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        # Filter out REFERENCE ONLY messages before updating session ID
        entry.messages = [msg for msg in entry.messages if not msg.startswith('[CONTEXT COMPACTION — REFERENCE ONLY]')]
        entry.session_id = agent.session_id
        self.session_store._save()

Notes

The provided code snippet is a suggestion and may require further modifications to fit the specific requirements of the system. Additionally, the root cause of the issue may be related to the timing of the entry.session_id update and the message inheritance process.

Recommendation

Apply the suggested workaround to filter out REFERENCE ONLY messages when inheriting messages from the parent session. This should prevent the compressed

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING