Pi Coding Agent: A Minimal, Extensible Stack
Pi is a coding-agent framework built around a small system prompt, a narrow default toolset, and visible project context. Instead of deciding a workflow for every user, it supplies a compact runtime that developers can extend.
Mario Zechner, the developer behind libGDX, created Pi after finding that the coding agent he used had become difficult to inspect and control. Pi later became the agent engine inside OpenClaw, giving this design a prominent test beyond the terminal.
This article reflects the project on April 27, 2026. At that point, the latest GitHub release was v0.70.2, published on April 24, and the repository showed roughly 40,800 stars. Those figures are snapshots; the architecture is the more useful subject.
A Small Core with More Control Surfaces
Pi defaults to a narrow terminal harness and exposes customization through project files, skills, TypeScript extensions, and packages. It supports multiple providers, branching sessions, compaction, and terminal or programmatic use, but those capabilities remain separate from the four-tool default. The design does not remove complexity; it moves it into components that can be selected and versioned.
| Layer | Role |
| ---------------------------------- | ------------------------------------------------------------------------ |
| AGENTS.md | Project commands, architecture, rules, and prohibited actions |
| .pi/settings.json | Models, thinking level, packages, skills, compaction, and retry defaults |
| .pi/extensions/ | TypeScript tools, hooks, commands, permission gates, and UI components |
| .pi/skills/ or .agents/skills/ | Detailed procedures loaded when needed |
| .pi/prompts/ | Reusable prompt templates |
| models.json | Custom, local, and OpenAI-compatible providers |
Why Zechner Reduced the Harness
Zechner described Claude Code as “a spaceship with 80% of functionality I have no use for.” His objections were technical: system prompts and tool definitions changed between releases, hidden injections made the model's actual context hard to reconstruct, and overlapping tools consumed context on every request.
Pi therefore defaults to read, bash, edit, and write. Shell commands cover search, directory listing, and Git history instead of separate tools for each operation. Optional read-only tools support inspection without file modification or shell execution.
The choice relies on two assumptions. Frontier coding models have extensive training on ordinary shell utilities, and every schema-visible tool competes for space and attention in every model request. A broad catalog may offer a cleaner API for individual operations, but it also asks the model to distinguish overlapping descriptions. Pi uses the shell as a common interface and leaves specialized tools to extensions. That gives bash considerable power, so the reduced catalog should not be mistaken for a reduced permission boundary.
In November 2025, Zechner said the system prompt and tool definitions then fit below 1,000 tokens, compared with more than 10,000 for Claude Code's system prompt. The number is version-dependent. By v0.70.2, Pi's generated prompt also included a dynamic tool list, operating guidance, documentation paths, the date, and the working directory; project context and skills add more. The stable claim is a narrow and visible default, not a permanent token count.
A five-trial-per-task Terminal-Bench 2.0 run published in December 2025 scored 0.4787 with Pi and Claude Opus 4.5. Zechner compared it with then-current entries for Codex, Cursor, and Windsurf using their native models. This was a dated leaderboard comparison, not a controlled experiment isolating the harness.
The Monorepo Separates the Runtime into Layers
Pi lives in the badlogic/pi-mono TypeScript monorepo. Internal dependencies form a directed acyclic graph: lower packages do not depend on the user interface or coding-agent application.
This separation permits selective use. pi-ai can serve as a multi-provider LLM library without an agent. pi-agent-core can embed the agent loop without Pi's terminal interface. The higher layers add session management, tools, extensions, and presentation.
The terminal UI is itself a reusable package. It uses retained-mode rendering: components persist between frames, cache output, and update only changed regions. This reduces flicker and lets extensions display tables, selectors, progress indicators, or highlighted code inside the same interface. The detail matters because Pi treats presentation as an extension surface rather than hard-wiring it to the agent loop.
A Normalized Model Interface
pi-ai maps supported providers onto four principal API families: OpenAI-compatible, Anthropic, Google Gemini, and Amazon Bedrock. This is an implementation strategy rather than a claim that provider behavior is identical.
Cross-provider handoff matters because API schemas differ. Pi serializes the existing conversation, converts it for the destination, and preserves reasoning traces when possible. Tool results can also have separate representations: concise text for the model and structured data for the terminal UI. The separation keeps presentation detail out of the model context.
An Inspectable Agent Loop
pi-agent-core implements a ReAct-style cycle: request a model response, execute tool calls, append observations, and repeat until the model returns an answer. Tool arguments use TypeBox schemas for TypeScript typing and runtime validation. The loop is small enough to inspect, though the surrounding product naturally contains more code for providers, sessions, errors, and UI.
Messages sent during a run have two meanings. A steering message interrupts and redirects the current generation; a follow-up waits for the current turn to finish. Making this distinction explicit avoids treating every new user message as either an emergency stop or a passive queue entry.
Sessions Are Branches, Not a Flat Transcript
Pi stores sessions as append-only JSONL nodes with an id and parentId. Returning to an earlier node creates another branch while retaining the previous path. This allows experimentation without copying an entire conversation or discarding later history.
Compaction replaces older active messages with a summary as the context window fills. The threshold and summary model are configurable, so a cheaper model can summarize while a stronger model handles the main task. The full transcript survives, but the active summary is lossy; compaction extends a session rather than creating unlimited memory.
All execution modes use the same AgentSession abstraction. Interactive mode provides the terminal UI; print and JSON modes suit scripts; RPC exposes a process boundary; SDK mode embeds the agent directly.
Extensions Hold the Features Pi Leaves Out
Extensions are TypeScript modules loaded through jiti, so they can run without a separate build step and reload during a session. They can register commands, tools, keyboard shortcuts, event handlers, provider adapters, UI components, and controls around file or shell access.
That design also lets Pi write an extension from a user's requirements and reload it for testing. Armin Ronacher, creator of Flask and Jinja2, described this as software “malleable like clay.” He reported that Pi implemented his /answer, /todos, /review, and /files extensions from requirements and examples. This is convenient, but generated extensions remain executable code and require the same review as other changes.
Pi deliberately omits built-in plan mode and native subagents. Plans can live in a file or extension; parallel agents can be implemented with subprocesses, terminal panes, or packages. The absence is part of the API boundary, not evidence that these workflows are impossible.
Skills provide a lighter form of extension. Pi implements the agentskills.io format and can discover project or global skill directories, including configured Claude Code or Codex locations. Metadata is available at startup; full instructions enter the context only on invocation. Portability still depends on the tools and behavior supplied by each host.
Packages distribute these resources together. The current ecosystem includes reusable Pi skills, Ollama-maintained web search and fetch tools, and an autonomous research loop for optimizing measurable targets such as test time or bundle size. Project-local resources can travel with a repository, while global ones follow a user between projects. This split makes provenance important: a skill may only add instructions, but an extension or package may execute code and install dependencies.
The extension model also explains Pi's range of operating styles. The default remains a ReAct loop, while a file can hold an approved plan, another agent can run as a subprocess, and an event hook can load a specialized tool only when the repository needs it. These are compositions of existing boundaries rather than named modes built into the core.
OpenClaw Tested the SDK Model
Peter Steinberger began OpenClaw as a weekend project: a personal assistant that answers through channels including WhatsApp, Telegram, Slack, Discord, Signal, iMessage, Microsoft Teams, and Matrix. It embeds Pi through createAgentSession() rather than launching it as an opaque subprocess. Channel sessions, provider choice, persistence, and custom extensions are built around the same SDK abstraction.
OpenClaw's growth does not prove that a minimal harness is superior for every task. It does show that Pi's agent core can operate as infrastructure inside a much larger application. Its architecture assigns isolated sessions to channels, retains conversations across restarts, adds scheduled events, and uses Docker as a workload-isolation layer. Provider independence lets deployments choose hosted or local models. Ollama's integration provides another example: it configures Pi as a client for local models and can add separate web-search tools without changing the core.
Context Is the Scarce Resource
The architecture repeatedly returns to context allocation. Tool definitions and always-loaded instructions accompany every later request; project files and external memory influence a result only when the harness retrieves them. Progressive skill loading, split model/UI output, compaction, and provider handoff are different responses to the same constraint.
Minimal context is not automatically better. An omitted instruction can cost more than it saves if the model repeats work or violates a project rule. A poor summary can discard the fact needed for a later decision. Pi's contribution is to make those choices observable: teams can see what is permanent, what arrives on demand, and what has been compressed. They can then measure the trade against their own workload rather than accept a hidden default.
This is also why the append-only transcript matters. The active model context is a temporary working set, while the session file records the larger history. Branching protects alternative paths; compaction decides which portion remains immediately available. Neither mechanism turns stored information into understanding. Retrieval and summary quality still determine what the model can use.
The Trade-Off
Pi moves complexity from fixed product behavior into configuration and code owned by the user. This improves traceability: project instructions are files, optional skills load on demand, provider routing is explicit, and extensions can be audited. It also transfers work to the developer. A team must choose, review, and maintain those layers instead of relying on a vendor's defaults.
The small toolset does not eliminate agent failures. Models can still misuse the shell, lose details during compaction, follow bad project instructions, or produce incorrect code. Extensions and packages enlarge the trust boundary, while multi-provider sessions can behave differently after a handoff. Inspectability makes these problems easier to locate; it does not solve them automatically.
Pi is most distinctive as an embeddable, composable agent stack rather than as a lighter imitation of a commercial coding assistant. Its case rests on a practical proposition: when software can edit a repository and run commands, the instructions and mechanisms guiding it should remain visible.
Status: project and release details checked against the sources listed below on April 27, 2026.
Pi is open source under the MIT license. Repository: badlogic/pi-mono. Official site: pi.dev.
OpenClaw: openclaw/openclaw. Armin Ronacher's analysis: Pi: The Minimal Agent Within OpenClaw.
Primary update sources: Pi official site, Pi README, extensions docs, skills docs, packages docs, settings docs, GitHub release v0.70.2, GitHub release v0.70.1, GitHub release v0.70.0, and Ollama's Pi integration.
Terminal-Bench and historical snapshots: Zechner's November 2025 post, submitted Terminal-Bench result, and archived OpenClaw repository snapshots from January 30, February 2, March 1, and March 14, 2026.