Sessions
edge-pi provides a SessionManager for persisting conversations as tree-structured JSONL files. Sessions support branching, compaction, and model changes.
Overview
Each session is stored as an append-only JSONL file. Every line is a typed entry: a message, compaction summary, branch summary, or model change. The file forms a tree structure where entries reference their parent, enabling conversation branching.
Creating Sessions
import { SessionManager } from "edge-pi";
// Create a new persistent session
const session = SessionManager.create(process.cwd(), "./sessions");
// Open an existing session file
const existing = SessionManager.open("./sessions/session-2025-01-15.jsonl");
// Create an in-memory session (not persisted)
const ephemeral = SessionManager.inMemory();Factory Methods
| Method | Description |
|---|---|
SessionManager.create(cwd, sessionDir) | Create a new session file in the given directory. |
SessionManager.open(path, sessionDir?) | Open an existing session file. |
SessionManager.inMemory(cwd?) | Create a session that is only kept in memory. |
Session Entries
A session file contains the following entry types:
| Type | Description |
|---|---|
session | Header entry with session metadata (version, ID, timestamp, cwd). |
message | A conversation message (user, assistant, or tool result). |
compaction | A summary of compacted (older) messages. |
branch_summary | A summary of an abandoned conversation branch. |
model_change | Records a switch to a different model. |
Appending Messages
// Append a message and get its entry ID
const id = session.appendMessage({
role: "user",
content: "Hello, world!",
});
// Record a model change
session.appendModelChange("anthropic", "claude-sonnet-4-20250514");
// Record a compaction
session.appendCompaction(
"Summary of previous conversation...",
firstKeptEntryId,
tokensBefore
);Tree Navigation
Sessions form a tree. Each entry has a parent ID, and you can navigate the tree to explore branches.
// Get the current branch (path from root to leaf)
const branch = session.getBranch();
// Get the current leaf (most recent entry)
const leaf = session.getLeafEntry();
// Get the full tree structure
const tree = session.getTree();
// Get a specific entry by ID
const entry = session.getEntry("some-entry-id");Branching
You can branch from any point in the conversation to explore alternative paths.
// Branch from a specific entry (future messages fork from here)
session.branch(entryId);
// Branch with a summary of the abandoned path
session.branchWithSummary(
entryId,
"Was working on refactoring the parser but hit a dead end."
);
// Reset to the beginning
session.resetLeaf();Using with CodingAgent
The simplest way to use sessions is to pass a SessionManager to CodingAgent. Messages are auto-restored from the session on construction and auto-persisted after generate() and stream() calls.
import { CodingAgent, SessionManager } from "edge-pi";
const session = SessionManager.create(process.cwd(), "./sessions");
const agent = new CodingAgent({ model, sessionManager: session });
// Messages are auto-restored from session
// Messages are auto-persisted after generate() and stream()To resume a different session, set the sessionManager property. This automatically restores messages from the new session:
const newSession = SessionManager.open("./sessions/previous.jsonl");
agent.sessionManager = newSession;
// agent.messages now contains the restored conversationBuilding Context (Standalone)
When not using the integrated CodingAgent approach, use buildSessionContext() to manually reconstruct the message history from a session. This handles compaction entries, branch summaries, and model changes.
// Build context from the current session state
const context = session.buildSessionContext();
// Restore messages into an agent
agent.setMessages(context.messages);
// Check the active model
if (context.model) {
console.log(`Active model: ${context.model.provider}/${context.model.modelId}`);
}Session File Format
Session files are JSONL (one JSON object per line). The first line is always the session header:
{"type":"session","version":1,"id":"abc123","timestamp":"2025-01-15T10:30:00Z","cwd":"/home/user/project"}
{"type":"message","id":"msg1","parentId":null,"timestamp":"...","message":{"role":"user","content":"Hello"}}
{"type":"message","id":"msg2","parentId":"msg1","timestamp":"...","message":{"role":"assistant","content":"Hi!"}}Properties
| Property | Type | Description |
|---|---|---|
sessionId | string | Unique session identifier. |
sessionFile | string | undefined | Path to the session file (undefined for in-memory). |
cwd | string | Working directory associated with the session. |