Overview
Install
Coding Agent
pi-ai
Agent Core
Packages
Extend
Deploy
GitHub @badlogic
badlogic/pi-mono

Pi Agent

A minimal TypeScript toolkit for building AI agents and managing LLM deployments. Seven composable packages. MIT licensed. Built by Mario Zechner.

The Pi philosophy: No sub-agents baked in. No plan mode. No permission popups. No background bash. Instead, minimalist primitives and a robust extension system. Users build features they need; the core stays small, honest, and hackable.
TypeScript
MIT License
7 packages
20+ LLM providers
OAuth + API keys
Subscription auth

Explore the Guide

Install & Quickstart
Install globally, authenticate via OAuth subscription or API key, and start pi.
npmoauth
Coding Agent CLI
Slash commands, @-mentions, sessions, branching, keyboard shortcuts.
piTUI
pi-ai Library
Unified LLM API for 20+ providers with TypeBox tool schemas.
librarytypebox
Agent Core
Stateful agent runtime with tool execution and event streaming.
runtimeevents
All Packages
pi-tui, pi-mom, pi-web-ui, pi-pods — the supporting cast.
monorepotui
Extensions & Skills
TypeScript extensions, skills, prompt templates, themes, Pi Packages.
extensionsskills
Self-Hosted Deployment
Deploy pi-coding-agent as a Cloudflare Pages site using Wrangler.
cloudflarewrangler

Quick Links

Monorepo
badlogic/pi-mono
@mariozechner/pi-coding-agent
npm package
@mariozechner/pi-ai
Unified LLM library
Mario Zechner
mariozechner.at
Getting Started

Install & Quickstart

Pi installs as a global npm package. You can authenticate via OAuth using an existing Claude/ChatGPT/Copilot subscription, or provide an API key directly.

Install

# Install the coding agent globally npm install -g @mariozechner/pi-coding-agent # Launch pi

Auth Option A — Subscription OAuth

If you already pay for Claude Pro/Max, ChatGPT Plus/Pro, GitHub Copilot, Google Gemini CLI, or Google Antigravity, you can use your subscription without an API key.

pi # Inside the TUI: /login # Select provider — opens browser for OAuth flow

Auth Option B — API Key

export ANTHROPIC_API_KEY=sk-ant-... # or export OPENAI_API_KEY=sk-... # or any supported provider pi
Why subscription auth matters: Subscription OAuth lets you use Pi without paying twice. If you already have Claude Pro, you get Claude Sonnet/Opus access through Pi at no extra cost—same for ChatGPT Plus and Copilot.

First Prompt

# Interactive mode pi # One-shot mode pi "List all .ts files in src/" # Print mode for scripting pi -p "Summarize this codebase" # Pipe input cat README.md | pi -p "Summarize this text" # Specific model pi --model openai/gpt-4o "Help me refactor" # High thinking effort pi --thinking high "Solve this complex problem" # Restrict tools pi --tools read,grep,find,ls -p "Review the code"

Configuration Locations

PathPurpose
~/.pi/agent/settings.jsonGlobal settings (thinking level, theme, transport)
.pi/settings.jsonProject-level overrides
~/.pi/agent/SYSTEM.mdGlobal system prompt replacement
.pi/SYSTEM.mdProject system prompt replacement
~/AGENTS.md or ./AGENTS.mdContext file (or CLAUDE.md)
~/.pi/agent/prompts/Global prompt templates (invoked via /name)
~/.pi/agent/skills/Global skills (Agent Skills standard)
~/.pi/agent/models.jsonCustom model definitions
~/.pi/agent/themes/Theme files (hot-reload)
pi-coding-agent

Coding Agent CLI

A minimal terminal coding harness with four built-in tools: read, write, edit, bash. Everything else is opt-in via extensions.

Built-in Tools

read

Read files from the filesystem with line numbers. Supports ranges.

write

Create or overwrite files with specified content.

edit

Exact string replacement edits—diff-based, reviewable changes.

bash

Execute shell commands, capture stdout/stderr, and return output.

Slash Commands

CommandPurpose
/loginOAuth authentication flow (select provider)
/logoutClear stored credentials
/modelSwitch AI models interactively
/settingsConfigure thinking, theme, delivery mode
/treeBrowse session history and branches
/forkCreate a new session branching from current point
/newStart a fresh session
/compactSummarize older messages to recover context
/copyCopy assistant's last message to clipboard
/export [file]Save session as HTML
/skill:nameInvoke a loaded skill by name
/templatenameExpand a prompt template

Editor Features

@-mentions

Type @ to fuzzy-search and reference project files inline.

Multi-line

Shift+Enter for newline (Ctrl+Enter on Windows Terminal).

Image Paste

Ctrl+V to paste images, or drag-and-drop from the desktop.

Bash Injection

!cmd runs and sends output; !!cmd runs silently.

Keyboard Shortcuts

ShortcutAction
Ctrl+LOpen model selector
Ctrl+P / Shift+Ctrl+PCycle through scoped models
Shift+TabAdjust thinking level (off / low / medium / high)
Escape (x2)Open session tree navigator
Ctrl+OCollapse / expand tool output
Ctrl+TCollapse / expand thinking blocks

Session Management

Sessions persist as JSONL files with branching support. Every message can be the root of a new fork—experiment freely without losing prior work.

JSONL storageAppend-only, human-readable session history
Branching/fork creates a new branch at any point
Navigation/tree browses the session graph
Compaction/compact summarizes old turns to recover context window
Export/export session.html renders a portable view

Execution Modes

Interactive

Default TUI mode—multi-line editor, streaming, session branching.

Print (-p)

Non-interactive output for scripting and pipelines.

JSON

Structured output for programmatic consumption.

RPC

Integration with parent processes over stdio RPC.

SDK

Embed Pi directly into your own TypeScript applications.

@mariozechner/pi-ai

Unified LLM Library

TypeScript library providing unified access to 20+ LLM providers with automatic model discovery, token tracking, cost monitoring, and context persistence.

Design constraint: pi-ai only includes models that support tool calling. This makes it ideal for agentic workflows but means you won't find raw text-completion-only models here.

Supported Providers

OpenAI
Anthropic
Google Gemini
Google Vertex AI
Azure OpenAI
Amazon Bedrock
Mistral
Groq
Cerebras
xAI
OpenRouter
Vercel AI Gateway
MiniMax
Kimi / Moonshot
GitHub Copilot
Ollama / LM Studio / vLLM

Basic Usage

import { getModel, complete, stream } from '@mariozechner/pi-ai'; // Type-safe model discovery with auto-complete const model = getModel('openai', 'gpt-4o-mini'); const context = { systemPrompt: 'You are a helpful assistant.', messages: [ { role: 'user', content: 'Hello!' } ] }; const result = await complete(model, context); console.log(result.content, result.cost);

Streaming

for await (const event of stream(model, context)) { switch (event.type) { case 'text_delta': process.stdout.write(event.delta); break; case 'toolcall_delta': // Partial tool arguments as JSON stream break; case 'thinking_delta': // Reasoning content break; case 'done': console.log('Stop reason:', event.stopReason); break; } }

Tool Calling with TypeBox

import { Type, StringEnum } from '@mariozechner/pi-ai'; const tools = [{ name: 'get_weather', description: 'Get current weather', parameters: Type.Object({ location: Type.String(), units: StringEnum(['celsius', 'fahrenheit']) }) }]; const result = await complete(model, { ...context, tools });

Extended Thinking

// Unified reasoning across Claude, GPT-5, Gemini 2.5 await completeSimple(model, context, { reasoning: 'high' // 'off' | 'low' | 'medium' | 'high' });

OAuth Login

import { loginGitHubCopilot, getOAuthApiKey } from '@mariozechner/pi-ai/oauth'; const credentials = await loginGitHubCopilot({ onVerificationUri: (uri) => console.log('Visit:', uri) }); const { apiKey } = await getOAuthApiKey('github-copilot', auth);

Streaming Events

EventDescription
text_deltaStreamed response text chunk
toolcall_deltaPartial tool arguments (JSON streaming)
thinking_deltaModel reasoning content
doneCompletion with stop reason and token usage
errorFailure with any partial content preserved

Custom Endpoints

const ollamaModel = { id: 'llama-3.1-8b', api: 'openai-completions', baseUrl: 'http://localhost:11434/v1', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 32000 };
Cross-provider handoffs: Switch models mid-conversation while preserving thinking blocks and tool results. Thinking automatically converts to <thinking> tagged text for providers that don't support native reasoning.
@mariozechner/pi-agent-core

Agent Core Runtime

Stateful agent with tool execution and event streaming, built on pi-ai. This is the engine powering the coding agent and the foundation for your own custom agents.

Quick Example

import { Agent } from '@mariozechner/pi-agent-core'; import { getModel } from '@mariozechner/pi-ai'; const agent = new Agent({ initialState: { systemPrompt: "You are a helpful assistant.", model: getModel("anthropic", "claude-sonnet-4-20250514"), }, }); agent.subscribe((event) => { if (event.type === "message_update") { process.stdout.write(event.assistantMessageEvent.delta); } }); await agent.prompt("Hello!");

Message System

pi-agent-core distinguishes between two message formats:

AgentMessagesInternal format: user, assistant, toolResult, plus custom types
transformContext()Pre-LLM transformation hook (filter, summarize, redact)
convertToLlm()Bridge: AgentMessages → Messages that models understand
LLM MessagesThe subset of messages sent to the model

Event System

EventDescription
agent_startAgent run has begun
agent_endFinal event—no more loop events will fire
turn_startA new LLM-call-plus-tool-execution cycle begins
turn_endThe current turn completes
message_startNew assistant message begins streaming
message_updateContent delta for an in-progress message
message_endMessage fully assembled
tool_execution_startA tool call is about to execute
tool_execution_updateProgress update from the tool
tool_execution_endTool call completed with result

Tool Execution

Tools are defined with AgentTool using TypeBox schemas for parameters. Two execution strategies are available:

Parallel (default)

Preflight sequentially, then execute all pending tool calls concurrently. Faster for independent operations.

Sequential

Execute one-by-one in order. Safer when tool calls have implicit dependencies.

Tool contract: Tools must throw errors on failure rather than returning error messages. The beforeToolCall hook can block execution; afterToolCall post-processes results.

State Management

// Access agent state agent.state.systemPrompt agent.state.model agent.state.thinkingLevel agent.state.tools agent.state.messages agent.state.isStreaming agent.state.streamingMessage agent.state.pendingToolCalls agent.state.errorMessage // Assigning arrays copies the top-level array before storing agent.state.tools = newTools;

Advanced Features

Steering / Follow-up

Interrupt running operations or queue work to run after completion.

Custom Messages

Extend message types via TypeScript declaration merging—add your own discriminated variants.

Proxy Support

Browser apps can proxy through backend servers to avoid exposing keys client-side.

Low-Level API

Direct control via agentLoop for advanced use cases where the Agent class is too opinionated.

Monorepo

All Packages

Seven packages that compose together. Use the full stack, or pick pieces for your own project.

Package Map

MONOREPO STRUCTURE pi-mono/ ├── packages/ │ ├── ai/ # @mariozechner/pi-ai │ ├── agent/ # @mariozechner/pi-agent-core │ ├── coding-agent/ # @mariozechner/pi-coding-agent │ ├── tui/ # @mariozechner/pi-tui │ ├── web-ui/ # @mariozechner/pi-web-ui │ ├── mom/ # @mariozechner/pi-mom (Slack bot) │ └── pods/ # pi-pods (GPU deployment) ├── AGENTS.md # Development rules ├── test.sh └── pi-test.sh # Run from source

pi-tui

Minimal terminal UI framework with flicker-free rendering. Three-strategy rendering only updates what changed, and CSI 2026 synchronized output prevents visual tearing.

Components

Text, Input, Editor, Markdown, Loader, SelectList, SettingsList, Image, Box, Container

Editor

Multi-line editing, syntax-highlighted code blocks, vertical scrolling

Bracketed Paste

Handles large pastes exceeding 10 lines without input glitches

IME Support

CJK input methods with proper cursor positioning

Inline Images

Kitty or iTerm2 graphics protocols for rendering images

Autocomplete

File paths and slash commands with fuzzy matching

pi-mom — Slack Agent

An autonomous Slack bot powered by an LLM. Responds to @mentions, DMs, and can execute bash, read/write files, and manage its own development environment.

  • Self-managing: installs dependencies and builds custom CLI tools ("skills") on demand
  • Sandboxed: Docker containers by default, host mode available
  • Persistent: conversation history, files, and tools all in one controlled directory
  • Memory: global and per-channel memory files for cross-session context
npm install @mariozechner/pi-mom # Then create a Slack app with Socket Mode enabled # Set env vars: SLACK_BOT_TOKEN, SLACK_APP_TOKEN, etc.

pi-web-ui

Reusable web components for building AI chat interfaces. Built on mini-lit web components and Tailwind CSS v4.

ChatPanel

Primary high-level interface: messages + artifacts viewer

AgentInterface

Lower-level chat for custom layouts with attachments and thinking

Artifacts

JavaScript REPL, HTML, SVG, Markdown rendering

File Handling

PDFs, Word, spreadsheets, presentations, images

IndexedDB Storage

Sessions, credentials, preferences persist in the browser

Local Providers

Ollama, LM Studio, vLLM—plus automatic CORS proxy

pi-pods — GPU Deployment

A Node.js CLI for running large language models on remote GPU pods. Automates vLLM setup, configures tool calling for agentic models, and exposes OpenAI-compatible endpoints.

DataCrunch
RunPod
Vast.ai
Prime Intellect
AWS EC2
Any Ubuntu + NVIDIA
export HF_TOKEN=token export PI_API_KEY=key # Set up a pod with shared NFS storage pi pods setup dc1 "ssh root@1.2.3.4" --mount "nfs_command" # Start a model with smart GPU allocation pi start Qwen/Qwen2.5-Coder-32B-Instruct --name qwen # Interactive chat against deployed model pi agent qwen -i
Multi-model per pod: pi-pods automatically assigns models to different GPUs on the same machine. Configure memory fraction (30–90%), context window (4k–128k), and GPU count per model.
Customization

Extensions & Skills

The Pi philosophy is minimalism at the core, extensibility everywhere else. Four layers let you shape the agent to your workflow.

Four Extension Layers

Prompt TemplatesMarkdown files in ~/.pi/agent/prompts/ — invoke with /name
SkillsSKILL.md files following the Agent Skills standard
ExtensionsTypeScript modules registering tools, commands, shortcuts, UI
ThemesTheme files in ~/.pi/agent/themes/ with hot reload

Prompt Templates

# Create ~/.pi/agent/prompts/commit.md --- name: commit description: Review changes and write a commit message --- Review the current git diff. Write a conventional commit message following the project's style. Then propose running git commit with that message. # Invoke inside pi: /commit

Skills

Skills follow the Agent Skills standard: a SKILL.md file with YAML frontmatter describing the skill's purpose, plus supporting files (scripts, templates, references) in the same directory.

~/.pi/agent/skills/pdf-extract/ ├── SKILL.md # Metadata + instructions ├── extract.py # Supporting script └── README.md # Documentation for the skill # Invoke in pi: /skill:pdf-extract

Extensions (TypeScript)

Extensions are TypeScript modules that can register:

  • Custom tools (beyond read/write/edit/bash)
  • Additional slash commands
  • Keyboard shortcuts
  • UI components (leveraging pi-tui)
  • Transport implementations
  • Editor integrations
Community examples include: git checkpointing, SSH remote execution, MCP integration, custom code editors, plan mode, sub-agent spawners, and permission systems—all the things Pi deliberately doesn't bake in.

Pi Packages

Bundle prompts, skills, extensions, and themes into distributable Pi Packages. Ship via npm or git.

# Install from npm pi install npm:@foo/pi-tools # Install from git pi install git:github.com/user/repo # List installed packages pi list # Update all pi update # Enable/disable resources interactively pi config

Custom Models

Add providers that aren't in pi-ai's built-in registry via ~/.pi/agent/models.json, as long as they speak the OpenAI or Anthropic API dialect.

{ "models": [ { "id": "my-local-model", "provider": "custom", "api": "openai-completions", "baseUrl": "http://localhost:8080/v1", "contextWindow": 128000, "maxTokens": 32000 } ] }

Context Files

Pi loads AGENTS.md (or CLAUDE.md for compatibility) from your home directory or project root. This is where project-specific instructions live—coding conventions, architectural notes, don't-do lists.

Distribution

Cloudflare Pages Deploy

Deploy this documentation site (or your own pi-web-ui application) to Cloudflare Pages using the Wrangler CLI.

This Site's Deployment

The guide you're reading is a single-file HTML SPA deployed to Cloudflare Pages. Here's the exact flow:

# 1. Install Wrangler (once) npm install -g wrangler # 2. Authenticate (once) wrangler login # 3. Create the Pages project (once per project) wrangler pages project create pi-agent-guide \ --production-branch=main # 4. Deploy the directory containing index.html wrangler pages deploy pi-agent \ --project-name=pi-agent-guide \ --commit-dirty=true # 5. Verify curl -sI "https://pi-agent-guide.pages.dev/"

Deploy pi-web-ui Applications

pi-web-ui ships reusable components for building a full chat UI in the browser. Because it uses IndexedDB for session/credential storage, no server is required—deploy as a static site on Cloudflare Pages.

# Create a new pi-web-ui project mkdir my-pi-app && cd my-pi-app npm init -y npm install @mariozechner/pi-web-ui @mariozechner/pi-agent-core # Build (assuming Vite or similar) npm run build # Deploy dist/ to Cloudflare Pages wrangler pages deploy dist \ --project-name=my-pi-app \ --commit-dirty=true

Local Dev with Wrangler

# Preview this site locally cd pi-agent wrangler pages dev . # Opens http://localhost:8788

Auto-Deploy via Git

For production workflows, connect your GitHub repository to Cloudflare Pages via the dashboard:

  • Build command: npm run build (or empty for static)
  • Build output directory: dist (or . for static)
  • Every push to main triggers a production deploy
  • PRs get preview deployments on unique URLs

Environment Secrets

# Pages deployments never ship API keys # Use Cloudflare Workers as a proxy for secure key handling wrangler secret put ANTHROPIC_API_KEY wrangler secret put OPENAI_API_KEY # In your Worker, proxy to the LLM provider # The browser app points at the Worker, not directly at OpenAI
Security model: Never expose API keys in client-side pi-web-ui bundles. Route requests through a Worker that injects the key server-side. pi-ai supports a proxyUrl option precisely for this pattern.

Monitoring

Analytics

Cloudflare Pages Analytics shows visits, bandwidth, and geographic distribution for free.

Web Vitals

Built-in Core Web Vitals tracking—LCP, CLS, FID—for performance monitoring.

Access Rules

Add authentication via Cloudflare Access to gate internal tools.

Custom Domains

Point your own domain via the Pages dashboard; SSL is automatic.

pi-agent-guide
8 sections
MIT
pi-agent-guide.pages.dev/#home