mjakl-pi-subagent

内容来源:README.md(说明文档) · 原始地址 · 查看安装指南

原始内容

Pi Subagent

Delegate prompts to specialized Pi subagents, optionally continuing named subagent sessions.

There are many subagent extensions for Pi; this one is mine.

User Guide

Why Pi Subagent

Specialization — Use tailored agents for review, research, testing, documentation, exploration, and other focused work.

Flexible Context — Let specialists start fresh, or give them the current conversation when that helps.

Named Continuation — Continue the same specialist conversation later for multi-step work.

Parallel Execution — Let the main agent ask multiple specialists at the same time.

Small Surface Area — Install the extension, define agents as Markdown, and let the main Pi agent handle delegation.

Features

  • Auto-Discovery — Agents are found at startup and listed in the main agent's system prompt.
  • Unified Delegation — One extension handles one specialist call or many parallel calls.
  • Named Persistent Sessions — Continue specialist subagents across multiple turns when useful.
  • Agent Session Guidance — Agent definitions can advise when persistent or ephemeral calls fit best.
  • Context Control — A subagent can start fresh or from the parent conversation snapshot.
  • Depth + Cycle Guards — Prevent runaway recursive delegation.
  • Streaming Updates — Watch progress in real time.
  • Rich TUI Rendering — Collapsed/expanded views with usage stats, tool calls, markdown output, and session metadata.

Install

Requires Pi 0.80.5 or newer.

Option 1: Install from npm (recommended)

pi install npm:@mjakl/pi-subagent

Option 2: Install via git

pi install git:github.com/mjakl/pi-subagent

Option 3: Manual Installation

Clone this repository to your Pi extensions directory:

cd ~/.pi/agent/extensions
git clone https://github.com/mjakl/pi-subagent.git
cd pi-subagent
npm install

Using Pi Subagent

Once installed, use Pi normally. Ask the main agent for work that benefits from a specialist, such as "review this diff" or "find where authentication is implemented." The main agent decides when to delegate, runs the subagent, and folds the result back into your conversation.

You do not need to call subagent, write JSON, or interact with tools directly.

What to expect:

  • Delegated work appears in the TUI with streaming progress and expandable details.
  • Each subagent runs in its own isolated pi process.
  • If you have no agents yet, pi-subagent creates a starter explore agent automatically.
  • Customize agents only when you want different or additional specialists.

Customizing Subagents

pi-subagent works out of the box — on first run it creates a starter explore agent for you. Customize it only if you want different or additional specialists.

Subagents are defined as Markdown files with YAML frontmatter.

User agents: ~/.pi/agent/agents/*.md by default, or $PI_CODING_AGENT_DIR/agents/*.md when PI_CODING_AGENT_DIR is set.

Project agents: .pi/agents/*.md.

Project agents win on name conflicts, but only after explicit project trust recorded in Pi's trust store or supplied with --approve. Implicit or session-only trust does not enable them. They are repo-controlled configuration and execute like user agents.

Starter Agent

If no user or project subagents can be found, pi-subagent creates a starter user agent named explore in the active user agents directory:

  • ~/.pi/agent/agents/explore.md by default
  • $PI_CODING_AGENT_DIR/agents/explore.md when PI_CODING_AGENT_DIR is set

The starter is read-only (read, grep, find, ls) and is meant for focused codebase exploration. It includes an advisory preference for topic-specific persistent sessions so follow-up exploration can reuse context. Existing files are never overwritten.

Example Agents

Small, focused definitions work best. The description helps the main agent choose a subagent; the Markdown body is the subagent's extra system prompt.

explore

A good default for fast codebase reconnaissance. It prefers named sessions because exploration often has follow-up questions.

---
name: explore
description: Codebase exploration specialist for focused searches and evidence-backed summaries.
tools: read,grep,find,ls
sessionPreference: persistent
sessionHint: Prefer a topic-specific named session for iterative codebase exploration, e.g. session="explore-auth". Use ephemeral calls for one-off or parallel independent searches.
---

You are a codebase exploration specialist. Find the relevant files, symbols, and tests for the request. Return concise findings with file paths and line references.
review

A useful complement to explore: stateless by default, judgment-oriented, and configured for deeper reasoning.

---
name: review
description: Pragmatic code reviewer for correctness, regression risk, test coverage, and maintainability.
thinking: high
sessionPreference: ephemeral
sessionHint: Use ephemeral calls for independent reviews; use a named session only when continuing the same review thread.
---

You review code changes. Focus on substantive issues, cite files and lines, and distinguish confirmed problems from suggestions. Keep the report concise.

Frontmatter Fields

Field Required Default Description
name Yes Agent identifier used in tool calls.
description Yes What the agent does; shown to the main agent.
model No Parent/default Pi model Sets the default model for this agent. A per-call model overrides it. Supports provider-prefixed values such as anthropic/claude-3-5-sonnet.
thinking No Parent/default Pi thinking level Sets the thinking level (off, minimal, low, medium, high, xhigh).
tools No Parent/default Pi tools Comma-separated allowlist of tool names to enable for this agent. Omitted or empty values inherit the parent configuration.
noTools No false Set to true to disable all built-in, extension, and custom tools for this agent.
sessionPreference No Advisory machine-readable hint for the main agent. One of ephemeral, persistent, or either.
sessionHint No Advisory free-form guidance shown to the main agent when choosing whether to pass session.

Notes:

  • Agent model is a default for that agent, not a lock. A model supplied in a subagent call wins.
  • tools is passed to Pi's --tools allowlist and can include built-in or extension tool names. noTools: true takes precedence over tools.
  • sessionPreference and sessionHint only guide the main agent. They do not automatically create, require, or name persistent sessions.
  • sessionHint can be used by itself for free-form guidance; the extension does not infer sessionPreference from it.
  • The Markdown body becomes the agent's system prompt and is appended to Pi's default system prompt.
  • Agent files are read when the tool runs; continued named sessions use the current definition of the agent name.

Available Built-in Tools

Available tools by default: read, bash, edit, write.

Optional built-in tools:

  • grep — Search file contents
  • find — Find files by glob pattern
  • ls — List directory contents

For a read-only agent, use tools: read,find,ls,grep. For an agent with no tools at all, use noTools: true.


Technical Reference

These sections document the subagent tool interface and runtime behavior. They are for advanced users, extension authors, and maintainers — you do not need them for everyday use.

How Subagents Run

Each subagent runs in a separate pi process:

  • No shared memory/state with the parent process.
  • No visibility into sibling subagents.
  • Its own model/tool/runtime loop.
  • Uses Pi's headless RPC mode so prompts are transported verbatim and completion follows Pi's settlement events.
  • Interactive UI requests from inherited extensions are cancelled because subagent processes have no interactive user; non-interactive extension hooks continue normally.
  • Started with PI_OFFLINE=1 to skip startup network operations and reduce latency.
  • Inherits relevant parent CLI configuration such as extensions, provider/theme/skill flags, model/thinking/tool defaults, and custom session storage when applicable. Temporary --approve trust is inherited only when the child uses the same working directory; --no-approve is always preserved. A per-call model overrides the agent file's default model.

The main agent receives a concise text summary for each subagent call. Tool calls, usage, generated session IDs, and creation metadata are available to the TUI and tool result details; the text summary includes only the logical session handle in the call header when one was provided.

Tool API

The tool is named subagent and accepts one top-level calls array. Use the same shape for one call and many calls.

{
  "calls": [
    {
      "agent": "explore",
      "prompt": "Find where authentication is implemented."
    }
  ]
}

A tool invocation accepts between 1 and 8 calls. Each call supports:

Field Required Default Description
agent Yes Exact name of an available subagent.
prompt Yes Non-empty prompt sent verbatim to the subagent.
model No Agent/default Pi model Model to use for this call. Overrides the agent file's default model.
cwd No Parent cwd Working directory for this subagent process.
initialContext No "empty" "empty" starts a newly-created child conversation without parent history. "parent" seeds a newly-created child conversation from the current parent session snapshot. Existing named sessions ignore this field.
session No Logical handle of at most 120 characters for a persistent child Pi session. Use this for multi-turn specialist work. Requires a persisted parent Pi session.
timeout No Unlimited Positive integer wall-clock timeout in seconds for this call (maximum 2,147,483). On expiry, partial output is preserved and the call fails.

One ephemeral call

{
  "calls": [
    {
      "agent": "explore",
      "prompt": "Find where authentication is implemented."
    }
  ]
}

Per-call model override

{
  "calls": [
    {
      "agent": "review",
      "model": "anthropic/claude-sonnet-4",
      "prompt": "Review correctness risks in the current diff."
    }
  ]
}

If omitted, the agent file's model is used when configured; otherwise the child uses the inherited/default Pi model.

Multiple parallel calls

{
  "calls": [
    {
      "agent": "review",
      "prompt": "Review correctness risks in the current diff."
    },
    {
      "agent": "testing-audit",
      "prompt": "Find missing test coverage in the current diff."
    }
  ]
}

Named persistent session

Start a durable subagent conversation:

{
  "calls": [
    {
      "agent": "review",
      "session": "api-review",
      "prompt": "Start a review plan for the API changes."
    }
  ]
}

Continue the same specialist conversation later:

{
  "calls": [
    {
      "agent": "review",
      "session": "api-review",
      "prompt": "Now review the implementation against your earlier plan."
    }
  ]
}

Parent-seeded named session

{
  "calls": [
    {
      "agent": "review",
      "session": "api-review",
      "initialContext": "parent",
      "prompt": "Use the current parent conversation as context and start a review plan."
    }
  ]
}

If the named session already exists, the subagent continues it and initialContext is ignored. If it does not exist, the new child session is seeded from the parent snapshot.

Named Session Semantics

A session value is a logical handle, not a Pi display name and not a raw Pi session ID.

The extension derives an opaque Pi session ID from:

pi-subagent/v1 + parentSessionId + effectiveCwd + agentName + sessionHandle

The generated Pi session ID looks like:

subagent.<hash>

The human-readable Pi display name is:

subagent: <agent> · <handle>

Important rules:

  • Same session handle + same parent session + same effective cwd + same agent continues the same child session.
  • A new top-level Pi parent session creates a new subagent session namespace, even in the same repository.
  • Same session handle with different agents resolves to different child sessions.
  • Same session handle with different effective cwd resolves to different child sessions.
  • A persistent child session can be used by only one running call at a time. The extension uses a session lock in the Pi session directory to guard this across parent processes. If a process is killed, a later call may report a stale lock and ask you to remove the lock directory manually after confirming no subagent is still running.
  • If two calls in the same tool invocation resolve to the same persistent session, the whole request is rejected before any child process starts.
  • Named child sessions require a persisted parent Pi session. If the parent is running with --no-session, omit session for ephemeral delegation.
  • Named child sessions are also unavailable from temporary parent-seeded subagent sessions. Use a named parent subagent session first if nested durable delegation is needed.
  • To start a fresh durable conversation, choose a new session handle.

Initial Context

initialContext controls only how a newly-created child conversation starts:

  • "empty" — start without parent conversation history.
  • "parent" — copy the current parent session branch into the new child conversation before sending the prompt.

Existing named sessions always continue their own history and ignore initialContext.

Calls without session are ephemeral:

  • no session, initialContext: "empty" — fresh temporary child conversation
  • no session, initialContext: "parent" — temporary child conversation seeded from the parent snapshot
  • with session — persistent child Pi session

When multiple calls need initialContext: "parent", they all receive the same parent snapshot captured at the start of the tool invocation.

Result Format

The main agent receives a uniform wrapper for one or many calls:

2/2 succeeded

[1: review session=api-review] completed:
...

[2: testing-audit] completed:
...

If any call fails, the tool result is marked as an error while still returning every call's output:

1/2 succeeded

[1: review session=api-review] completed:
...

[2: testing-audit] failed:
Unknown agent: "testing-audit".

Model-facing output is limited to 50KB or 2000 lines. When a captured result exceeds either limit, every call's status remains visible, captured details remain available in the expanded TUI, and the complete captured summary is written to a mode-0600 temporary file for the lifetime of the parent Pi session.

Process capture is separately bounded to prevent a long-running child from consuming unbounded memory. The runner retains a rolling 5MB window of assistant messages. Earlier messages and oversized tool-only messages may be omitted; oversized final text is retained in truncated form with an explicit marker. The temporary summary artifact contains the complete captured summary, not an unbounded raw event transcript.

Full session metadata, including generated session ID, effective cwd, creation status, and applied initial context, is available in the tool result details and TUI expanded view.

Delegation Guards

By default, this extension enforces two runtime guards:

  1. Depth guard (--subagent-max-depth, default 3)
    • Main agent starts at depth 0.
    • Delegation is allowed while currentDepth < maxDepth.
    • With default depth 3: depth 0, 1, and 2 can delegate; depth 3 cannot.
  2. Cycle guard (--subagent-prevent-cycles, default true)
    • Blocks delegating to any agent name already present in the current delegation stack.
    • Prevents self-recursion and loops.

Configure depth with either:

  • CLI flag: --subagent-max-depth <n>
  • Environment variable: PI_SUBAGENT_MAX_DEPTH=<n>

Configure cycle prevention with either:

  • CLI flag: --subagent-prevent-cycles / --no-subagent-prevent-cycles
  • Environment variable: PI_SUBAGENT_PREVENT_CYCLES=true|false

Internal env vars managed by the extension and propagated to child processes:

  • PI_SUBAGENT_DEPTH
  • PI_SUBAGENT_MAX_DEPTH
  • PI_SUBAGENT_STACK (JSON array of ancestor agent names)
  • PI_SUBAGENT_PREVENT_CYCLES

Recommended integration note: if another extension needs to detect whether it is running inside a delegated subagent process, check PI_SUBAGENT_DEPTH. Treat PI_SUBAGENT_DEPTH > 0 as "this pi process is a subagent".

Attribution

Inspired by implementations from vaayne/agent-kit and mariozechner/pi-mono.

License

MIT