Sessions & Context
PizzaPi sessions are powered by pi’s session engine — a tree-structured conversation format that supports branching, forking, and automatic context compaction. This page covers how sessions work under the hood and the tools available for managing them.
Session Basics
Section titled “Session Basics”Starting and Resuming
Section titled “Starting and Resuming”| Command | Description |
|---|---|
/new |
Start a fresh session |
/resume |
Browse and resume a previous session — fuzzy-search by name, ID, or content in the picker |
/name <name> |
Give the current session a display name |
/session |
Show session info (path, tokens, cost) |
Sessions auto-save as JSONL files under ~/.pizzapi/sessions/, organized by working directory.
Session Storage
Section titled “Session Storage”Each session is a single .jsonl file with a tree structure. Every entry has an id and parentId, enabling in-place branching without creating new files. The file format preserves all history — even when you branch or compact, nothing is deleted.
Session Inspector / analysis
Section titled “Session Inspector / analysis”The web UI’s Analysis panel shows context and cache telemetry for the active session. Live sessions receive analysis in session metadata; the panel can also fetch reconstructed analysis from:
GET /api/runners/:runnerId/analysis/:sessionIdThe runner handles that request by parsing the saved transcript and reconstructing context growth from assistant usage records. The panel shows:
| Metric | Source |
|---|---|
| Cache hit | cacheRead / (input + cacheRead + cacheWrite) when usage telemetry is complete. |
| Estimated cache savings | Provider pricing applied to cache-read tokens when pricing is known. |
| Peak context | Largest observed prompt size. |
| Compactions | Compaction boundaries found in the transcript. |
| Context growth | Per-turn blocks in a sparkline and treemap. |
| Cost by model | usage.cost.total accumulated per provider/model. |
Failed turns are counted for billed token/cost totals when usage exists, but they are treated as separators for context-growth continuity. Missing usage makes cache metrics unknown instead of guessing.
Background shells
Section titled “Background shells”PizzaPi replaces pi’s bash execution layer with background-aware shell handling.
| Tool / command | Purpose |
|---|---|
bash with run_in_background: true |
Start a command, return immediately, and keep stdout/stderr in a temp log. |
bash without run_in_background |
Streams in the foreground until the configured threshold, then auto-backgrounds if still running. |
bash_output |
List background shells, or read new output for one PID since the last read. |
kill_shell |
Kill a background shell and its process group. |
/background or ctrl+shift+b |
Send the currently running foreground bash call to the background. |
/shells |
List background shells and status. |
When a background shell exits, PizzaPi sends a background-bash message back into the session with the exit code or signal and the log path. The agent is instructed not to sleep-poll; it should continue work and use bash_output only when it needs intermediate output.
Configure the foreground window in ~/.pizzapi/config.json:
{ "bash": { "backgroundAfterSeconds": 300 }}Override for one process with PIZZAPI_BASH_BACKGROUND_SECONDS. 0 backgrounds immediately.
Session attachments
Section titled “Session attachments”Remote image/file attachments sent through the web UI are downloaded by the runner and saved per session by the session-attachments extension. The default storage path is:
~/.pizzapi/session-attachments/{sessionId}/Each saved file gets a .meta.json sidecar with the original filename, MIME type, byte size, saved timestamp, and stored filename. Filenames and session IDs are sanitized for filesystem use, and duplicate filenames are suffixed (file-2.png, file-3.png, …).
Override the root directory with:
export PIZZAPI_SESSION_ATTACHMENTS_DIR=/path/to/session-attachmentsAttachments are session-scoped. cleanupSessionAttachments() removes the session directory when a session ends; sweepOrphanedAttachments() removes directories that no longer match active sessions after restarts or crashes.
Automatic commit-message generation
Section titled “Automatic commit-message generation”The Git panel can request a commit-message suggestion for staged changes. The runner’s Git service handles git_commit_message_suggest by reading the staged diff and asking the model-backed generator first. If model generation fails, times out, has no auth, or returns no subject, the Git service falls back to its deterministic staged-file heuristic.
The model generator:
- reads auth from
~/.pizzapi/auth.jsonand custom models from~/.pizzapi/models.jsonunder the configured agent directory; - registers the Ollama Cloud provider explicitly so
ollama-cloudcan be selected outside a live extension session; - sends at most the first 20,000 characters of the staged diff;
- asks for a conventional commit message only;
- times out after 30 seconds;
- picks a cheap/fast available model first (
mini,flash-lite, orhaiku; thenflash/fast; otherwise the first available model).
Session processes panel
Section titled “Session processes panel”The runner tracks OS processes spawned by a session so the web UI can show a Processes panel. Background shells are listed with PID, command, title, status, runtime, and log path. The panel can tail a background shell’s log and send a kill request for the shell or other listed session process.
When a session restarts its worker in place, processes left in the previous worker’s process group (for example an MCP stdio server that did not exit with its parent) are kept running so the session continues, but the runner records that group with the session. They stay visible in the Processes panel and are terminated (SIGTERM, then SIGKILL after the shutdown grace period) together with the current worker when the session ends.
The TUI also has a lightweight session-processes widget. It polls the session’s process group every five seconds using pgrep -g 0 and ps, then shows a compact line such as ⚙ 2 procs vite:1234 · bun:5678. If the platform lacks those commands, the widget stays hidden.
Branching with /tree
Section titled “Branching with /tree”The /tree command opens a tree-based navigator showing your full conversation history. Unlike linear chat, pi sessions form a tree — every time you go back and try a different approach, a new branch is created.
What You Can Do
Section titled “What You Can Do”- Navigate to any point in the conversation
- Branch from any message to try a different approach
- View branches side by side to compare approaches
- Label important messages as bookmarks
How It Works
Section titled “How It Works”When you select a user message in the tree:
- The conversation pointer moves to the parent of that message
- The message text is placed in your editor for re-submission
- You can edit it and submit, creating a new branch
When you select a non-user message (assistant response, compaction, etc.):
- The conversation continues from that point
- The editor stays empty
Branch Summarization
Section titled “Branch Summarization”When switching between branches, you’ll be asked whether to summarize the branch you’re leaving. This creates a compact summary that preserves context without keeping every message in the active context window. Options:
- No summary — switch immediately
- Summarize — generate a summary with the default prompt
- Summarize with custom prompt — provide focus instructions for the summary
Forking with /fork
Section titled “Forking with /fork”While /tree branches within the same session file, /fork creates an entirely new session from any previous user message in the current one.
| Feature | /tree |
/fork |
|---|---|---|
| Result | New branch in same file | New session file |
| History | Shared | Copied (independent) |
| Summarization | Optional | Never |
Use /fork when you want to explore a completely different direction without cluttering the original session’s tree.
Compaction
Section titled “Compaction”Long conversations eventually fill the model’s context window. Compaction summarizes older messages while keeping recent ones, freeing up context space.
Automatic Compaction
Section titled “Automatic Compaction”Enabled by default. Triggers when:
contextTokens > contextWindow − reserveTokensWhen triggered, pi:
- Walks backwards from the newest message, keeping recent messages (default: 20,000 tokens)
- Summarizes everything older into a structured summary
- Continues with the summary + recent messages
Manual Compaction
Section titled “Manual Compaction”Use /compact to trigger compaction manually, optionally with focus instructions:
/compact # Default summarization/compact focus on the auth module # Guided summarizationThis is useful when you want to steer what the summary emphasizes before the context runs out naturally.
Compaction Settings
Section titled “Compaction Settings”Configure in ~/.pizzapi/settings.json (global) or .pizzapi/settings.json (project):
{ "compaction": { "enabled": true, "reserveTokens": 16384, "keepRecentTokens": 20000 }}| Setting | Default | Description |
|---|---|---|
compaction.enabled |
true |
Enable automatic compaction |
compaction.reserveTokens |
16384 |
Tokens reserved for the model’s response |
compaction.keepRecentTokens |
20000 |
Recent tokens to keep (not summarized) |
Session Settings
Section titled “Session Settings”Additional session-related settings:
Branch Summary
Section titled “Branch Summary”{ "branchSummary": { "reserveTokens": 16384, "skipPrompt": false }}| Setting | Default | Description |
|---|---|---|
branchSummary.reserveTokens |
16384 |
Tokens reserved for branch summarization |
branchSummary.skipPrompt |
false |
Skip the “Summarize branch?” prompt (defaults to no summary) |
Retry on Errors
Section titled “Retry on Errors”{ "retry": { "enabled": true, "maxRetries": 3, "baseDelayMs": 2000, "provider": { "maxRetryDelayMs": 60000 } }}| Setting | Default | Description |
|---|---|---|
retry.enabled |
true |
Auto-retry on transient errors |
retry.maxRetries |
3 |
Maximum retry attempts |
retry.baseDelayMs |
2000 |
Base delay (exponential backoff: 2s, 4s, 8s) |
retry.provider.maxRetryDelayMs |
60000 |
Max delay before failing (prevents multi-hour waits) |
retry.maxDelayMs is still accepted for backward compatibility and is migrated to retry.provider.maxRetryDelayMs.
Custom Session Directory
Section titled “Custom Session Directory”{ "sessionDir": "/path/to/sessions"}Priority: --session-dir CLI flag → PI_CODING_AGENT_SESSION_DIR env var → sessionDir in settings → default (~/.pizzapi/sessions/).
Exporting and Sharing
Section titled “Exporting and Sharing”| Command | Description |
|---|---|
/export [file] |
Export the current session to an HTML file. If the path ends in .jsonl, the session is exported as JSONL instead. |
/import <path.jsonl> |
Import a previously exported JSONL session |
/clone |
Clone the current session into a new file |
/share |
Upload as a private GitHub gist with a shareable HTML link |
/copy |
Copy the last assistant message to your clipboard |
Context Files
Section titled “Context Files”pi automatically loads context files at startup to give the agent project-specific knowledge. These files are loaded from multiple locations and concatenated:
| File | Location | Purpose |
|---|---|---|
AGENTS.md or CLAUDE.md |
~/.pizzapi/, parent directories, current directory |
Project instructions, conventions, common commands |
rules/*.md |
~/.pizzapi/rules/ (global), .pizzapi/rules/ (project) |
Modular instructions, sorted lexicographically within each directory |
SYSTEM.md |
.pizzapi/SYSTEM.md (project) or ~/.pizzapi/SYSTEM.md (global) |
Replace the default system prompt entirely |
APPEND_SYSTEM.md |
Same locations | Append to the system prompt without replacing it |
How Context Files Load
Section titled “How Context Files Load”- Global
AGENTS.mdfrom~/.pizzapi/ - Global
~/.pizzapi/rules/*.md, sorted lexicographically - Walk up from the current working directory, loading each
AGENTS.mdorCLAUDE.mdfound (the current directory is included) - Project
.pizzapi/rules/*.md, sorted lexicographically
All files are concatenated and included in the system prompt. This means you can have repository-wide instructions in the repo root and more specific instructions in subdirectories.