Pi-Mono

Anatomy of a Viral AI Agent Toolkit

Deep Dive into Pi's Architecture, Code & Culture

github.com/badlogic/pi-mono

The Creator: Mario Zechner

Austrian developer, 15+ years of open source

  • libGDX — Java game framework, millions of downloads
  • RoboVM — Java/Kotlin to iOS compiler
  • Spine — 2D skeletal animation tool
  • Angel investor, coach, serial builder
  • GitHub: badlogic

Philosophy

"If I don't need it, it won't be built. I'm a simple boy who likes simple, predictable tools."

Website: shittycodingagent.ai

(that's actually pi.dev)

Why Pi Blew Up

The OpenClaw Connection

  • Peter Steinberger (Austrian dev, PSPDFKit founder) built OpenClaw
  • OpenClaw = personal AI assistant running locally
  • Pi is the engine inside OpenClaw (via RPC)
  • OpenClaw went viral: 145,000+ GitHub stars in ONE WEEK (Jan 2026)

Triple Rename in 4 Days

Clawdbot → Moltbot → OpenClaw

(Anthropic trademark dispute)

  • Featured on Syntax FM #976 with Armin Ronacher (Flask creator)
  • MIT Technology Review's 2026 Breakthrough Technologies list

What is Pi-Mono?

AI agent toolkit monorepo — 7 packages

"Tools for building AI agents and managing LLM deployments"

  • pi-coding-agent — Coding agent CLI
  • pi-ai — Unified LLM API
  • pi-agent-core — Agent runtime
  • pi-tui — Terminal UI library
  • pi-web-ui — Web components
  • pi-mom — Slack bot
  • pi-pods — GPU pod manager

Key Facts

  • All TypeScript, MIT licensed
  • npm: @mariozechner/pi-*
  • 20+ LLM providers supported
  • Self-contained monorepo

By The Numbers

6 months of relentless shipping

0
Commits
0
Lines of TypeScript
0
Contributors
0
Releases
7
Packages
20+
LLM Providers

System Architecture

Five-layer stack

Applications pi-coding-agent, pi-mom, pi-pods
Agent Runtime pi-agent-core
LLM Abstraction pi-ai (20+ providers)
UI Libraries pi-tui, pi-web-ui
Consumers OpenClaw, custom apps, Slack

Package Dependency Graph

How the packages connect

pi-ai
pi-agent-core
pi-coding-agent
pi-mom
pi-pods
pi-tui
pi-web-ui

Hover over nodes to highlight connections. pi-ai is the foundation with no internal dependencies.

Technology Stack

Modern TypeScript, minimal dependencies

CategoryTechnology
LanguageTypeScript 5.9.2, Node.js ≥ 20, ESM
Buildtsgo (native TS compiler), Biome 2.3.5 (linter + formatter)
TestVitest 3.2.4
SchemasTypeBox (JSON Schema via types)
LLM SDKsAnthropic, OpenAI, Google AI SDKs
StyleTabs, 120 char width, indentWidth 3
Frontendmini-lit (tiny Web Components), Tailwind CSS v4
"If I don't need it, it won't be built."

Design Philosophy

pi-ai: Unified LLM API

The foundation layer — 20+ providers, one interface

Supported Providers:

  • OpenAI, Anthropic, Google
  • Azure, Bedrock, Vertex AI
  • Ollama, vLLM, xAI, DeepSeek
  • Mistral, Groq, Cerebras, SambaNova
  • Together, OpenRouter, Requesty
  • AI Gateway, custom OpenAI-compatible

Key Features:

  • Unified streaming via AssistantMessageEventStream
  • Progressive JSON parsing for tool calls
  • Token counting & cost calculation per provider
  • Thinking block cross-provider conversion
  • Prompt caching (Anthropic, OpenAI, Google)
  • ~12,207 lines auto-generated model definitions

pi-ai: Provider Registry

One interface, many backends

// Event types for unified streaming
type AssistantMessageEvent =
  | { type: "start" }
  | { type: "text_delta", text: string }
  | { type: "thinking_delta", text: string }
  | { type: "toolcall_delta", ... }
  | { type: "done" }
  | { type: "error", error: Error }

// Provider dispatch
const streamFunctions: Record<Api, StreamFunction> = {
  "openai-completions": streamOpenAICompletions,
  "anthropic-messages": streamAnthropic,
  "google-generative-ai": streamGoogle,
  // ... 15+ more providers
};

pi-agent-core: The Brain

Stateful agent runtime — only ~3,271 lines

  • Agent loop: prompt → LLM → tool calls → execute → repeat
  • Event-driven: AgentEvent types
  • Message types: User, Assistant, ToolResult + extensible custom
  • Tool validation with TypeBox schemas
  • Model switching mid-conversation (cross-provider)

AgentEvent Types:

agent_start
turn_start
message_update
tool_execution_start
tool_execution_end
turn_end
agent_end

Message Transformation Pipeline

How messages flow from app to LLM

AgentMessage[] (extensible app messages)
↓ transformContext() — prune/filter
AgentMessage[] (filtered)
↓ convertToLlm() — convert to provider format
Message[] (provider-compatible)
↓ LLM API call
AssistantMessageEventStream (streaming response)

pi-coding-agent: The Product

The user-facing coding agent — 63,036 lines (largest package)

4 Modes:

  • Interactive — Full TUI experience
  • Print — Single-shot output
  • JSON — Structured output
  • RPC — For embedding (OpenClaw uses this)

Key Features:

  • Extension system with 20+ lifecycle hooks
  • Session persistence with JSONL branching (git-like)
  • Context compaction (summarize old, keep recent)
  • Skill system (SKILL.md with YAML frontmatter)
  • Prompt templates & theme support

Extension Architecture

The spine of pi-coding-agent

ExtensionRunner dispatches events
Extension registered handlers, tools, commands
ExtensionRuntime shared state

20+ Lifecycle Hooks:

session_start
before_agent_start
tool_call
tool_result
context
before_send
message_update
turn_end
session_end
// ... and more

Interactive Mode Data Flow

From keystroke to tool execution

User types → Editor → onSubmit
↓
agent.prompt(text)
↓
Agent emits events → TUI subscribes & renders
↓
Tool calls → execute → result → next LLM turn
↓
Loop until assistant stops

pi-tui: Terminal UI Library

~17,388 lines of TUI magic

  • Differential rendering — only changed lines
  • Synchronized output — CSI 2026 for atomic updates, no flicker
  • Component-based architecture
  • IME support for CJK input methods
  • Inline images (Kitty/iTerm2 graphics protocol)
interface Component {
  render(width: number): string[];
  handleInput?(data: string): void;
  invalidate?(): void;
}

// Built-in components:
// Text, Input, Editor,
// Markdown, Loader,
// SelectList, Image

pi-tui: Rendering Pipeline

Zero-flicker terminal output

Component.render(width) → string[]
↓
Diff engine — compare previous vs current lines
↓
CSI 2026 synchronized output — atomic write
↓
Terminal — only redrawn lines update

Traditional TUI: clear screen → redraw everything → flicker. Pi-tui: diff → patch → no flicker.

pi-web-ui: Web Components

Reusable UI for AI chat interfaces

  • ChatPanel → AgentInterface → MessageList + InputArea
  • Storage abstraction (IndexedDB backend)
  • Pluggable tool result renderers
  • Artifact management (HTML, SVG, Markdown)
  • CORS proxy handling

No React

Uses mini-lit — a tiny Web Components library. Tailwind CSS v4 for styling. Zero framework dependencies.

pi-web-ui: Component Tree

Composable, framework-free architecture

ChatPanel                      // Top-level container
  |
  +-- AgentInterface            // Manages agent state
  |     |
  |     +-- MessageList          // Renders conversation
  |     |     |
  |     |     +-- MessageBubble    // User/assistant message
  |     |     +-- ToolResultView  // Pluggable renderers
  |     |     +-- ArtifactView    // HTML/SVG/MD preview
  |     |
  |     +-- InputArea            // Text input + controls
  |
  +-- StorageBackend            // IndexedDB abstraction

pi-mom: The Slack Bot

An AI agent that lives in Slack — and commits code

  • Delegates Slack messages to pi coding agent
  • Channel-specific conversation history
  • Self-managing: installs packages, configures credentials
  • Memory: global MEMORY.md + per-channel MEMORY.md
  • Custom skills (bash scripts with frontmatter)

The Bot Commits Code

"mom" has 18 commits in the repo. It autonomously writes and commits code via Slack.

  • Events: immediate, one-shot, periodic (cron)
  • Docker sandbox support

pi-pods: GPU Management

CLI for deploying vLLM on GPU infrastructure

Supported Providers:

  • DataCrunch, RunPod, Vast.ai
  • AWS EC2
  • Any Ubuntu + NVIDIA machine

Pre-configured Models:

  • Qwen, GPT-OSS, GLM
  • Auto-configures tool calling per model

GPU Intelligence

  • Memory allocation: 30% to 90% GPU
  • Multi-GPU: tensor/pipeline parallelism
  • Built-in agent CLI for testing agentic workloads

Event-Driven Everything

Two-level event system enables real-time UI without polling

pi-ai Level:

AssistantMessageEvent
  "start"
  "text_delta"
  "thinking_delta"
  "toolcall_delta"
  "toolcall_end"
  "done"
  "error"

agent-core Level:

AgentEvent
  "agent_start"
  "turn_start"
  "message_update"
  "tool_execution_start"
  "tool_execution_end"
  "turn_end"
  "agent_end"

Both use async iterators. Subscribe once, get every event. TUI, web, Slack — all consume the same stream.

Credential Detection Hierarchy

How Pi finds your API keys

1. User-provided apiKey (explicit in config)
↓ not found?
2. Function parameter (passed at call site)
↓ not found?
3. Environment variables (ANTHROPIC_API_KEY, etc.)
↓ not found?
4. OAuth refresh (token refresh flow)
↓ not found?
5. Error (clear message about which key is missing)

Session Persistence with Branching

JSONL with parent references — git-like conversation history

// Linear conversation
{ "id": "1", "role": "user", "content": "Fix the login bug" }
{ "id": "2", "parentId": "1", "role": "assistant", ... }
{ "id": "3", "parentId": "2", "role": "user", "content": "Now add tests" }

// Branch! Different follow-up from same parent
{ "id": "4", "parentId": "2", "role": "user", "content": "Actually, refactor instead" }

Why Branching?

Enables /tree command to browse conversation branches without creating files. Navigate alternate realities of your coding session.

Compaction Strategy

Lossy compression, lossless storage

// Before compaction
[old_msg_1, old_msg_2, old_msg_3, recent_1, recent_2]

// Token count exceeds limit? Compact!
→ [summary_of_old_messages, recent_1, recent_2]

// ~30% of original tokens

Lossy in Context

Old messages are summarized. Detail is lost from the LLM's perspective.

Lossless in Storage

Full history preserved in JSONL. You can always go back.

Extension Power

Extensions are first-class citizens

Extensions can:

  • Register tools, commands, shortcuts
  • Hook into 20+ lifecycle events
  • Block or modify tool calls and results
  • Replace the editor entirely
  • Add UI overlays
  • Persist state in sessions
  • Control tool activation
  • Run pre/post processing on messages
  • Inject system prompts
  • Define custom themes

Extensions are not plugins. They have full API access and lifecycle control. Think middleware, not add-ons.

Repo Stats Dashboard

Aug 2025 → Feb 2026

0
Total Commits
184
Days Old
129
Active Days (70%)
15.9
Avg Commits/Day
125
Peak Day (Jan 3)
6 mo
Total Duration

Commit Velocity Over Time

Exponential growth curve

85
Aug
53
Sep
129
Oct
280
Nov
872
Dec
1,224
Jan
277*
Feb

* Feb 2026: 9 days only (~31/day pace). Jan peak driven by OpenClaw virality.

Who Builds Pi?

Commit distribution by contributor

Mario (80.5%)
Community (18.3%)
Bots (1.2%)

Top Community Contributors:

ContributorCommits
Helmut Januschka64
Markus Ylisiurunen35
Aliou Diallo34
Sviatoslav Abakumov30
Nico Bailon28
Armin Ronacher (Flask!)20

The Night Owl Pattern

Commit activity by hour (CET)

Peak: Midnight–1am

282 commits at 00:00 CET. Secondary peak at 9–11pm.

Deep Trough: 5–10am

"This developer codes until sunrise."

No Weekends Off

Commits by day of week — remarkably uniform

428
Mon
406
Tue
414
Wed
446
Thu
429
Fri
403
Sat
394
Sun

"Uniform distribution — no weekend dip. 7 days/week for 6 months straight."

Release Velocity

178 releases in ~85 days = 2.1 releases/day average

v0.0.1 First release — the beginning
Nov 20 10 releases in one day — single-day record
Feb 5 7 releases in 4 hours — speed record
v0.52.9 Latest — 178th release

Lockstep Versioning

All 7 packages share the same version number. One bump, one release, all packages.

AI-Native Development

AI is woven into every layer of the project

  • AGENTS.md: 216 lines of AI agent instructions
  • .pi/ directory: custom extensions and prompts for the project itself
  • "mom" bot: 18 autonomous commits via Slack
  • Co-Authored-By: Claude headers in commits
  • CONTRIBUTING.md: "Using AI to write code is fine"
  • Pi is used to build Pi (dogfooding)
  • PR review via /pr prompt template
  • Multiple agents can work in parallel on same worktree

The tool builds itself. The bot commits code. The agents review PRs. This is what AI-native means.

The Approval Gate

Quality threshold without gatekeeping ideas

1. New contributor opens issue
↓
2. Maintainer comments "lgtm"
↓
3. GitHub Actions auto-adds to APPROVED_CONTRIBUTORS
↓
4. Now they can submit PRs
↓
5. pr-gate.yml auto-closes unapproved PRs

118 approved contributors — 40 unique external PR authors

Code Hotspots

File churn analysis — where the action is

FileChangesRole
interactive-mode.ts283Core UI — the TUI experience
agent-session.ts155Core agent session management
main.ts147CLI entry point
coding-agent
56.6%
ai
20.3%
web-ui
11.0%
tui
10.9%

Commit Message Discipline

43% conventional commits — trending toward consistency

488
fix
318
feat
145
docs
120
chore
73
refactor

Fix > Feat by 1.53x

"Fix fast, ship faster."

488 fixes vs 318 features. Maintenance-first mentality.

Package Activity Distribution

Where development effort concentrates

coding-agent
56.6%
ai
20.3%
web-ui
11.0%
tui
10.9%
agent-core
6.3%
mom
5.3%
pods
3.3%

The coding agent is the product; everything else is infrastructure. 77% of effort is in coding-agent + ai.

How to Ship Like Mario

Key lessons for software teams

  1. Minimal core, maximum extensibility — 4 built-in tools, everything else is an extension
  2. Trunk-based development — commit directly to main, no long-lived branches
  3. Ship multiple times per day — 2.1 releases/day average
  4. Dogfood your own tools — Pi is used to build Pi
  5. Gate contributions, not ideas — approval system lets anyone propose, quality filter on execution

AI-Augmented Development

Use AI agents to build AI agents

  • AGENTS.md as first-class documentation
  • Custom prompts for PR review and changelog
  • "mom" bot for autonomous maintenance
  • Multiple agents can work in parallel on same worktree

The Recursion

Pi builds Pi. The coding agent writes its own extensions. The Slack bot commits to the repo that defines it. This is recursive self-improvement in practice.

Community Building

Open source from day one

  • Approval gate creates quality threshold without gatekeeping ideas
  • 118 contributors in 6 months
  • "Using AI to write code is fine" — inclusive policy

Notable Contributors

  • Armin Ronacher — creator of Flask
  • Peter Steinberger — PSPDFKit founder
  • 40 unique external PR authors

Key Architectural Takeaways

  1. Provider abstraction is comprehensive — not just text: streaming, tools, thinking, caching, cost tracking
  2. Agent is transport-agnostic — browser, terminal, Slack, RPC — same core
  3. Sessions are first-class — JSONL branching, compaction, full history
  4. Extensions are not "second-class" — full API access, lifecycle hooks, can replace core components
  5. Skills are human + machine readable — YAML frontmatter + markdown, works for both developers and agents

agent37.club

agent37.club

github.com/badlogic/pi-mono

shittycodingagent.ai (pi.dev)

deepwiki.com/badlogic/pi-mono

mariozechner.at

Pi-Mono Deep Dive