This is an extension for Pi for spawning subagents, and for them to reserve/receive files and send/receive messages to one another.
All sessions auto-register immediately when they start; so when a new Pi session is started, it is already part of the collaborating agents system.
Install this extension and its included skill using either npm (recommended) or the git URL.
pi install npm:@baochunli/pi-collaborating-agentspi install https://github.com/baochunli/pi-collaborating-agentsUse the command:
pi configTo confirm that the collaborating-agents extension and the collaborating-agents-system skill have been activated. Use Esc to leave the configuration session.
To uninstall this extension:
pi remove npm:@baochunli/pi-collaborating-agentsor (if you installed using git URL):
pi remove https://github.com/baochunli/pi-collaborating-agentsThe /agents slash command opens an integrated agents and messages overlay with four tabs:
Agentstab contains a list of all active and recently completed agents, and it allows the user to switch to the selected active session and tracks the target session in real time.Feedtab shows recent message activity across agents.File reservationstab shows active reservation patterns and which agent currently owns each one.Chattab provides a shared chat stream and input box for@allbroadcasts and direct@AgentNamemessages.
Newly-started agents show up immediately; if their transcript file is not persisted yet they are marked session pending. Completed subagents remain visible in the Agents tab as completed until the next time an orchestrator agent spawns new subagents, which clears prior historical completed-subagent entries from that list.
Messaging input is available in the Chat tab. Use @AgentName message for direct messages or @all message for broadcast. Prefix the message body with !! to mark it urgent.
Examples:
- Direct:
@BlueFalcon Status update: parsing complete. - Direct + urgent:
@BlueFalcon !! Need your decision now. - Broadcast:
@all Wave 2 complete. - Broadcast + urgent:
@all !! Stop edits in src/server/ until migration finishes.
The user can spawn a single subagent manually in the background using the /subagent [type] <task> slash command. It uses the default subagent type (worker/default) from this extension by default, but you can also specify a subagent type to use specialized configurations. All agents use readable two-word callsigns (for example: SilverHarbor). An immediate Spawning subagent ... status message with runtime name and prompt will be shown immediately.
# Use default subagent type
/subagent "Implement user authentication"
# Use a specific subagent type
/subagent scout "Find all TypeScript files in the project"
/subagent documenter "Write API documentation for the auth module"
/subagent reviewer "Check for security issues in src/auth/"The parent (orchestrator agent) sessions automatically collect final subagent outputs on completion (single and parallel), without requiring subagents to send a separate final direct message summary. All direct subagent → parent status messages are optional, but are useful for blockers/questions only. Inbox delivery uses Pi's message routing: normal messages are queued with followUp, and urgent: true messages interrupt immediately with steer.
The following tools are provided for agents to call autonomously. Users should use the slash commands above.
The extension provides a dedicated agent_message tool for autonomous agent-to-agent messaging.
Actions:
status– current identity, focus mode, peer count, and your reservation countlist– list active agents (includes reservation counts when present)send– send direct message (to+message, optionalurgent)broadcast– send to all active peers (message, optionalurgent)feed– recent global message log (limitoptional)thread– direct-message thread with one peer (to,limitoptional)reserve– reserve files/directories for write/edit coordination (paths, optionalreason)release– release reservations (pathsoptional; omit to release all)
Reservation patterns are validated. Empty patterns are rejected, and broad patterns (for example ., /, ./, ../, or a top-level directory like src/) are allowed but return warnings.
Examples:
agent_message({ action: "list" })
agent_message({ action: "send", to: "BlueFalcon", message: "I finished parsing" })
agent_message({ action: "send", to: "BlueFalcon", message: "Need your decision now", urgent: true })
agent_message({ action: "broadcast", message: "Wave 2 complete" })
agent_message({ action: "thread", to: "BlueFalcon", limit: 10 })
agent_message({ action: "reserve", paths: ["src/server/", "src/routes/account.tsx"], reason: "auth refactor" })
agent_message({ action: "release", paths: ["src/server/"] })
agent_message({ action: "release" })The extension also provides a lightweight subagent tool for agents to call when they need to spawn subagents.
Modes:
- Single:
{ task }or{ type, task } - Parallel:
{ tasks: [{ task, cwd? }, ...] }or{ type, tasks: [...] }
Parameters:
task(string, optional) – Task prompt for single-modetasks(array, optional) – Array of task objects for parallel-modetype(string, optional) – Subagent type to use (e.g., "scout", "documenter", "reviewer")cwd(string, optional) – Working directory for spawned subagentssessionControl(boolean, optional) – Spawn with--session-control(default: true)
Examples:
// Default subagent type
subagent({ task: "Implement auth tags and report back via agent_message" })
// With specific subagent type
subagent({
type: "scout",
task: "Find all TypeScript files in the project"
})
// Parallel subagents
subagent({
tasks: [
{ task: "Implement backend pieces" },
{ task: "Implement frontend pieces" }
]
})
// Parallel with specific type (applies to all tasks)
subagent({
type: "documenter",
tasks: [
{ task: "Document backend API" },
{ task: "Document frontend components" }
]
})You can define custom subagent types using TOML configuration files. These allow you to create specialized subagents with different prompts, models, and reasoning levels.
Subagent type configurations are loaded in precedence order (later entries override earlier ones when names match):
- Bundled defaults:
examples/subagents/*.toml(included with this extension) - Global overrides:
- Preferred:
~/.pi/agents/*.toml - Legacy (still supported):
~/.pi/agent/subagents/*.toml
- Preferred:
- Project overrides (nearest ancestor to current cwd):
- Preferred:
<cwd>/.pi/agents/*.toml - Legacy (still supported):
<cwd>/.pi/subagents/*.toml
- Preferred:
This means the extension uses bundled examples/subagents out of the box, while user/project configs take priority when present.
Each .toml file defines one subagent type:
name = "scout"
description = "Exploration specialist for finding files and patterns"
# Optional: Override the model (defaults to parent session's model)
model = "openai/gpt-4o-mini"
# Optional: Set reasoning level (low, medium, high, xhigh)
reasoning = "low"
# Required: The system prompt for this subagent type
prompt = """You are a Scout subagent specialized in exploration...
## Guidelines
- Be quick and focused
- Use bash, find, grep efficiently
- Report findings in structured format
"""When no type is specified, the extension resolves the default in this order:
workerfrom user/project overridesdefaultfrom user/project overrides- bundled
workerfromexamples/subagents/*.toml - Bundled
examples/subagents/worker.toml - Emergency inline fallback (only if bundled files are unavailable)
To customize the default behavior, create worker.toml in ~/.pi/agents/ or your project’s .pi/agents/ directory.
The extension includes example configurations for common use cases:
| Type | Purpose | Reasoning |
|---|---|---|
worker |
General-purpose development tasks | medium |
scout |
Exploration and discovery | low |
documenter |
Documentation writing | medium |
reviewer |
Code review and analysis | high |
See the examples/subagents/ directory for complete example configurations.
Via slash command:
/subagent scout "Find all API endpoints in src/"
/subagent documenter "Write README for the auth module"
/subagent reviewer "Check src/auth.ts for security issues"Via the subagent tool:
// Single subagent with type
subagent({
type: "scout",
task: "Find all TypeScript files"
})
// Parallel subagents with types
subagent({
tasks: [
{ task: "Document auth module" }, // uses default/worker type
{ task: "Review auth module" } // uses default/worker type
],
type: "documenter" // applies to all tasks
})This extension supports both JSON config files and environment variables.
The extension loads and merges configuration in this order:
- Built-in defaults
- Global config:
~/.pi/agent/collaborating-agents.json - Project config:
<cwd>/.pi/collaborating-agents.json(overrides global)
Only positive numeric values are accepted. Invalid values fall back to defaults.
Default history depth used by the overlay feed/chat loader.
- Larger values allow more history at once but increase read/format work.
- Smaller values keep UI snappier in very high-message sessions.
This is a default baseline; runtime calls may still request larger limits.
Overrides the storage root used by the extension. Default:
~/.pi/agent/collaborating-agents
This affects:
registry/(active agent registrations)inbox/(per-agent inbound queue)messages.jsonl(global append-only message log)
Use this to isolate per-project state or relocate agent data.
Forces an explicit runtime agent name instead of auto-generated names.
Useful for deterministic scripts/tests or named coordinator sessions.
Recursion guard for nested subagent spawning.
PI_COLLAB_SUBAGENT_DEPTHtracks current depth.PI_COLLAB_SUBAGENT_MAX_DEPTHsets max allowed depth (default max is2).
If depth >= max, subagent spawn is blocked.
Messages use Pi's delivery system: normal messages queue until the recipient finishes their current turn, urgent ones interrupt immediately. No polling is needed.
Reservations are enforced by hooking Pi's edit and write tools. When an agent tries to edit a reserved file, the tool call gets blocked and the agent sees who reserved it, why, and a suggestion to coordinate via the agent_message({ action: "send", ... }) tool. Write and edit calls are blocked when another active agent has a matching reservation. Reads remain allowed.
States in this extension are stored at ~/.pi/agent/collaborating-agents/:
.pi/agent/collaborating-agents/
├── registry/ # One JSON file per agent
├── inbox/{name}/ # Inbound messages as JSON files, watched with fs.watch, one directory for each agent
└── messages.jsonl # Append-only log of all messages in the system
To run all tests:
bun test