mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
feat(cli): add /exit --delete flag to remove session on quit (#27101)
Port from google-gemini/gemini-cli#19332. Users can now exit with '/exit --delete' (or '/quit --delete', '/exit -d') to permanently remove the current session's SQLite history plus on-disk transcripts (*.json / *.jsonl / request_dump_*) in one shot. Useful for privacy-sensitive workflows and one-off interactions where leaving a session recording behind is undesirable. Implementation: - New HermesCLI._delete_session_on_exit one-shot flag (defaults False). - process_command() parses --delete / -d after /exit or /quit and arms the flag. Unknown args print a hint and keep the CLI running (prevents typos like '/exit -delete' from accidentally exiting). - Shutdown path calls SessionDB.delete_session(session_id, sessions_dir=...) right after end_session() when the flag is set. That API already existed for 'hermes sessions delete' and handles both SQLite removal (orphaning child sessions so FK constraints hold) and on-disk file cleanup. - /quit CommandDef now advertises '[--delete]' in args_hint so /help and CLI autocomplete surface it. Tests: tests/cli/test_exit_delete_session.py (12 cases covering both aliases, case insensitivity, whitespace, short form, unknown-arg rejection, and registry metadata). E2E-verified with isolated HERMES_HOME: session row deleted, all three transcript/request-dump files removed, second delete_session call correctly returns False.
This commit is contained in:
parent
c844d15c3d
commit
fc03c95da1
4 changed files with 150 additions and 3 deletions
28
cli.py
28
cli.py
|
|
@ -2824,6 +2824,11 @@ class HermesCLI:
|
|||
# turn (which would make Ctrl+C feel like it did nothing).
|
||||
self._last_turn_interrupted = False
|
||||
self._should_exit = False
|
||||
# /exit --delete: when True, the current session's SQLite history and
|
||||
# on-disk transcripts are deleted during shutdown. Set by
|
||||
# process_command() when the user runs /exit --delete or /quit --delete.
|
||||
# Ported from google-gemini/gemini-cli#19332.
|
||||
self._delete_session_on_exit = False
|
||||
self._last_ctrl_c_time = 0
|
||||
self._clarify_state = None
|
||||
self._clarify_freetext = False
|
||||
|
|
@ -7653,6 +7658,16 @@ class HermesCLI:
|
|||
canonical = _cmd_def.name if _cmd_def else _base_word
|
||||
|
||||
if canonical in {"quit", "exit"}:
|
||||
# Parse --delete flag: /exit --delete also removes the current
|
||||
# session's transcripts + SQLite history. Ported from
|
||||
# google-gemini/gemini-cli#19332.
|
||||
_rest = cmd_original.split(None, 1)
|
||||
_args = (_rest[1] if len(_rest) > 1 else "").strip().lower()
|
||||
if _args in ("--delete", "-d"):
|
||||
self._delete_session_on_exit = True
|
||||
elif _args:
|
||||
_cprint(f" {_DIM}✗ Unknown argument: {_escape(_args)}. Use /exit --delete to also remove session history.{_RST}")
|
||||
return True
|
||||
return False
|
||||
elif canonical == "help":
|
||||
self.show_help()
|
||||
|
|
@ -13822,6 +13837,19 @@ class HermesCLI:
|
|||
self._session_db.end_session(self.agent.session_id, "cli_close")
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
logger.debug("Could not close session in DB: %s", e)
|
||||
# /exit --delete: also remove the current session's transcripts
|
||||
# and SQLite history. Ported from google-gemini/gemini-cli#19332.
|
||||
if getattr(self, '_delete_session_on_exit', False):
|
||||
try:
|
||||
from hermes_constants import get_hermes_home as _ghh
|
||||
_sessions_dir = _ghh() / "sessions"
|
||||
_sid = self.agent.session_id
|
||||
if self._session_db.delete_session(_sid, sessions_dir=_sessions_dir):
|
||||
_cprint(f" {_DIM}✓ Session {_escape(_sid)} deleted{_RST}")
|
||||
else:
|
||||
_cprint(f" {_DIM}✗ Session {_escape(_sid)} not found for deletion{_RST}")
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
logger.debug("Could not delete session on exit: %s", e)
|
||||
# Plugin hook: on_session_end — safety net for interrupted exits.
|
||||
# run_conversation() already fires this per-turn on normal completion,
|
||||
# so only fire here if the agent was mid-turn (_agent_running) when
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue