hermes - ✅(Solved) Fix [Bug]: _summary_failure_cooldown_until not reset on /new or /reset — compression skipped silently in new session [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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#15547Fetched 2026-04-26 05:26:45
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Timeline (top)
labeled ×3cross-referenced ×2commented ×1

Error Message

ContextCompressor.on_session_reset() clears all per-session state except _summary_failure_cooldown_until. When a transient summary error (network timeout, rate limit, etc.) sets this cooldown to time.monotonic() + 60 and the user immediately runs /reset or /new, the cooldown carries into the new session. If the new session reaches the compression threshold before the cooldown expires, _generate_summary() returns None silently, middle turns are dropped without a summary, and the agent continues with no indication that compaction was skipped.

Root Cause

on_session_reset() in agent/context_compressor.py resets _previous_summary, _last_summary_error, _ineffective_compression_count and others, but omits _summary_failure_cooldown_until.

def on_session_reset(self) -> None:
    super().on_session_reset()
    self._context_probed = False
    self._context_probe_persistable = False
    self._previous_summary = None
    self._last_summary_error = None
    self._last_compression_savings_pct = 100.0
    self._ineffective_compression_count = 0
    # _summary_failure_cooldown_until NOT reset — stale cooldown carries over

Fix Action

Fixed

PR fix notes

PR #15548: fix(compressor): reset _summary_failure_cooldown_until in on_session_reset()

Description (problem / solution / changelog)

What does this PR do?

ContextCompressor.on_session_reset() clears _previous_summary, _last_summary_error, and _ineffective_compression_count but leaves _summary_failure_cooldown_until intact. When a transient summary error (network timeout, rate limit) sets a 60 s cooldown — or 600 s when no auxiliary provider is configured — and the user immediately runs /reset or /new, the cooldown carries into the new session. If the new session reaches the compression threshold before the cooldown expires, _generate_summary() returns None early: middle turns are silently dropped without a summary and the agent continues with no indication that compaction was skipped.

One-line fix in on_session_reset(): set _summary_failure_cooldown_until = 0.0, matching the value assigned in __init__ and symmetric with the other per-session fields already cleared there. Scoped to session reset only — no behavior change for sessions that never hit an error.

Related Issue

Fixes #15547

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests
  • ♻️ Refactor
  • 🎯 New skill

Changes Made

  • agent/context_compressor.py: add self._summary_failure_cooldown_until = 0.0 to on_session_reset() (+1 line)

How to Test

  1. Trigger a context compression failure (disable auxiliary provider or simulate a network error in _generate_summary)
  2. Confirm _summary_failure_cooldown_until is set to a future timestamp
  3. Call on_session_reset()
  4. Assert _summary_failure_cooldown_until == 0.0
import time
from unittest.mock import patch

with patch("agent.context_compressor.get_model_context_length", return_value=100000):
    c = ContextCompressor(model="test/model", quiet_mode=True)

c._summary_failure_cooldown_until = time.monotonic() + 60
c.on_session_reset()
assert c._summary_failure_cooldown_until == 0.0

Checklist

Code

  • Contributing Guide okundu
  • Conventional Commits
  • Duplicate PR yok
  • Sadece bu fix
  • pytest çalıştırıldı
  • Platform: macOS

Documentation & Housekeeping

  • Docs güncellendi — N/A
  • cli-config.yaml.example — N/A
  • CONTRIBUTING.md/AGENTS.md — N/A
  • Cross-platform impact — N/A
  • Tool descriptions — N/A

Changed files

  • agent/context_compressor.py (modified, +1/-0)

PR #15681: fix: reset _summary_failure_cooldown_until on session reset (#15547)

Description (problem / solution / changelog)

Problem

ContextCompressor.on_session_reset() clears all per-session state except _summary_failure_cooldown_until. When a transient summary error (network timeout, rate limit) sets a cooldown, and the user then runs /new or /reset, the cooldown persists into the new session, silently blocking context compression.

Fix

Add self._summary_failure_cooldown_until = 0.0 to on_session_reset(), matching the initialization in __init__.

Before vs After

ScenarioBeforeAfter
Summary fails, then /newCompression blocked for remaining cooldownCooldown cleared, compression works immediately

Fixes NousResearch/hermes-agent#15547

Changed files

  • agent/context_compressor.py (modified, +1/-0)
  • cron/jobs.py (modified, +11/-0)
  • hermes_cli/web_server.py (modified, +4/-1)

Code Example

def on_session_reset(self) -> None:
    super().on_session_reset()
    self._context_probed = False
    self._context_probe_persistable = False
    self._previous_summary = None
    self._last_summary_error = None
    self._last_compression_savings_pct = 100.0
    self._ineffective_compression_count = 0
    # _summary_failure_cooldown_until NOT reset — stale cooldown carries over
RAW_BUFFERClick to expand / collapse

Bug Description

ContextCompressor.on_session_reset() clears all per-session state except _summary_failure_cooldown_until. When a transient summary error (network timeout, rate limit, etc.) sets this cooldown to time.monotonic() + 60 and the user immediately runs /reset or /new, the cooldown carries into the new session. If the new session reaches the compression threshold before the cooldown expires, _generate_summary() returns None silently, middle turns are dropped without a summary, and the agent continues with no indication that compaction was skipped.

The 600-second cooldown (triggered when no auxiliary LLM provider is configured) makes this more pronounced in gateway/cron setups where the same AIAgent instance is reused across sessions.

Steps to Reproduce

  1. Configure Hermes without an auxiliary provider, or simulate a transient summary failure
  2. Trigger context compression (fill context past threshold)
  3. Observe _summary_failure_cooldown_until is set
  4. Run /reset or /new
  5. Fill context again in the new session within the cooldown window
  6. Compression triggers but _generate_summary() returns None — middle turns dropped silently

Root Cause

on_session_reset() in agent/context_compressor.py resets _previous_summary, _last_summary_error, _ineffective_compression_count and others, but omits _summary_failure_cooldown_until.

def on_session_reset(self) -> None:
    super().on_session_reset()
    self._context_probed = False
    self._context_probe_persistable = False
    self._previous_summary = None
    self._last_summary_error = None
    self._last_compression_savings_pct = 100.0
    self._ineffective_compression_count = 0
    # _summary_failure_cooldown_until NOT reset — stale cooldown carries over

Expected Behavior

A fresh session after /reset should not inherit the compression cooldown from the previous session.

Are you willing to submit a PR?

Yes, fix is ready.

extent analysis

TL;DR

Reset the _summary_failure_cooldown_until attribute in the on_session_reset method to prevent the cooldown from carrying over to new sessions.

Guidance

  • Identify the on_session_reset method in agent/context_compressor.py and modify it to reset _summary_failure_cooldown_until to None or a default value.
  • Verify that the cooldown is properly reset by checking the value of _summary_failure_cooldown_until after calling on_session_reset.
  • Test the fix by reproducing the steps to reproduce and ensuring that the compression cooldown does not carry over to new sessions.
  • Consider adding a test case to cover this scenario and prevent similar issues in the future.

Example

def on_session_reset(self) -> None:
    super().on_session_reset()
    self._context_probed = False
    self._context_probe_persistable = False
    self._previous_summary = None
    self._last_summary_error = None
    self._last_compression_savings_pct = 100.0
    self._ineffective_compression_count = 0
    self._summary_failure_cooldown_until = None  # Reset cooldown

Notes

This fix assumes that resetting _summary_failure_cooldown_until to None is the desired behavior. If a different default value is required, it should be used instead.

Recommendation

Apply the workaround by resetting _summary_failure_cooldown_until in the on_session_reset method, as this directly addresses the root cause of the issue and prevents the cooldown from carrying over to new sessions.

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

hermes - ✅(Solved) Fix [Bug]: _summary_failure_cooldown_until not reset on /new or /reset — compression skipped silently in new session [2 pull requests, 1 comments, 2 participants]