@wolido/async-subagent-isolation 1.0.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/ADVANCED.en.md +305 -0
- package/ADVANCED.md +305 -0
- package/LICENSE +21 -0
- package/README.en.md +294 -0
- package/README.md +294 -0
- package/examples/README.en.md +100 -0
- package/examples/README.md +100 -0
- package/examples/pi/agent/agents/coder.md +36 -0
- package/examples/pi/agent/agents/reviewer.md +39 -0
- package/examples/pi/agent/agents/writer.md +36 -0
- package/examples/pi/agent/master.md +63 -0
- package/examples/pi/agent/skills/brainstorming/SKILL.md +54 -0
- package/examples/pi/agent/skills/systematic-debugging/SKILL.md +319 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/SKILL.md +88 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/02-elementary-rules-of-usage.md +214 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/03-elementary-principles-of-composition.md +394 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/04-a-few-matters-of-form.md +90 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/05-words-and-expressions-commonly-misused.md +346 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/common-issues.md +22 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/full-example.md +19 -0
- package/examples/pi/agent/skills/writing-clearly-and-concisely/references/signs-of-ai-writing.md +345 -0
- package/logo.svg +33 -0
- package/package.json +72 -0
- package/src/index.ts +2300 -0
package/README.en.md
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
<div align="right"><a href="README.md">中文</a></div>
|
|
2
|
+
|
|
3
|
+
<div align="center"><img src="logo.svg" alt="async-subagent-isolation logo" width="150"></div>
|
|
4
|
+
|
|
5
|
+
# async-subagent-isolation
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
[]()
|
|
10
|
+
[]()
|
|
11
|
+
[](https://www.npmjs.com/package/@wolido/async-subagent-isolation)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
**async-subagent-isolation** is an extension for [Pi Agent](https://github.com/earendil-works/pi) and the **async evolution** of [subagent-isolation](https://github.com/Wolido/subagent-isolation) (the synchronous version).
|
|
17
|
+
|
|
18
|
+
The core constraint is unchanged: **the main agent can't touch code**. No `write`, no `edit`, no `bash` — only the four read-only tools `read`, `grep`, `find`, `ls`, plus a `subagent` tool for delegation. All file changes, shell commands, and execution logic go to subagents, each running in its own `pi` process with its own system prompt and skills. No shared state between the main agent and subagents, or between subagents.
|
|
19
|
+
|
|
20
|
+
The key difference is **async**: in TUI mode, the main agent dispatches a subagent and gets an **immediate receipt** (`已派出 <agent>. taskId: <taskId>`) without blocking. The subagent runs in a background process; when it finishes, the result arrives as a **[subagent-result] system notification**. If the main agent is idle the notification triggers processing right away; if busy, it queues. Meanwhile the main agent can dispatch multiple tasks in parallel and keep working.
|
|
21
|
+
|
|
22
|
+
Subagents split an ever-growing context into pieces, each handling its own slice; async keeps the main agent's context down to "what to do" and "what came back", while the subagent's long execution trail stays in its own process.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Sync vs async
|
|
27
|
+
|
|
28
|
+
This project is the async evolution of [subagent-isolation](https://github.com/Wolido/subagent-isolation). Both share the same goal — strip execution from the main agent and run it in isolated `pi` processes. The only difference is delegation semantics:
|
|
29
|
+
|
|
30
|
+
| | Sync (original) | Async (this project) |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| After dispatch | Blocks until the subagent finishes | **Returns a receipt immediately** (with `taskId`) |
|
|
33
|
+
| Result delivery | Inlined in the tool return value | Arrives as a `[subagent-result]` system notification |
|
|
34
|
+
| Parallelism | Each call blocks — serial only | Multiple tasks can be dispatched in parallel |
|
|
35
|
+
| Waiting period | Main agent's turn is occupied | Main agent continues other work |
|
|
36
|
+
| Result blocks the turn | Yes | No |
|
|
37
|
+
|
|
38
|
+
**The original project continues to be maintained as the synchronous version.** Use the original for synchronous, blocking semantics (results returned in place); use this project for async parallelism, background execution, and dispatch-and-return.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Face the dispatcher, not the cluster
|
|
43
|
+
|
|
44
|
+
In the sync version, every delegation blocks, so the experience feels like facing a "swarm of agents": the main agent dispatches and goes silent until the subagent finishes, leaving you with stretches of relayed execution. The async version flips this — **your conversation is always with the main agent alone**.
|
|
45
|
+
|
|
46
|
+
The main agent is the dispatcher: it understands the request, splits it into tasks, dispatches them, and summarizes the results. Subagents are behind-the-scenes workers, each running in its own background process and reporting back through a `[subagent-result]` notification. You never talk to a subagent directly, and you shouldn't need to: read results with `/subagent-result`, cancel with `/subagent-cancel`, and leave everything in between to the dispatcher.
|
|
47
|
+
|
|
48
|
+
More important is **the freedom after dispatch**. While a task runs in the background, you keep talking to the main agent — refine the requirements, adjust the plan, discuss next steps, or raise a new task. The main agent doesn't wait idle; it can keep planning and even dispatch more tasks in parallel. Foreground conversation and background work move forward together.
|
|
49
|
+
|
|
50
|
+
Finally, **review when the result returns**. The subagent finishes, the notification arrives, and the main agent processes it and reports back. While you wait, you can check in-flight status any time (the progress widget or `subagent_status`), but you never have to watch.
|
|
51
|
+
|
|
52
|
+
In one line: sync traps you in the "swarm execution" block; async keeps you facing a single dispatcher while background work runs alongside your own pace.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## How this differs from plain subagents
|
|
57
|
+
|
|
58
|
+
Many subagent implementations are just "spawn a tool call inside the main agent": the subagent still reuses the main agent's prompt and skills, and the main agent keeps write and shell access — isolation is optional and partial.
|
|
59
|
+
|
|
60
|
+
async-subagent-isolation enforces complete isolation:
|
|
61
|
+
|
|
62
|
+
- **Process isolation**: every subagent starts in its own `pi` process.
|
|
63
|
+
- **Prompt isolation**: each subagent has its own agent definition file (e.g. `coder.md`), not the main agent's `master.md`.
|
|
64
|
+
- **Skill isolation**: the main agent and each subagent load only their own skills, with no cross-contamination.
|
|
65
|
+
- **Execution isolation**: the main agent loses `write`, `edit`, and `bash`; it can only delegate.
|
|
66
|
+
- **Independent configuration**: each agent defines its own `tools` and `skills`, controlling exactly what it can and cannot do.
|
|
67
|
+
|
|
68
|
+
Beyond that, a subagent sees only the one task it was delegated — not the main agent's execution trail (context isolation) — and cannot delegate further (recursion depth capped at 1).
|
|
69
|
+
|
|
70
|
+
Plain subagents split work. async-subagent-isolation splits everything.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Async workflow
|
|
75
|
+
|
|
76
|
+
This is the biggest difference from the sync version, and the primary way to use it (TUI mode).
|
|
77
|
+
|
|
78
|
+
### 1. Dispatch (the `subagent` tool)
|
|
79
|
+
|
|
80
|
+
The main agent calls `subagent`, which spawns an isolated `pi` process. Non-TUI modes (print/json) automatically fall back to synchronous — they wait for the subagent and return the result directly, with no notification.
|
|
81
|
+
|
|
82
|
+
### 2. Receipt (returns immediately)
|
|
83
|
+
|
|
84
|
+
In TUI mode, `subagent` **returns a dispatch receipt immediately** and does not block:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
已派出 coder. taskId: 01912345-6789-7abc-8def-0123456789ab
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The `taskId` is the session ID; reuse it later to continue the same task. **The receipt is not the result** — do not fabricate results.
|
|
91
|
+
|
|
92
|
+
### 3. Background execution + progress widget
|
|
93
|
+
|
|
94
|
+
The subagent runs in a background process. A progress widget appears above the TUI editor, listing all in-flight tasks (taskId, agent, phase, elapsed time):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
● 01912345-abcd... coder ⚡ read... 01:23
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 4. Result notification (`[subagent-result]`)
|
|
101
|
+
|
|
102
|
+
When the subagent finishes, its result is pushed as a **`[subagent-result]` system notification** (a system message, not a user request):
|
|
103
|
+
|
|
104
|
+
- If the main agent is **idle**, the notification triggers a new turn immediately.
|
|
105
|
+
- If the main agent is **busy**, it is queued and triggers a turn after the current one finishes.
|
|
106
|
+
|
|
107
|
+
Results arrive automatically — **no polling**. To confirm which tasks are still in flight (e.g. after a `/tree` rewind loses the receipts), use the `subagent_status` tool.
|
|
108
|
+
|
|
109
|
+
### 5. Read the full result (`/subagent-result`)
|
|
110
|
+
|
|
111
|
+
The notification card shows only a summary. Use `/subagent-result <taskId>` to read the full output in a full-screen viewer: `↑↓`/`jk` scroll, `Space`/`b` page, `g`/`G` top/bottom, `Enter`/`Esc`/`q` close.
|
|
112
|
+
|
|
113
|
+
### The flow at a glance
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Main agent dispatches subagent
|
|
117
|
+
│ immediate receipt (已派出 <agent>. taskId: <id>)
|
|
118
|
+
▼
|
|
119
|
+
Subagent runs in a background process (progress widget updates live)
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
On completion, a [subagent-result] notification is pushed ──► processed now if idle, queued if busy
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
User runs /subagent-result <taskId> to read the full output
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Tools and commands
|
|
131
|
+
|
|
132
|
+
### Tools (for the main agent)
|
|
133
|
+
|
|
134
|
+
| Tool | Purpose | Key constraint |
|
|
135
|
+
|------|---------|----------------|
|
|
136
|
+
| `subagent` | Async dispatch (TUI mode); falls back to sync in non-TUI | Receipt ≠ result; results arrive as notifications, don't poll |
|
|
137
|
+
| `subagent_status` | List in-flight tasks (taskId, agent, description, **no elapsed time**) | Only confirm "what's still running"; never poll with it |
|
|
138
|
+
| `subagent_cancel` | Main agent cancels one in-flight task | Only when clearly wrong or no longer needed; never for being slow |
|
|
139
|
+
|
|
140
|
+
### Commands (for the user)
|
|
141
|
+
|
|
142
|
+
| Command | Purpose |
|
|
143
|
+
|---------|---------|
|
|
144
|
+
| `/subagent-cancel <taskId>` | Cancel one running background task (lists running tasks with no argument) |
|
|
145
|
+
| `/subagent-cancel-all` | Cancel all running background tasks at once |
|
|
146
|
+
| `/subagent-result <taskId>` | Read a task's full result in a full-screen viewer |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Notification envelope and card
|
|
151
|
+
|
|
152
|
+
The `[subagent-result]` notification is **self-contained** — it carries everything the main agent needs to process the result in one message:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
## [subagent-result] coder 成功 (taskId: 01912345-6789-7abc-8def-0123456789ab)
|
|
156
|
+
|
|
157
|
+
- 状态: 成功
|
|
158
|
+
- 任务: 将认证中间件重构为使用 async/await。
|
|
159
|
+
- 耗时: 02:34 · 用量: 5 turns/↑12.5k/↓3.2k/$0.0042
|
|
160
|
+
- 会话: 01912345-6789-7abc-8def-0123456789ab
|
|
161
|
+
|
|
162
|
+
在途任务: 1
|
|
163
|
+
- 01912345-aaaa-7bbb-8ccc-0123456789ab (writer): 更新 README。
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
<full subagent output>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- **Status**: `成功` (success) / `失败` (failure) / `超时` (timeout) / `已取消` (cancelled).
|
|
170
|
+
- **In-flight block**: lists the other background tasks still running (not itself), so the main agent knows how many are outstanding — while the count is non-zero, do not report "all done" to the user.
|
|
171
|
+
- **Full result**: the body enters the LLM context in full, untruncated.
|
|
172
|
+
|
|
173
|
+
In the TUI, the user sees a **tinted summary card**, not the full result: success green (✓), failure red (✗), timeout/cancelled yellow. The card shows the agent, status, taskId, and usage summary, plus the hint `查看全文: /subagent-result <taskId>`; the full text lives in the task's session file.
|
|
174
|
+
|
|
175
|
+
See [ADVANCED.en.md](ADVANCED.en.md) for the complete envelope format, status semantics, and cancel-origin distinctions.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Design discipline
|
|
180
|
+
|
|
181
|
+
Async mode introduces a few rules, baked into the tool prompts and implementation, that the main agent follows automatically:
|
|
182
|
+
|
|
183
|
+
- **Cancel-origin distinction**: `已取消` (cancelled) has three origins — user (`/subagent-cancel`), main agent (`subagent_cancel` tool), and session shutdown (`session_shutdown`). A user-initiated cancel must **never be auto-retried**; ask the user first.
|
|
184
|
+
- **No polling**: results arrive automatically as notifications. `subagent_status` only confirms what's in flight (e.g. after a `/tree` rewind), carries no elapsed time, and is not meant to be called frequently.
|
|
185
|
+
- **Anti-abuse cancellation**: `subagent_cancel` ships with prompt guidance — cancel only when the task is clearly wrong or no longer needed, never just because it's slow (background subagents are expected to run long).
|
|
186
|
+
- **Resource-conflict discipline**: before dispatching multiple tasks in parallel, consider whether they touch the same files or code areas; when in doubt, dispatch sequentially or ask the user.
|
|
187
|
+
- **Recursion blocked entirely**: a subagent (depth ≥ 1) can never dispatch `subagent`; delegation depth is capped at 1.
|
|
188
|
+
- **TUI async / non-TUI sync fallback**: only TUI mode takes the async path; print/json and other non-TUI modes fall back to synchronous blocking.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Prerequisites: install Pi Agent
|
|
193
|
+
|
|
194
|
+
Install Pi Agent first (Node.js >= 20 required):
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
curl -fsSL https://pi.dev/install.sh | sh
|
|
198
|
+
# or via npm:
|
|
199
|
+
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Quick start
|
|
205
|
+
|
|
206
|
+
### 1. Install the extension
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
pi install npm:@wolido/async-subagent-isolation
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 2. Copy the example agents and skills
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
cp examples/pi/agent/agents/*.md ~/.pi/agent/agents/
|
|
216
|
+
cp examples/pi/agent/master.md ~/.pi/agent/master.md
|
|
217
|
+
cp -r examples/pi/agent/skills/* ~/.pi/agent/skills/
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 3. Start the main agent
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
pi --tools read,grep,find,ls,subagent \
|
|
224
|
+
--no-skills \
|
|
225
|
+
--append-system-prompt ~/.pi/agent/master.md \
|
|
226
|
+
--skill ~/.pi/agent/skills/brainstorming/
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
This restricts the main agent to read-only tools plus `subagent` delegation (no `write`/`edit`/`bash`), and loads the main agent prompt and brainstorming skill. For daily use, add an alias:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
alias pp='pi --tools read,grep,find,ls,subagent --no-skills --append-system-prompt ~/.pi/agent/master.md --skill ~/.pi/agent/skills/brainstorming/'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Then just say what you need — for example, "Refactor the auth middleware to use async/await." The main agent dispatches the `coder` subagent automatically. Subagents (`coder`, `writer`) load their own skills via the `skills:` frontmatter field — no CLI flag needed. For project-scoped agents, place them in `.pi/agents/`.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Example agents
|
|
240
|
+
|
|
241
|
+
The GitHub repo ships three ready-to-reference agents in [`examples/pi/agent/agents/`](https://github.com/Wolido/subagent-isolation/tree/main/examples/pi/agent/agents):
|
|
242
|
+
|
|
243
|
+
| Agent | Purpose | Tools | Skill |
|
|
244
|
+
|-------|---------|-------|-------|
|
|
245
|
+
| [`coder`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/coder.md) | Write, modify, and validate code | `read, write, edit, bash, grep, find, ls` | `systematic-debugging` |
|
|
246
|
+
| [`reviewer`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/reviewer.md) | Read-only review with actionable feedback | `read, grep, find, ls` | _(none)_ |
|
|
247
|
+
| [`writer`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/writer.md) | Write docs, READMEs, commit messages | `read, write, edit, grep, find, ls` | `writing-clearly-and-concisely` |
|
|
248
|
+
|
|
249
|
+
Copy the ones you need into `~/.pi/agent/agents/` (user-scoped) or `.pi/agents/` (project-scoped; project overrides user on name collisions). Feel free to modify them or create your own.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Per-subagent model configuration
|
|
254
|
+
|
|
255
|
+
Use `subagent-isolation.json` to assign a model and thinking level per subagent (the file name is retained from the sync original, so both projects can share the same config):
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"coder": { "model": "deepseek/deepseek-v4-pro", "thinking": "high" },
|
|
260
|
+
"writer": "deepseek/deepseek-v4-flash"
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Put it in `~/.pi/agent/subagent-isolation.json` (user-level) or `.pi/subagent-isolation.json` (project-level, which overrides user-level keys of the same name). Thinking levels, priority, and merge rules are in [ADVANCED.en.md](ADVANCED.en.md).
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Example skills
|
|
269
|
+
|
|
270
|
+
`examples/pi/agent/skills/` ships three skills: `brainstorming` (main-agent planning), `systematic-debugging` (coder), and `writing-clearly-and-concisely` (writer). Copy them into `~/.pi/agent/skills/` (user scope) or `.pi/skills/` (project scope). Subagents load them automatically via the `skills:` frontmatter field; the main agent loads them with the `--skill` flag.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Advanced usage
|
|
275
|
+
|
|
276
|
+
Manual `subagent` calls, `sessionId` reuse, envelope and in-flight block details, `subagent_status` queries, cancellation, and environment variables are covered in [ADVANCED.en.md](ADVANCED.en.md).
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Project structure
|
|
281
|
+
|
|
282
|
+
- `src/index.ts` — main extension source
|
|
283
|
+
- `examples/pi/agent/` — example agent and skill definitions (`master.md`, `agents/`, `skills/`)
|
|
284
|
+
- `package.json` — npm package manifest
|
|
285
|
+
- `tsconfig.json` — TypeScript configuration
|
|
286
|
+
- `README.md` / `README.en.md` — documentation
|
|
287
|
+
- `ADVANCED.md` / `ADVANCED.en.md` — advanced reference
|
|
288
|
+
- `LICENSE` — MIT license
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
<div align="right"><a href="README.en.md">English</a></div>
|
|
2
|
+
|
|
3
|
+
<div align="center"><img src="logo.svg" alt="async-subagent-isolation logo" width="150"></div>
|
|
4
|
+
|
|
5
|
+
# async-subagent-isolation
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
[]()
|
|
10
|
+
[]()
|
|
11
|
+
[](https://www.npmjs.com/package/@wolido/async-subagent-isolation)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
**async-subagent-isolation** 是 [Pi Agent](https://github.com/earendil-works/pi) 的扩展,也是 [subagent-isolation](https://github.com/Wolido/subagent-isolation)(同步版)的**异步演进**。
|
|
17
|
+
|
|
18
|
+
核心约束不变:**主 agent 不能碰代码**。没有 `write`、没有 `edit`、没有 `bash`,只有 `read`、`grep`、`find`、`ls` 四个只读工具,外加一个 `subagent` 工具用来委派任务。所有修改文件、跑命令、执行逻辑的工作都交给子 agent——每个子 agent 跑在独立的 `pi` 进程中,有自己的 system prompt 和 skills,主 agent 与子 agent、子 agent 与子 agent 之间进程完全隔离。
|
|
19
|
+
|
|
20
|
+
关键区别在**异步**:TUI 模式下,主 agent 派发子 agent 后**立即返回回执**(`已派出 <agent>. taskId: <taskId>`),不阻塞等待;子 agent 在后台独立进程运行,完成后结果以 **[subagent-result] 系统通知**推回对话。主 agent 空闲时通知直接触发处理,忙碌时排队。等待期间主 agent 可以并行派发多个任务、继续做其他工作。
|
|
21
|
+
|
|
22
|
+
子 agent 把不断膨胀的上下文切成小块、各管一段;异步让主 agent 的上下文只保留"要做什么"和"结果是什么",子 agent 冗长的执行痕迹留在自己的进程里,不污染主 agent。
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 同步版 vs 异步版
|
|
27
|
+
|
|
28
|
+
本项目是 [subagent-isolation](https://github.com/Wolido/subagent-isolation) 的异步演进,两者目标一致——把执行能力从主 agent 剥离、放进隔离的 `pi` 进程;区别只在委派语义:
|
|
29
|
+
|
|
30
|
+
| | 同步版(原项目) | 异步版(本项目) |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| 派发后 | 阻塞等待子 agent 完成 | **立即返回回执**(含 `taskId`) |
|
|
33
|
+
| 结果呈现 | 在工具返回值处直接内联 | 以 `[subagent-result]` 系统通知到达 |
|
|
34
|
+
| 并行 | 每次调用阻塞,只能串行 | 可并行派发多个任务 |
|
|
35
|
+
| 等待期 | 主 agent 回合被占用 | 等待期间继续其他工作 |
|
|
36
|
+
| 结果是否阻塞主 agent 回合 | 阻塞 | 不阻塞 |
|
|
37
|
+
|
|
38
|
+
**原项目继续作为同步版维护。** 需要同步阻塞语义(结果就在调用处返回)用原项目;需要异步并行、后台执行、派发即返回用本项目。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 直接面对调度者
|
|
43
|
+
|
|
44
|
+
同步版里,每次委派都阻塞等待,体验上你面对的是一个"智能体集群":主 agent 派完活就沉默,等子 agent 干完才回来,中间是一段段接力执行的空白。异步版把这一点翻了过来,**你的对话对象始终只有主 agent 一个**。
|
|
45
|
+
|
|
46
|
+
主 agent 是调度者:理解需求、拆任务、派发、汇总结果。子 agent 是幕后工人,每个都在后台独立进程里跑,完成后用 `[subagent-result]` 通知把结果送回主 agent。你不直接和子 agent 对话,也不需要;查看结果用 `/subagent-result`,取消任务用 `/subagent-cancel`,中间过程交给调度者。
|
|
47
|
+
|
|
48
|
+
更关键的是**派发之后的自由**。任务在后台跑的时候,你可以继续和主 agent 聊天:细化需求、调整规划、商量下一步,或提出新任务。主 agent 不必干等,可以继续规划,甚至并行派发更多任务。前台对话与后台工作并行推进。
|
|
49
|
+
|
|
50
|
+
最后是**结果回来再验收**。子 agent 完成,通知到达,主 agent 处理并向你汇报。等待期间你可以随时查看在途状态(进度 widget 或 `subagent_status`),但不必盯着。
|
|
51
|
+
|
|
52
|
+
一句话:同步版让你陷在"集群执行"的阻塞感里;异步版让你只面对调度者,后台工作与你自己的节奏并行。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 和常规子 agent 的区别
|
|
57
|
+
|
|
58
|
+
很多子 agent 实现只是"在主 agent 内部开一个工具调用":子 agent 仍复用主 agent 的提示词和 skills,主 agent 也仍保留写文件、跑命令的能力——隔离是可选的、不彻底的。
|
|
59
|
+
|
|
60
|
+
async-subagent-isolation 做的是强制且完全的隔离:
|
|
61
|
+
|
|
62
|
+
- **进程完全隔离**:每个子 agent 启动独立的 `pi` 进程。
|
|
63
|
+
- **提示词完全隔离**:子 agent 有自己的 agent 定义文件(如 `coder.md`),不继承主 agent 的 `master.md`。
|
|
64
|
+
- **Skills 完全隔离**:主 agent 和每个子 agent 各自加载自己的 skill,互不干扰。
|
|
65
|
+
- **执行能力完全隔离**:主 agent 被剥夺 `write`/`edit`/`bash`,只能委派,无法自己执行。
|
|
66
|
+
- **独立可配置**:每个 agent 单独定义自己的 `tools` 和 `skills`,精确控制它能做什么、不能做什么。
|
|
67
|
+
|
|
68
|
+
此外,子 agent 只拿到委派的那一句话、看不到主 agent 的执行痕迹(上下文隔离),且不可再委派(递归深度限制为 1)。
|
|
69
|
+
|
|
70
|
+
常规子 agent 是"分工";async-subagent-isolation 是"彻底分家"。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 异步工作流
|
|
75
|
+
|
|
76
|
+
这是与同步版最大的不同,也是核心使用方式(TUI 模式)。
|
|
77
|
+
|
|
78
|
+
### 1. 派发(`subagent` 工具)
|
|
79
|
+
|
|
80
|
+
主 agent 调用 `subagent`,为子 agent 启动独立的 `pi` 进程。非 TUI 模式(print/json)自动降级为同步——等待完成后直接返回结果,无通知。
|
|
81
|
+
|
|
82
|
+
### 2. 回执(立即返回)
|
|
83
|
+
|
|
84
|
+
TUI 模式下 `subagent` **立即返回派发回执**,不阻塞:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
已派出 coder. taskId: 01912345-6789-7abc-8def-0123456789ab
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`taskId` 就是 session ID,之后可复用来继续同一任务。**回执不是结果**——不要臆造结果。
|
|
91
|
+
|
|
92
|
+
### 3. 后台执行 + 进度 widget
|
|
93
|
+
|
|
94
|
+
子 agent 在后台独立进程运行。TUI 编辑器上方显示进度 widget,实时列出所有在飞任务(taskId、agent、当前阶段、耗时):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
● 01912345-abcd... coder ⚡ read... 01:23
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 4. 结果通知(`[subagent-result]`)
|
|
101
|
+
|
|
102
|
+
子 agent 完成后,结果以 **`[subagent-result]` 系统通知**推送到对话(系统消息,不是用户请求):
|
|
103
|
+
|
|
104
|
+
- 主 agent **空闲**时,通知直接触发新的对话回合,立即处理。
|
|
105
|
+
- 主 agent **忙碌**时,通知进入队列,当前回合结束后再触发。
|
|
106
|
+
|
|
107
|
+
结果自动到达,**无需轮询**。如需确认还有哪些任务在途(例如 `/tree` 回退后回执丢失),用 `subagent_status` 工具查询。
|
|
108
|
+
|
|
109
|
+
### 5. 查看全文(`/subagent-result`)
|
|
110
|
+
|
|
111
|
+
通知卡片只显示摘要。用 `/subagent-result <taskId>` 在全屏查看器中阅读完整返回:`↑↓`/`jk` 滚动、`Space`/`b` 翻页、`g`/`G` 首尾、`Enter`/`Esc`/`q` 关闭。
|
|
112
|
+
|
|
113
|
+
### 完整流程一览
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
主 agent 派发 subagent
|
|
117
|
+
│ 立即返回回执(已派出 <agent>. taskId: <id>)
|
|
118
|
+
▼
|
|
119
|
+
子 agent 在后台独立进程运行(进度 widget 实时显示)
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
完成后推 [subagent-result] 系统通知 ──► 主 agent 空闲直接处理 / 忙碌排队
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
用户 /subagent-result <taskId> 查看完整返回
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 工具与命令面
|
|
131
|
+
|
|
132
|
+
### 工具(主 agent 使用)
|
|
133
|
+
|
|
134
|
+
| 工具 | 作用 | 关键约束 |
|
|
135
|
+
|------|------|----------|
|
|
136
|
+
| `subagent` | 异步派发任务(TUI 模式);非 TUI 自动降级同步 | 回执≠结果;结果以通知到达,勿轮询 |
|
|
137
|
+
| `subagent_status` | 查询在途任务(taskId、agent、任务描述,**无耗时**) | 仅确认"还有什么在跑",勿用它轮询完成 |
|
|
138
|
+
| `subagent_cancel` | 主 agent 取消单个在途任务 | 仅当任务明显错误或不再需要,勿因耗时久而取消 |
|
|
139
|
+
|
|
140
|
+
### 命令(用户使用)
|
|
141
|
+
|
|
142
|
+
| 命令 | 作用 |
|
|
143
|
+
|------|------|
|
|
144
|
+
| `/subagent-cancel <taskId>` | 取消单个运行中的后台任务(不带参数时列出运行中任务) |
|
|
145
|
+
| `/subagent-cancel-all` | 一键取消全部运行中的后台任务 |
|
|
146
|
+
| `/subagent-result <taskId>` | 全屏查看某任务的完整返回 |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 通知信封与卡片
|
|
151
|
+
|
|
152
|
+
`[subagent-result]` 通知是**自包含**的,一次带全主 agent 处理结果所需的全部信息:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
## [subagent-result] coder 成功 (taskId: 01912345-6789-7abc-8def-0123456789ab)
|
|
156
|
+
|
|
157
|
+
- 状态: 成功
|
|
158
|
+
- 任务: 将认证中间件重构为使用 async/await。
|
|
159
|
+
- 耗时: 02:34 · 用量: 5 turns/↑12.5k/↓3.2k/$0.0042
|
|
160
|
+
- 会话: 01912345-6789-7abc-8def-0123456789ab
|
|
161
|
+
|
|
162
|
+
在途任务: 1
|
|
163
|
+
- 01912345-aaaa-7bbb-8ccc-0123456789ab (writer): 更新 README。
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
<子 agent 完整结果文本>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- **状态**:`成功` / `失败` / `超时` / `已取消`。
|
|
170
|
+
- **在途任务块**:列出其余仍在运行的后台任务(不含自身),让主 agent 知道还有几个任务没回来——剩余不为 0 时,不要向用户汇报"全部完成"。
|
|
171
|
+
- **完整结果**:正文全量进入 LLM 上下文,不截断。
|
|
172
|
+
|
|
173
|
+
用户在 TUI 中看到的是**带底色的摘要卡片**,不是全文:成功绿色(✓)、失败红色(✗)、超时/已取消黄色。卡片只显示 agent、状态、taskId 和用量摘要,并提示 `查看全文: /subagent-result <taskId>`;完整结果保存在任务会话文件中。
|
|
174
|
+
|
|
175
|
+
信封完整格式、状态语义与取消来源区分见 [ADVANCED.md](ADVANCED.md)。
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 设计纪律
|
|
180
|
+
|
|
181
|
+
异步模式引入的几条纪律,内嵌在工具提示词和实现中,主 agent 自动遵守:
|
|
182
|
+
|
|
183
|
+
- **取消来源区分**:`已取消` 有用户(`/subagent-cancel`)、主 agent(`subagent_cancel`)、会话关闭(`session_shutdown`)三种来源;用户取消**不得自动重试**,须先询问。
|
|
184
|
+
- **防轮询**:结果以通知自动到达;`subagent_status` 只用于确认在途(如 `/tree` 回退后),不带耗时、不鼓励频繁调用。
|
|
185
|
+
- **防滥用取消**:`subagent_cancel` 内嵌提示词——仅当任务明显错误或不再需要时取消,勿因耗时长而取消(后台任务本就预期长时间运行)。
|
|
186
|
+
- **资源冲突纪律**:并行派发多个任务前,考虑它们是否会改同一批文件或代码区域;冲突时串行派发或先问用户。
|
|
187
|
+
- **递归委派完全禁止**:子 agent(深度 ≥ 1)不可再派发 `subagent`,深度限制为 1。
|
|
188
|
+
- **TUI 异步 / 非 TUI 同步降级**:只在 TUI 模式走异步路径;print/json 等非 TUI 模式降级为同步阻塞。
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 前置条件:安装 Pi Agent
|
|
193
|
+
|
|
194
|
+
先安装 Pi Agent(需 Node.js >= 20):
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
curl -fsSL https://pi.dev/install.sh | sh
|
|
198
|
+
# 或通过 npm:
|
|
199
|
+
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 快速开始
|
|
205
|
+
|
|
206
|
+
### 1. 安装扩展
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
pi install npm:@wolido/async-subagent-isolation
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 2. 复制示例 agent 与 skill
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
cp examples/pi/agent/agents/*.md ~/.pi/agent/agents/
|
|
216
|
+
cp examples/pi/agent/master.md ~/.pi/agent/master.md
|
|
217
|
+
cp -r examples/pi/agent/skills/* ~/.pi/agent/skills/
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 3. 启动主 agent
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
pi --tools read,grep,find,ls,subagent \
|
|
224
|
+
--no-skills \
|
|
225
|
+
--append-system-prompt ~/.pi/agent/master.md \
|
|
226
|
+
--skill ~/.pi/agent/skills/brainstorming/
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
这条命令把主 agent 限制为只读工具 + `subagent` 委派(剥夺 `write`/`edit`/`bash`),并加载主 agent 提示词和 brainstorming skill。日常使用可设 alias:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
alias pp='pi --tools read,grep,find,ls,subagent --no-skills --append-system-prompt ~/.pi/agent/master.md --skill ~/.pi/agent/skills/brainstorming/'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
启动后直接说需求,例如"把认证中间件重构为 async/await",主 agent 会自动派 `coder` 子 agent。子 agent(coder、writer)通过 frontmatter 的 `skills:` 字段自动加载各自 skill,无需命令行指定;项目级 agent 放 `.pi/agents/` 即可。
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 示例 agents
|
|
240
|
+
|
|
241
|
+
仓库 [`examples/pi/agent/agents/`](https://github.com/Wolido/subagent-isolation/tree/main/examples/pi/agent/agents) 提供三个可直接参考的 agent:
|
|
242
|
+
|
|
243
|
+
| Agent | 作用 | 可用工具 | 加载的 skill |
|
|
244
|
+
|-------|------|----------|-------------|
|
|
245
|
+
| [`coder`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/coder.md) | 写代码、改代码、跑验证 | `read, write, edit, bash, grep, find, ls` | `systematic-debugging` |
|
|
246
|
+
| [`reviewer`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/reviewer.md) | 只读评审,输出可操作的反馈 | `read, grep, find, ls` | _(无)_ |
|
|
247
|
+
| [`writer`](https://github.com/Wolido/subagent-isolation/blob/main/examples/pi/agent/agents/writer.md) | 写文档、改 README、生成 commit message | `read, write, edit, grep, find, ls` | `writing-clearly-and-concisely` |
|
|
248
|
+
|
|
249
|
+
复制到 `~/.pi/agent/agents/`(用户级)或 `.pi/agents/`(项目级,同名时 project 覆盖 user)即可使用,可按需修改或新建。
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 为子 agent 指定模型
|
|
254
|
+
|
|
255
|
+
可用 `subagent-isolation.json` 为每个子 agent 单独指定模型与 thinking level(配置文件名沿用同步版,两者可共享):
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"coder": { "model": "deepseek/deepseek-v4-pro", "thinking": "high" },
|
|
260
|
+
"writer": "deepseek/deepseek-v4-flash"
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
文件放在 `~/.pi/agent/subagent-isolation.json`(用户级)或 `.pi/subagent-isolation.json`(项目级,覆盖用户级同名 key)。thinking 等级、优先级与合并规则详见 [ADVANCED.md](ADVANCED.md)。
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 示例 skills
|
|
269
|
+
|
|
270
|
+
`examples/pi/agent/skills/` 提供三个 skill:`brainstorming`(主 agent 规划)、`systematic-debugging`(coder)、`writing-clearly-and-concisely`(writer)。复制到 `~/.pi/agent/skills/`(用户级)或 `.pi/skills/`(项目级)即可;子 agent 在 frontmatter 用 `skills:` 声明自动加载,主 agent 用 `--skill` 标志加载。
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 进阶用法
|
|
275
|
+
|
|
276
|
+
手写 `subagent` 调用、复用 `sessionId`、信封与在途任务块细节、`subagent_status` 查询、取消任务、环境变量等见 [ADVANCED.md](ADVANCED.md)。
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 项目结构
|
|
281
|
+
|
|
282
|
+
- `src/index.ts` — 扩展主源码
|
|
283
|
+
- `examples/pi/agent/` — 示例 agent 和 skill 定义(`master.md`、`agents/`、`skills/`)
|
|
284
|
+
- `package.json` — npm 包清单
|
|
285
|
+
- `tsconfig.json` — TypeScript 配置
|
|
286
|
+
- `README.md` / `README.en.md` — 说明文档
|
|
287
|
+
- `ADVANCED.md` / `ADVANCED.en.md` — 进阶参考
|
|
288
|
+
- `LICENSE` — MIT 许可证
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
MIT
|