pi-herdr-orchestrator0.6.1
herdr-backed subagent orchestrator for the Pi coding agent: real panes, per-agent result contracts, and local deterministic task/result gates
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-herdr-orchestrator
Subagent orchestration for the Pi coding agent, built on herdr panes.
Every subagent is a real Pi session in a real terminal pane you can watch, attach to, and scroll. Results come back through files and wake the parent session — no polling loops, no screen scraping, no stale pane handles.
Why panes
An in-process subagent is invisible until it finishes. This extension takes the opposite stance: each subagent gets a pane, a shell, and a written contract, so a stuck agent is something you can see instead of something you infer from silence.
- Visible work —
herdrtab holds one pane per subagent; the shared tab is bound to the parent's workspace. - File-based results — the child writes
result.md; the parent reads it. A crashed pane never loses a finished report. - Contract in the prompt — five required sections: what was done, files changed, verification level, blockers and risks, remaining work.
- Structured wakeups — the parent session is woken with a classified outcome (
done,blocked,no_result,failed,timeout), not raw terminal text.
Install
pi install npm:pi-herdr-orchestrator
Prerequisites:
- herdr running, with its Pi integration installed:
herdr integration install pi. - Pi with
before_agent_start.systemPromptOptionssupport (verified on Pi 1.4.0).
Local development:
git clone <this repo> ~/code/pi-herdr-orchestrator
ln -s ~/code/pi-herdr-orchestrator ~/.pi/agent/extensions/pi-herdr-orchestrator
Agent guidance is part of the plugin
The extension owns its orchestration instructions in src/guidance.ts. At
before_agent_start it adds the herd_orchestration system-prompt section only
when herd_spawn is selected and not hidden. If the tool is unavailable, the
extension removes its own section without touching other prompt sections.
Subagents do not load the orchestrator and receive no parent guidance.
No copy/paste into AGENTS.md is required. The contract opens with the
when to delegate — parallel branches, long search that should return only a
summary, independent review of the parent's own diff — and the four cases that
stay inline (tiny edits, Q&A, cross-turn conversation, meta work). Keep
host-specific safety policies
there, not plugin tools, defaults, or implementation details. When migrating an
existing setup, first activate the updated plugin, then remove the old
orchestration section from the global AGENTS.md. Source edits alone do not
update an installed npm package; do not remove the old guidance before deploying.
One entry point: /herdr
Available in both the parent session and subagent panes.
- Bottom-docked selector that renders in the editor area, so it never fights terminal images or overlays.
- The main list shows only live or retained subagents; finished work is folded into
📁 Archive (N tasks). Enterfocuses a subagent's pane, or opens its report when the pane is gone.Escreturns.✕ Close all subagentssits at the end of the list and asks for confirmation.- In a subagent pane, the first row returns you to the main session.
Activity card above the editor (Tasks): ⠏ running, ? blocked, + done, ! no result, x failed. Rows for successful runs that already exited are dropped after 30 seconds; blocked and failed rows stay until handled.
Tools
| Tool | Purpose |
|---|---|
herd_spawn |
Start a subagent: task, optional definition, cwd, files, async, keepAlive, timeoutMs |
herd_status |
Snapshot of every subagent for this parent session |
herd_wait |
Block until a subagent reaches a terminal state |
herd_steer |
Send additional direction to a running subagent |
herd_reply |
Answer a subagent's question and resume it |
herd_close |
Close a subagent's pane (idempotent) |
Subagents get no orchestration tools, so delegation cannot nest.
Roles
Agent definitions live in ~/.pi/agent/agents/*.md and are re-read on every spawn — adding a role takes effect immediately, no reload.
---
name: designer
description: UI/UX layout and frontend styling.
model: local-cpa/gpt-6.1-sol
thinking: high
tools: [read, grep, find, ls, bash, edit, write]
---
You own only the explicitly assigned UI surface...
- Roles come from
~/.pi/agent/agents/and nowhere else. Omittingmodel/thinking/toolsmeans inherit, so a role is never silently completed from a file you did not write. descriptionis the routing hint:herd_statusprints the roster asname (model) — first sentence, and the model picks from it.- Seeded on first run only:
scout,worker,reviewerare copied into~/.pi/agent/agents/when that directory has no.mdfiles. After that the packaged copies are never read, so deleting a role really deletes it.
Task and result gates (local)
No network, no API key, no model call: both gates are deterministic lints that ship with the extension.
- Task gate —
herd_spawnrejects a task that names neither a file path nor an acceptance bar. Anything less severe becomes ataskGate.missingnote inmeta.jsonplus a reminder line in the child's contract header. - Result gate — a result that is a lone
READY., shorter than 120 characters, or missing the required sections is reported asverdict: suspectin the wake-up message.
Definition routing
There is no router. herd_status prints the roster — name (model) — when to use it — alongside the session's agents, and herd_spawn requires a definition from it. An unknown name is an error, never a substituted default: a child running under the wrong role and model is a silent permission bug.
Agent definitions are owner-only
A definition pins the model, thinking level and tool set of every future child, so children cannot create or edit one. child-ui.ts blocks write/edit calls whose path is under ~/.pi/agent/agents/ (and shell redirects that touch it), and the parent re-audits at terminal state: any definition file that appeared while a child ran is moved to <run>/<label>/tampered/ and reported.
Config lives at ~/.pi/agent/pi-herdr/config.json (override the root with PI_HERDR_ROOT).
Layout on disk
~/.pi/agent/pi-herdr/
├── config.json
└── runs/<parentSessionId>/<label>/
├── meta.json # state, pane id, herdr name
├── task.md # the handed-off task
├── log.jsonl # lifecycle events
├── ask.json # present while blocked on a question
└── result.md # written by the subagent
When a subagent misbehaves, read meta.json and log.jsonl before guessing.
Notes and limits
- A subagent that ends its turn without writing
result.mdis asked once to dump the report ("rescue") and getsrescueMs(default 180000) to do it before the pane is closed. SetrescueMs: 0to disable. - A wait budget (
timeoutMs, default1800000= 30 min) is the caller's, not a global rule: when it expires the run is classifiedtimeout, rescued, then closed. /reloadkeeps that session's subagents running and re-attaches to them on the way back (keepChildrenOnReload, default true). A real quit still closes them, even withkeepAlive: true.- In
pi -p(non-interactive) mode,async: truesubagents are killed when the parent exits. Useasync: falsethere. - A subagent that only replies
READY.gets classified asno_result— write the report toresult.md.
Development
npm test # unit + lifecycle tests
npm run test:herdr # opt-in: real herdr panes, parent/child navigation, no model calls
DESIGN.md records the design and an appendix of assumptions that real runs disproved.
中文速览
pi install npm:pi-herdr-orchestrator
herdr integration install pi
/herdr:底栏选单,只列活跃/保留子任务,历史进📁 Archive;可跳 pane、返回主窗口、确认后全部关闭。- 子 agent 结果写
result.md,父会话读到终态后自动唤醒;blocked保活,用herd_reply回答后继续。 - 角色定义放
~/.pi/agent/agents/*.md,每次派活重读,无需 reload。 - 编排指引由插件自动注入,无需复制到全局
AGENTS.md;主机安全限制仍保留在该文件中。 /reload默认保留并重新接管本会话子 agent;真正退出仍会关闭它们。pi -p场景用async: false。
License
MIT