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:
parent
154c382d65
commit
a76aa6198c
3 changed files with 65 additions and 0 deletions
|
|
@ -712,6 +712,14 @@ class CLICommandsMixin:
|
|||
return
|
||||
|
||||
old_session_id = self.session_id
|
||||
# Flush un-persisted messages before ending the old session (#47202).
|
||||
if self.agent:
|
||||
try:
|
||||
self.agent._flush_messages_to_session_db(
|
||||
self.conversation_history
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
# End current session
|
||||
try:
|
||||
self._session_db.end_session(self.session_id, "resumed_other")
|
||||
|
|
@ -851,6 +859,15 @@ class CLICommandsMixin:
|
|||
# Save the current session's state before branching
|
||||
parent_session_id = self.session_id
|
||||
|
||||
# Flush un-persisted messages before ending the old session (#47202).
|
||||
if self.agent:
|
||||
try:
|
||||
self.agent._flush_messages_to_session_db(
|
||||
self.conversation_history
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# End the old session
|
||||
try:
|
||||
self._session_db.end_session(self.session_id, "branched")
|
||||
|
|
|
|||
|
|
@ -240,3 +240,21 @@ class TestBranchCommandDef:
|
|||
from hermes_cli.commands import COMMAND_REGISTRY
|
||||
branch = next(c for c in COMMAND_REGISTRY if c.name == "branch")
|
||||
assert branch.category == "Session"
|
||||
|
||||
|
||||
class TestBranchFlushesBeforeEndSession:
|
||||
"""Regression for #47202: /branch must flush un-persisted messages to
|
||||
the session DB before ending the old session, just like /new and
|
||||
compress_context() already do."""
|
||||
|
||||
def test_branch_flushes_when_agent_present(self, cli_instance, session_db):
|
||||
from cli import HermesCLI
|
||||
|
||||
agent = MagicMock()
|
||||
cli_instance.agent = agent
|
||||
|
||||
HermesCLI._handle_branch_command(cli_instance, "/branch")
|
||||
|
||||
agent._flush_messages_to_session_db.assert_called_once_with(
|
||||
cli_instance.conversation_history
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue