The Pi runtime is the foundation. It manages the complexity of the agent-LLM cycle so you don't have to.
Manages the message → thinking → tool calls → response cycle for every agent. Native streaming with automatic backpressure.
Anthropic, OpenAI, and custom providers. Authentication, retry with exponential backoff, and automatic fallback — no boilerplate.
Runs tools with configurable timeouts, JSON schema validation, and structured error handling. Results flow back into context automatically.
// Pi runtime Extension API interface
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
export default function myExtension(api: ExtensionAPI) {
// Register a new tool for the agents
api.registerTool("search_docs", {
description: "Search the project documentation",
parameters: { query: { type: "string" } },
execute: async ({ query }) => {
return await searchDocs(query);
}
});
// Register a CLI command
api.registerCommand("sync", async (args) => {
await syncProjectData();
});
}
Pi solves the single-agent problem. AgentOffice solves the orchestration problem.
| What Pi does | What AgentOffice adds |
|---|---|
| Manages the conversation loop per agent | Semantic routing across multiple agents |
| Executes registered tools | coms-net hub or NATS — teams communicate with each other, across any project |
| Authentication with LLM providers | Next.js portal — real-time supervision |
| Streams responses per agent | SSE routing:decision events for the portal |
| Extension API (registerTool, registerCommand) | A2A Protocol for external interoperability |
| Per-session context | 7-layer persona system with persistence |
The Pi runtime manages the lifecycle. Just install and import.
Scraping, fetch, and headless browsing for agents. Includes content extraction, screenshots, and browser control.
Secure sandboxed code execution for builder agents. Supports Node.js, Python, and shell with resource limits.
Persistent vector memory with a simple interface. Stores embeddings, semantic search, and context-aware retrieval.
AgentOffice ships with four Pi extensions that cover orchestration, communication, industry-standard protocols, and interoperability.
The core extension. Provisions the routing HTTP API and integrates the supervision portal. The entry point for every request. It's the same extension any agent can spin up on its own Pi to become a team in its own right — teams of teams, with no limit on depth.
Agent-to-agent communication hub. Namespaces isolated per project. Supports SSE endpoints for asynchronous communication.
Model Context Protocol with support for 3 transports. Compatible with any MCP server on the market.
Google Agent-to-Agent Protocol. Bidirectional communication with external agents. Discovery via well-known URL.
Configure multiple providers in the same cluster. Each agent can use a different model.
Claude 3.5 Sonnet, Opus, and Haiku. Recommended. Best-in-class reasoning and tool use.
"providers": {
"anthropic": {
"apiKey": "sk-ant-..."
}
}
GPT-4o, GPT-4 Turbo, and GPT-3.5. Solid tool integration. Native function calling support.
"providers": {
"openai": {
"apiKey": "sk-..."
}
}
Any provider with an OpenAI-compatible API. Works with Ollama and LM Studio for local use, with no API cost.
"providers": {
"custom": {
"baseUrl": "http://..."
}
}
{
"agents": [
{
"id": "orchestrator",
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"persona": "personas/orchestrator.md"
},
{
"id": "coder",
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"persona": "personas/coder.md"
},
{
"id": "reviewer",
"provider": "openai",
"model": "gpt-4o",
"persona": "personas/reviewer.md"
}
]
}
Connect any MCP server to the ecosystem. The right transport depends on your deployment environment.
Local process, no network. Maximum security — the MCP server runs as a child of the Pi process, communicating via stdin/stdout.
{
"transport": "stdio",
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem"
]
}
Remote server via EventSource. Stateful — keeps a persistent connection. Ideal for servers that hold state between calls.
{
"transport": "sse",
"url": "http://mcp-server:3001"
}
The newer MCP spec, stateless and production-ready. No persistent connection — scales horizontally with no session affinity.
{
"transport": "streamable-http",
"url": "http://mcp-server:3001"
}
Any capability your agents need can be wrapped as a Pi extension and distributed as an npm package.
Use the Pi runtime's ExtensionAPI to register tools, commands, and event handlers.
Add "my-extension" to the extensions array in settings.json.
import type { ExtensionAPI, ToolResult } from "@mariozechner/pi-coding-agent";
import { z } from "zod";
/**
* MyExtension — sample extension for AgentOffice
* Registers tools, CLI commands, and event handlers.
*/
export default function myExtension(api: ExtensionAPI) {
// ── Tool available to the agents ──────────────────────────
api.registerTool("fetch_data", {
description: "Fetch external data and return structured JSON",
parameters: z.object({
url: z.string().url().describe("Endpoint URL"),
timeout: z.number().optional().default(5000)
}),
execute: async ({ url, timeout }): Promise<ToolResult> => {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const res = await fetch(url, { signal: controller.signal });
const data = await res.json();
return { content: JSON.stringify(data, null, 2) };
} catch (err) {
return { isError: true, content: String(err) };
} finally {
clearTimeout(id);
}
}
});
// ── CLI command: agentoffice my-extension sync ────────────
api.registerCommand("sync", async (args) => {
const dry = args.includes("--dry-run");
console.log(`[my-extension] sync ${dry ? "(dry-run)" : ""}`);
if (!dry) await performSync();
});
// ── Lifecycle hook ─────────────────────────────────────────
api.on("agent:start", ({ agentId }) => {
console.log(`[my-extension] agent ${agentId} started`);
});
}
async function performSync() {
// your sync logic here
}
Five minutes to get your first agent running. The whole stack is open source.