Pi Agents
A practical book about finding the right layer for agent behaviour, using Pi to see and build each one: from a direct model call, through an agent core and the coding-agent application, out to interfaces and authority boundaries — worked from the least powerful mechanism that solves the problem.
Most people write agents by writing prompts. That works right up until the moment it does not: the prompt gets longer, the instructions start to contradict each other, and the same task works on Tuesday and fails on Thursday for reasons nobody can name.
Pi is useful here because an agent is not merely a conversation; it is a program with explicit places to attach behaviour. Context files, prompt templates and skills shape what the model reads. Extensions add executable tools, commands and event handlers inside Pi’s process. Those choices have different costs in maintenance, review and trust. Some other mechanisms, such as providers and packages, solve different problems rather than simply adding more power.
This book is about choosing a mechanism that fits the requirement, then building it in the layer that owns the decision. The goal is not always to climb upward: different mechanisms solve different kinds of problem.
What is the least powerful Pi mechanism that solves this problem?
Underneath that question runs a second: not which mechanism, but which layer owns the decision? Chapter 11 turns the two into a practical procedure:
Use the least powerful mechanism that solves the requirement — and put it in the narrowest layer that actually owns the decision.
A third question becomes unavoidable when a requirement is a prohibition: what will still stop the action if the model or agent makes a mistake? Chapter 42 answers that in terms of independently enforced permissions and authority boundaries.
Chapter 1 grounds the layering argument in Pi’s package graph, then asks where that neat separation runs out. Pi has an embeddable agent core, but some lifecycle decisions are not exposed at a public extension seam early enough to control them. Chapter 39 tests the difference between observing a decision and intercepting it. A custom SDK host may own decisions that an extension cannot.
What the book builds
Six parts, forty-two numbered chapters, three appendices, and this introduction. Part I makes the agent loop and its inputs concrete. Part II chooses between instructions, prompts, skills, extensions and related ways of changing Pi. Part III examines the state that survives, the work that can continue, and the failures that must be recovered. Part IV compares five ways to drive the coding agent: interactive, print, JSON, SDK and RPC. Part V uses the model-access and agent-core packages directly to build and evaluate a claim checker. Part VI asks what any of those mechanisms is authorised to do.
The layers, in the direction of dependency:
interface drives and observes: terminal, print, JSON, RPC, an SDK host
application / host purpose and deployment policy; external controls may enforce authority
agent application sessions, compaction policy, extensions, workflow (pi-coding-agent)
agent core loop, messages, state, tool execution, events (pi-agent-core)
model / provider access one request to one model (pi-ai)
provider Anthropic, OpenAI, a local server
An agent sits above the model layer and below the application that gives it a purpose. The book argues that many hard-to-diagnose agent failures are mistakes about which layer owns a decision. Pi makes that claim concrete: you can inspect its layers, run examples against a pinned release, and recognise when an extension is too late to enforce the requirement.
Part I: The Agent Loop (chapters 1 to 10).
What Pi is and what you are writing against. The loop that every extension
attaches to, installation and a first task, models and thinking level, the
context window as a budget rather than a container, where sessions live, the
built-in tools, where configuration comes from and in what order it wins, the
project .pi directory and the trust decision in front of it, the shell Pi
actually invokes, and how to write a task the agent can finish.
Part II: The Four Building Blocks (11 to 22). How you change Pi. Chapter 11 is the decision chapter, and everything after it assumes you have made the decision. Then prompt templates and their argument substitution; skills and their description-based routing; skills that carry scripts, references and assets; your first extension; the lifecycle and the event contracts; tools in depth including exposure and nested calls; changing what the model knows; where state goes and why the four storage choices are not interchangeable; slash commands and terminal UI; MCP; and shipping the result as a package.
Part III: Long Sessions and Control (23 to 30). What happens when the conversation gets big. Compaction and what a summary does and does not preserve; branching and forking over a tree rather than a list; steering, queueing and aborting work in flight; the message types the whole system is built from; the session file format on disk; context admission, meaning who decides which instructions reach the model; failures, retries and recovery; and debugging by layer.
Part IV: Pi as a Program (31 to 35). When the interface is not the agent. Why the terminal is one driver of one agent; headless operation through print and JSON modes; the JSONL event stream and how to reconstruct state from it; the TypeScript SDK creating sessions in process; and driving a live Pi over RPC.
Part V: Building Below the Coding Agent (36 to 41). Using the layers Pi is built from. One chapter per layer step, with one running example, a claim checker, and code that runs: a single model call that returns a typed value; the agent core on its own; a stochastic step as a typed function; the hooks on the core and which decisions each can still change; composing operations without turning everything into an agent; and testing software that contains a model.
Part VI: Authority (42). What any of it may do. A closing chapter that gathers trust, permissions, tool annotations and isolation into one answer to the question the reader should have been asking since chapter 1: what makes an agent worth building at all?
Appendices. A: references and further reading. B: the terminal interface in detail, for the reader who is building a terminal component. C: Pi Patch Desk: the capstone, a supplement added after initial publication that brings the mechanisms together in one runnable, evidence-bearing fixture repair. Its implementation lives in the public pi-agents repository.
The decision the book is really about
Pi’s quickstart advises starting with the least powerful mechanism that meets the need, and offers this practical choice of mechanisms:
AGENTS.md persistent instructions for a folder
prompt template reuse a prompt from the / menu
skill task-specific instructions plus supporting files
extension executable tools, commands, or event handlers
terminal UI a custom component in the terminal
custom provider an unsupported model service
package install or distribute several resources at once
Chapter 11 turns those choices into a procedure. They are not a strict ladder of permissions: a package distributes resources, a provider connects a model, and a terminal component changes presentation. The crucial difference is between text that guides behaviour and executable code that can act with Pi’s process permissions. An extension may inspect messages, tool calls, files and session history; a prompt template cannot execute code on its own. For a prohibition, the mechanism choice is not enough. Chapter 42 identifies the external control that must enforce it.
What kind of claims this book makes
Three kinds, kept apart in the prose.
Documented is what Pi’s documentation or its exported type declarations state. The book asserts these plainly and names the doc topic. Observed is behaviour that was run and recorded, with the version noted. Proposed is a pattern that belongs to this book and not to Pi — a reasonable way to structure an extension, a shape for a skill directory — and it is always signalled as such.
The runnable examples are kept in examples/ and target the book’s pinned
Pi 1.0.4 release. Example markers and the verification scripts help check
that documented snippets agree with their source files; any prose or code edits
must be synchronized with those files before claiming a fresh test result.
Run this book’s examples gives the
commands and prerequisites. A green scripted-provider suite demonstrates
specific code paths, not the reliability of a real model. Chapter 41 explains
what a real-model evaluation would require.
This separation is the book’s method. Most agent writing goes wrong not because a technique was wrong but because a pattern that happened to work got described as though the framework guaranteed it. Where the book recommends something Pi does not require, it says so.
Who this is for
You have used a coding agent and want it to do one specific thing reliably. You are comfortable enough with TypeScript to read an event declaration. You would rather understand the mechanism than copy a snippet, and you want to know which parts of what you built depend on a documented contract and which parts are your own judgement.
No prior Pi experience is assumed. Parts I and III explain the mechanics without requiring TypeScript. Part II introduces extensions and expects you to read small async functions and schemas; Parts IV and V are most useful to readers building integrations or software on the SDK and core packages.
Find your problem
Most readers arrive with a symptom, not a plan. This table starts from the symptom. Chapter 42’s closing table is the foundation — it maps a requirement to a mechanism — but you should not have to reach the end of the book to find which chapter owns your problem.
| What you see | Chapter | What to look for |
|---|---|---|
| My skill never loads | 13 | Check discovery, the required SKILL.md metadata and whether its description was offered for selection; discovery is not the same as invocation |
| My skill loads but does nothing | 14 | Bundled files do not execute themselves; the model must read the instructions and an available execution tool must run any script |
| A bundled script runs in the wrong directory | 14 | Ask the environment for the target repository rather than counting parent directories |
| The model ignores what I told it | 18 | An instruction is not authority. First check whether the section, skill or context file was admitted at all |
| My command stalls in RPC | 35 | Separate command acceptance from run completion; check for an outstanding extension-UI request, unread stdout and a missing agent_settled |
My command does nothing under --print |
32 | Print has no interactive approval dialog; inspect stderr, process status and the generated result rather than treating an exit code as proof of task success |
| The session has a message the model cannot see | 27, then 30 | Stored, projected and sent are three different things. get_messages is the second, not the third |
| The context window overflowed | 29 | Check stopReason and the overflow-recovery events before blaming the model |
| Something ran and I cannot tell which layer did it | 30 | Replace the layer below the one you suspect. Does the symptom survive? |
| The model called a tool I did not enable | 6, then 17 | Check the effective tool set, tool exposure and MCP selection; registering, declaring and reaching a tool are different questions |
| My extension’s handler never fires | 16 | Registration order, and which events transform versus only notify |
| An effect happened that I wanted stopped first | 39, then 42 | beforeToolCall can refuse calls it mediates, but external permissions must constrain effects that bypass the gate |
| Which mechanism does this requirement use? | 11, then 42 | Least powerful mechanism; narrowest layer that owns it |
| The agent can reach something it should not | 42 | The four rungs, instruction to host containment. Availability is not consent |
| I want a typed value back from a model | 36 | A direct call can yield a schema-validated value; validation of its shape does not establish whether the answer is true |
| A model call will not submit the required value | 38 | A bounded loop may repair a rejected submission or fail with a named error; it cannot guarantee compliance or correctness |
| My suite is green and the agent still fails | 41 | Scripted tests exercise known paths; reliability requires representative real-model trials and meaningful acceptance checks |
| I want to run the code this book shows | Run this book’s examples | The pinned install, the prerequisites, and what a green run proves |
How to read it
If you are here to build one thing, start with chapter 11 and follow its decision procedure. If you want to build below the coding-agent application, read chapter 1, then Part V. For extensions, start with Part I and use Parts II and III as references. For integrations, Part IV compares the available interfaces; Part V shows what changes when you own the model call and loop. For unattended or privileged operation, read chapter 42 before granting the agent access to production resources.
Chapters
The Loop You Are Writing For
Before you write an extension, know the loop it attaches to: how a submitted message becomes a model request, how a tool call becomes a result, and when the run is over.
Install, First Session, First Task
Get Pi running and give it something real to do: installation, the working folder, authentication, a first task, and what to do when the result is not what you wanted.
Models and Thinking Level
Which model the agent runs on, how hard it thinks, how credentials are resolved, and why a model choice can explain a behaviour you attributed to your code.
The Context Window Is a Budget
What Pi sends to the model each turn, the arithmetic that triggers compaction, and how to tune reserveTokens and keepRecentTokens for your model.
Sessions and Where They Live
Session files are append-only JSONL trees keyed by id and parentId; here is how to read one, resume it, fork it, and control where it is stored.
The Built-In Tools
The eight built-in Pi tools, what defaultTools actually selects, how tool results reach the transcript, and when to add codemode.
Settings and Where Configuration Comes From
Pi merges the agent-directory and project .pi settings files: scalars override, resource lists combine, and environment variables and CLI flags are documented per setting rather than as higher layers.
The Project .pi Directory and Trust
Which project resources Pi loads only after trust, and which context files load regardless of the trust decision.
Shells, Processes, and Environment Variables
Pi runs shell commands in separate non-interactive processes. Learn how shell selection, startup files, command prefixes, and session environment variables affect what the model can execute.
Writing a Task Pi Can Finish
Pi does not ask before tool calls, so the task statement has to carry the scope, the acceptance check, and the files; here is a shape that works.
Four Ways to Change Pi
A decision procedure for choosing between context files, prompt templates, skills, and extensions, with four worked cases and one running example for the rest of this part.
Prompt Templates
Prompt templates turn a Markdown file into a slash command with shell-style argument substitution; here is the frontmatter, the substitution table, and where templates load from.
Skills
Pi advertises each skill by name and description and loads its full instructions on demand; here is how to write the description that makes routing work.
Run This Book's Examples
Get the code this book runs, install the pinned Pi release, verify that the chapters and the code agree, and know what the resulting evidence does and does not prove.
Skills That Carry Files
SKILL.md can reference scripts, references and assets by relative path; here is the layout, the path convention, and how to distribute the whole directory as a package.
Your First Extension
An extension is a TypeScript module with a default factory receiving ExtensionAPI; here is the smallest working tool, how it loads, and the lifecycle rules for the factory.
Events and the Extension Lifecycle
Pi dispatches named events to handlers in registration order; here is the run lifecycle, what each event may return, and a force-push guard built on tool_call.
Tools in Depth
A tool declares a name, description, schema and execute(); this chapter covers exposure, annotations, structured output, terminate, and nested calls.
Changing What Pi Knows
Four surfaces change the model's input - SYSTEM.md, APPEND_SYSTEM.md, before_agent_start sections, and the context event - each with a different lifetime and cost.
Extension State and Persistence
Where an extension puts its state so it survives reload, resume, and fork, and why the answer is almost always a session entry rather than a module variable.
Slash Commands and Custom UI
How an extension adds a / command and renders its own screen, and the mode rules that decide whether that screen exists at all.
MCP Servers
Connecting Model Context Protocol servers over stdio and HTTP, controlling how their tools reach the model, and what a permission gate can and cannot see of them.
Packages: Shipping an Agent
How a Pi package carries an extension, its skills, prompts and themes as one installable unit, and which dependencies must never be bundled.
Compaction
How Pi decides when the context window is full, what it replaces with a summary, what survives untouched, and where an extension can take the summarization over.
Branching and Forking
Three ways to go back — /tree, /fork and /clone — and how to choose when a wrong turn stays in the session or becomes separate work.
Steering, Queuing, and Changing Direction
What happens when you type while Pi is working — steering enters after the current turn, follow-ups wait for the run to finish, and Escape returns the queue.
Message Types
The eight roles AgentMessage covers, the content blocks they share, and which fields are authoritative — including the one timestamp type that catches everyone.
The Session File Format
One JSON object per line, a tree of entries, and the three-pass walk that turns a stored session into exactly the messages a model request contains.
Context Admission Is Application Policy
A file existing, being discovered, being admitted and reaching the model are four different facts; this chapter separates them, shows which are Pi's rules and which belong to the application, and runs the discovery rules.
Failures, Retries, and Recovery
Three different responses to a failed request — repeat it, repair the context and retry once, or stop — and the settings and events that tell them apart.
Debugging by Layer
A failure in an agent is a failure in one layer, and the fastest way to find which is to replace the layer below it and see whether the symptom survives; this chapter pairs each layer with its symptoms and its instrument.
The Interface Is Not the Agent
The terminal, print mode, the JSON stream, RPC and the SDK are five ways to drive one agent; what survives a change of interface is the evidence that the agent is a separate layer, and what does not survive is the design rule for extensions.
Headless Pi
Running Pi with no person attached — print and JSON modes, how the mode is chosen, what survives without a terminal, and what each mode costs and gives you.
The JSON Event Stream
The wire reference for Pi's JSONL events — strict LF framing, the event vocabulary, and the reconstruction rule that turns deltas back into authoritative messages.
SDK Sessions
Embedding Pi in a Node.js or Bun process — createAgentSession, the injected boundaries, session replacement, and the rules that keep an in-process agent well behaved.
RPC
Driving a live Pi subprocess over JSONL — four record families, correlated commands, an extension UI subprotocol, and the shutdown contract.
Model Access Without the Coding Agent
Most of what an application needs from a model is one call, not an agent: this chapter uses pi-ai directly to get a typed result from a model with no loop, no session and no terminal.
The Agent Core on Its Own
pi-agent-core's Agent class is Pi's loop with the coding agent removed: this chapter runs the claim-checking task as an agent with a tool and shows exactly what the host was providing.
A Stochastic Step Is a Typed Function
Wrap an agent loop as a typed function: validate a submit-tool result, bound unsuccessful runs, and compose steps while keeping schema validity separate from correctness.
Seams, Hooks, and Irreversible Decisions
Every hook on the agent core can see something; only some can change it and fewer can refuse it. This chapter maps each hook by what it can still decide, measured rather than assumed.
Composing Agent Operations
A pipeline is not a team of agents: this chapter composes a function, a model call, a check and an agent into one claim-checking pipeline, and spends the expensive part only when the cheap part cannot decide.
Testing Stochastic Software
Unit tests, structural tests and evaluations answer three different questions about code that contains a model; this chapter builds all three against the claim checker and shows why the average success rate hides the number that matters.
Authority, Isolation, and What Makes an Agent Worth Building
The closing argument: capability is not authority, a boundary must act in time and be out of reach of what it constrains, a value chosen by the inspected party cannot gate the inspection, and where each requirement belongs on the four-rung ladder from instruction to host containment.
Appendix A — References and Further Reading
The sources behind this book: Pi's own documentation, published research on agent loops, interfaces, context and security, ecosystem projects that demonstrate particular designs, and the companion books that take these questions further.
Appendix B — The Terminal Interface, in Detail
Reference for the terminal UI as a layered system: reporting protocols, the pi-tui component model, keybindings, themes, and per-terminal fixes. Moved out of the main line because it describes the interface, not the agent.
Appendix C — Pi Patch Desk: The Capstone
A guided capstone walkthrough: reproduce a parser bug, let Pi edit a disposable fixture, inspect a proposed patch and its host verification, and see a prohibited action refused.