🌏 中文版
TL;DR
- Install:
npm i -g @earendil-works/pi-coding-agentorollama launch pi - 5 Modes: Interactive (default), Print, JSON, RPC, SDK — same core, different interfaces
- Session: JSONL in
~/.pi/agent/sessions/, tree structure supports branching, replay, fork - Model Switch:
/model,Ctrl+Lmenu,Ctrl+Pcycle favorites, works mid-session - Message Interjection:
Enter= steering (inject after current tool),Alt+Enter= follow-up (inject after agent stops) - Navigation:
/treevisual branch view, jump to any node;/exportHTML,/sharegist
Installation & First Launch
# npm global install (recommended)
npm install -g @earendil-works/pi-coding-agent
# Or one-shot with Ollama (auto-pulls model)
ollama launch pi
# Verify version
pi --version
# @earendil-works/pi-coding-agent@0.x.x
Package & repo renamed: npm scope
@mariozechner→@earendil-works, GitHubbadlogic/pi-mono→earendil-works/pi. Existing installs runpi update --selfto auto-migrate.
First launch enters Interactive mode (TUI):
$ pi
╭────────────────────────────────────────────────────────────╮
│ pi 0.x.x • Session: a1b2c3d4 • Model: anthropic/claude-3-5-sonnet-20241022 │
├────────────────────────────────────────────────────────────┤
│ > your prompt... │
╰────────────────────────────────────────────────────────────╯
Five Run Modes: One Core, Five Interfaces
| Mode | Trigger | Use Case | Output |
|---|---|---|---|
| Interactive | pi (no args) | Daily dev, long conversations | TUI, live rendering, keybindings |
pi -p "prompt" | Single-turn Q&A, script embedding | Plain text, direct to stdout | |
| JSON | pi --json -p "prompt" | Programmatic integration, CI/CD | JSON object with metadata, tool calls |
| RPC | pi --rpc | Long-lived, IDE integration, daemon | JSON-RPC 2.0 over stdin/stdout |
| SDK | import { createAgentSession } from '@earendil-works/pi-coding-agent' | Embed in own app | Full programmatic control |
Print Mode Examples
# Single-turn, pipeline-friendly
pi -p "Explain async/await in traditional Chinese" --model ollama:qwen3:1.7b
# Specify output format
pi --json -p "List 3 TypeScript utility types" | jq '.result'
JSON Mode Output Structure
{
"sessionId": "a1b2c3d4",
"model": "anthropic/claude-3-5-sonnet-20241022",
"result": "Async/await is...",
"toolCalls": [],
"usage": { "inputTokens": 42, "outputTokens": 156 },
"stopReason": "end_turn"
}
RPC Mode: For IDEs/Plugins
# Start RPC server (stdin/stdout)
pi --rpc
# Client sends JSON-RPC 2.0 request
{"jsonrpc":"2.0","id":1,"method":"prompt","params":{"text":"hello"}}
# Streaming event responses
{"jsonrpc":"2.0","method":"event","params":{"type":"message_start",...}}
Architecture Preview: All 5 modes share the same
AgentSessioncore (packages/coding-agent/src/core/sdk.ts), differing only in howrunPrintMode,runRpcMode,InteractiveModewrap the event stream.
Session: Not Just History — An Editable Tree
Where It Lives
~/.pi/agent/sessions/
└── --your-project-path--/
├── 2026-08-31T10-30-00_a1b2c3d4.jsonl # latest session
└── 2026-08-30T14-22-11_e5f6g7h8.jsonl # yesterday's session
- Format: JSONL (one entry per line), append-only
- Naming:
ISO8601_timestamp_sessionId.jsonl - Encoding: Directory name wraps
cwdwith--, path separators become-
Entry Types at a Glance
| Entry Type | Purpose | Enters LLM Context? |
|---|---|---|
message | user/assistant/toolResult | ✅ |
thinking_level_change | Thinking level toggle | ✅ (via context settings) |
model_change | Model switch record | ✅ (via context settings) |
compaction | Summary compression point | ✅ (represents summarized history) |
branch_summary | Branch summary | ✅ |
custom_message | Extension-injected message | ✅ |
custom | Extension internal state | ❌ |
label | User bookmarks | ❌ |
session_info | Display name | ❌ |
Tree Structure: Branch, Reset, Fork
# In TUI
/tree # Visual branch tree, ↑↓ to pick node, Enter to resume from there
/branch # New branch from current position (history unchanged)
/reset # Back to root (rewrite first user message)
/fork # Copy entire session to new file (cross-project capable)
Key Concept: Session is an append-only tree. Every append creates a child of current leaf. /branch just moves leaf pointer to an old node; next message becomes a new branch. History is never deleted or mutated.
Model Switching: Hot-Swap Mid-Session
pi supports 15+ providers: Anthropic, OpenAI, Google, Azure, Bedrock, Mistral, Groq, Cerebras, xAI, Hugging Face, Kimi, MiniMax, NVIDIA, OpenRouter, Ollama.
Three Ways to Switch
# 1. Command menu (searchable, grouped)
/model
# 2. Hotkey menu (Ctrl+L)
# 3. Cycle favorites (Ctrl+P)
Live Demo: Switch Mid-Conversation
> Write a quicksort in Python
# ... Claude 3.5 Sonnet replies ...
> /model switch to ollama:qwen3:1.7b
Model switched to ollama:qwen3:1.7b
> Now rewrite that in Rust
# ... Qwen3 1.7B continues with full context ...
Under the Hood: Switch writes a model_change entry; buildSessionContext() picks up latest model for next LLM call. System prompt, tools, history fully preserved.
Message Interjection: Steering vs Follow-up
pi's most distinctive interaction — you can send messages while the agent is working:
| Key | Name | Timing | Use Case |
|---|---|---|---|
Enter | Steering | After current tool finishes, before next LLM call | "Don't run that cmd", "Use grep instead", "Add condition" |
Alt+Enter | Follow-up | After agent decides to stop (turn ends) | "Test after done", "Continue to next step" |
Visual Timeline
Agent state: [Thinking] → [Tool: bash] → [Thinking] → [Tool: edit] → [Thinking] → [Done]
↑ ↑
Steering inject Steering inject
(before next turn) (before next turn)
↑
Follow-up inject
(after agent stops)
Architecture Preview: Maps to AgentLoopConfig.getSteeringMessages() (steering) and getFollowUpMessages() (follow-up), handled in the double-while loop in agent-loop.ts.
Essential Commands Cheatsheet
| Command | Function | Key Params |
|---|---|---|
/model | Switch model | Keyword filter |
/tree | Show branch tree | Enter to resume, Space expand/collapse |
/branch | Branch from current node | Optional summary of abandoned path |
/compact | Manual compaction trigger | Compress old conversation |
/export | Export HTML | --file path.html |
/share | Upload gist | Requires GitHub token |
/session | List/switch sessions | new, resume <id>, list |
/settings | Settings panel | Theme, Keybindings, Tools, Trust |
/help | All commands & keybindings | Categorized display |
Key Keybindings
| Shortcut | Action |
|---|---|
Ctrl+L | Model menu |
Ctrl+P | Cycle favorite models |
Ctrl+O | Open file (fuzzy) |
Ctrl+R | Command history search |
Alt+Enter | Follow-up message |
Escape | Interrupt generation/tool |
Tab | Autocomplete (commands, files, models) |
Local Models: Ollama Integration in Practice
pi is uniquely small-model friendly — tiny system prompt + 4 tools = low token burn.
# Pull models
ollama pull qwen3:1.7b
ollama pull gemma2:2b
# Run with local model
pi -p "Say hello world in traditional Chinese" --model ollama:qwen3:1.7b
# Or pick Ollama group in /model inside Interactive mode
| Scenario | Suggested Tier | Tested Working Models |
|---|---|---|
| Light use (read files, small fixes) | 1.7B~2B | Qwen3:1.7B, Gemma2:2B |
| General dev (refactor, write tests) | 7B~8B | Qwen2.5:7B, Llama3.1:8B |
| Complex tasks (architecture, multi-file) | Flagship | Claude 3.5 Sonnet, GPT-4o, Opus |
Why do small models work? Pi's system prompt ~300 tokens (Claude Code: thousands), only 4 tools, near-perfect prompt cache hit rate. Something "full-featured harnesses" can't achieve.
Hands-On: Build Your First Session Tree
# 1. Enter a Git repo project dir
cd your-project
# 2. Launch pi
pi
# 3. Send a few prompts to establish mainline
> Help me add a README.md
> Now extract main function into separate module
# 4. View tree with /tree
/tree
# Select first user message → Enter to resume
# 5. Send new message at branch point (auto-creates branch)
> Actually write tests first then refactor
# 6. /tree again to see branches
# Two paths now, jump freely between them
# 7. Export HTML for review
/export --file session-review.html
# 8. Share with colleague
/share
# Outputs gist URL
References
- Pi Official Website pi.dev — CLI Docs & Command Reference
- GitHub - earendil-works/pi — Source: packages/coding-agent/src/cli.ts
- Pi Author Blog: Building a Minimal Coding Agent — Interactive Mode Design
- Ollama Official Model Library — Small Models Suitable for pi
- Previous Pi Intro: 4 Modes, Extension System, TUI Engine
Next Up
Part 2: Monorepo Architecture & Core Abstractions
How do 7 packages divide responsibilities? Why one-way dependency flow? What does
pi-ai,pi-agent-core,pi-coding-agent,pi-tui,pi-telemetry,pi-client/server/protocoleach own? From "what users see" into "invisible architectural decisions".
Loading...