Final rebrand: rename remaining Rust source file to complete the gsd → forge transition. All parser references already use forge_parser after earlier commits. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
3.5 KiB
Markdown
81 lines
3.5 KiB
Markdown
# Sessions — Memory That Branches
|
|
|
|
Sessions are pi's memory system. They're more sophisticated than simple conversation history.
|
|
|
|
### Storage Format
|
|
|
|
Sessions are **JSONL files** (one JSON object per line). Each line is an "entry" with a `type`, `id`, and `parentId`:
|
|
|
|
```
|
|
~/.sf/agent/sessions/--path--to--project--/<timestamp>_<uuid>.jsonl
|
|
```
|
|
|
|
### The Entry Tree
|
|
|
|
Entries form a **tree structure**, not a linear list. This is the key architectural insight:
|
|
|
|
```
|
|
┌─ [user] ─ [assistant] ─ [tool] ─ [assistant] ← Branch A
|
|
[header] ─ [user] ─┤
|
|
└─ [user] ─ [assistant] ← Branch B (via /tree)
|
|
```
|
|
|
|
Every entry has an `id` and `parentId`. When you navigate to a previous point with `/tree` and continue from there, a new branch is created from that point. **All branches coexist in the same file.** Nothing is deleted.
|
|
|
|
### Entry Types
|
|
|
|
| Type | Purpose |
|
|
|------|---------|
|
|
| `session` | Header — file metadata, version, working directory |
|
|
| `message` | A conversation message (user, assistant, tool result, custom) |
|
|
| `compaction` | Summary of older messages (created by compaction) |
|
|
| `branch_summary` | Summary of an abandoned branch (created by `/tree`) |
|
|
| `model_change` | Records when the user switched models |
|
|
| `thinking_level_change` | Records when the user changed thinking level |
|
|
| `custom` | Extension state (NOT sent to LLM) |
|
|
| `custom_message` | Extension-injected message (IS sent to LLM) |
|
|
| `label` | User bookmark on an entry |
|
|
| `session_info` | Session metadata (display name) |
|
|
|
|
### Message Types Within Entries
|
|
|
|
Message entries contain typed message objects:
|
|
|
|
| Role | What it is |
|
|
|------|-----------|
|
|
| `user` | User's prompt (text and/or images) |
|
|
| `assistant` | LLM's response (text, thinking, tool calls) — includes model, provider, usage stats |
|
|
| `toolResult` | Output from a tool execution — includes `details` for rendering and state |
|
|
| `bashExecution` | Output from user's `!command` (not from LLM tool calls) |
|
|
| `custom` | Extension-injected message |
|
|
| `branchSummary` | Summary of an abandoned branch |
|
|
| `compactionSummary` | Summary from compaction |
|
|
|
|
### Context Building
|
|
|
|
When pi needs to send messages to the LLM, it walks the tree from the current leaf to the root:
|
|
|
|
1. If there's a compaction entry on the path → emit the summary first, then messages from `firstKeptEntryId` onward
|
|
2. If there's a branch summary → include it as context
|
|
3. Custom message entries → included in LLM context
|
|
4. Custom entries (extension state) → NOT included in LLM context
|
|
|
|
### Session Commands
|
|
|
|
| Command | What it does |
|
|
|---------|-------------|
|
|
| `/tree` | Navigate to any point in the session tree and continue from there |
|
|
| `/fork` | Create a new session file from the current branch |
|
|
| `/resume` | Browse and switch to a previous session |
|
|
| `/new` | Start a fresh session |
|
|
| `/name <name>` | Set a display name for the session |
|
|
| `/session` | Show session info (path, tokens, cost) |
|
|
| `/compact` | Manually trigger compaction |
|
|
|
|
### Branching in Practice
|
|
|
|
**`/tree`** — In-place branching. You select a previous point, the conversation continues from there. The old branch is preserved and can be revisited. Pi optionally generates a summary of the branch you're leaving so context isn't lost.
|
|
|
|
**`/fork`** — Creates a new session file from the current branch. Opens a selector, copies history up to the selected point, and puts that message in the editor for modification. Good for "start fresh but keep the context."
|
|
|
|
---
|