From edf2cb4bf850455f25f83ab177fdc8f8720c7f99 Mon Sep 17 00:00:00 2001 From: kshitij <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 8 Aug 2026 13:25:04 +0530 Subject: [PATCH] perf(sessions): skip counting entirely when transcript guards are disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With sessions.max_*_messages: 0 the guards previously still ran an unbounded COUNT (full lineage for resume) — the exact pathological work disabling them is meant to avoid. Live callers use the raise side effect only, so return 0 without touching the messages table. --- hermes_state.py | 20 ++++++++++---------- tests/test_hermes_state.py | 13 +++++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/hermes_state.py b/hermes_state.py index c073746c594df..3fc57c6defa5d 100644 --- a/hermes_state.py +++ b/hermes_state.py @@ -7929,9 +7929,11 @@ class SessionDB(SessionSearchMixin, SessionSchemaMixin, SessionPortabilityMixin) if max_messages < 0: raise ValueError("max_messages must be non-negative") if max_messages == 0: - # Guard disabled by config — never materialize an unbounded - # COUNT here; callers only need "safe", not an exact figure. - return self.get_resume_message_count(session_id) + # Guard disabled by config — skip counting entirely. Every live + # caller invokes this for its raise side effect and ignores the + # return value, and an unbounded lineage COUNT here would do the + # exact pathological work the disable exists to avoid. + return 0 session_ids = self._session_lineage_root_to_tip(session_id) placeholders = ",".join("?" for _ in session_ids) with self._read_ctx() as conn: @@ -7966,14 +7968,12 @@ class SessionDB(SessionSearchMixin, SessionSchemaMixin, SessionPortabilityMixin) max_messages = resolved_max_export_messages() if max_messages < 0: raise ValueError("max_messages must be non-negative") + if max_messages == 0: + # Guard disabled by config — skip the COUNT; live callers use + # this for its raise side effect only (and skip calling it + # entirely when the limit is 0). + return 0 with self._read_ctx() as conn: - if max_messages == 0: - row = conn.execute( - "SELECT COUNT(*) FROM messages " - "WHERE session_id = ? AND active = 1", - (session_id,), - ).fetchone() - return int(row[0] if row else 0) row = conn.execute( "SELECT COUNT(*) FROM (" "SELECT 1 FROM messages WHERE session_id = ? AND active = 1 LIMIT ?" diff --git a/tests/test_hermes_state.py b/tests/test_hermes_state.py index a21900a17545d..12c1925f9ecf0 100644 --- a/tests/test_hermes_state.py +++ b/tests/test_hermes_state.py @@ -3847,15 +3847,16 @@ class TestGetMessagesPagination: with pytest.raises(hermes_state.SessionExportTooLargeError): db.assert_export_safe("big", max_messages=2) - # ...but a config-resolved limit of 0 disables both guards and - # returns the true count without raising. + # ...but a config-resolved limit of 0 disables both guards: no raise, + # and no counting work at all (returns 0 — callers use the raise side + # effect only). monkeypatch.setattr(hermes_state, "resolved_max_resume_messages", lambda: 0) monkeypatch.setattr(hermes_state, "resolved_max_export_messages", lambda: 0) - assert db.assert_resume_safe("big") == 5 - assert db.assert_export_safe("big") == 5 + assert db.assert_resume_safe("big") == 0 + assert db.assert_export_safe("big") == 0 # An explicit 0 disables too, independent of config. - assert db.assert_resume_safe("big", max_messages=0) == 5 - assert db.assert_export_safe("big", max_messages=0) == 5 + assert db.assert_resume_safe("big", max_messages=0) == 0 + assert db.assert_export_safe("big", max_messages=0) == 0 def test_guard_limits_resolve_from_config_at_call_time(self, db, monkeypatch): db.create_session(session_id="cfg", source="cli")