fix(cli): flush un-persisted messages before /resume and /branch end the old session

compress_context() and /new already flush un-persisted messages before
calling end_session() (fixed in #47202), but /resume and /branch still
call end_session() directly. When a turn is interrupted mid-flight and
the user immediately runs /resume or /branch, messages generated during
that turn have not yet been written to state.db and are silently lost on
session rotation.

Add the same best-effort _flush_messages_to_session_db() call before
end_session() in both _handle_resume_command and _handle_branch_command,
mirroring the pattern established in cli.py:new_session().

Regression tests verify the flush is called when an agent is present.
This commit is contained in:
srojk34 2026-06-19 05:19:04 +03:00 committed by kshitij
parent 154c382d65
commit a76aa6198c
3 changed files with 65 additions and 0 deletions

View file

@ -321,3 +321,33 @@ class TestRestoreSessionCwdMarkup:
assert "Working directory" in printed or "working" in printed.lower()
finally:
os.chdir(original_cwd)
class TestResumeFlushesBeforeEndSession:
"""Regression for #47202: /resume must flush un-persisted messages to
the session DB before ending the old session, just like /new and
compress_context() already do."""
def test_resume_flushes_when_agent_present(self):
cli_obj = _make_cli()
cli_obj.conversation_history = [
{"role": "user", "content": "hello"},
{"role": "assistant", "content": "hi"},
]
agent = MagicMock()
cli_obj.agent = agent
cli_obj._session_db.get_session.return_value = {"id": "target", "title": "T"}
cli_obj._session_db.get_messages_as_conversation.return_value = []
cli_obj._session_db.resolve_resume_session_id.return_value = "target"
with (
patch("hermes_cli.main._resolve_session_by_name_or_id", return_value="target"),
patch("cli._cprint"),
):
cli_obj._handle_resume_command("/resume target")
agent._flush_messages_to_session_db.assert_called_once_with(
[{"role": "user", "content": "hello"}, {"role": "assistant", "content": "hi"}]
)
cli_obj._session_db.end_session.assert_called_once()