pi-orchestrator-config
v4.6.0
Published
Orchestrator pattern for pi: specialist subagents, enforcement, code review loop, workflow commands
Readme
Pi Orchestrator Config
A pi package that implements an orchestrator pattern — the main agent delegates all work to specialist subagents.
What's Included
Extension: orchestrator
Single extension that provides:
| Feature | Description |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Subagent tool | Delegate tasks to specialist agents (single, parallel, chain, async modes); optional model param for model override |
| list_models | List available models and providers for subagent model override |
| Async background agents | Spawn agents in background with async: true — results surface automatically when complete. Fullscreen overlay dashboard with live output, keyboard nav, and kill support (/async-status, /async-kill). On acpx parents, optional async is coerced to sync; dream/cron need internal_operations_provider + internal_operations_model. cli-* providers support async natively (see dev-docs/cli-provider.md) |
| CLI / ACPX providers | Optional cli_agents / acpx_agents register cli-* / acpx-* via native createProvider (pi ≥ 0.84): /login cli-<agent> or /login acpx-<agent>, model refresh, filter when unavailable. Missing context window / maxTokens / cost filled from models.dev (~/.pi/pi-config/models.dev.json, 1-day refresh). Cold-start default restore (#753): gates startup|new, empty enabledModels, trusted project merge — see dev-docs/cli-provider.md. Headless Cursor --approve-mcps when CLI_APPROVE_MCPS is set (false opts out) or the process is a sidecar (SIDECAR_PORT; startSidecar() stamps it while running and restores it on close()). Executable sidecar consumers should call bindSidecarListenExit() so bind/stopped fatals exit 1. Headless Gemini defaults GEMINI_CLI_TRUST_WORKSPACE=true and preserves an explicit parent value (including false). |
| /btw command | Quick side questions without polluting conversation history — ephemeral overlay |
| /async-status command | Show status of background agents — select one for live output streaming |
| /async-kill command | Kill async agents (overlay picker or by name/id) |
| ask_user tool | Structured user input with options and free-text — used by workflows |
| Python/pip enforcement | Auto-fixes python/python3 → uv run python; blocks pip/pip3 — requires uv |
| Git protection | Blocks commits/pushes to main/master, merged branches, --no-verify, git add . |
| Remote script exec block | Blocks curl \| bash, eval $(curl), etc. Allows safe VAR=$(curl ...) variable assignments |
| Dangerous command gate | Confirms rm -rf, sudo, mkfs, etc. |
| Rule injection | Injects orchestrator routing rules into system prompt |
| Git status | Live git status in status line with colored icons — updates after every tool call. Shows clickable #N when the branch has an open PR. Last-activity clock ⏱ HH:MM (Xm/Xh ago) shows time since last response |
| Desktop notifications | Notifies via notify-send on task completion, waiting for input, and action required |
| File preview | Serves generated HTML/frontend files via HTTP for browser preview from container |
| Graft integration | When graft_enable=true, main agents and subagents query the local Graft graph before raw project navigation on substantive prompts. Children only consume graphs. Stale graphs remain usable, retrieval failures fall back to raw tools, and main processes coordinate rebuilds with a cross-process lock. |
| Pidash dashboard | Live web dashboard — multi-session monitoring, browser messaging, model switching, live session name updates, reasoning token display |
| Pidiff viewer | Per-project diff viewer with review comments — branch diffs, file tree, inline comments, git-based ignore rules |
| Dreaming | Background memory consolidation — extracts memories from sessions, deduplicates, maintains topic-based memory |
| Memory enforcement | Code-enforced memory entries — triggers on bash/tool/file events, actions: block, run_after, warn. LLM cannot ignore enforced rules. Dreaming-safe via (enforced) marker |
| Upgrade changelog | Shows release notes on session start after pi-config version upgrade |
| Task tracking | Structured task lists for multi-step workflows — live widget, progress tracking, reminder nudges (owned, based on @tintinweb/pi-tasks MIT) |
| Neovim integration | Send changed files and review findings to nvim's quickfix list — only active when running inside nvim |
| Inter-agent communication | P2P (/coms) agent communication — on-demand activation via slash command |
| Slash commands | /pr-review, /issue-review, /release, /review-local, /review-status, /query-db, /btw, /async-status, /async-kill, /status, /dream, /remember, /coms, /pi-config-settings, /mcpc connect — with autocomplete argument hints |
| GitHub autocomplete | Type # in the editor to get issue/PR suggestions from the current repo — lazy-loaded, 5min cache |
| Command arg completions | Tab-complete arguments for slash commands — providers and models for /external-ai, branches for /review-local, PR numbers for /pr-review, and more |
| Discord bot | Control pi sessions from your phone via Discord DMs — send prompts, answer ask_user dialogs, switch sessions |
Agents (26)
| Category | Agents | | -------------- | --------------------------------------------------------------------------------------------------------------- | | Languages | python-expert, go-expert, ts-expert, java-expert, bash-expert | | Infrastructure | docker-expert, kubernetes-expert, jenkins-expert | | Dev workflow | git-expert, github-expert, test-runner, test-automator, debugger | | Documentation | technical-documentation-writer, api-documenter, docs-fetcher | | Code review | code-reviewer-quality, code-reviewer-guidelines, code-reviewer-security, code-reviewer-docs, code-reviewer-spec | | Security | security-auditor | | Workflow | scout, planner, worker, reviewer |
Prompt Templates
| Prompt | Description |
| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /implement <task> | scout → planner → worker |
| /scout-and-plan <task> | scout → planner |
| /implement-and-review <task> | worker → 5 reviewers → worker |
| /pr-review [number\|url] | Fetch PR diff, check past review comments, review with guidelines, post and track comments |
| /issue-review | Review a GitHub issue spec and fix it |
| /release [flags] | Create GitHub release with changelog and version bumping |
| /review-local [branch] | Review local uncommitted or branch changes |
| /qodo-review [--autofix] [--fast\|--deep] [--ticket <url>] [path ...] | Review local changes with Qodo, attach session context, and optionally autofix (max 3 cycles) |
| /review-handler [url] [--autorabbit] [--autoqodo] | Process PR review comments, fix approved items |
| /domain-model [focus area] | Scan codebase and build/update a CONTEXT.md domain glossary for consistent AI vocabulary |
| /refine-review <url> | Refine and improve existing PR review comments |
| /coderabbit-rate-limit [number\|url] | Handle CodeRabbit rate limiting on PRs |
| /create-coms-feature-manager | Generate a coms feature-manager prompt customized for the current project (source template: templates/coms-feature-manager-prompt.md) |
| /query-db <command> | Query the review comments database |
| /external-ai <agent> [--model <model>] [--session-id <id>] [--fix\|--peer\|--resume] <prompt> | Run prompts via AI CLIs directly (cursor, claude, gemini) — full model access |
| /external-ai-models-refresh | Refresh cached AI CLI models for autocomplete |
| /dream | Run memory consolidation — extract, deduplicate, maintain topic-based memory |
| /remember <what> | Save a memory for future sessions |
| /dream-auto | Toggle automatic memory dreaming (every 3h + session end) |
| /cron add\|list\|list-all\|remove [--persist] | Schedule recurring tasks. Session jobs end with the session; --persist keeps a job across Pi sessions in this project. Add/remove mutations still work when leader election fails closed on an unsupported platform. For example: /cron add every 2h check for new issues --persist or /cron remove persist:<uuid>. /cron list opens an overlay for the selected jobs (or both when omitted). Persistent delivery is local at-least-once: a crash or leader recovery can repeat a run. Project cron writes use a stable OS flock (included in Docker via util-linux) across the entire transaction; native installations need flock and a shared filesystem that supports advisory locks. A busy or unavailable lock fails closed after two seconds. Upgrade gate (enforced): stop and drain every old Pi process writing crons on the shared mount before starting a version with this kernel lock; old directory-lock writers do not honor flock and must not resume. If a legacy crons.json.mutation.lock directory exists, new writes fail closed even if its PID is invisible or its heartbeat expired. Only after verifying every old writer cannot resume may an operator remove that stale directory (not crons.json or cron tasks). Never remove it merely because a write timed out. |
| /async-kill [name\|id\|all] | Kill async agents (overlay picker or by name/id) |
| /pi-config-settings [project\|global] | Interactive TUI settings editor — browse all pi-config settings with scope indicators, smart pickers for providers/models, and immediate save |
| /status | Unified session snapshot — async agents, cron tasks, git branch, context usage |
| /nvim-changed-files | Send git changed files to nvim's quickfix list (only inside nvim) |
| /pidiff start\|stop\|restart\|status | Manage the pidiff diff viewer server (per-project) |
| /coms start\|stop\|status | P2P local agent communication (Unix socket) |
| /mcpc connect | Connect MCP servers from ~/.pi/pi-config/mcp.json (mcpc connect --stdio). Run after editing that file. |
Inter-Agent Communication (coms)
Two systems for Pi agents to communicate with each other, activated on-demand via slash commands:
P2P Local (/coms) — Direct Unix socket communication between agents on the same machine. No server needed.
/coms start --name planner --purpose "Plans the work"
/coms stop
/coms statusTools available once activated:
| Tool | Description |
| -------------------- | --------------------------------------------------------------- |
| *_list | List peer agents with names, models, context usage, queue depth |
| *_send | Send a prompt to a peer agent |
| *_get | Non-blocking poll for a response |
| *_await | Block until response arrives |
| coms_queue_inspect | Preview owned queued P2P messages before recovery |
| coms_queue_clear | Irreversibly clear only an inspect preview |
Queue recovery is explicit. Run coms_queue_inspect first and review its
body-free preview. Then pass its preview_id to coms_queue_clear.
Reconnects and timeouts never clear queues. This recovers the local P2P coms
queue. Pi RPC hosts may separately offer clear_queue for their steering and
follow-up queue. It is a distinct queue and must also be previewed and cleared
explicitly. RPC preview tokens expire after five minutes, retain at most 20
entries per provider, and require a host-side atomic snapshot comparison before
clearing.
Forked from disler/pi-vs-claude-code coms extensions. We own these files — FIFO message queue, structured task delegation via coms protocol.
Installation
Docker (Recommended)
The recommended way to run pi-config is via the pre-built container image. It provides filesystem isolation, consistent tooling, and all dependencies pre-installed.
docker pull ghcr.io/myk-org/pi-config:latestSee the Docker section below for the full run command and shell alias.
Native (without Docker)
Install from npm and PyPI — no git clone of this repo:
pi install npm:pi-orchestrator-config
pi install npm:@myk-org/pi-vertex-claude # optional Vertex Claude models
pi install npm:pi-web-access # optional web search/fetch
uv tool install myk-pi-toolsOr run the interactive installer (downloads the script only; packages still come from npm/PyPI):
uv run https://raw.githubusercontent.com/myk-org/pi-config/main/scripts/install.pyIf you already have the dev clone:
uv run scripts/install.pyThe installer covers:
- Pi Packages — pi-config, pi-vertex-claude, pi-web-access, myk-pi-tools, bun
- Python Tools — prek
- npm Packages — mcpc, acpx, agent-browser, graft
- Browser Automation — playwright + chromium
- Environment Setup — gitignore configuration
For non-interactive (CI) usage:
uv run scripts/install.py --allUpdating
Docker
docker pull ghcr.io/myk-org/pi-config:latestThe container runs pi update automatically on each start.
Native
pi update # Pi package
uv tool upgrade myk-pi-tools # CLI toolAfter updating, run /reload in pi or restart pi to pick up changes.
Refresh the global agent package after acpx-provider / cli-provider / settings
changes so ~/.pi is not a mixed checkout (see issue #651).
Usage
Automatic delegation
Just describe your task — the orchestrator routes to the right specialist:
Add retry logic to the HTTP client in src/api.pyWorkflow prompts
/implement add Redis caching to the session store
/scout-and-plan refactor auth to support OAuth
/implement-and-review add input validation to API endpointsSlash commands
/pr-review 42
/release --dry-run
/review-local main
/query-db stats
/mcpc connectDirect subagent usage
Use python-expert to fix the type errors in src/models.py
Run scout and planner in a chain to analyze the auth moduleRun agent with specific model:
# Discover available models
list_models(provider="my-provider")
# Run agent with explicit model
subagent(agent="worker", task="...", model="my-provider/model-id")
# Parallel tasks with per-task models
subagent(tasks=[{agent: "worker", task: "...", model: "my-provider/model-id", cwd: "..."}])OpenAI-compatible model discovery
Set discoverModels: true on a static openai-completions provider in models.json to load
its /v1/models catalog at interactive session start. Discovery never writes models.json. It
augments the configured provider in Pi's runtime registry, so Pi's ordinary /model picker
displays each result under the exact configured provider key, for example
chatgpt-image-latest [litellm]. The selected model keeps that same provider key and streams
through the configured provider. Existing static models remain available. Only exact duplicate
returned IDs are deduplicated.
After discovery and runtime registration both succeed, Pi appends a durable transcript entry such
as Providers: litellm (242). The key and count come from that session's configured provider and
discovery response. Failed discovery or registration appends no entry, so a prior session's count
is never presented as current.
Each returned string ID remains selectable, including opaque, blank, and whitespace-preserved IDs.
Discovery materializes a complete Pi Model object for every result. It uses source metadata for
name, reasoning, input, cost, contextWindow, and maxTokens when the response provides
it. Missing or invalid metadata uses Pi's static-model compatibility defaults: reasoning: false,
zero costs, contextWindow: 128000, and maxTokens: 16384. Unknown input declares
['text', 'image'] so Pi can safely inspect model.input. That declaration only satisfies Pi's
model contract. It does not filter discovery results or claim that the endpoint accepts image input.
Code Review Loop
review_loop_enforcement controls automatic review-agent dispatch and commit enforcement.
trueautomatically dispatches 6 agents in parallel (5 reviewers +test-runner) after code changes and requires a clean review before commits.falsedisables automatic review-agent and test-agent dispatch. Manual reviews and test runs are optional. No review state, cycle, or result is required before commit.
When review_loop_enforcement is enabled, the loop stops once all reviewers approve with 0 findings and tests pass
(tests_passed: true in pi-config-review-state.jsonl). tests_passed is set only by a detected
successful test command; completion of async test-runner or test-automator agents does not set it.
OR after review_loop_max_cycles total cycles (default 3,
valid integers 1-10; env: digit string "1"-"10" only (after trim)) — whichever comes first. Each cycle
always completes fix/explain (5a) before the cap check; the cap only blocks re-dispatch
(step 2 / all 6 agents, including test-runner), not responding to findings.
At cap, report Not fixed (explained why not → outstanding) vs Fixed
(verification blocked by the cap — cannot re-dispatch to confirm clean). Invalid values (including non-digit
forms like "10.0" / "1e1") fall through to the next resolution layer / default 3. Disable the review loop via
review_loop_enforcement: false, not via max_cycles. Commit blocking is code-enforced via isCommitAllowed:
allows commit when isReviewClean (status: clean + tests_passed: true, or status: none), or when max cycles are exhausted
(status is has_findings or clean, no pending reviewers, cycle >= review_loop_max_cycles — no tests_passed requirement).
Review enforcement and dirty tracking are automatically skipped on chore/bump-version-<version> branches (e.g. chore/bump-version-4.2.1-1234567890, used by the release workflow).
Staged mode (--autorabbit/--autoqodo in /review-handler) shares one total review_loop_max_cycles budget
across both its Spec Compliance and Code Quality stages — not a separate cap per stage.
Use /review-status to inspect the current review loop state. Pass a worktree path to check a specific worktree (e.g., /review-status .worktrees/issue-42).
Customization
Project Settings
Copy the example file to your project and customize:
cp pi-config-settings.example.jsonc .pi/pi-config-settings.jsonSettings files support JSONC (JSON with // comments).
See pi-config-settings.example.jsonc for all available settings with descriptions.
Resolution order: project file → global ~/.pi/pi-config-settings.json → env var → default.
See dev-docs/project-settings.md for the full settings table.
Reviewer Environment Variables
These are set automatically by the orchestrator when spawning reviewer agents:
| Variable | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PI_REVIEW_BASE_BRANCH | Base branch for diff comparison (auto-detected from PR or falls back to main) |
| PI_HAS_PR | true if a PR exists for the current branch, false for pre-push reviews. When false, reviewers skip Review History and code-reviewer-spec runs a reduced flow (issue-only checks) |
Per-Project Resource Management
Use pi config -l to manage which resources (reviewers, skills, prompt templates) are enabled per-project:
pi config -l # Open project-local resource configPress Tab to switch between global and project-local views. This lets you disable specific reviewers or skills for a project without editing JSON files.
Override agents
Place a .md file with the same name frontmatter in ~/.pi/agent/agents/ (user) or .pi/agents/ (project) to override a bundled agent.
Priority: project > user > package (bundled).
Custom Rules
The orchestrator loads rules from three directories (later layers override same-filename entries):
| Layer | Path | Scope | Number range |
| ------- | ---------------------- | -------------------------- | ------------ |
| Package | <pi-config>/rules/ | All users, all projects | 00-69 |
| User | ~/.pi/agent/rules/ | All projects for this user | 70-89 |
| Project | <project>/.pi/rules/ | Current project only | 90-99 |
To add a custom rule, create a .md file in the appropriate directory:
# User-level rule (applies to all projects)
mkdir -p ~/.pi/agent/rules
cat > ~/.pi/agent/rules/75-my-rule.md << 'EOF'
# My Rule
Your orchestrator instructions here.
EOF
# Project-level rule (applies to current project only)
mkdir -p .pi/rules
cat > .pi/rules/90-project-rule.md << 'EOF'
# Project Rule
Project-specific instructions.
EOFRules auto-load alphabetically. Same-filename entries are overridden (project > user > package). Missing directories are silently skipped.
Conditional assembly
Rules support settings/feature conditionals at prompt assembly (assembleRuleText in
rule-placeholders.ts). Full syntax, truthiness, and assembly order:
dev-docs/project-settings.md (Rules assembly).
Markers: {{IF:key}}…{{/IF}}, {{IFNOT:key}}…{{/IFNOT}}, comparisons
{{IF:key==value}} / {{IF:key!=value}}. Whole-file frontmatter: requires_setting /
requires. Conditionals run per file (no cross-file matching), then bodies are
joined, then placeholders like {{REVIEW_LOOP_MAX_CYCLES}} are substituted.
Add project agents
Create .pi/agents/my-agent.md in your project with frontmatter:
---
name: my-agent
description: What this agent does
tools: read, write, edit, bash
---
Agent system prompt here.Project agents included by default (agentScope defaults to "both").
Image Generation
The generate_image tool creates images from structured descriptions via Gemini API.
Configuration:
Set image_model in pi-config-settings.json or use PI_IMAGE_MODEL env var.
| Setting / Variable | Description |
| ------------------------------------ | -------------------------------------------------------------------------------------------------- |
| image_model / PI_IMAGE_MODEL | Google/Gemini image model for generate_image (Settings TUI filters to google; empty = disabled). |
| GEMINI_API_KEY or GOOGLE_API_KEY | Gemini API key (env only) |
Usage: Ask naturally — "generate an image of a sunset" — or use structured params: subject, action, scene, composition, lighting, style, text, aspect_ratio.
In containers, images are auto-served via HTTP for browser preview.
Graft repository graph (optional)
Set graft_enable to true in .pi/pi-config-settings.json (or set
PI_GRAFT_ENABLE=true) to enable local Graft repository graph context:
{
"graft_enable": true
}Graft requires Node.js 22+, npm 12+, node-gyp prerequisites (Python 3, make, and
G++), and the graft CLI. The container includes them; native installs can use
uv run scripts/install.py. The installer downloads @nanonets/graft@latest with
scripts disabled into a dedicated npm prefix, audits that isolated dependency tree
for lifecycle scripts, and strictly rebuilds it with only those packages approved.
The completed prefix is then published under the global npm prefix and its graft
binary linked globally, so unrelated global packages are never evaluated. The
installer verifies graft --version; DO_NOT_TRACK=1 disables Graft telemetry.
When enabled, Graft reads the trusted project and writes a regenerable ./graft/
cache. Delete that directory or set graft_enable to false to disable it. If the
native CLI is unavailable or its installation fails, pi continues without Graft.
Cache Miss Notices
Enable showCacheMissNotices in pi settings to see transcript notices on significant prompt-cache misses — useful for investigating unexpected token costs:
pi config # Toggle showCacheMissNotices in settings UIDefaults to false. Enable when debugging cost spikes from cache invalidation.
Docker (Sandboxed Execution)
Run pi inside a disposable container for filesystem isolation — the agent can only access your mounted project directory and pi settings. Everything else on the host is protected.
Why?
- Safety — Prevents accidental
rm -rf, modifications outside the project, or unintended system changes - Filesystem isolation — pi can only read/write the mounted project directory
- Consistent tooling — All required tools pre-installed in a single image
- Disposable — Container is destroyed after each session (
--rm)
Graft (optional graft_enable): The image installs the latest
@nanonets/graft with DO_NOT_TRACK=1. It downloads with scripts disabled, derives
an exact script allowlist by auditing the installed package's reachable dependency
metadata in a dedicated npm prefix, then strictly rebuilds that isolated tree with
those approvals. Only after the rebuild succeeds is the completed prefix moved under
the global npm prefix and its graft binary linked globally. This prevents unrelated
global packages from entering npm's strict preflight. The allowlist is command-scoped
and changes with @latest; other npm commands keep npm 12's install-script
protections. The image includes Python 3,
make, and the GCC/G++ toolchain required by node-gyp for Graft and other native
npm packages; these remain available for reliable package rebuilds. The build then
verifies graft --version. Enable Graft in trusted project or global pi-config
settings; it reads the project locally and stores its regenerable graph in ./graft/. Set
graft_enable to false and delete that directory to disable and remove the cache.
Native installations require Node.js 22+, npm 12+, Python 3, make, and G++; the
installer uses the same audited strict installation and failure remains non-fatal.
Persistent cron locking: The image includes flock from util-linux for kernel-backed,
cross-container store mutations on shared mounts. The shared filesystem must support
advisory locks. Before deploying this version alongside old Pi containers, stop and
drain every legacy cron writer. An existing legacy mutation-lock directory blocks
new writes until an operator verifies old writers cannot resume and removes only
that directory. Do not stop running containers merely to test this PR.
CLI provider binaries (optional cli_agents): The image installs the CLIs used by
cli-* providers — claude (Claude Code), gemini (@google/gemini-cli), and
agent (Cursor Agent CLI). Enable with cli_agents in settings (e.g.
["claude","cursor","gemini"]). Binary missing at load → cli-* not registered.
After register, filterModels hides models when unavailable: PATH cleared while
agent state remains, restore PATH; after session_shutdown (AgentState cleared
and initialized reset) the next factory re-registers on /new|/resume|/fork
(PATH alone is not enough). See dev-docs/cli-provider.md.
ACPX provider agents (optional acpx_agents): ACPX wraps CLI agents via the
ACP runtime. Supported agents: cursor, claude, gemini. Enable with
acpx_agents in settings (e.g. ["cursor","claude","gemini"]). Each ACPX agent
requires the underlying CLI binary on PATH (agent for cursor, claude for claude,
gemini for gemini) — missing binary → acpx-* not registered.
CLI specialist agents (Cursor / Claude / Gemini): On container start, entrypoint.sh
symlinks package agents/*.md into the mounted project:
.cursor/agents/.claude/agents/.gemini/agents/
Uses ln -sfn (safe if multiple pi-docker sessions share the same folder). Those three
directories are added to the container global gitignore. Native installs do not auto-
sync — copy or symlink yourself (see dev-docs/cli-provider.md).
Extension ops logs: cli-provider and dreaming write to ~/.pi/logs/ (not the chat
UI). Fallback: $TMPDIR/pi-logs/. Details in dev-docs/cli-provider.md (Logging).
Pre-built image
docker pull ghcr.io/myk-org/pi-config:latestBuild from source (optional)
Note: The image is built for linux/amd64 only. On ARM hosts, build with
--platform linux/amd64.
gi