fix(oneshot): honor --resume/--continue so -z can be session-aware - #40333
Closed
jibot3 wants to merge 1 commit into
Closed
fix(oneshot): honor --resume/--continue so -z can be session-aware#40333jibot3 wants to merge 1 commit into
jibot3 wants to merge 1 commit into
Conversation
`hermes -z` (oneshot) bypasses cli.py and historically ignored --resume/--continue, always building a fresh AIAgent and calling agent.chat(). Any frontend that drives oneshot with a stable session id per conversation — e.g. an HTTP shim that runs `hermes --profile p -z "<prompt>" --continue <id>` for each inbound message — therefore got an amnesiac agent: every turn started with history=0 and wrote a new throwaway session, so the id never accumulated a transcript. Make oneshot session-aware when (and only when) a session is requested: - main.py `-z` dispatch resolves --resume/-r <id|title> or --continue/-c [name] (reusing _resolve_session_by_name_or_id / _resolve_last_session) and passes session_id to run_oneshot. - run_oneshot threads session_id to _run_agent. - _run_agent, when session_id is set: walks the compression chain to the live tip, loads prior history via get_messages_as_conversation, reopens the session, builds AIAgent(session_id=...), and runs via run_conversation(conversation_history=...) so the transcript replays and only new messages flush back under the same id. With no session_id the path is unchanged — a fresh, stateless one-shot run. create_session is INSERT OR IGNORE, so reusing an id is idempotent and a brand-new conversation id works on its first turn (empty history, created on first write). Tests: main dispatch forwards the resolved session id; _run_agent resumes with replayed history via run_conversation (not chat) and reopens the session; the no-session path stays on chat() with session_id=None.
This was referenced Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
hermes -z(oneshot) bypasses cli.py entirely and historically ignored--resume/--continue. It always built a freshAIAgentand calledagent.chat(), so the flags were silently dropped.This bites any frontend that drives oneshot with a stable session id per conversation — e.g. a small HTTP shim that runs
hermes --profile p -z "<prompt>" --continue <id>for each inbound message (a piped-channel bridge). The agent is amnesiac: every turn starts withhistory=0and writes a new throwaway timestamped session, so the requested id never accumulates a transcript. The user sees "this is the first thing you've said to me" on every message.Reproduce:
Fix
Make oneshot session-aware when (and only when) a session is requested:
hermes_cli/main.py-zdispatch resolves--resume/-r <id|title>or--continue/-c [name](reusing the existing_resolve_session_by_name_or_id/_resolve_last_session) and passessession_idtorun_oneshot.hermes_cli/oneshot.pyrun_oneshotthreadssession_idto_run_agent._run_agent, whensession_idis set: walks the compression chain to the live tip (resolve_resume_session_id), loads prior history (get_messages_as_conversation), reopens the session, buildsAIAgent(session_id=...), and runs viarun_conversation(conversation_history=...)so the transcript replays and only new messages flush back under the same id. With nosession_idthe path is unchanged — a fresh, stateless one-shot run.create_sessionisINSERT OR IGNORE, so reusing an id is idempotent and a brand-new conversation id works on its first turn (empty history, created on first write).Why not switch the caller to
chat -q --resume?That path is session-aware but emits banner/box/"Resume this session with…" chrome on stdout, which a piping caller then has to strip with fragile rules. Fixing oneshot keeps
-z's clean single-block stdout contract intact.Tests
Added to
tests/hermes_cli/test_tui_resume_flow.py:-zdispatch forwards the resolved session id torun_oneshot;_run_agent(session_id=...)resumes with replayed history viarun_conversation(notchat) and reopens the session;chat()withsession_id=None(stateless behavior unchanged).Also updated the existing
test_main_top_level_oneshot_accepts_toolsetsexact-match assertion for the newsession_idkwarg. Full file: 48 passed.After: turn 2 above correctly answers
PURPLE-NARWHAL-42, and a single session id holds the whole conversation.