From 5602f04a6ec0ed7fd8e8fa7a1f662193b9319263 Mon Sep 17 00:00:00 2001 From: Christopher <210261288+Christopher-Schulze@users.noreply.github.com> Date: Sat, 15 Aug 2026 22:25:15 +0200 Subject: [PATCH] fix(agent): clear in-memory cooldown when hygiene overwrites the shared row A later hygiene idle-timeout write can replace an aux-model cooldown on the shared column. Drop the in-memory timer on that refresh so the in-agent compressor is not still blocked after the DB row is hygiene. --- agent/context_compressor.py | 5 ++++ ...test_hygiene_timeout_cooldown_isolation.py | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/agent/context_compressor.py b/agent/context_compressor.py index c28ff546a2..d66bee1cad 100644 --- a/agent/context_compressor.py +++ b/agent/context_compressor.py @@ -2484,6 +2484,11 @@ class ContextCompressor(ContextEngine): # 429/aux-model fault. The in-conversation compressor has its own # budget and must still be allowed to run (#86972). if _is_hygiene_idle_timeout_error(state.get("error")): + # A later hygiene write can overwrite a previous aux-model row + # on the shared column. Drop any in-memory cooldown so the + # in-agent compressor is not still blocked after this refresh. + self._summary_failure_cooldown_until = 0.0 + self._last_summary_error = None return None self._summary_failure_cooldown_until = now_mono + remaining_seconds diff --git a/tests/agent/test_hygiene_timeout_cooldown_isolation.py b/tests/agent/test_hygiene_timeout_cooldown_isolation.py index b53baf179e..e1493bbab5 100644 --- a/tests/agent/test_hygiene_timeout_cooldown_isolation.py +++ b/tests/agent/test_hygiene_timeout_cooldown_isolation.py @@ -65,3 +65,30 @@ def test_aux_model_fault_cooldown_still_blocks_in_agent_compressor(tmp_path: Pat assert state is not None assert state["error"] == "rate limited" db.close() + + +def test_hygiene_row_clears_stale_in_memory_aux_cooldown(tmp_path: Path): + """A later hygiene overwrite must not leave the in-memory aux cooldown armed.""" + db = SessionDB(db_path=tmp_path / "state.db") + session_id = "hyg-overwrite-sid" + db.create_session(session_id, source="telegram") + db.record_compression_failure_cooldown( + session_id, + time.time() + 300, + "rate limited", + ) + + compressor = _bound_compressor(db, session_id) + loaded = compressor.get_active_compression_failure_cooldown() + assert loaded is not None + assert loaded["error"] == "rate limited" + + db.record_compression_failure_cooldown( + session_id, + time.time() + 300, + _HYGIENE_TIMEOUT_ERROR, + ) + + assert compressor.get_active_compression_failure_cooldown(refresh=True) is None + assert compressor.get_active_compression_failure_cooldown() is None + db.close()