pi-team-agent
v0.2.0
Published
Agent orchestration for pi: subagent_spawn (single/chain), mid-run steering via subagent_steer, AI-driven handoff to a fresh session, and /handoff
Maintainers
Readme
pi-team-agent
Agent orchestration extension for pi.
Spawns subagents in isolated pi RPC subprocesses so the dispatching session's
context stays clean, adds mid-run steering over the same persistent channel, and
provides a /handoff command to transfer context into a fresh session.
Features
subagent_spawn— delegate a task to a subagent in an isolated pi subprocess. Two modes:- single:
{ agent, task } - chain:
{ chain: [...] }(sequential,{previous}placeholder, stops at first failure) - For independent parallel work, issue several
subagent_spawncalls in one turn (pi executes tool calls concurrently); no separate parallel mode.
- single:
subagent_steer— inject a steering instruction into a running background subagent without restarting or aborting it.subagent_abort— kill a running background subagent's whole process tree.- Result discipline — model-visible output is capped at 50 KB; longer
results are written to
.pi/subagents/artifacts/and referenced by path. handofftool (AI-driven) — hand off to a fresh session with a clean context: pass a ready-made prompt (entry doc / spec references, no summarization) or a goal (the plugin summarizes this session with a cheap model), optionally switching the new session to a different model (e.g. a stronger frontend model). The new session starts working immediately./handoff <goal>command (human-driven) — same relay, but the generated handoff prompt opens in an editor for review before the switch.
Install
pi install npm:pi-team-agentFor development from this repository:
pi -e .Agent definitions
Markdown files with a small frontmatter block:
---
name: my-agent
description: What this agent does
tools: read, grep, find, ls
---
System prompt for the agent.tools: comma-separated whitelist. Omit to allow the default tool set.- Definitions carry no model — the dispatching model picks one per spawn via
the
modelargument (see Model routing), so a definition stays portable across hosts and pricing changes. A leftovermodel:field in old files is ignored.
Locations:
~/.pi/agent/agents/*.md— user-level, always loaded.pi/agents/*.md— project-level, requires per-invocation confirmation in untrusted projects (repo-controlled definitions can steer the model)
Model routing
Priority: the model argument of subagent_spawn / handoff > inherit the
dispatching session's model and thinking level. Agent definitions never pin a
model.
A model value is either a concrete provider/id, or a capability code:
four digits in fixed order — price / intelligence / speed / multimodal,
each 0–9 (shaped like a Unix permission mode: compact, fixed-width, one digit
per dimension).
// ~/.pi/agent/subagent-models.json
{
"acme/flagship": "8591",
"acme/swift": "3971",
"acme/mini": "1860"
}Each entry rates one model from the host's ~/.pi/agent/models.json. Ratings
are relative to the models listed in this file — nothing absolute: a price
of 8 just means "expensive compared to its fleet-mates". Higher price digit =
more expensive; multimodal 0 = text-only. pi's own metadata supplies the facts
(context window, accepted inputs) — this file only adds the four subjective
digits.
Codes are soft requirements. A request pays a penalty only where a model falls short — price above the requested level, or intelligence / speed / multimodal below it:
penalty = max(0, model.price − request.price) // cheaper than asked: free
+ max(0, request.intel − model.intel) // stronger than asked: free
+ max(0, request.speed − model.speed)
+ max(0, request.mm − model.mm)The lowest-penalty model wins; ties go to the cheaper model, then to file
order. A request can therefore never come up empty — a dispatcher asking for
the impossible ("dirt cheap AND genius") gets the closest fit instead of an
error, and subagent_spawn reports the model each task actually used in its
result details.
Examples:
"0000"— cheapest, no capability needs (the handoff summarizer uses this)"1990"— cheap-ish, smart, moderate speed, no multimodal needed"9999"— most capable, price no object
Validation fails loudly instead of silently falling back: every rated id must
exist in the host's models.json, and a model rated multimodal > 0 must
actually accept image input there. A bare model id that is itself four digits
is read as a code — address such a model as provider/id.
Migrating from 0.1.x
0.1.x mapped three capability labels (primary / vision / cheap) to
concrete ids. To migrate ~/.pi/agent/subagent-models.json:
- Keep the model ids (the old mapping values); drop the label keys.
- Rate each model with four digits (price / intelligence / speed /
multimodal) relative to the others in the list — the old
cheapmodel typically gets the lowest price digit, the oldvisionmodel a multimodal digit ≥ 1. Models that only accept text input must be rated multimodal 0. - Delete
model:lines from agent definition files; pass a model per spawn instead.
Development
npm install
npm test # unit + integration (integration spawns real pi subprocesses)
npm run typecheckLicense
MIT
