diff --git a/cli.py b/cli.py index 2cc1a8f16db..126d0a1038a 100644 --- a/cli.py +++ b/cli.py @@ -5833,6 +5833,12 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin): """ if not self._session_db or not session_id: return False + # In-memory transcript is authoritative: if this CLI object holds + # conversation messages (flushed to the DB or not), the session is + # not empty. Protects against pruning a real conversation whose DB + # flush failed or hasn't happened yet. + if getattr(self, "conversation_history", None): + return False try: from hermes_constants import get_hermes_home as _ghh return self._session_db.delete_session_if_empty( diff --git a/tests/test_empty_session_hygiene.py b/tests/test_empty_session_hygiene.py index 7166ce936e1..3576e7dce72 100644 --- a/tests/test_empty_session_hygiene.py +++ b/tests/test_empty_session_hygiene.py @@ -113,6 +113,7 @@ class TestCLIDiscardSessionIfEmpty: cli = HermesCLI.__new__(HermesCLI) cli._session_db = db + cli.conversation_history = [] return cli def test_discards_empty(self, db): @@ -146,3 +147,15 @@ class TestCLIDiscardSessionIfEmpty: cli = self._make_cli(Boom()) assert cli._discard_session_if_empty("x") is False + + def test_in_memory_history_blocks_prune(self, db): + """The live transcript is authoritative: even if the DB row has no + flushed messages yet, a CLI holding conversation history must not + prune the session (covers flush-failed / not-yet-flushed turns).""" + db.create_session(session_id="unflushed", source="cli", model="test") + db.end_session("unflushed", "new_session") + + cli = self._make_cli(db) + cli.conversation_history = [{"role": "user", "content": "hello"}] + assert cli._discard_session_if_empty("unflushed") is False + assert db.get_session("unflushed") is not None