Skip to content

The harness

Owners: pi-extensions (read at 7cb808e), pi-toolkit (read at 7c05901), the shared fleet extensions in docker-compose-repo common/pi (read at dc3770f), and the upstream pi packages

The harness is everything around the model that decides what the agent can see and do. The model only produces text. The harness turns that text into tool calls, decides which tools exist, checks calls before they run and shows the person what is happening. pi is built to be extended, and most of what makes this setup different from plain pi lives here.

How pi is extended

Mechanism What it is Ours come from
Extensions TypeScript modules loaded into the pi process. They add tools and commands, react to events (such as a tool call about to run), and draw parts of the screen. pi-extensions and mempalace-toolkit, baked into the image; the fleet extensions, mounted read-only from docker-compose-repo and linked in at start
Packages bundles of extensions and resources, listed in the settings pi-fork, pi-observational-memory, pi-atelier and, in the -studio image, pi-studio
Settings ~/.pi/agent/settings.json: default model, effort tiers, package options a template in pi-toolkit, merged into existing settings at container start without overwriting what you changed
Models models.json: extra model providers the fleet's shared models.json, which adds ERDC's chat models
Skills Markdown procedures the agent reads when a task matches see Skills and tools
Global instructions ~/.pi/agent/AGENTS.md, loaded into every session pi-toolkit's pi-global-AGENTS.md, to which the image build appends its own block

The fleet extensions and models.json are mounted from one directory in docker-compose-repo, so changing them needs no new image. A change to an existing file reaches a device with a git pull and a /reload. A new extension file is linked in at the next container start.

Delegating work: fork and task

An agent can hand part of a job to a child agent, which is a second pi process. What matters most is how much of the parent's session the child can see:

Level The child sees Tool
L0 only the goal task
L1 the goal and the names of files to read task
L2 the goal and facts the parent selected task
L4 the parent's entire session fork

A child that sees too much tends to finish the parent's pending work instead of its own, and in a long session it has overridden explicit prohibitions. A child that sees too little has to work out again what the parent already knows. The rule is to use the lowest level that can still do the job.

  • task runs the pi-task runner from pi-toolkit. The child gets a written specification and returns a checked pass or fail. Every directory it watches is compared before and after, and a change outside the allowed set fails the task. Each run leaves an audit record.
  • fork, from the pi-fork package, suits read-only exploration that needs the current conversation, or several independent opinions on one question.

The fork-gate extension turns a fork that should have been a task into a task.

Model tiers

Delegated work names an effort level instead of a model: fast for mechanical lookups, balanced for normal work, deep for design, security and hard debugging. The settings map each level to a provider and model, so a device can change which model does what without touching any instructions.

pi-task can also name a fallback model per level. A model can be unusable for reasons that have nothing to do with the task, such as an expired sign-in or a provider taking a model down for maintenance. pi reports such a failure as a normal run with an error message, and pi-task detects it and retries on the fallback.

The fleet uses two providers:

  • Amazon Bedrock is the default provider for sessions.
  • ERDC inference provides chat models and, through fleet extensions, models that do not chat: classifiers that score a text or image against a question (used by the guardrails and by check_screenshot), and tools for embeddings, reranking, speech, image segmentation and forecasting.

Staying signed in

Bedrock is reached with an AWS single sign-on session that expires. The aws-sso extension (pi-extensions) runs the sign-in again before a request fails, and you still approve it. It is off until a device enables it, and it acts only when something in the session actually uses Bedrock: the session model, the observational-memory model, or the model a delegated task would run on.

Working on another machine

ssh-controlmaster (pi-extensions) runs pi's file and shell tools on a remote host when pi is started with --ssh user@host. It opens one SSH connection at session start, and every tool call reuses it.

What the person sees

  • pi-atelier draws the terminal interface: a sidebar of panels, a status line and a theme. The fleet adds two panels. One keeps the agent's to-do list expanded while a turn runs. The other shows what delegated task runs and classifier calls cost, which atelier's own panels cannot see.
  • pi-studio (in the -studio image) attaches a browser workspace to a session, for editing prompts, previewing documents and running REPLs. The studio-demo repository is a plain-language guide to it.
  • notify sends a terminal notification when the agent has finished a long run and is waiting for input.

Smaller helpers

Extension What it does
git-checkpoint saves the working tree at the start of every turn, so /fork can restore files to an earlier point
ext-toggle /ext lists the installed extensions and switches them on or off without leaving pi
todo gives the agent a to-do list for multi-step work, stored in the session so it follows resumes and forks
check_screenshot asks a classifier whether a browser screenshot shows an error page or the expected content, so the agent only reads an image itself when something looks wrong

Sources

  • pi docs/how-pi-works.md, docs/configuration.md
  • pi-extensions README.md, docs/aws-sso.md
  • pi-toolkit README.md: "bin/pi-task", "Model fallback", "The context ladder"
  • docker-compose-repo common/pi/*.ts (file headers)
  • pi-devbox entrypoint-user.sh (settings merge, extension linking)