Skip to main content
Pi is a first-class Observal harness integration. Observal can install Pi agent profiles, configure MCP servers, expose skills, install the telemetry extension, and collect Pi session telemetry.

Overview

Pi is harness-centric: the whole of Pi is one agent. There is no per-agent profile file the way Kiro or OpenCode have one. Instead, Observal writes the agent’s rules into AGENTS.md, which becomes Pi’s system prompt, and writes MCP servers and skills next to it. To let several registry agents coexist, a user-scope observal agent pull writes each agent into its own profile directory under ~/.pi/agent/agents/{agent}/. The Observal extension’s /agent command swaps a profile into the live ~/.pi/agent/ location. A project-scope pull writes the rules straight to the project’s AGENTS.md, which Pi reads directly. Pi session telemetry uses an in-process TypeScript extension, ~/.pi/agent/extensions/observal.ts. It is installed by observal doctor patch and is shared by every agent; agent pulls do not embed telemetry hooks.

Supported capabilities


Setup

1. Install the Observal CLI

Pi 0.74.0 or newer is required by the telemetry extension.

2. Authenticate

This writes credentials to ~/.observal/config.json. Unless you pass --no-setup or --output json, login then installs the bundled Observal skills into every detected harness (Pi counts once ~/.pi/ exists) and runs observal doctor, which warns if the Pi telemetry extension is missing or stale. A healthy install prints no Pi warning.

3. Pull an agent into Pi

Pi’s default scope is user scope. The agent is written to ~/.pi/agent/agents/{agent-name}/. To install into the current project:
Project pulls write the rules to AGENTS.md in the project root, which Pi reads directly, and the agent’s MCP servers and skills to .pi/agents/{agent-name}/. Pi loads project MCP servers from .pi/mcp.json and project skills from .pi/skills/{name}/SKILL.md, and /agent handles only user-scope profiles, so activate them by hand:
Merge instead of copying if .pi/mcp.json already lists other servers.

4. Install or refresh the telemetry extension

This writes the bundled extension to ~/.pi/agent/extensions/observal.ts when it is missing, and refreshes a copy Observal recognises as its own when that copy has fallen behind or been edited, recording the CLI version it came from in an adjacent .observal-extension.json. A file Observal did not write is reported and left alone. If npm:observal-pi is registered in ~/.pi/agent/settings.json, that takes precedence: nothing is installed locally, and a local copy Observal recognises as its own is removed (kept as observal.ts.bak) so Pi does not load the extension twice. A local file Observal did not write is left alone. Restart Pi or run /reload afterwards. doctor patch refuses to run until observal auth login has written a server URL, although it does not contact the server.

5. Activate the agent inside Pi

Inside a Pi session, run /agent and pick the pulled agent. See Agent profiles and swapping.

6. Check what is installed


Config paths

Pi MCP configs use the mcpServers key.

Agent profiles and swapping

Because Pi reads a single AGENTS.md, mcp.json, and skills/ directory, only one Observal agent can be active at a time. In user scope, observal agent pull does not touch the active files. It writes into the per-agent profile directory, and the extension’s /agent command makes a profile active:
  1. On first use, /agent backs up the current AGENTS.md, SYSTEM.md, mcp.json, skills/, and sandboxes/ into ~/.pi/agent/agents/default/.
  2. It removes the active AGENTS.md, SYSTEM.md, mcp.json, skills/, and sandboxes/, then copies in whichever of those the chosen profile contains. Items the profile lacks stay absent until you swap back to default.
  3. When Observal credentials are configured, it records the chosen agent as active_agent in ~/.observal/config.json and refreshes the layer snapshot.
  4. It offers to reload the session so the new system prompt takes effect.
Run /agent with no argument to pick from installed profiles, or /agent <name> to swap directly. Choose default to restore the backed-up configuration and clear the active agent. /agent lists only user-scope profiles under ~/.pi/agent/agents/.

Extension spec

Observal installs a TypeScript extension named observal.ts. It has no runtime dependencies beyond node:* built-ins and is fail-open: telemetry failures never interrupt Pi. Ingest and checkpoint calls time out after five seconds, and the layer-snapshot upload after ten. The extension also registers two commands, /agent and /obs-sync: doctor patch compares the installed file with the bundled source and replaces stale copies.

Attribution

Pi does not expose an Observal agent id in its session file. The extension resolves attribution from Observal’s own state:
  1. observal agent pull records the agent name, id, version, scope, pull time, and directory under the pi harness in ~/.observal/lockfile.json.
  2. The pull also records that agent as active_agent in ~/.observal/config.json, and /agent updates the entry whenever you swap profiles.
  3. On session_start, the extension reads active_agent and looks it up in the lockfile entry for the configured server URL, matching by id first and then by name.
  4. The session payload is sent with the resolved agent_id and agent_version.
  5. If there is no active_agent, or it has no id, the session is sent with a null agent id. If there is an active_agent but no lockfile match, the stored id is sent as-is; no directory-based guessing takes place.

Session push behavior

The Pi extension implements the same acknowledged delivery contract as the Python harnesses:
  1. Resolve the session JSONL file and id from Pi’s session manager.
  2. Read complete records after the acknowledged byte and line cursor in ~/.observal/sync_state.json.
  3. Persist each pending batch under ~/.observal/pi_session_outbox/ before network delivery, in chunks of at most 500 lines.
  4. Retry the batch idempotently until the server returns a contiguous acknowledgement covering it.
  5. Advance the local cursor only to that acknowledged checkpoint.
  6. On session_shutdown, send a SHA-256 audit manifest and replay any range the server asks to repair.
  7. On the next startup, retry every pending outbox batch, then re-push unfinished sessions from the current project that changed within the last seven days until five have been finalized. Attempts that fail do not count toward the five. A missing or corrupt cursor is rebuilt from the server checkpoint on the next push.
Pi’s pending batches are the files under ~/.observal/pi_session_outbox/. observal ops telemetry status reports server ingest health and the Python exporters’ outbox; it does not count this directory.

Agent profile format

Observal writes the agent’s rules as plain Markdown into AGENTS.md. Pi loads that file as the system prompt, so the whole file is the agent:
There is no frontmatter and no model field. observal agent pull does not write a model into Pi’s configuration; the model is chosen inside Pi.

Skill file format

Pi skills live at: Example:
When Codex is also installed, the bundled Observal skills are written once to the shared ~/.agents/skills/{name}/SKILL.md location, which both harnesses read, instead of being duplicated under ~/.pi/agent/skills/.

Caveats

One active agent at a time. A user-scope pull does not activate the agent. Run /agent inside Pi, or copy the profile into ~/.pi/agent/ by hand. /agent does not see project-scope profiles under .pi/agents/; copy their mcp.json and skills/ into .pi/ as shown in Setup step 3. /agent replaces the active files. The first swap backs up your existing AGENTS.md, SYSTEM.md, mcp.json, skills/, and sandboxes/ into the default profile. Later swaps remove those five items and install only what the chosen profile contains, so a profile without SYSTEM.md leaves Pi with no SYSTEM.md. Edit the profile directory, not the active files, if you want changes to survive a swap. The extension is shared per Pi install. It is installed by doctor patch, not by each agent pull, and lives only in user scope. Guidance files are scanned, with two exceptions. Observal layers AGENTS.md, .pi/SYSTEM.md, and .pi/APPEND_SYSTEM.md as context. Scanning and observal agent pull never rewrite the project’s .pi/SYSTEM.md or .pi/APPEND_SYSTEM.md. A project-scope pull does write the project’s AGENTS.md, because that file is the agent’s rules in Pi, and /agent swaps do replace the user-scope ~/.pi/agent/SYSTEM.md as described above. Attribution depends on the lockfile and /agent. A profile copied by hand does not update active_agent, so its sessions keep whatever binding ~/.observal/config.json already holds, or carry no agent id if it has none. MCP config is Pi-specific. Pi uses mcp.json with the mcpServers key under .pi/ or ~/.pi/agent/, not Claude Code or Kiro MCP paths.