Skip to content

features sessions and branching

Zachary BENSALEM edited this page Aug 15, 2026 · 1 revision

Sessions and branching

Active contributors: Mario Zechner, kt, Armin Ronacher

Purpose

Every conversation in Prime Agent is a session, an append-only transcript persisted as a JSONL file under ~/.prime/agent/sessions/. Sessions let you continue work across processes, fork from an earlier turn into a new session, and revisit alternative branches in place. The session system is the shared persistence core behind the terminal UI, the daemon, and the web chat: all three create, resume, and branch the same session files.

A session is a tree, not a flat log. Every entry has an id and a parentId, and the current position in that tree is tracked by a "leaf" pointer. New entries append as children of the current leaf; branching moves the leaf to an earlier entry and continues from there, either in the same file (via /tree) or in a new file (via /fork and /clone).

How it works

packages/coding-agent/src/core/session-manager.ts owns the on-disk format and the in-memory tree. SessionManager.newSession writes a session header entry with the session id, timestamp, cwd, optional parentSession, RLM depth, and a git snapshot; appendMessage and the other append* methods push typed entries as children of the leaf and append one JSON line to the file. buildSessionContext walks from the current leaf back to the root and resolves the message list actually sent to the model, folding in compaction summaries and branch summaries along the way.

The file is append-only: entries are never edited or deleted, only added. Format migrations run on load (migrateV1ToV2, migrateV2ToV3; CURRENT_SESSION_VERSION is 3), so old files upgrade in place. Session files are identified by a v7 UUID id, and the session list reads only the metadata it needs per line, caching it by (size, mtime) so a large session dir stays cheap to refresh.

Entry types cover both conversation and bookkeeping:

  • message, custom_message: user, assistant, and extension-injected messages.
  • model_change, thinking_level_change, service_tier_change: settings carried forward in context.
  • compaction, branch_summary: summaries that bound context.
  • session_info, label: display name and user bookmarks.
  • session_state: the lifecycle state (active | archived; legacy sleep/hidden normalize to archived, crash is read-only back-compat).
  • agent_status, git_state, child_usage_attributed: daemon bookkeeping ignored by buildSessionContext.

Session lifecycle, in terms of the persisted state:

stateDiagram-v2
    [*] --> New: createAgentSession / POST /api/chat/new
    New --> Active: first user message
    Active --> Saved: assistant response appended to JSONL
    Saved --> Active: /resume or web resume
    Active --> Compacted: /compact writes compaction entry
    Compacted --> Active: continues at new leaf
    Saved --> Archived: session_state archived
    Active --> Archived: daemon idle/archived
    Archived --> Resumed: picker reopens it
    Resumed --> Active: becomes active again
    Active --> Forked: /fork or /clone
    Forked --> New: creates a fresh session file
    Archived --> [*]: deleteSessionFile (trash/unlink)
Loading

Web session routes

The web app creates, resumes, and lists sessions through thin route shells in web/app/src/routes/api/chat/ that delegate to web/server handlers:

  • new.ts -> handleChatNewPost (web/server/src/handlers/chat-new.ts) calls bridge.createSession and returns the new session id, path, and cwd.
  • resume.ts -> handleChatResumePost (web/server/src/handlers/chat-resume.ts) resumes by session id or file path and returns the message list.
  • sessions.ts -> handleChatSessionsGet (web/server/src/handlers/chat-sessions.ts) lists sessions (optionally filtered by cwd) for the conversation picker in the header.

The session picker UI

The TUI opens an interactive picker via /resume or prime-agent --resume. You can search by typing, toggle path display (Ctrl+P), toggle sort (Ctrl+S), filter to named sessions (Ctrl+N), rename (Ctrl+R), and delete (Ctrl+D with confirmation). Deletion goes through deleteSessionFile in packages/coding-agent/src/core/session-file-actions.ts, which tries the trash CLI first and falls back to unlink, then removes the session's artifact directory under session-artifacts/<id>.

The web chat uses the GET /api/chat/sessions catalog to render its own conversation picker, and /agents (a web stand-in for the TUI agent tray) lists the same saved sessions.

Fork, clone, and tree navigation

docs/sessions.md (packages/coding-agent/docs/sessions.md) documents the three branching commands:

  • /tree: navigate the tree in the same session file. Selecting a user or custom message moves the leaf to its parent, puts the text in the editor, and lets you resubmit, creating a new branch; selecting an assistant or tool entry just moves the leaf so you can continue from that point.
  • /fork: create a new session file from a previous user message.
  • /clone: duplicate the current active branch into a new session file.

In the web port, /tree, /fork, and /clone are served by handleChatCommandPost in web/server/src/handlers/chat-command.ts, which calls bridge.navigateTree, bridge.forkSession, and bridge.getSessionTree. The web fork flow surfaces a fork-picker dialog listing candidate user-message entries.

Compaction and branch summarization

/compact summarizes older context into a compaction entry so the context window stays bounded; buildSessionContext keeps the summary first and records how many retained messages follow it for clients to render. When /tree switches away from a branch, Prime Agent can also write a branch_summary entry that preserves the abandoned path's context without replaying it. Both are covered in depth in Session runtime and are implemented in packages/coding-agent/src/core/compaction/.

The agents view

packages/coding-agent/src/modes/agents-view/ implements a multi-session monitoring mode. agents-view-mode.ts builds the view and drives attachments; agents-view-state.ts unifies daemon SessionSummary records with saved-session info into UnifiedSessionRecords and classifies each into a section (running, idle, or inactive); session-view-search.ts powers in-view search. It relies on agent_status entries persisted by SessionManager so off-daemon sessions retain their last recap and task verdict.

Integration points

  • The JSONL format and SessionManager API are documented in packages/coding-agent/docs/session-format.md and packages/coding-agent/docs/sessions.md.
  • web/server's PrimeBridge coordinates sessions for the web chat; see Web server.
  • The TUI InteractiveMode drives session replacement (/new, resume, /fork, import) through AgentSessionRuntime; see Session runtime.
  • Session state, agent status, and the kernel are defined in Glossary.

Entry points for modification

  • Session file format and tree traversal: packages/coding-agent/src/core/session-manager.ts.
  • Session replacement flows (/new, resume, /fork, import): packages/coding-agent/src/core/agent-session-runtime.ts and packages/coding-agent/src/core/agent-session.ts.
  • Session deletion: packages/coding-agent/src/core/session-file-actions.ts.
  • Agents view: packages/coding-agent/src/modes/agents-view/.
  • Web session endpoints: web/server/src/handlers/chat-new.ts, chat-resume.ts, chat-sessions.ts, chat-command.ts and the routes in web/app/src/routes/api/chat/.

Key source files

File Purpose
packages/coding-agent/src/core/session-manager.ts JSONL transcript persistence, tree traversal, buildSessionContext, branch creation
packages/coding-agent/src/core/session-file-actions.ts deleteSessionFile, trash-then-unlink deletion and artifact cleanup
packages/coding-agent/src/core/agent-session-runtime.ts AgentSessionRuntime, session replacement (new/resume/fork/import)
packages/coding-agent/src/modes/agents-view/agents-view-mode.ts Multi-session agents view UI
packages/coding-agent/src/modes/agents-view/agents-view-state.ts Unified running/idle/inactive session roster
web/server/src/handlers/chat-new.ts Web POST /api/chat/new handler
web/server/src/handlers/chat-resume.ts Web POST /api/chat/resume handler
web/server/src/handlers/chat-sessions.ts Web GET /api/chat/sessions handler
web/server/src/handlers/chat-command.ts Web /tree, /fork, /clone, /name, /session command execution
packages/coding-agent/docs/sessions.md User documentation for resume, picker, naming, and branching
packages/coding-agent/docs/session-format.md JSONL format and SessionManager API reference

Related pages

Clone this wiki locally