@gotgenes/pi-subagents 5.1.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +176 -133
- package/docs/architecture/architecture.md +148 -92
- package/docs/decisions/0001-deferred-patches.md +11 -5
- package/docs/plans/0048-implement-subagents-api.md +2 -1
- package/docs/plans/0049-remove-group-join-output-file-rpc.md +22 -5
- package/docs/plans/0051-update-adr-0001-hard-fork.md +2 -1
- package/docs/plans/0052-remove-scheduled-subagents.md +4 -2
- package/docs/plans/0057-structured-debug-logging.md +22 -52
- package/docs/plans/0069-create-subagent-runtime.md +345 -0
- package/docs/plans/0071-extract-session-config-assembler.md +362 -0
- package/docs/retro/0049-remove-group-join-output-file-rpc.md +15 -4
- package/docs/retro/0051-update-adr-0001-hard-fork.md +7 -3
- package/docs/retro/0053-extract-model-resolution-from-execute.md +14 -4
- package/docs/retro/0054-decompose-index-into-modules.md +20 -5
- package/docs/retro/0057-structured-debug-logging.md +77 -0
- package/docs/retro/0069-create-subagent-runtime.md +43 -0
- package/package.json +1 -1
- package/src/agent-manager.ts +7 -0
- package/src/agent-runner.ts +51 -189
- package/src/debug.ts +4 -2
- package/src/index.ts +37 -28
- package/src/runtime.ts +62 -0
- package/src/session-config.ts +263 -0
- package/src/tools/agent-tool.ts +4 -2
- package/src/ui/agent-menu.ts +16 -13
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,43 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [5.3.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v5.2.0...pi-subagents-v5.3.0) (2026-05-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add assembleSessionConfig in session-config.ts ([ee8076d](https://github.com/gotgenes/pi-packages/commit/ee8076dc2292ec957b64894af3fcd22567f23be5))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
* add [#80](https://github.com/gotgenes/pi-packages/issues/80) to architecture roadmap, mark [#69](https://github.com/gotgenes/pi-packages/issues/69) and [#71](https://github.com/gotgenes/pi-packages/issues/71) done ([5744e28](https://github.com/gotgenes/pi-packages/commit/5744e28ac993454f8cb33afb18e5247569f9f971))
|
|
19
|
+
* plan session-config assembler extraction ([#71](https://github.com/gotgenes/pi-packages/issues/71)) ([5d2cd4f](https://github.com/gotgenes/pi-packages/commit/5d2cd4f8de214a03a11688b56221679591aedafd))
|
|
20
|
+
* **retro:** add retro notes for issue [#69](https://github.com/gotgenes/pi-packages/issues/69) ([18cbbdb](https://github.com/gotgenes/pi-packages/commit/18cbbdb627f2ae63f8109c1f5597c31265738415))
|
|
21
|
+
|
|
22
|
+
## [5.2.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v5.1.0...pi-subagents-v5.2.0) (2026-05-19)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add SubagentRuntime interface and factory ([b316c12](https://github.com/gotgenes/pi-packages/commit/b316c1222cecf34d1149fa2a847a1c11883164c1))
|
|
28
|
+
* thread defaultMaxTurns and graceTurns through RunOptions ([db9f1ac](https://github.com/gotgenes/pi-packages/commit/db9f1ac7c47b7b42559ddf659f86c02f78a82d23))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* remove pi-subagents/README.md from rumdl exclude and fix 131 lint issues ([50f334c](https://github.com/gotgenes/pi-packages/commit/50f334c83edf08ee2cb413b1e6520f6c5a26cd41))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Documentation
|
|
37
|
+
|
|
38
|
+
* enforce one-sentence-per-line across all markdown files ([a533869](https://github.com/gotgenes/pi-packages/commit/a533869e09ea33a2da8c4ac022d9be4674be4b18))
|
|
39
|
+
* one sentence per line throughout architecture.md; add Issue-prefix and sentence rules to markdown-conventions ([f274ea8](https://github.com/gotgenes/pi-packages/commit/f274ea8003e23c3ad37516422d052f7c815da638))
|
|
40
|
+
* **pi-subagents:** add structural refactoring roadmap with issue sequencing ([a820538](https://github.com/gotgenes/pi-packages/commit/a8205382624acbd26721594630d25976373fc617))
|
|
41
|
+
* plan SubagentRuntime to eliminate module-scope mutable state ([#69](https://github.com/gotgenes/pi-packages/issues/69)) ([fa5eee4](https://github.com/gotgenes/pi-packages/commit/fa5eee4434724fd47dc384092787b50ea9859f4d))
|
|
42
|
+
* **retro:** add follow-up retro notes for issue [#57](https://github.com/gotgenes/pi-packages/issues/57) ([629e11f](https://github.com/gotgenes/pi-packages/commit/629e11f2eaed1294fa756ad3e54fe692428e1c0e))
|
|
43
|
+
* **retro:** add retro notes for issue [#57](https://github.com/gotgenes/pi-packages/issues/57) ([1701841](https://github.com/gotgenes/pi-packages/commit/1701841f387b3418286f670ae0eb10613b5f2b4b))
|
|
44
|
+
|
|
8
45
|
## [5.1.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v5.0.0...pi-subagents-v5.1.0) (2026-05-19)
|
|
9
46
|
|
|
10
47
|
|
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# @gotgenes/pi-subagents
|
|
2
2
|
|
|
3
|
-
A [pi](https://pi.dev) extension that brings **Claude Code-style autonomous sub-agents** to pi.
|
|
3
|
+
A [pi](https://pi.dev) extension that brings **Claude Code-style autonomous sub-agents** to pi.
|
|
4
|
+
Spawn specialized agents that run in isolated sessions — each with its own tools, system prompt, model, and thinking level.
|
|
5
|
+
Run them in foreground or background, steer them mid-run, resume completed sessions, and define your own custom agent types.
|
|
4
6
|
|
|
5
7
|
> **Fork notice:** This package is a friendly fork of [`tintinweb/pi-subagents`](https://github.com/tintinweb/pi-subagents), published to npm as `@gotgenes/pi-subagents`.
|
|
6
8
|
> It carries a small number of patches on top of upstream — peer-dep migration to `@earendil-works/pi-*`, a post-`bindExtensions` active-tool re-filter, and an `<active_agent>` system-prompt tag for permission resolution.
|
|
7
9
|
> See [Deviations from upstream](#deviations-from-upstream) at the bottom of this README for details.
|
|
8
|
-
|
|
10
|
+
>
|
|
9
11
|
> **Status:** Early release.
|
|
10
12
|
|
|
11
13
|
<img width="600" alt="pi-subagents screenshot" src="https://github.com/gotgenes/pi-subagents/raw/main/media/screenshot.png" />
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
https://github.com/user-attachments/assets/8685261b-9338-4fea-8dfe-1c590d5df543
|
|
15
|
-
|
|
15
|
+
<https://github.com/user-attachments/assets/8685261b-9338-4fea-8dfe-1c590d5df543>
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
@@ -24,17 +24,18 @@ https://github.com/user-attachments/assets/8685261b-9338-4fea-8dfe-1c590d5df543
|
|
|
24
24
|
- **Mid-run steering** — inject messages into running agents to redirect their work without restarting
|
|
25
25
|
- **Session resume** — pick up where an agent left off, preserving full conversation context
|
|
26
26
|
- **Graceful turn limits** — agents get a "wrap up" warning before hard abort, producing clean partial results instead of cut-off output
|
|
27
|
-
- **Case-insensitive agent types** — `"explore"`, `"Explore"`, `"EXPLORE"` all work.
|
|
27
|
+
- **Case-insensitive agent types** — `"explore"`, `"Explore"`, `"EXPLORE"` all work.
|
|
28
|
+
Unknown types fall back to general-purpose with a note
|
|
28
29
|
- **Fuzzy model selection** — specify models by name (`"haiku"`, `"sonnet"`) instead of full IDs, with automatic filtering to only available/configured models
|
|
29
30
|
- **Context inheritance** — optionally fork the parent conversation into a sub-agent so it knows what's been discussed
|
|
30
31
|
- **Persistent agent memory** — three scopes (project, local, user) with automatic read-only fallback for agents without write tools
|
|
31
32
|
- **Git worktree isolation** — run agents in isolated repo copies; changes auto-committed to branches on completion
|
|
32
33
|
- **Skill preloading** — inject named skills into agent system prompts, discovered from `.pi/skills/`, `.agents/skills/`, and global locations (Pi-standard `<name>/SKILL.md` directory layout supported)
|
|
33
34
|
- **Tool denylist** — block specific tools via `disallowed_tools` frontmatter
|
|
34
|
-
- **Styled completion notifications** — background agent results render as themed, compact notification boxes (icon, stats, result preview) instead of raw XML.
|
|
35
|
+
- **Styled completion notifications** — background agent results render as themed, compact notification boxes (icon, stats, result preview) instead of raw XML.
|
|
36
|
+
Expandable to show full output
|
|
35
37
|
- **Event bus** — lifecycle events (`subagents:created`, `started`, `completed`, `failed`, `steered`, `compacted`) emitted via `pi.events`, enabling other extensions to react to sub-agent activity
|
|
36
38
|
|
|
37
|
-
|
|
38
39
|
## Install
|
|
39
40
|
|
|
40
41
|
```bash
|
|
@@ -51,7 +52,7 @@ pi -e ./src/index.ts
|
|
|
51
52
|
|
|
52
53
|
The parent agent spawns sub-agents using the `Agent` tool:
|
|
53
54
|
|
|
54
|
-
```
|
|
55
|
+
```text
|
|
55
56
|
Agent({
|
|
56
57
|
subagent_type: "Explore",
|
|
57
58
|
prompt: "Find all files that handle authentication",
|
|
@@ -60,13 +61,14 @@ Agent({
|
|
|
60
61
|
})
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
Foreground agents block until complete and return results inline.
|
|
64
|
+
Foreground agents block until complete and return results inline.
|
|
65
|
+
Background agents return an ID immediately and notify you on completion.
|
|
64
66
|
|
|
65
67
|
## UI
|
|
66
68
|
|
|
67
69
|
The extension renders a persistent widget above the editor showing all active agents:
|
|
68
70
|
|
|
69
|
-
```
|
|
71
|
+
```text
|
|
70
72
|
● Agents
|
|
71
73
|
├─ ⠹ Agent Refactor auth module · ⟳5≤30 · 5 tool uses · 33.8k token (62%) · 12.3s
|
|
72
74
|
│ ⎿ editing 2 files…
|
|
@@ -78,25 +80,28 @@ The extension renders a persistent widget above the editor showing all active ag
|
|
|
78
80
|
```
|
|
79
81
|
|
|
80
82
|
The token field is annotated with two optional signals inside parens:
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
+
|
|
84
|
+
- **`NN%`** — context-window utilization (color-coded: <70% dim, 70–85% warning, ≥85% error).
|
|
85
|
+
Omitted when the model has no declared `contextWindow`, or briefly right after compaction.
|
|
86
|
+
- **`↻N`** — number of times the session has compacted, when > 0.
|
|
87
|
+
Stays dim; the percent's color carries urgency.
|
|
83
88
|
|
|
84
89
|
Individual agent results render Claude Code-style in the conversation:
|
|
85
90
|
|
|
86
|
-
| State
|
|
87
|
-
|
|
88
|
-
| **Running**
|
|
89
|
-
| **Completed**
|
|
91
|
+
| State | Example |
|
|
92
|
+
| -------------- | ---------------------------------------------------------------------------------------- |
|
|
93
|
+
| **Running** | `⠹ ⟳3≤30 · 3 tool uses · 12.4k token (8%)` / `⎿ searching, reading 3 files…` |
|
|
94
|
+
| **Completed** | `✓ ⟳8 · 5 tool uses · 33.8k token (62%) · 12.3s` / `⎿ Done` |
|
|
90
95
|
| **Wrapped up** | `✓ ⟳50≤50 · 50 tool uses · 89.1k token (84% · ↻2) · 45.2s` / `⎿ Wrapped up (turn limit)` |
|
|
91
|
-
| **Stopped**
|
|
92
|
-
| **Error**
|
|
93
|
-
| **Aborted**
|
|
96
|
+
| **Stopped** | `■ ⟳3 · 3 tool uses · 12.4k token (8%)` / `⎿ Stopped` |
|
|
97
|
+
| **Error** | `✗ ⟳3 · 3 tool uses · 12.4k token (8%)` / `⎿ Error: timeout` |
|
|
98
|
+
| **Aborted** | `✗ ⟳55≤50 · 55 tool uses · 102.3k token (95% · ↻3)` / `⎿ Aborted (max turns exceeded)` |
|
|
94
99
|
|
|
95
100
|
Completed results can be expanded (ctrl+o in pi) to show the full agent output inline.
|
|
96
101
|
|
|
97
102
|
Background agent completion notifications render as styled boxes:
|
|
98
103
|
|
|
99
|
-
```
|
|
104
|
+
```text
|
|
100
105
|
✓ Find auth files completed
|
|
101
106
|
⟳3 · 3 tool uses · 12.4k token · 4.1s
|
|
102
107
|
⎿ Found 5 files related to authentication...
|
|
@@ -107,28 +112,32 @@ The LLM receives structured `<task-notification>` XML for parsing, while the use
|
|
|
107
112
|
|
|
108
113
|
## Default Agent Types
|
|
109
114
|
|
|
110
|
-
| Type
|
|
111
|
-
|
|
112
|
-
| `general-purpose` | all 7
|
|
113
|
-
| `Explore`
|
|
114
|
-
| `Plan`
|
|
115
|
+
| Type | Tools | Model | Prompt Mode | Description |
|
|
116
|
+
| ----------------- | -------------------------- | ----------------------------- | ---------------------- | ------------------------------------------------------------------------------------- |
|
|
117
|
+
| `general-purpose` | all 7 | inherit | `append` (parent twin) | Inherits the parent's full system prompt — same rules, CLAUDE.md, project conventions |
|
|
118
|
+
| `Explore` | read, bash, grep, find, ls | haiku (falls back to inherit) | `replace` (standalone) | Fast codebase exploration (read-only) |
|
|
119
|
+
| `Plan` | read, bash, grep, find, ls | inherit | `replace` (standalone) | Software architect for implementation planning (read-only) |
|
|
115
120
|
|
|
116
|
-
The `general-purpose` agent is a **parent twin** — it receives the parent's entire system prompt plus a sub-agent context bridge, so it follows the same rules the parent does.
|
|
121
|
+
The `general-purpose` agent is a **parent twin** — it receives the parent's entire system prompt plus a sub-agent context bridge, so it follows the same rules the parent does.
|
|
122
|
+
Explore and Plan use standalone prompts tailored to their read-only roles.
|
|
117
123
|
|
|
118
124
|
Default agents can be **ejected** (`/agents` → select agent → Eject) to export them as `.md` files for customization, **overridden** by creating a `.md` file with the same name (e.g. `.pi/agents/general-purpose.md`), or **disabled** per-project with `enabled: false` frontmatter.
|
|
119
125
|
|
|
120
126
|
## Custom Agents
|
|
121
127
|
|
|
122
|
-
Define custom agent types by creating `.md` files.
|
|
128
|
+
Define custom agent types by creating `.md` files.
|
|
129
|
+
The filename becomes the agent type name.
|
|
130
|
+
Any name is allowed — using a default agent's name overrides it.
|
|
123
131
|
|
|
124
132
|
Agents are discovered from two locations (higher priority wins):
|
|
125
133
|
|
|
126
|
-
| Priority
|
|
127
|
-
|
|
128
|
-
| 1 (highest) | `.pi/agents/<name>.md`
|
|
129
|
-
| 2
|
|
134
|
+
| Priority | Location | Scope |
|
|
135
|
+
| ----------- | -------------------------------------------------------------------------------- | ----------------------------- |
|
|
136
|
+
| 1 (highest) | `.pi/agents/<name>.md` | Project — per-repo agents |
|
|
137
|
+
| 2 | `$PI_CODING_AGENT_DIR/agents/<name>.md` (default `~/.pi/agent/agents/<name>.md`) | Global — available everywhere |
|
|
130
138
|
|
|
131
|
-
Project-level agents override global ones with the same name, so you can customize a global agent for a specific project.
|
|
139
|
+
Project-level agents override global ones with the same name, so you can customize a global agent for a specific project.
|
|
140
|
+
The global location follows the upstream `PI_CODING_AGENT_DIR` env var — set it to relocate all pi-coding-agent state (agents, skills, settings) to a custom directory.
|
|
132
141
|
|
|
133
142
|
### Example: `.pi/agents/auditor.md`
|
|
134
143
|
|
|
@@ -141,7 +150,9 @@ thinking: high
|
|
|
141
150
|
max_turns: 30
|
|
142
151
|
---
|
|
143
152
|
|
|
144
|
-
You are a security auditor.
|
|
153
|
+
You are a security auditor.
|
|
154
|
+
Review code for vulnerabilities including:
|
|
155
|
+
|
|
145
156
|
- Injection flaws (SQL, command, XSS)
|
|
146
157
|
- Authentication and authorization issues
|
|
147
158
|
- Sensitive data exposure
|
|
@@ -152,7 +163,7 @@ Report findings with file paths, line numbers, severity, and remediation advice.
|
|
|
152
163
|
|
|
153
164
|
Then spawn it like any built-in type:
|
|
154
165
|
|
|
155
|
-
```
|
|
166
|
+
```text
|
|
156
167
|
Agent({ subagent_type: "auditor", prompt: "Review the auth module", description: "Security audit" })
|
|
157
168
|
```
|
|
158
169
|
|
|
@@ -160,26 +171,28 @@ Agent({ subagent_type: "auditor", prompt: "Review the auth module", description:
|
|
|
160
171
|
|
|
161
172
|
All fields are optional — sensible defaults for everything.
|
|
162
173
|
|
|
163
|
-
| Field
|
|
164
|
-
|
|
165
|
-
| `description`
|
|
166
|
-
| `display_name`
|
|
167
|
-
| `tools`
|
|
168
|
-
| `extensions`
|
|
169
|
-
| `skills`
|
|
170
|
-
| `memory`
|
|
171
|
-
| `disallowed_tools`
|
|
172
|
-
| `isolation`
|
|
173
|
-
| `model`
|
|
174
|
-
| `thinking`
|
|
175
|
-
| `max_turns`
|
|
176
|
-
| `prompt_mode`
|
|
177
|
-
| `inherit_context`
|
|
178
|
-
| `run_in_background` | `false`
|
|
179
|
-
| `isolated`
|
|
180
|
-
| `enabled`
|
|
181
|
-
|
|
182
|
-
Frontmatter is authoritative.
|
|
174
|
+
| Field | Default | Description |
|
|
175
|
+
| ------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
176
|
+
| `description` | filename | Agent description shown in tool listings |
|
|
177
|
+
| `display_name` | — | Display name for UI (e.g. widget, agent list) |
|
|
178
|
+
| `tools` | all 7 | Comma-separated built-in tools: read, bash, edit, write, grep, find, ls. `none` for no tools |
|
|
179
|
+
| `extensions` | `true` | Inherit MCP/extension tools. `false` to disable |
|
|
180
|
+
| `skills` | `true` | Inherit skills from parent. Can be a comma-separated list of skill names to preload (see [Skill Preloading](#skill-preloading) for discovery locations) |
|
|
181
|
+
| `memory` | — | Persistent agent memory scope: `project`, `local`, or `user`. Auto-detects read-only agents |
|
|
182
|
+
| `disallowed_tools` | — | Comma-separated tools to deny even if extensions provide them |
|
|
183
|
+
| `isolation` | — | Set to `worktree` to run in an isolated git worktree |
|
|
184
|
+
| `model` | inherit parent | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
|
|
185
|
+
| `thinking` | inherit | off, minimal, low, medium, high, xhigh |
|
|
186
|
+
| `max_turns` | unlimited | Max agentic turns before graceful shutdown. `0` or omit for unlimited |
|
|
187
|
+
| `prompt_mode` | `replace` | `replace`: body is the full system prompt (no AGENTS.md / CLAUDE.md inheritance). `append`: body appended to parent's prompt (agent acts as a "parent twin" — inherits parent's AGENTS.md / CLAUDE.md) |
|
|
188
|
+
| `inherit_context` | `false` | Fork parent conversation into agent |
|
|
189
|
+
| `run_in_background` | `false` | Run in background by default |
|
|
190
|
+
| `isolated` | `false` | No extension/MCP tools, only built-in |
|
|
191
|
+
| `enabled` | `true` | Set to `false` to disable an agent (useful for hiding a default agent per-project) |
|
|
192
|
+
|
|
193
|
+
Frontmatter is authoritative.
|
|
194
|
+
If an agent file sets `model`, `thinking`, `max_turns`, `inherit_context`, `run_in_background`, `isolated`, or `isolation`, those values are locked for that agent.
|
|
195
|
+
`Agent` tool parameters only fill fields the agent config leaves unspecified.
|
|
183
196
|
|
|
184
197
|
## Tools
|
|
185
198
|
|
|
@@ -187,62 +200,66 @@ Frontmatter is authoritative. If an agent file sets `model`, `thinking`, `max_tu
|
|
|
187
200
|
|
|
188
201
|
Launch a sub-agent.
|
|
189
202
|
|
|
190
|
-
| Parameter
|
|
191
|
-
|
|
192
|
-
| `prompt`
|
|
193
|
-
| `description`
|
|
194
|
-
| `subagent_type`
|
|
195
|
-
| `model`
|
|
196
|
-
| `thinking`
|
|
197
|
-
| `max_turns`
|
|
198
|
-
| `run_in_background` | boolean
|
|
199
|
-
| `resume`
|
|
200
|
-
| `isolated`
|
|
201
|
-
| `isolation`
|
|
202
|
-
| `inherit_context`
|
|
203
|
+
| Parameter | Type | Required | Description |
|
|
204
|
+
| ------------------- | ------------ | -------- | ---------------------------------------------------------------- |
|
|
205
|
+
| `prompt` | string | yes | The task for the agent |
|
|
206
|
+
| `description` | string | yes | Short 3-5 word summary (shown in UI) |
|
|
207
|
+
| `subagent_type` | string | yes | Agent type (built-in or custom) |
|
|
208
|
+
| `model` | string | no | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
|
|
209
|
+
| `thinking` | string | no | Thinking level: off, minimal, low, medium, high, xhigh |
|
|
210
|
+
| `max_turns` | number | no | Max agentic turns. Omit for unlimited (default) |
|
|
211
|
+
| `run_in_background` | boolean | no | Run without blocking |
|
|
212
|
+
| `resume` | string | no | Agent ID to resume a previous session |
|
|
213
|
+
| `isolated` | boolean | no | No extension/MCP tools |
|
|
214
|
+
| `isolation` | `"worktree"` | no | Run in an isolated git worktree |
|
|
215
|
+
| `inherit_context` | boolean | no | Fork parent conversation into agent |
|
|
203
216
|
|
|
204
217
|
### `get_subagent_result`
|
|
205
218
|
|
|
206
219
|
Check status and retrieve results from a background agent.
|
|
207
220
|
|
|
208
|
-
| Parameter
|
|
209
|
-
|
|
210
|
-
| `agent_id` | string
|
|
211
|
-
| `wait`
|
|
212
|
-
| `verbose`
|
|
221
|
+
| Parameter | Type | Required | Description |
|
|
222
|
+
| ---------- | ------- | -------- | ----------------------------- |
|
|
223
|
+
| `agent_id` | string | yes | Agent ID to check |
|
|
224
|
+
| `wait` | boolean | no | Wait for completion |
|
|
225
|
+
| `verbose` | boolean | no | Include full conversation log |
|
|
213
226
|
|
|
214
227
|
### `steer_subagent`
|
|
215
228
|
|
|
216
|
-
Send a steering message to a running agent.
|
|
229
|
+
Send a steering message to a running agent.
|
|
230
|
+
The message interrupts after the current tool execution.
|
|
217
231
|
|
|
218
|
-
| Parameter
|
|
219
|
-
|
|
220
|
-
| `agent_id` | string | yes
|
|
221
|
-
| `message`
|
|
232
|
+
| Parameter | Type | Required | Description |
|
|
233
|
+
| ---------- | ------ | -------- | ----------------------------------------- |
|
|
234
|
+
| `agent_id` | string | yes | Agent ID to steer |
|
|
235
|
+
| `message` | string | yes | Message to inject into agent conversation |
|
|
222
236
|
|
|
223
237
|
## Commands
|
|
224
238
|
|
|
225
|
-
| Command
|
|
226
|
-
|
|
239
|
+
| Command | Description |
|
|
240
|
+
| --------- | --------------------------------- |
|
|
227
241
|
| `/agents` | Interactive agent management menu |
|
|
228
242
|
|
|
229
243
|
The `/agents` command opens an interactive menu:
|
|
230
244
|
|
|
231
|
-
```
|
|
245
|
+
```text
|
|
232
246
|
Running agents (2) — 1 running, 1 done ← only shown when agents exist
|
|
233
247
|
Agent types (6) ← unified list: defaults + custom
|
|
234
248
|
Create new agent ← manual wizard or AI-generated
|
|
235
249
|
Settings ← max concurrency, max turns, grace turns
|
|
236
250
|
```
|
|
237
251
|
|
|
238
|
-
- **Agent types** — unified list with source indicators: `•` (project), `◦` (global), `✕` (disabled).
|
|
252
|
+
- **Agent types** — unified list with source indicators: `•` (project), `◦` (global), `✕` (disabled).
|
|
253
|
+
Select an agent to manage it:
|
|
239
254
|
- **Default agents** (no override): Eject (export as `.md`), Disable
|
|
240
255
|
- **Default agents** (ejected/overridden): Edit, Disable, Reset to default, Delete
|
|
241
256
|
- **Custom agents**: Edit, Disable, Delete
|
|
242
257
|
- **Disabled agents**: Enable, Edit, Delete
|
|
243
258
|
- **Eject** — writes the embedded default config as a `.md` file to project or personal location, so you can customize it
|
|
244
|
-
- **Disable/Enable** — toggle agent availability.
|
|
245
|
-
|
|
259
|
+
- **Disable/Enable** — toggle agent availability.
|
|
260
|
+
Disabled agents stay visible in the list (marked `✕`) and can be re-enabled
|
|
261
|
+
- **Create new agent** — choose project/personal location, then manual wizard (step-by-step prompts for name, tools, model, thinking, system prompt) or AI-generated (describe what the agent should do and a sub-agent writes the `.md` file).
|
|
262
|
+
Any name is allowed, including default agent names (overrides them)
|
|
246
263
|
- **Settings** — configure max concurrency, default max turns, and grace turns at runtime
|
|
247
264
|
|
|
248
265
|
## Graceful Max Turns
|
|
@@ -253,27 +270,33 @@ Instead of hard-aborting at the turn limit, agents get a graceful shutdown:
|
|
|
253
270
|
2. Up to 5 grace turns to finish cleanly
|
|
254
271
|
3. Hard abort only after the grace period
|
|
255
272
|
|
|
256
|
-
| Status
|
|
257
|
-
|
|
258
|
-
| `completed` | Finished naturally
|
|
259
|
-
| `steered`
|
|
260
|
-
| `aborted`
|
|
261
|
-
| `stopped`
|
|
273
|
+
| Status | Meaning | Icon |
|
|
274
|
+
| ----------- | ----------------------------- | ---------- |
|
|
275
|
+
| `completed` | Finished naturally | `✓` green |
|
|
276
|
+
| `steered` | Hit limit, wrapped up in time | `✓` yellow |
|
|
277
|
+
| `aborted` | Grace period exceeded | `✗` red |
|
|
278
|
+
| `stopped` | User-initiated abort | `■` dim |
|
|
262
279
|
|
|
263
280
|
## Concurrency
|
|
264
281
|
|
|
265
|
-
Background agents are subject to a configurable concurrency limit (default: 4).
|
|
282
|
+
Background agents are subject to a configurable concurrency limit (default: 4).
|
|
283
|
+
Excess agents are automatically queued and start as running agents complete.
|
|
284
|
+
The widget shows queued agents as a collapsed count.
|
|
266
285
|
|
|
267
286
|
Foreground agents bypass the queue — they block the parent anyway.
|
|
268
287
|
|
|
269
288
|
## Persistent Settings
|
|
270
289
|
|
|
271
|
-
Runtime tuning values set via `/agents` → Settings (max concurrency, default max turns, grace turns) persist across pi restarts.
|
|
290
|
+
Runtime tuning values set via `/agents` → Settings (max concurrency, default max turns, grace turns) persist across pi restarts.
|
|
291
|
+
Two files, merged on load:
|
|
272
292
|
|
|
273
|
-
- **Global:** `~/.pi/agent/subagents.json` — your machine-wide defaults.
|
|
274
|
-
|
|
293
|
+
- **Global:** `~/.pi/agent/subagents.json` — your machine-wide defaults.
|
|
294
|
+
Edit by hand; the `/agents` menu never writes here.
|
|
295
|
+
- **Project:** `<cwd>/.pi/subagents.json` — per-project overrides.
|
|
296
|
+
Written by `/agents` → Settings.
|
|
275
297
|
|
|
276
|
-
**Precedence:** project overrides global on any field present in both.
|
|
298
|
+
**Precedence:** project overrides global on any field present in both.
|
|
299
|
+
Missing fields fall back to the hardcoded defaults (max concurrency `4`, default max turns unlimited, grace turns `5`).
|
|
277
300
|
|
|
278
301
|
**Example — global defaults for a beefy machine:**
|
|
279
302
|
|
|
@@ -287,7 +310,8 @@ cat > ~/.pi/agent/subagents.json <<'EOF'
|
|
|
287
310
|
EOF
|
|
288
311
|
```
|
|
289
312
|
|
|
290
|
-
Every project now starts with concurrency 16 and grace 10, without ever touching the menu.
|
|
313
|
+
Every project now starts with concurrency 16 and grace 10, without ever touching the menu.
|
|
314
|
+
Individual projects can still override via `/agents` → Settings.
|
|
291
315
|
|
|
292
316
|
**Failure behavior:** missing file is silent; malformed JSON logs a `[pi-subagents] Ignoring malformed settings at …` warning to stderr; invalid/out-of-range field values are dropped per-field; write failures downgrade the `/agents` toast to a warning with `(session only; failed to persist)`.
|
|
293
317
|
|
|
@@ -295,22 +319,25 @@ Every project now starts with concurrency 16 and grace 10, without ever touching
|
|
|
295
319
|
|
|
296
320
|
Agent lifecycle events are emitted via `pi.events.emit()` so other extensions can react:
|
|
297
321
|
|
|
298
|
-
| Event
|
|
299
|
-
|
|
300
|
-
| `subagents:created`
|
|
301
|
-
| `subagents:started`
|
|
302
|
-
| `subagents:completed`
|
|
303
|
-
| `subagents:failed`
|
|
304
|
-
| `subagents:steered`
|
|
305
|
-
| `subagents:compacted`
|
|
306
|
-
| `subagents:settings_loaded`
|
|
307
|
-
| `subagents:settings_changed` | `/agents` → Settings mutation was applied
|
|
308
|
-
|
|
309
|
-
`tokens.total` = `input + output + cacheWrite`.
|
|
322
|
+
| Event | When | Key fields |
|
|
323
|
+
| ---------------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
324
|
+
| `subagents:created` | Background agent registered | `id`, `type`, `description`, `isBackground` |
|
|
325
|
+
| `subagents:started` | Agent transitions to running (including queued→running) | `id`, `type`, `description` |
|
|
326
|
+
| `subagents:completed` | Agent finished successfully | `id`, `type`, `durationMs`, `tokens` (lifetime `{ input, output, total }`), `toolUses`, `result` |
|
|
327
|
+
| `subagents:failed` | Agent errored, stopped, or aborted | same as completed + `error`, `status` |
|
|
328
|
+
| `subagents:steered` | Steering message sent | `id`, `message` |
|
|
329
|
+
| `subagents:compacted` | Agent's session successfully compacted | `id`, `type`, `description`, `reason` (`"manual"` / `"threshold"` / `"overflow"`), `tokensBefore`, `compactionCount` |
|
|
330
|
+
| `subagents:settings_loaded` | Persisted settings applied at extension init | `settings` (merged global + project) |
|
|
331
|
+
| `subagents:settings_changed` | `/agents` → Settings mutation was applied | `settings`, `persisted` (`boolean` — `false` on write failure) |
|
|
332
|
+
|
|
333
|
+
`tokens.total` = `input + output + cacheWrite`.
|
|
334
|
+
`cacheRead` is excluded — each turn's `cacheRead` is the cumulative cached prefix re-read on that one API call, so summing per-message would over-count it.
|
|
335
|
+
Use `contextUsage.percent` (surfaced as `(NN%)` in the widget) for current context size.
|
|
310
336
|
|
|
311
337
|
## Persistent Agent Memory
|
|
312
338
|
|
|
313
|
-
Agents can have persistent memory across sessions.
|
|
339
|
+
Agents can have persistent memory across sessions.
|
|
340
|
+
Set `memory` in frontmatter to enable:
|
|
314
341
|
|
|
315
342
|
```yaml
|
|
316
343
|
---
|
|
@@ -318,13 +345,16 @@ memory: project # project | local | user
|
|
|
318
345
|
---
|
|
319
346
|
```
|
|
320
347
|
|
|
321
|
-
| Scope
|
|
322
|
-
|
|
323
|
-
| `project` | `.pi/agent-memory/<name>/`
|
|
324
|
-
| `local`
|
|
325
|
-
| `user`
|
|
348
|
+
| Scope | Location | Use case |
|
|
349
|
+
| --------- | -------------------------------- | ---------------------------------- |
|
|
350
|
+
| `project` | `.pi/agent-memory/<name>/` | Shared across the team (committed) |
|
|
351
|
+
| `local` | `.pi/agent-memory-local/<name>/` | Machine-specific (gitignored) |
|
|
352
|
+
| `user` | `~/.pi/agent-memory/<name>/` | Global personal memory |
|
|
326
353
|
|
|
327
|
-
Memory uses a `MEMORY.md` index file and individual memory files with frontmatter.
|
|
354
|
+
Memory uses a `MEMORY.md` index file and individual memory files with frontmatter.
|
|
355
|
+
Agents with write tools get full read-write access.
|
|
356
|
+
**Read-only agents** (no `write`/`edit` tools) automatically get read-only memory — they can consume memories written by other agents but cannot modify them.
|
|
357
|
+
This prevents unintended tool escalation.
|
|
328
358
|
|
|
329
359
|
The `disallowed_tools` field is respected when determining write capability — an agent with `tools: write` + `disallowed_tools: write` correctly gets read-only memory.
|
|
330
360
|
|
|
@@ -332,15 +362,18 @@ The `disallowed_tools` field is respected when determining write capability —
|
|
|
332
362
|
|
|
333
363
|
Set `isolation: worktree` to run an agent in a temporary git worktree:
|
|
334
364
|
|
|
335
|
-
```
|
|
365
|
+
```text
|
|
336
366
|
Agent({ subagent_type: "refactor", prompt: "...", isolation: "worktree" })
|
|
337
367
|
```
|
|
338
368
|
|
|
339
|
-
The agent gets a full, isolated copy of the repository.
|
|
369
|
+
The agent gets a full, isolated copy of the repository.
|
|
370
|
+
On completion:
|
|
371
|
+
|
|
340
372
|
- **No changes:** worktree is cleaned up automatically
|
|
341
373
|
- **Changes made:** changes are committed to a new branch (`pi-agent-<id>`) and returned in the result
|
|
342
374
|
|
|
343
|
-
If the worktree cannot be created (not a git repo, no commits, or `git worktree add` fails), the `Agent` tool returns a clear error instead of running unisolated — `isolation: "worktree"` is a strict guarantee, not a hint.
|
|
375
|
+
If the worktree cannot be created (not a git repo, no commits, or `git worktree add` fails), the `Agent` tool returns a clear error instead of running unisolated — `isolation: "worktree"` is a strict guarantee, not a hint.
|
|
376
|
+
Initialize git and commit at least once, or omit `isolation`.
|
|
344
377
|
|
|
345
378
|
## Skill Preloading
|
|
346
379
|
|
|
@@ -354,13 +387,13 @@ skills: api-conventions, error-handling
|
|
|
354
387
|
|
|
355
388
|
**Discovery roots** (checked in this order, first match wins):
|
|
356
389
|
|
|
357
|
-
| Scope
|
|
358
|
-
|
|
359
|
-
| Project | `<cwd>/.pi/skills/`
|
|
360
|
-
| Project | `<cwd>/.agents/skills/`
|
|
361
|
-
| User
|
|
362
|
-
| User
|
|
363
|
-
| User
|
|
390
|
+
| Scope | Path | Source |
|
|
391
|
+
| ------- | -------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
392
|
+
| Project | `<cwd>/.pi/skills/` | Pi-standard |
|
|
393
|
+
| Project | `<cwd>/.agents/skills/` | [Agent Skills spec](https://agentskills.io/integrate-skills) |
|
|
394
|
+
| User | `$PI_CODING_AGENT_DIR/skills/` (default `~/.pi/agent/skills/`) | Pi-standard |
|
|
395
|
+
| User | `~/.agents/skills/` | [Agent Skills spec](https://agentskills.io/integrate-skills) |
|
|
396
|
+
| User | `~/.pi/skills/` | Legacy (pre-Pi) |
|
|
364
397
|
|
|
365
398
|
**Per root, a skill named `foo` resolves to the first of:**
|
|
366
399
|
|
|
@@ -368,9 +401,12 @@ skills: api-conventions, error-handling
|
|
|
368
401
|
- `<root>/foo/SKILL.md` — directory skill (top-level)
|
|
369
402
|
- `<root>/*/.../foo/SKILL.md` — directory skill, found by recursive descent
|
|
370
403
|
|
|
371
|
-
Recursion skips dotfile directories and `node_modules`.
|
|
404
|
+
Recursion skips dotfile directories and `node_modules`.
|
|
405
|
+
A directory that itself contains a `SKILL.md` is treated as a single skill — we don't descend into it.
|
|
406
|
+
Traversal is byte-order sorted for deterministic resolution across filesystems.
|
|
372
407
|
|
|
373
|
-
**Security:** symlinks are rejected at every layer (root, flat file, skill directory, `SKILL.md` inside a skill directory) — intentional deviation from Pi, which follows symlinks.
|
|
408
|
+
**Security:** symlinks are rejected at every layer (root, flat file, skill directory, `SKILL.md` inside a skill directory) — intentional deviation from Pi, which follows symlinks.
|
|
409
|
+
Skill names with path-traversal characters (`..`, `/`, `\`, spaces, leading dot, >128 chars) are rejected.
|
|
374
410
|
|
|
375
411
|
## Tool Denylist
|
|
376
412
|
|
|
@@ -387,7 +423,7 @@ This is useful for creating agents that inherit extension tools but should not h
|
|
|
387
423
|
|
|
388
424
|
## Architecture
|
|
389
425
|
|
|
390
|
-
```
|
|
426
|
+
```text
|
|
391
427
|
src/
|
|
392
428
|
index.ts # Extension entry: tool/command registration, rendering
|
|
393
429
|
types.ts # Type definitions (AgentConfig, AgentRecord, etc.)
|
|
@@ -410,11 +446,18 @@ src/
|
|
|
410
446
|
|
|
411
447
|
## Deviations from upstream
|
|
412
448
|
|
|
413
|
-
This fork carries three divergences from [`tintinweb/pi-subagents`](https://github.com/tintinweb/pi-subagents).
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
449
|
+
This fork carries three divergences from [`tintinweb/pi-subagents`](https://github.com/tintinweb/pi-subagents).
|
|
450
|
+
Each has a corresponding upstream PR:
|
|
451
|
+
|
|
452
|
+
1. **Peer-dep migration to `@earendil-works/pi-*`** — `peerDependencies` and all imports point at `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` (the active scope on npm) instead of the deprecated `@mariozechner/pi-*` scope.
|
|
453
|
+
Also fixes a latent bug where `ThinkingLevel` was imported from `pi-agent-core` (an undeclared transitive dep that breaks under pnpm).
|
|
454
|
+
Upstream PR: [tintinweb/pi-subagents#71](https://github.com/tintinweb/pi-subagents/pull/71).
|
|
455
|
+
2. **Post-`bindExtensions` active-tool re-filter** (`src/agent-runner.ts`) — `runAgent` re-runs its active-tool filter after `session.bindExtensions(...)` so extension-registered tools join the child's active tool set.
|
|
456
|
+
Without this, the `extensions: string[]` allowlist branch was functionally dead for extension tools, and `extensions: true` with a `disallowedTools` denylist let denylisted extension tools slip through.
|
|
457
|
+
Upstream PR: [tintinweb/pi-subagents#72](https://github.com/tintinweb/pi-subagents/pull/72).
|
|
458
|
+
3. **`<active_agent>` system-prompt tag** (`src/prompts.ts`) — `buildAgentPrompt` prepends `<active_agent name="${config.name}"/>` to every assembled child system prompt (both `replace` and `append` modes).
|
|
459
|
+
Downstream extensions like [`@gotgenes/pi-permission-system`](https://github.com/gotgenes/pi-permission-system) parse this tag to resolve per-agent `permission:` frontmatter inside the child session.
|
|
460
|
+
Upstream PR: [tintinweb/pi-subagents#73](https://github.com/tintinweb/pi-subagents/pull/73).
|
|
418
461
|
|
|
419
462
|
The upstream `vitest` suite plus tests added for each patch all pass on every commit.
|
|
420
463
|
|