@harms-haus/pi-subagents 0.1.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/LICENSE +21 -0
- package/README.md +362 -0
- package/docs/architecture.md +554 -0
- package/docs/changelog.md +61 -0
- package/docs/profiles.md +546 -0
- package/docs/settings.md +52 -0
- package/docs/tools-reference.md +519 -0
- package/package.json +59 -0
- package/src/cache.ts +24 -0
- package/src/commands/profile.ts +176 -0
- package/src/format-tool-call.ts +597 -0
- package/src/format-transcript.ts +151 -0
- package/src/index.ts +117 -0
- package/src/profile-editor.ts +356 -0
- package/src/profile-formatting.ts +178 -0
- package/src/profile-types.ts +73 -0
- package/src/profiles.ts +577 -0
- package/src/schemas.ts +65 -0
- package/src/settings.ts +155 -0
- package/src/skill-discovery.ts +30 -0
- package/src/spawner.ts +523 -0
- package/src/tools/delegate-render.ts +285 -0
- package/src/tools/delegate.ts +867 -0
- package/src/tools/retrieval.ts +287 -0
- package/src/types.ts +232 -0
- package/src/utils.ts +168 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 harms-haus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# pi-subagents
|
|
2
|
+
|
|
3
|
+
A pi extension that allows the main agent to spawn parallel sub-agents, with each sub-agent's latest output rendered in a rolling TUI window inline with the main agent's conversation history.
|
|
4
|
+
|
|
5
|
+
Sub-agents can optionally use **named profiles** that pre-configure provider/model, system prompts, thinking levels, and other model settings. Profiles are stored as individual `.md` files with YAML frontmatter.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### Installed as a pi package (Recommended)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pi install git:github.com/harms-haus/pi-subagents
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or use `https://` / `ssh://` instead of `git:` if you prefer.
|
|
16
|
+
|
|
17
|
+
### Local Development
|
|
18
|
+
|
|
19
|
+
Clone the repo and install the local path (use `-l` for project-local install):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd pi-subagents
|
|
23
|
+
pi install . -l
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Once installed, the LLM can use the tool:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"delegate_to_subagents": {
|
|
33
|
+
"tasks": [
|
|
34
|
+
{
|
|
35
|
+
"name": "linter-src",
|
|
36
|
+
"prompt": "Review and fix all linting errors in the src/ directory."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "linter-tests",
|
|
40
|
+
"prompt": "Review and fix all linting errors in the tests/ directory.",
|
|
41
|
+
"profile": "fast-worker"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Providing File Context
|
|
49
|
+
|
|
50
|
+
Each task can include a `files` array to read file contents and prepend them to the sub-agent's prompt:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"delegate_to_subagents": {
|
|
55
|
+
"tasks": [
|
|
56
|
+
{
|
|
57
|
+
"name": "fix-lint",
|
|
58
|
+
"prompt": "Fix all linting errors in this file.",
|
|
59
|
+
"files": ["src/utils.ts"]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
File specs support line ranges: `{ "path": "src/main.ts", "start": 10, "end": 50 }`, `{ "path": "log.txt", "tail": 20 }`, or `{ "path": "config.json", "head": 5 }`.
|
|
67
|
+
|
|
68
|
+
> See [docs/tools-reference.md](docs/tools-reference.md) for complete parameter documentation.
|
|
69
|
+
|
|
70
|
+
After `delegate_to_subagents` completes, it returns **session IDs** for each task. Use `get_subagent_output` to retrieve the final text output:
|
|
71
|
+
|
|
72
|
+
### Parameters
|
|
73
|
+
|
|
74
|
+
| Name | Type | Required | Description |
|
|
75
|
+
| --------- | ------------------------------------------------------------------ | -------- | ---------------------------------------------------------------- |
|
|
76
|
+
| `tasks` | `Array<{name, prompt, cwd?, profile?, timeout?, resume?, files?}>` | Yes | Array of tasks to delegate. Each gets its own sub-agent process. |
|
|
77
|
+
| `profile` | `string` | No | Default profile for all tasks (overridden by per-task profile) |
|
|
78
|
+
|
|
79
|
+
Each task:
|
|
80
|
+
|
|
81
|
+
| Field | Type | Required | Description |
|
|
82
|
+
| --------- | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `name` | `string` | Yes | Display label shown in the TUI window header |
|
|
84
|
+
| `prompt` | `string` | Yes | Prompt sent to the sub-agent (same as typing into pi directly) |
|
|
85
|
+
| `cwd` | `string` | No | Working directory for the sub-agent (default: current directory) |
|
|
86
|
+
| `profile` | `string` | No | Named profile to use for this sub-agent (see below) |
|
|
87
|
+
| `timeout` | `number` | No | Timeout in seconds for this sub-agent. Default: 600. Timeouts auto-extend when the sub-agent is actively producing output — after the initial timeout expires, the sub-agent is only killed after a configurable idle period (see `extend_timeout_debounce` setting). |
|
|
88
|
+
| `resume` | `string` | No | Previous session ID to resume from. The resumed sub-agent receives the prior session's transcript as context. Only completed or errored sessions can be resumed. |
|
|
89
|
+
| `files` | `Array<FileSpec>` | No | File paths to read and prepend to the sub-agent's prompt. See "Providing File Context" above. |
|
|
90
|
+
|
|
91
|
+
The `maxLinesPerWindow` setting is configured in `settings.json` under `subagents.maxLinesPerWindow` (default: 15).
|
|
92
|
+
|
|
93
|
+
### Retrieving Sub-agent Output
|
|
94
|
+
|
|
95
|
+
After `delegate_to_subagents` completes, each task has a session ID. Use these tools to retrieve results:
|
|
96
|
+
|
|
97
|
+
- **`get_subagent_output(sessionId)`** — Returns the last assistant text output from a sub-agent session. For resumed sessions, returns the latest run's output. This is the primary way to get results.
|
|
98
|
+
- **`get_subagent_session(sessionId)`** — Returns the full session transcript including all messages, tool calls, and results. For resumed sessions, returns all runs' data concatenated. Use for debugging.
|
|
99
|
+
- **`list_subagent_profiles()`** — Lists all available subagent profiles that can be used with `delegate_to_subagents`.
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"get_subagent_output": {
|
|
104
|
+
"sessionId": "a1b2c3d4e5f6a7b8"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Resuming Sessions
|
|
110
|
+
|
|
111
|
+
Use the `resume` parameter to continue work from a previously completed (or errored) sub-agent session. The resumed agent receives the full transcript of all prior runs prepended to its prompt:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"delegate_to_subagents": {
|
|
116
|
+
"tasks": [
|
|
117
|
+
{
|
|
118
|
+
"name": "continue-refactor",
|
|
119
|
+
"prompt": "Continue the refactoring. Focus on the remaining utility modules.",
|
|
120
|
+
"resume": "a1b2c3d4e5f6a7b8"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Key behaviors:
|
|
128
|
+
|
|
129
|
+
- The resumed agent's prompt is prefixed with `Previously:\n\n<transcript>\n\nInstructions:\n\n<your prompt>`, giving it full context of prior work.
|
|
130
|
+
- Only **completed** or **errored** sessions can be resumed. Running sessions will throw an error.
|
|
131
|
+
- A session can be resumed multiple times — each resume creates a new "run" appended to the session record.
|
|
132
|
+
- `get_subagent_output` returns output from the **latest run** only.
|
|
133
|
+
- `get_subagent_session` returns **all runs** concatenated with run separators.
|
|
134
|
+
|
|
135
|
+
## Subagent Profiles
|
|
136
|
+
|
|
137
|
+
Profiles let you pre-configure the provider, model, system prompt, thinking level, and other settings for sub-agents. Each profile is a `.md` file with YAML frontmatter.
|
|
138
|
+
|
|
139
|
+
### Profile Locations
|
|
140
|
+
|
|
141
|
+
| Scope | Directory |
|
|
142
|
+
| ------- | --------------------------------- |
|
|
143
|
+
| Global | `~/.pi/agent/agent-profiles/*.md` |
|
|
144
|
+
| Project | `.pi/agent-profiles/*.md` |
|
|
145
|
+
|
|
146
|
+
Project-local profiles override global profiles with the same name.
|
|
147
|
+
|
|
148
|
+
### Example Profiles
|
|
149
|
+
|
|
150
|
+
**`~/.pi/agent/agent-profiles/code-reviewer.md`**:
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
---
|
|
154
|
+
name: code-reviewer
|
|
155
|
+
provider: anthropic
|
|
156
|
+
model: claude-sonnet-4-5
|
|
157
|
+
thinkingLevel: high
|
|
158
|
+
tools: read,bash,grep,find
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
You are an expert code reviewer. Focus on bugs, security issues, and performance problems. Be thorough but concise.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**`~/.pi/agent/agent-profiles/fast-worker.md`**:
|
|
165
|
+
|
|
166
|
+
```markdown
|
|
167
|
+
---
|
|
168
|
+
name: fast-worker
|
|
169
|
+
model: dashscope/qwen3.5-plus
|
|
170
|
+
appendSystemPrompt: Be concise. Skip explanations unless asked.
|
|
171
|
+
thinkingLevel: off
|
|
172
|
+
---
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**`.pi/agent-profiles/researcher.md`** (project-local):
|
|
176
|
+
|
|
177
|
+
```markdown
|
|
178
|
+
---
|
|
179
|
+
name: researcher
|
|
180
|
+
provider: openai
|
|
181
|
+
model: gpt-4o
|
|
182
|
+
appendSystemPrompt: Use web search to find information. Cite sources when possible.
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
You are a research assistant.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Profile Fields
|
|
189
|
+
|
|
190
|
+
| Field | Type | Description |
|
|
191
|
+
| -------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
192
|
+
| `name` | `string` | **Required.** Profile identifier (from YAML frontmatter name field) |
|
|
193
|
+
| `provider` | `string` | Provider name (e.g., `"anthropic"`, `"openai"`, `"dashscope"`) |
|
|
194
|
+
| `model` | `string` | Model pattern or ID. Supports `"provider/id"` format and `":thinking"` shorthand (e.g., `"sonnet:high"`) |
|
|
195
|
+
| `systemPrompt` | N/A | Set via the **body** of the markdown file (text after `---`). Replaces the default system prompt entirely. |
|
|
196
|
+
| `appendSystemPrompt` | `string` | Append text to the default system prompt |
|
|
197
|
+
| `thinkingLevel` | `string` | Thinking level: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"` |
|
|
198
|
+
| `noTools` | `boolean` | Disable all tools |
|
|
199
|
+
| `tools` | `string` or `string[]` | Comma-separated string or YAML array of tool names to enable (allowlist) |
|
|
200
|
+
| `excludeTools` | `string` or `string[]` | Comma-separated string or YAML array of tool names to exclude (blacklist; mutually exclusive with `tools`) |
|
|
201
|
+
| `noExtensions` | `boolean` | Disable all extensions |
|
|
202
|
+
| `extensions` | `string` or `string[]` | Comma-separated string or YAML array of extension paths to load |
|
|
203
|
+
| `noSkills` | `boolean` | Disable skills. Mutually exclusive with `suggestedSkills` and `loadSkills` |
|
|
204
|
+
| `suggestedSkills` | `string` or `string[]` | Skill names to _suggest_ to the sub-agent via `--skill` CLI flags; the model chooses whether to load them |
|
|
205
|
+
| `loadSkills` | `string` or `string[]` | Skill names to _pre-load_ into the sub-agent's system prompt (content wrapped in `<loaded_skill>` XML tags) |
|
|
206
|
+
| `noContextFiles` | `boolean` | Disable AGENTS.md/CLAUDE.md context files |
|
|
207
|
+
| `apiKey` | `string` | Custom API key (stored as `PI_API_KEY` env var, not in CLI args) |
|
|
208
|
+
| `extraArgs` | `string` or `string[]` | Comma-separated string or YAML array of additional CLI arguments |
|
|
209
|
+
|
|
210
|
+
Array fields (`tools`, `extensions`, `extraArgs`, `suggestedSkills`, `loadSkills`) support both YAML arrays and comma-separated strings:
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
tools:
|
|
214
|
+
- read
|
|
215
|
+
- bash
|
|
216
|
+
- grep
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
or equivalently:
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
tools: read,bash,grep
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Using Profiles
|
|
226
|
+
|
|
227
|
+
**Per-task profile** — each task specifies its own profile:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"delegate_to_subagents": {
|
|
232
|
+
"tasks": [
|
|
233
|
+
{ "name": "review", "prompt": "Review src/...", "profile": "code-reviewer" },
|
|
234
|
+
{ "name": "research", "prompt": "Find best practices for...", "profile": "researcher" }
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Default profile for all tasks** — set at the top level, overridden by per-task profiles:
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"delegate_to_subagents": {
|
|
245
|
+
"profile": "fast-worker",
|
|
246
|
+
"tasks": [
|
|
247
|
+
{ "name": "task-a", "prompt": "..." },
|
|
248
|
+
{ "name": "task-b", "prompt": "...", "profile": "code-reviewer" }
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Profile Resolution Order
|
|
255
|
+
|
|
256
|
+
1. Per-task `profile` field (highest priority)
|
|
257
|
+
2. Top-level `profile` parameter
|
|
258
|
+
3. If neither is specified, no profile is applied (uses pi defaults)
|
|
259
|
+
|
|
260
|
+
Profiles are loaded from `.md` files:
|
|
261
|
+
|
|
262
|
+
1. Global: `~/.pi/agent/agent-profiles/*.md`
|
|
263
|
+
2. Project-local: `.pi/agent-profiles/*.md` (overrides global profiles with the same name)
|
|
264
|
+
|
|
265
|
+
The profile cache refreshes every 5 seconds.
|
|
266
|
+
|
|
267
|
+
### Settings
|
|
268
|
+
|
|
269
|
+
Additional settings are configured in `settings.json` under the `subagents` key:
|
|
270
|
+
|
|
271
|
+
| Setting | Type | Default | Description |
|
|
272
|
+
| ------------------------- | -------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
273
|
+
| `maxLinesPerWindow` | `number` | `15` | Number of lines shown in each sub-agent's rolling TUI window |
|
|
274
|
+
| `commandPreviewWidth` | `number` | Terminal width − 4 (TTY) or `160` (non-TTY) | Controls tool call preview truncation width in the rolling window. **In TTY mode, terminal width − 4 is used as a hard override — settings files are never consulted.** In non-TTY mode, falls back through settings files (global → project → default 160). Minimum: 20 |
|
|
275
|
+
| `extend_timeout_debounce` | `number` | `30` | Seconds of idle time (no output activity) before a timed-out sub-agent is killed. The initial timeout starts this idle window; any output resets it. Range: 0–300. |
|
|
276
|
+
| `looping_tool_count` | `number` | `5` | Number of consecutive tool calls checked for loop detection. Set to `0` to disable. Range: 0–50. |
|
|
277
|
+
| `looping_tool_similarity` | `number` | `0.95` | Bigram similarity threshold for loop detection. When the last `looping_tool_count` tool calls are all pairwise similar above this threshold, the sub-agent is killed. Range: 0–1. |
|
|
278
|
+
|
|
279
|
+
Settings are loaded from `~/.pi/agent/settings.json` (global) and `.pi/settings.json` (project-local, overrides global). **Note:** `commandPreviewWidth` settings are only consulted in non-TTY mode.
|
|
280
|
+
|
|
281
|
+
## The `/profile` Command
|
|
282
|
+
|
|
283
|
+
Use `/profile` interactively to manage subagent profiles without editing files by hand:
|
|
284
|
+
|
|
285
|
+
| Command | Description |
|
|
286
|
+
| ------------------------ | -------------------------------------- |
|
|
287
|
+
| `/profile list` | List all profiles with summaries |
|
|
288
|
+
| `/profile show <name>` | Display full details of a profile |
|
|
289
|
+
| `/profile <name>` | Alias for `show` |
|
|
290
|
+
| `/profile create <name>` | Interactively create a new profile |
|
|
291
|
+
| `/profile edit <name>` | Interactively edit an existing profile |
|
|
292
|
+
| `/profile delete <name>` | Delete a profile |
|
|
293
|
+
|
|
294
|
+
### Interactive Editor
|
|
295
|
+
|
|
296
|
+
`/profile create` and `/profile edit` walk you through each setting:
|
|
297
|
+
|
|
298
|
+
1. **Scope** — save to global (`~/.pi/agent/agent-profiles/`) or project-local (`.pi/agent-profiles/`) directory
|
|
299
|
+
2. **Provider** — e.g. `anthropic`, `openai`, `dashscope`
|
|
300
|
+
3. **Model** — supports `provider/id` and `:thinking` shorthand
|
|
301
|
+
4. **System prompt** — the body text of the `.md` file (replaces default system prompt)
|
|
302
|
+
5. **Append system prompt** — optionally append to the default
|
|
303
|
+
6. **Thinking level** — off, minimal, low, medium, high, xhigh
|
|
304
|
+
7. **Tools** — choose to disable all (`noTools`), enable a specific set (`tools`), or exclude specific tools (`excludeTools`)
|
|
305
|
+
8. **Extensions** — restrict or disable
|
|
306
|
+
9. **Skills** — if skills are already set, offers to remove them; otherwise asks whether to configure skills, then prompts for comma-separated suggested and/or pre-loaded skill names
|
|
307
|
+
10. **Review & save** — shows full profile as markdown before confirming
|
|
308
|
+
|
|
309
|
+
You can skip any field by answering "No" — it will be omitted from the profile (using pi defaults).
|
|
310
|
+
|
|
311
|
+
## Features
|
|
312
|
+
|
|
313
|
+
- **Parallel execution**: Multiple sub-agents run concurrently (up to 4 at a time by default)
|
|
314
|
+
- **Rolling window**: Each sub-agent shows its latest N lines in real-time
|
|
315
|
+
- **Live updates**: The TUI re-renders as sub-agents stream output
|
|
316
|
+
- **Expandable (Ctrl+O)**: Collapse to rolling window, expand to see full sub-agent output
|
|
317
|
+
- **Error handling**: Non-zero exit codes and errors are highlighted
|
|
318
|
+
- **Abort support**: Hitting Escape cancels all running sub-agents
|
|
319
|
+
- **Session resume**: Continue work from completed/errored sessions with full transcript context
|
|
320
|
+
- **Per-task timeouts**: Configurable timeout per sub-agent (default 600s), with auto-extension while the agent remains active
|
|
321
|
+
- **Loop detection**: Automatically kills sub-agents that repeat the same tool calls in a tight loop
|
|
322
|
+
- **Session persistence**: Sessions are persisted to the main agent's session log immediately after each sub-agent completes. On agent restart, sessions are reconstructed from the log — no data is lost across restarts.
|
|
323
|
+
|
|
324
|
+
## Architecture
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
Main Agent TUI
|
|
328
|
+
│
|
|
329
|
+
└── delegate_to_subagents
|
|
330
|
+
│
|
|
331
|
+
├── Resolve profiles from .md files
|
|
332
|
+
│ ├── Global: ~/.pi/agent/agent-profiles/*.md
|
|
333
|
+
│ └── Project: .pi/agent-profiles/*.md
|
|
334
|
+
│
|
|
335
|
+
├── Validate profile skills (suggestedSkills/loadSkills vs noSkills)
|
|
336
|
+
│
|
|
337
|
+
├── Resolve skill names → file paths (suggestedSkills) or injected content (loadSkills)
|
|
338
|
+
│
|
|
339
|
+
├── Validate resume targets (must be completed/errored)
|
|
340
|
+
│
|
|
341
|
+
├── For each task (concurrency ≤ 4):
|
|
342
|
+
│ │
|
|
343
|
+
│ ├── [resume?] Inject prior session transcript into prompt
|
|
344
|
+
│ │
|
|
345
|
+
│ ├── Spawn: pi --mode json -p --no-session [profile args...] "prompt"
|
|
346
|
+
│ │ │
|
|
347
|
+
│ │ ├── Parse JSONL stdout events
|
|
348
|
+
│ │ ├── Update rolling window (latest N lines)
|
|
349
|
+
│ │ ├── Track tool calls & results
|
|
350
|
+
│ │ └── [timeout?] Abort if task timeout exceeded
|
|
351
|
+
│ │
|
|
352
|
+
│ ├── Store session data (messages, status, exit code)
|
|
353
|
+
│ └── persistSession → pi.appendEntry() (fault-tolerant)
|
|
354
|
+
│
|
|
355
|
+
├── On session_start (restart/resume):
|
|
356
|
+
│ └── Reconstruct sessionStore from persisted entries
|
|
357
|
+
│ └── Stale "running" sessions → auto-converted to "error"
|
|
358
|
+
│
|
|
359
|
+
└── Return session IDs → get_subagent_output / get_subagent_session
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Each sub-agent is a separate `pi` process in JSON mode. We parse JSONL events from stdout and maintain a rolling line buffer per agent. The tool's `renderResult` builds a `Container` of `Text` components, displayed inline with the conversation history.
|