@oai404iao/pi-subagent 0.2.0 → 0.4.0-alpha.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/README.md CHANGED
@@ -5,7 +5,7 @@ The design independently adapts the
5
5
  [DeepSeek Harness subagent seam](https://github.com/deepseek-ai/deepseek-harness/tree/4d03472cd098dc48a630e526ca620f4f37f18a0e/docs/subsystems)
6
6
  to Pi's extension and SDK APIs.
7
7
 
8
- Compatibility: Pi 0.84.2 or newer; tested against 0.84.2.
8
+ Peer floor: Pi 0.84.2; tested against 0.84.2 and 0.85.1.
9
9
 
10
10
  > npm identity: `@oai404iao/pi-subagent`. Once the selected version is
11
11
  > available on npm, install it from npm; use a local checkout before its
@@ -15,21 +15,29 @@ Compatibility: Pi 0.84.2 or newer; tested against 0.84.2.
15
15
 
16
16
  - **Named providers**
17
17
  - `spawn`: fresh child with no parent conversation
18
- - `fork`: one-shot child seeded through the parent's latest completed turn
18
+ - `fork`: child seeded through the parent's latest completed turn
19
+ - **Readable task paths** such as `/root/review/auth`, with relative addressing
20
+ - **Explicit context inheritance**: `fresh`, `all_completed`, or
21
+ `last_n_completed`
19
22
  - **Two lifecycles**
20
23
  - foreground one-shot runs return the child's final answer
21
- - background continuable runs return a child session id immediately
24
+ - background continuable runs return a readable path and stable agent id at
25
+ prompt acceptance
22
26
  - **Foreground-only policy** that removes background scheduling and lifecycle controls
23
27
  - **Independent context and session** for every child
24
- - **Bundled presets without filesystem writes by default**, with opt-in
25
- materialization, backup, and replacement
28
+ - **User-owned agent catalog** with bundled templates used only for
29
+ first-install and package-version initialization
26
30
  - **Durable descriptors and lineage** stored in child JSONL sessions
27
- - **Cold resume** through `send_message`
31
+ - **Two background protocols**: compatible immediate follow-ups or an opt-in
32
+ durable mailbox with explicit turn starts
33
+ - **Quiet durable completion updates** with event-driven `wait_agent`
28
34
  - **Control plane** with listing and interruption
29
35
  - **Child-to-parent `report` channel** for continuable children
30
36
  - **Nested delegation** with an absolute persisted depth limit
31
37
  - **Dynamic agent-name enums** generated from the effective user/project catalog
32
38
  - **Parallel-safe delegation**: multiple `subagent` calls in one assistant message may overlap
39
+ - **Bounded background execution** with per-agent cold-resume serialization
40
+ - **Optional idle runtime LRU** with transparent cold resume
33
41
  - **Composable tool ceilings** that preserve model/extension tool decisions
34
42
  - **Usage accounting, streaming progress, output caps, and custom TUI rendering**
35
43
 
@@ -57,17 +65,19 @@ For a temporary test:
57
65
  pi -e /absolute/path/to/pi-extensions/pi-subagent
58
66
  ```
59
67
 
60
- This implementation targets Pi `0.84.2`.
68
+ Development is pinned to Pi `0.85.1`; full compatibility checks retain the `0.84.2` floor.
61
69
 
62
70
  ## Model-facing tools
63
71
 
64
72
  | Tool | Behavior |
65
73
  | --- | --- |
66
- | `subagent` | Starts a fresh child. Background continuable mode is the default unless configured otherwise; foreground-only mode always waits for the answer. |
67
- | `subagent_fork` | Starts a foreground one-shot child with the parent's completed-turn history. The in-flight tool turn is excluded. |
68
- | `send_message` | Sends the next FIFO turn to a direct continuable child; cold-resumes a persisted child when background execution is enabled. |
69
- | `interrupt_agent` | Requests cancellation of a live descendant's current turn without deleting its session. Active only when background execution is enabled. |
70
- | `list_agents` | Lists direct children or all descendants as `running`, `idle`, or `ready`. Active only when background execution is enabled. |
74
+ | `subagent` | Starts a named child with selectable context inheritance. Background continuable mode is the default unless configured otherwise; foreground-only mode always waits for the answer. |
75
+ | `subagent_fork` | Starts a child with all completed parent turns. It remains foreground by default; `run_in_background: true` creates a continuable fork. |
76
+ | `send_message` | Targets a direct child by path or durable id. Legacy starts/joins the next FIFO turn; `mailbox-v2` only durably appends. |
77
+ | `followup_task` | `mailbox-v2` only: targets a direct child by path or id, atomically claims the pending FIFO batch, and starts one scheduled turn. |
78
+ | `wait_agent` | `mailbox-v2` only: waits event-driven for unread direct-child completions without starting a model turn or consuming a scheduler slot. |
79
+ | `interrupt_agent` | Requests cancellation of a live descendant by path or id without deleting its session. Active only when background execution is enabled. |
80
+ | `list_agents` | Lists readable descendant paths as `running`, `idle`, or `ready`, including separate `pending=N` task and `updates=N` completion counts. Active only when background execution is enabled. |
71
81
  | `report` | Child-only return channel. Installed automatically in continuable children. |
72
82
 
73
83
  The `/subagents` command shows the effective scheduling mode, available agent definitions,
@@ -92,52 +102,118 @@ Use subagent_fork with planner to plan the change using our completed discussion
92
102
  List my subagents, then send the scout a follow-up asking for exact call sites.
93
103
  ```
94
104
 
105
+ With `"backgroundProtocol": "mailbox-v2"`, enqueue first and start explicitly:
106
+
107
+ ```text
108
+ Send the scout two mailbox messages, then call followup_task once so it handles
109
+ the current FIFO batch in one turn. Call wait_agent when the next action needs
110
+ its quiet completion update.
111
+ ```
112
+
95
113
  Pi executes sibling tool calls in parallel, so this package deliberately accepts one delegation per `subagent` call instead of embedding a separate `tasks` array.
96
114
 
97
- ## Agent definitions
115
+ ### Task paths and context
116
+
117
+ Every new child has an immutable path rooted at `/root`:
98
118
 
99
- The package includes `scout`, `planner`, `reviewer`, and `worker`. By default,
100
- these bundled definitions are read directly from the package. Startup does
101
- **not** create, replace, remove, or back up files in the Pi agent directory.
102
- `/subagents` reports those defaults as `(bundled)`.
119
+ ```text
120
+ /root
121
+ ├─ review
122
+ │ └─ auth
123
+ └─ tests
124
+ ```
103
125
 
104
- User and project definitions can override the same names without modifying
105
- package files. Runtime locations and precedence are:
126
+ Set `task_name` to choose the final path segment. Names use 1–64 lowercase
127
+ ASCII letters, digits, hyphens, or underscores. If omitted, the extension
128
+ slugs `description` and appends `-2`, `-3`, and so on to avoid sibling
129
+ collisions. Explicit duplicate sibling names fail before child creation.
106
130
 
107
- 1. bundled package definitions
108
- 2. `<Pi agent dir>/agents/*.md`
109
- 3. nearest trusted `.pi/agents/*.md`
131
+ Control tools retain their existing parameter names for compatibility, but
132
+ accept any of:
110
133
 
111
- Project definitions replace user and bundled definitions with the same name
112
- when project scope is enabled. Project agents are disabled by the default
113
- `agentScope: "user"`. Setting the scope to `project` explicitly selects only
114
- project definitions; `both` loads bundled definitions, user overrides, then
115
- project overrides.
134
+ - a durable UUIDv7 agent id;
135
+ - an absolute path such as `/root/review/auth`;
136
+ - a path relative to the caller, such as `auth`, `./auth`, or `../tests`.
116
137
 
117
- When upgrading from a version that synchronized presets by default, unchanged
118
- previously managed files are recognized read-only and do not shadow newer
119
- package defaults. Edited managed files remain user overrides. The default
120
- never deletes or rewrites those existing files.
138
+ References cannot escape `/root`. Path lookup is resolved to the durable agent
139
+ id before per-agent serialization; mailbox ownership, events, and durable
140
+ lineage remain UUID-based. Direct-child restrictions still apply to
141
+ `send_message` and `followup_task`, while `interrupt_agent` still requires a
142
+ descendant. Paths do not bypass those checks.
121
143
 
122
- ### Opt-in managed preset synchronization
144
+ `subagent` accepts an optional context object:
123
145
 
124
- Set `syncBundledAgents: true` only if you explicitly want the package to
125
- materialize its bundled definitions into:
146
+ ```json
147
+ {
148
+ "task_name": "review",
149
+ "context": {
150
+ "mode": "last_n_completed",
151
+ "completed_turns": 2
152
+ }
153
+ }
154
+ ```
155
+
156
+ Context modes are:
157
+
158
+ | Mode | Initial child context |
159
+ | --- | --- |
160
+ | `fresh` | No parent conversation. This is the compatible `subagent` default. |
161
+ | `all_completed` | The parent's compaction-aware context through its latest completed assistant turn. |
162
+ | `last_n_completed` | The last `completed_turns` complete parent turns, bounded to 1–100. |
163
+
164
+ The active assistant/tool-call suffix is always excluded. A compaction summary
165
+ is retained when it is the only safe representation of completed history; if
166
+ it prevents exact turn counting, `last_n_completed` keeps that summary only
167
+ when fewer than the requested number of explicit completed turns remain.
168
+ Context is copied once into a new child session. Descriptor, lineage, mailbox,
169
+ completion, and other plain extension-state entries are not copied.
170
+
171
+ `subagent_fork` is the compatibility shortcut for `all_completed`. It remains
172
+ foreground unless `run_in_background: true` is explicitly supplied, even when
173
+ `defaultBackground` is true. A background fork is continuable and supports the
174
+ same legacy or mailbox-v2 follow-up lifecycle as a fresh child.
175
+
176
+ New sessions persist descriptor version 3 with their task path and context
177
+ policy. Version-2 descriptors remain readable and controllable by UUID; they
178
+ are displayed under the deterministic compatibility namespace
179
+ `/root/.legacy/<agent-id>`.
180
+
181
+ ## Agent definitions
182
+
183
+ The package ships `scout`, `planner`, `reviewer`, and `worker` as initialization
184
+ templates. On the first extension startup after installation, and whenever the
185
+ detected package version changes, those templates are materialized into:
126
186
 
127
187
  ```text
128
188
  <Pi agent dir>/agents/*.md
129
189
  ```
130
190
 
131
- With that opt-in, runtime discovery uses the managed user files rather than
132
- reading package copies directly, and `/subagents` reports built-ins as
133
- `(user)`. Synchronization behavior is then:
191
+ The package copies are **never runtime agent definitions or fallbacks**.
192
+ Runtime discovery reads only:
193
+
194
+ 1. `<Pi agent dir>/agents/*.md`
195
+ 2. nearest trusted `.pi/agents/*.md`
196
+
197
+ Project definitions replace user definitions with the same name when project
198
+ scope is enabled. Project agents are disabled by the default
199
+ `agentScope: "user"`. Setting the scope to `project` selects only project
200
+ definitions; `both` loads user definitions followed by project overrides.
201
+
202
+ After the current package version has been initialized, the user directory is
203
+ authoritative. Same-version startups do not restore missing files or refresh
204
+ changed templates. If the user deletes every agent definition, the effective
205
+ catalog is empty and delegation tools are inactive after restart or `/reload`.
206
+ A later package-version change starts a new initialization pass and installs
207
+ missing bundled templates again.
208
+
209
+ Initialization behavior:
134
210
 
135
211
  1. **First startup:** missing presets are installed. A different pre-existing same-name file
136
212
  is backed up before the bundled version replaces it.
137
213
  2. **Ordinary restart of the same release:** user edits are preserved.
138
214
  3. **Plugin update:** differing user presets are backed up, then replaced with the new
139
- bundled versions. A bundled prompt hash change also triggers this refresh even if the
140
- package version was not bumped.
215
+ bundled versions. A bundled prompt change without a package-version change does not
216
+ trigger a refresh.
141
217
  4. **Retired preset:** a formerly bundled name is backed up and removed so an obsolete
142
218
  prompt does not remain silently active.
143
219
  5. Files whose names were never managed bundled presets are left untouched.
@@ -146,8 +222,10 @@ Synchronization holds a cross-process lock, then preflights and stages the whole
146
222
  before changing agent files. If a commit fails, it rolls back already-applied changes and
147
223
  fails extension startup rather than falling back to package prompts. Same-name symbolic
148
224
  links are preserved as symbolic links inside the backup directory before the user path is
149
- replaced. An invalid synchronization manifest is copied to a timestamped `.corrupt-*` file
150
- and startup fails closed until the manifest is repaired or deliberately removed.
225
+ replaced. An invalid synchronization manifest is copied to a content-addressed
226
+ `.corrupt-*` file and skips template initialization; user and project agent discovery
227
+ continues with a warning. Repair the manifest, or deliberately remove it to request a new
228
+ first-install initialization pass.
151
229
 
152
230
  Synchronization state and backups live at:
153
231
 
@@ -236,12 +314,15 @@ See [`config.example.json`](config.example.json) and [`config.schema.json`](conf
236
314
  {
237
315
  "$schema": "/path/to/pi-subagent/config.schema.json",
238
316
  "agentScope": "user",
239
- "syncBundledAgents": false,
240
317
  "maxDepth": 3,
241
318
  "enableRunInBackground": true,
242
319
  "defaultBackground": true,
320
+ "maxConcurrentBackgroundRuns": 4,
321
+ "maxIdleRuntimes": 0,
322
+ "backgroundProtocol": "legacy",
243
323
  "reportDelivery": "wakeup",
244
324
  "inheritExtensions": false,
325
+ "openAIIdentity": false,
245
326
  "maxOutputBytes": 51200
246
327
  }
247
328
  ```
@@ -249,16 +330,33 @@ See [`config.example.json`](config.example.json) and [`config.schema.json`](conf
249
330
  | Setting | Default | Meaning |
250
331
  | --- | --- | --- |
251
332
  | `agentScope` | `user` | Select user definitions, project definitions, or user definitions followed by project overrides. |
252
- | `syncBundledAgents` | `false` | **User-level config only.** Opt in to writing managed bundled presets into `<Pi agent dir>/agents`. `true` may install, replace, retire, and back up those files. |
253
333
  | `maxDepth` | `3` | Absolute delegation depth; a top-level Pi session is depth 0. |
254
334
  | `enableRunInBackground` | `true` | Enable continuable background children and their model-facing lifecycle controls. Set `false` for strict foreground-only mode. |
255
- | `defaultBackground` | `true` | Default scheduling for fresh `subagent` calls when background execution is enabled. |
256
- | `reportDelivery` | `wakeup` | `wakeup` starts/queues a parent turn; `quiet` waits for the parent's next turn. |
335
+ | `defaultBackground` | `true` | Default scheduling for `subagent` calls when background execution is enabled. `subagent_fork` remains foreground unless explicitly requested. |
336
+ | `maxConcurrentBackgroundRuns` | `4` | Maximum continuable subagent turns executing at once in one extension runtime. Additional top-level runs wait in FIFO order; nested work fails at capacity instead of deadlocking its parent turn. |
337
+ | `maxIdleRuntimes` | `0` | Process-wide LRU capacity for settled continuable runtimes. `0` preserves immediate unload; a positive value keeps the most recently used idle runtimes and transparently cold-resumes evicted paths. |
338
+ | `backgroundProtocol` | `legacy` | `legacy` preserves immediate `send_message` turns. `mailbox-v2` makes `send_message` enqueue-only and requires `followup_task` to start a turn. The protocol is snapshotted in each child descriptor. |
339
+ | `reportDelivery` | `wakeup` | Controls explicit `report` calls: `wakeup` starts/queues a parent turn; `quiet` waits for the parent's next turn. Mailbox-v2 completion updates are always quiet. |
257
340
  | `inheritExtensions` | `false` | Load other Pi extensions in child runtimes. This package filters itself out; explicit agent tool ceilings still apply. |
258
- | `maxOutputBytes` | `51200` | Cap for parent-visible foreground output, reports, and settlement notices. Full output remains in the child session. |
341
+ | `openAIIdentity` | `false` | For OpenAI Responses child models, inject only the named `pi-codex-minimal-tools` identity lifecycle inline. Codex Session/Thread/Turn/Window ids remain owned and serialized by that package. |
342
+ | `maxOutputBytes` | `51200` | Cap for parent-visible foreground output, reports, completion updates, and legacy settlement notices. Full output remains in the child session. |
259
343
 
260
344
  Invalid configuration and unknown child tool names fail loud before the child's first model request.
261
345
 
346
+ The retired user-level `syncBundledAgents` key from versions 0.2 and 0.3 is
347
+ accepted for configuration compatibility but ignored. Template initialization
348
+ is now automatic and runtime discovery never reads bundled definitions.
349
+
350
+ `openAIIdentity` and `inheritExtensions` are independent. The former adds only
351
+ the lightweight Codex identity lifecycle even when normal extension inheritance
352
+ is disabled. Enable `inheritExtensions` as well when the child should receive
353
+ the complete separately installed Codex extension tool surface such as
354
+ `web_search` and `apply_patch`.
355
+
356
+ The Codex adapter is an optional package dependency. If an installation omits
357
+ optional dependencies, `openAIIdentity: true` fails before the child starts
358
+ with an actionable missing-adapter error.
359
+
262
360
  ### Foreground-only mode
263
361
 
264
362
  ```json
@@ -273,14 +371,15 @@ In this mode:
273
371
  - `run_in_background` is removed from the model-facing schema at session startup;
274
372
  - a forced `run_in_background: true` call is rejected before a child is created;
275
373
  - nested subagents inherit the foreground-only policy through the durable runtime snapshot;
276
- - `send_message`, `interrupt_agent`, and `list_agents` are removed from the active
374
+ - `send_message`, `followup_task`, `wait_agent`, `interrupt_agent`, and `list_agents` are removed from the active
277
375
  model tool set, including inside nested children;
278
376
  - sibling foreground calls may still execute in parallel in one assistant message.
279
377
 
280
- `subagent_fork` is already foreground-only and is unchanged. The `/subagents` command
281
- remains available for human inspection of historical children, but persisted continuable
282
- children cannot be resumed until background execution is re-enabled. Run `/reload` or
283
- restart Pi after changing this setting so the active tool set and displayed schema are
378
+ `subagent_fork` remains foreground in this mode and its `run_in_background`
379
+ field is removed too. The `/subagents` command remains available for human
380
+ inspection of historical children, but persisted continuable children cannot
381
+ be resumed until background execution is re-enabled. Run `/reload` or restart
382
+ Pi after changing this setting so the active tool set and displayed schema are
284
383
  refreshed.
285
384
 
286
385
  ## Lifecycle
@@ -301,38 +400,131 @@ The caller waits for one isolated child run. Only the child's last non-empty ass
301
400
 
302
401
  ### Continuable
303
402
 
304
- The start tool resolves at prompt preflight acceptance and returns the stable child session id. When an activation settles:
305
-
306
- 1. the runtime sends the parent a settlement notice with the stop reason and closing message;
307
- 2. the child runtime is disposed once its owned descendants are done;
308
- 3. its persistent session becomes `ready`;
309
- 4. `send_message` can cold-resume that same session for another FIFO turn.
310
-
311
- A child can explicitly call `report` before settlement. Reports and settlement notices are separate by design.
312
-
313
- ### Fork boundary
314
-
315
- The parent is executing a tool when `subagent_fork` starts, so its current assistant/tool-result sequence is incomplete. The provider copies only through the latest assistant message whose stop reason is not `toolUse`. This avoids seeding an invalid unbalanced tool turn.
403
+ The start tool resolves at prompt preflight acceptance and returns the child's
404
+ readable task path plus stable agent id (UUIDv7). Agent ids are independent of
405
+ Pi session (file) ids: they are
406
+ generated once per subagent, recorded in the child's session as `pi-subagent/agent`,
407
+ and chained through `parentAgentId` in the descriptor, so children stay addressable
408
+ even when a parent session is forked or re-created. When an activation settles:
409
+
410
+ 1. `legacy` sends the parent its existing wakeup settlement; `mailbox-v2`
411
+ appends a quiet completion update to the direct parent's session instead;
412
+ 2. once owned descendants are done, the child runtime is either disposed or
413
+ retained in the optional idle LRU;
414
+ 3. an unloaded persistent session is `ready`; a retained settled runtime is
415
+ `idle`;
416
+ 4. legacy `send_message`, or mailbox-v2 `followup_task`, can cold-resume that
417
+ same session for another turn.
418
+
419
+ A child can explicitly call `report` before settlement. Reports retain
420
+ `reportDelivery` behavior and are separate from quiet mailbox-v2 completions.
421
+
422
+ Continuable turns share a bounded scheduler. Calls targeting the same durable
423
+ agent are serialized so concurrent messages cannot create multiple cold
424
+ runtimes for one child session. Every scheduler-admitted run has a stable
425
+ `turnId` in delegation details and the paired `pi-subagent:turn-start` /
426
+ `pi-subagent:turn-end` events. FIFO follow-ups accepted while that
427
+ `AgentSession` is already running remain part of the same admitted run.
428
+ Existing `pi-subagent:start` / `pi-subagent:end` events continue to describe
429
+ the wider activation lifecycle and now include `taskPath`.
430
+
431
+ With `maxIdleRuntimes: 0`, disposal behavior is unchanged. A positive value
432
+ retains only settled continuable runtimes with no active run, owned descendant,
433
+ or pending mailbox claim. LRU accounting is serialized across concurrent
434
+ settlements. Eviction disposes only the runtime; the descriptor, path, context,
435
+ session history, task mailbox, and completion mailbox remain durable, so the
436
+ next accepted turn cold-resumes normally.
437
+
438
+ #### Mailbox-v2
439
+
440
+ Set `"backgroundProtocol": "mailbox-v2"` to separate delivery from execution:
441
+
442
+ 1. `send_message` appends a bounded message record to the direct child's JSONL
443
+ session and returns its stable message id. It does not create a runtime,
444
+ acquire a scheduler permit, create a `turnId`, or emit turn events.
445
+ 2. `followup_task` snapshots the current pending FIFO prefix, waits for the
446
+ normal background scheduler, and starts one turn containing that batch.
447
+ Messages arriving after the snapshot remain pending for a later turn.
448
+ 3. A claim is committed only after Pi prompt preflight succeeds. The durable
449
+ user-turn marker makes a claim without its corresponding prompt recoverable
450
+ after a crash. Once the user turn is durable, the batch is consumed even if
451
+ that model turn later fails or is interrupted.
452
+ 4. Scheduler rejection, cancellation while queued, and shutdown before prompt
453
+ acceptance leave the batch pending. Concurrent sends and starts for one
454
+ agent are serialized within the extension process.
455
+ 5. A completed turn appends a stable completion record to the direct parent's
456
+ separate notification mailbox before the child unloads. This custom entry
457
+ does not enter model context and does not wake or start the parent.
458
+ 6. `wait_agent` returns existing unread updates immediately or subscribes to
459
+ in-process mailbox activity and rechecks durable state after wakeup. Its
460
+ optional timeout defaults to 30 seconds and is capped at 120 seconds.
461
+ 7. A returned update becomes read only after Pi durably appends the successful
462
+ `wait_agent` tool result. An interrupted/failed delivery is released at the
463
+ end of the parent turn; a process restart also makes an orphan reservation
464
+ available again. Delivery output is bounded to a 256 KiB FIFO prefix.
465
+ 8. If the parent completion append fails, the child records an undelivered
466
+ fallback in its own session and emits `pi-subagent:completion-error` before
467
+ normal residency cleanup; no false completion is exposed to `wait_agent`.
468
+
469
+ Each message is limited to 131,072 characters; a mailbox is limited to 256 pending
470
+ messages and 256 KiB of pending UTF-8 content. `list_agents` exposes task
471
+ `pending` and completion `updates` independently from lifecycle and scheduler
472
+ state.
473
+
474
+ FIFO follows durable append order after target resolution, not the invocation
475
+ order of concurrent `send_message` calls. Each returned `pendingMessages` count
476
+ describes that append. If one message must precede another, await the first send
477
+ before starting the next.
478
+
479
+ `mailbox-v2` is opt-in. Existing descriptors without a protocol field resume as
480
+ `legacy`, and the default legacy tool behavior is unchanged. A persisted
481
+ mailbox-v2 child keeps its protocol snapshot. `followup_task` and `wait_agent` remain available
482
+ when such a child exists even if the current default is later changed back to
483
+ legacy.
484
+
485
+ `wait_agent` observes only completions written by the current agent's direct
486
+ children. Nested parents consume their own child updates; a root wait does not
487
+ steal grandchild updates. Legacy settlements and all explicit reports retain
488
+ their previous behavior.
489
+
490
+ ### Inherited-context boundary
491
+
492
+ The parent is executing a tool when an inherited-context child starts, so its
493
+ current assistant/tool-result sequence is incomplete. The provider projects
494
+ Pi's active compaction-aware context only through a safe completed boundary,
495
+ then copies model-facing entries into a new child session. This avoids seeding
496
+ an invalid unbalanced tool turn and prevents parent control-log records from
497
+ becoming child descriptors or mailbox ownership.
316
498
 
317
499
  ## Security
318
500
 
319
501
  - Extensions and subagents run with the user's OS permissions.
320
- - Opt-in `syncBundledAgents: true` synchronizes bundled presets into the user
321
- agent directory and may create backups under
322
- `<Pi agent dir>/.pi-subagent/backups`. The default does not write these
323
- paths.
502
+ - First-install and package-version initialization writes bundled templates
503
+ into the user agent directory and may create backups under
504
+ `<Pi agent dir>/.pi-subagent/backups`.
324
505
  - Project-local agents are repository-controlled prompts. They are loaded only when the project is trusted and configuration enables project scope.
325
506
  - `inheritExtensions` is disabled by default because loading an extension in a child executes its code and may duplicate external side effects.
326
507
  - Explicit agent tool lists are enforced as registry ceilings, but this controls model visibility and execution composition rather than providing an OS sandbox.
327
- - A child may send content only to its recorded direct parent through `report`; `send_message` likewise requires direct-parent identity.
508
+ - A child may send content only to its recorded direct parent through `report`;
509
+ path resolution is only an address lookup, and `send_message` /
510
+ `followup_task` still require direct-parent identity.
328
511
 
329
512
  ## Current limitations
330
513
 
331
- - Activations and ownership are process-local; there is no cross-process lease or durable mailbox.
332
- - Pi does not expose stable inbox message ids, so control acknowledgements return the child id rather than a delivery id.
333
- - A process crash can lose a prompt accepted just before Pi writes it to the child JSONL; there is no durable mailbox for accepted-but-unlogged work.
514
+ - Activations, scheduling ownership, and mailbox serialization are process-local;
515
+ two Pi processes must not concurrently control the same child session.
516
+ - Readable-path reservation and idle-LRU accounting are process-local. Durable
517
+ UUID identity remains authoritative when multiple processes are involved,
518
+ which is still unsupported.
519
+ - Resident parents still retain `ownedChildren` until descendants settle;
520
+ actor-graph residency, orphan handling, and background GC are not implemented.
521
+ - Pi lazily creates a new child JSONL file on its first assistant entry. The
522
+ initial background agent id therefore has a crash window after prompt
523
+ acceptance; mailbox-v2 `send_message` waits for that first durable checkpoint
524
+ before acknowledging an enqueue.
525
+ - Legacy `send_message` still has Pi's prompt-acceptance crash window. Use
526
+ `mailbox-v2` when delivery must be persisted before an explicit turn start.
334
527
  - `interrupt_agent` is fire-and-return and relies on Pi's current `AgentSession.abort()` queue behavior.
335
- - The fork provider is intentionally one-shot.
336
528
  - Structured-output delegation is not implemented yet.
337
529
  - Continuable starts require a persisted parent session; ephemeral (`--no-session`) parents can use foreground one-shot delegation only.
338
530
  - `subagent_fork` needs a persisted parent to copy completed history; before the first completed turn its safe prefix is empty and it behaves like a fresh child.
@@ -352,6 +544,5 @@ The test suite includes provider-boundary, descriptor, configuration, discovery,
352
544
  MIT © 2026 oai404iao. See [LICENSE](LICENSE) and
353
545
  [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
354
546
 
355
- Managed global-preset synchronization is opt-in through
356
- `syncBundledAgents: true`; the default reads bundled definitions without
357
- writing user files.
547
+ Bundled presets are initialization templates only. Runtime agent discovery is
548
+ limited to user and trusted project configuration.
package/agents/worker.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: worker
3
3
  description: General-purpose implementation agent with coding tools
4
- tools: read, grep, find, ls, bash, $mutation, subagent, subagent_fork, send_message, interrupt_agent, list_agents
4
+ tools: read, grep, find, ls, bash, $mutation, subagent, subagent_fork, send_message, followup_task, wait_agent, interrupt_agent, list_agents
5
5
  thinking: high
6
6
  ---
7
7
 
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "$schema": "./config.schema.json",
3
3
  "agentScope": "user",
4
- "syncBundledAgents": false,
5
4
  "maxDepth": 3,
6
5
  "enableRunInBackground": true,
7
6
  "defaultBackground": true,
7
+ "maxConcurrentBackgroundRuns": 4,
8
+ "maxIdleRuntimes": 0,
9
+ "backgroundProtocol": "legacy",
8
10
  "reportDelivery": "wakeup",
9
11
  "inheritExtensions": false,
12
+ "openAIIdentity": false,
10
13
  "maxOutputBytes": 51200
11
14
  }
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "syncBundledAgents": {
21
21
  "type": "boolean",
22
- "description": "User-level configuration only. Opt in to materializing bundled presets under the Pi agent directory. When true, startup may install, replace, retire, and back up managed agent files; when false, bundled definitions are read directly without writing user files.",
23
- "default": false
22
+ "deprecated": true,
23
+ "description": "Retired user-level compatibility key from versions 0.2 and 0.3. It is validated but ignored; template initialization is automatic and bundled definitions are never used at runtime."
24
24
  },
25
25
  "maxDepth": {
26
26
  "type": "integer",
@@ -36,13 +36,33 @@
36
36
  },
37
37
  "defaultBackground": {
38
38
  "type": "boolean",
39
- "description": "Default run mode for the fresh spawn provider when background execution is enabled. Ignored in foreground-only mode.",
39
+ "description": "Default run mode for subagent calls when background execution is enabled. subagent_fork remains foreground unless explicitly requested.",
40
40
  "default": true
41
41
  },
42
+ "maxConcurrentBackgroundRuns": {
43
+ "type": "integer",
44
+ "minimum": 1,
45
+ "maximum": 9007199254740991,
46
+ "description": "Maximum number of continuable subagent turns that may execute concurrently within one extension runtime.",
47
+ "default": 4
48
+ },
49
+ "maxIdleRuntimes": {
50
+ "type": "integer",
51
+ "minimum": 0,
52
+ "maximum": 9007199254740991,
53
+ "description": "Maximum settled continuable child runtimes retained in the process-wide idle LRU. Zero unloads immediately.",
54
+ "default": 0
55
+ },
56
+ "backgroundProtocol": {
57
+ "type": "string",
58
+ "enum": ["legacy", "mailbox-v2"],
59
+ "description": "Background message protocol. legacy starts or follows a turn from send_message; mailbox-v2 durably enqueues until followup_task explicitly starts one turn.",
60
+ "default": "legacy"
61
+ },
42
62
  "reportDelivery": {
43
63
  "type": "string",
44
64
  "enum": ["wakeup", "quiet"],
45
- "description": "Whether child reports trigger a parent turn or wait for the parent's next turn.",
65
+ "description": "Whether explicit child reports trigger a parent turn or wait for the parent's next turn. mailbox-v2 completion updates are always quiet.",
46
66
  "default": "wakeup"
47
67
  },
48
68
  "inheritExtensions": {
@@ -50,6 +70,11 @@
50
70
  "description": "Load the parent's other Pi extensions in child runtimes. pi-subagent itself is filtered out and explicit agent tool ceilings still apply.",
51
71
  "default": false
52
72
  },
73
+ "openAIIdentity": {
74
+ "type": "boolean",
75
+ "description": "Inject the pi-codex-minimal-tools identity lifecycle as a named inline extension for OpenAI Responses child models.",
76
+ "default": false
77
+ },
53
78
  "maxOutputBytes": {
54
79
  "type": "integer",
55
80
  "minimum": 1024,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oai404iao/pi-subagent",
3
- "version": "0.2.0",
3
+ "version": "0.4.0-alpha.0",
4
4
  "description": "Durable, continuable subagents for Pi with spawn/fork providers and lifecycle controls.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,11 +37,14 @@
37
37
  "@earendil-works/pi-tui": ">=0.84.2",
38
38
  "typebox": "*"
39
39
  },
40
+ "optionalDependencies": {
41
+ "@oai404iao/pi-codex-minimal-tools": "1.4.1-alpha.0"
42
+ },
40
43
  "devDependencies": {
41
- "@earendil-works/pi-agent-core": "^0.84.2",
42
- "@earendil-works/pi-ai": "^0.84.2",
43
- "@earendil-works/pi-coding-agent": "^0.84.2",
44
- "@earendil-works/pi-tui": "^0.84.2",
44
+ "@earendil-works/pi-agent-core": "0.85.1",
45
+ "@earendil-works/pi-ai": "0.85.1",
46
+ "@earendil-works/pi-coding-agent": "0.85.1",
47
+ "@earendil-works/pi-tui": "0.85.1",
45
48
  "@types/node": "^26.2.0",
46
49
  "tsx": "^4.20.6",
47
50
  "typebox": "^1.1.24",
@@ -84,5 +87,5 @@
84
87
  "optional": true
85
88
  }
86
89
  },
87
- "gitHead": "ef42984c0e40ef1f26ead4b4c7d149b21280e66b"
90
+ "gitHead": "53026bf9e3f6a1d16a9c990e6034b49041928eab"
88
91
  }