Skip to content

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.


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.

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.


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/:sessionId

The 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.


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.


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:

Terminal window
export PIZZAPI_SESSION_ATTACHMENTS_DIR=/path/to/session-attachments

Attachments 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.


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.json and custom models from ~/.pizzapi/models.json under the configured agent directory;
  • registers the Ollama Cloud provider explicitly so ollama-cloud can 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, or haiku; then flash/fast; otherwise the first available model).

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.


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.

  • 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

When you select a user message in the tree:

  1. The conversation pointer moves to the parent of that message
  2. The message text is placed in your editor for re-submission
  3. You can edit it and submit, creating a new branch

When you select a non-user message (assistant response, compaction, etc.):

  1. The conversation continues from that point
  2. The editor stays empty

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

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.


Long conversations eventually fill the model’s context window. Compaction summarizes older messages while keeping recent ones, freeing up context space.

Enabled by default. Triggers when:

contextTokens > contextWindow − reserveTokens

When triggered, pi:

  1. Walks backwards from the newest message, keeping recent messages (default: 20,000 tokens)
  2. Summarizes everything older into a structured summary
  3. Continues with the summary + recent messages

Use /compact to trigger compaction manually, optionally with focus instructions:

/compact # Default summarization
/compact focus on the auth module # Guided summarization

This is useful when you want to steer what the summary emphasizes before the context runs out naturally.

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)

Additional session-related settings:

{
"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": {
"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.

{
"sessionDir": "/path/to/sessions"
}

Priority: --session-dir CLI flag → PI_CODING_AGENT_SESSION_DIR env var → sessionDir in settings → default (~/.pizzapi/sessions/).


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

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
  1. Global AGENTS.md from ~/.pizzapi/
  2. Global ~/.pizzapi/rules/*.md, sorted lexicographically
  3. Walk up from the current working directory, loading each AGENTS.md or CLAUDE.md found (the current directory is included)
  4. 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.