pi-durable-subagents 0.0.0-stage → 1.0.3
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 +59 -0
- package/LICENSE +21 -0
- package/README.md +318 -2
- package/agents/LICENSE +21 -0
- package/agents/delegate.md +17 -0
- package/agents/evidence-auditor.md +31 -0
- package/agents/oracle.md +32 -0
- package/agents/researcher.md +35 -0
- package/agents/reviewer.md +35 -0
- package/agents/scout.md +25 -0
- package/agents/worker.md +35 -0
- package/dist/agent/capabilities.js +32 -0
- package/dist/agent/child/history.js +49 -0
- package/dist/agent/child/live.js +62 -0
- package/dist/agent/child/schema.js +86 -0
- package/dist/agent/child.js +305 -0
- package/dist/agent/extension.js +56 -0
- package/dist/agent/main/snapshots.js +95 -0
- package/dist/agent/main/tool.js +118 -0
- package/dist/agent/main.js +307 -0
- package/dist/cli/chaos/host.js +17 -0
- package/dist/cli/chaos/index.js +74 -0
- package/dist/cli/chaos/observer.js +14 -0
- package/dist/cli/chaos/provider.js +52 -0
- package/dist/cli/chaos/scenario.js +175 -0
- package/dist/cli/chaos/stack.js +176 -0
- package/dist/cli/control.js +119 -0
- package/dist/cli/doctor.js +147 -0
- package/dist/cli/main.js +207 -0
- package/dist/cli/service.js +87 -0
- package/dist/cli/smoke.js +121 -0
- package/dist/compat/agents.js +287 -0
- package/dist/compat/fanout.js +39 -0
- package/dist/compat/frontmatter.js +64 -0
- package/dist/compat/model.js +29 -0
- package/dist/compat/pi-args.js +29 -0
- package/dist/compat/result.js +7 -0
- package/dist/compat/spec.js +74 -0
- package/dist/evaluator/host.js +150 -0
- package/dist/evaluator/worker.js +178 -0
- package/dist/kernel/guards.js +38 -0
- package/dist/kernel/ids.js +37 -0
- package/dist/kernel/journal.js +146 -0
- package/dist/kernel/lifecycle.js +103 -0
- package/dist/kernel/mailbox.js +153 -0
- package/dist/orchestrator/contract.js +1 -0
- package/dist/orchestrator/engine.js +732 -0
- package/dist/orchestrator/evaluator-client.js +134 -0
- package/dist/orchestrator/executor/effects/gate.js +195 -0
- package/dist/orchestrator/executor/effects/index.js +35 -0
- package/dist/orchestrator/executor/effects/output.js +82 -0
- package/dist/orchestrator/executor/effects/prepare.js +146 -0
- package/dist/orchestrator/executor/generation.js +24 -0
- package/dist/orchestrator/executor/hibernate.js +32 -0
- package/dist/orchestrator/executor/index.js +974 -0
- package/dist/orchestrator/executor/memory.js +21 -0
- package/dist/orchestrator/executor/observe.js +165 -0
- package/dist/orchestrator/executor/session.js +112 -0
- package/dist/orchestrator/executor/sweep.js +95 -0
- package/dist/orchestrator/executor/time.js +50 -0
- package/dist/orchestrator/executor/usage.js +55 -0
- package/dist/orchestrator/main.js +64 -0
- package/dist/orchestrator/snapshot.js +422 -0
- package/dist/orchestrator/store.js +375 -0
- package/dist/paths.js +20 -0
- package/dist/platform/containment.js +108 -0
- package/dist/platform/lock.js +78 -0
- package/dist/platform/proctable.js +120 -0
- package/dist/types.js +60 -0
- package/dist/ui/cards.js +68 -0
- package/dist/ui/data.js +124 -0
- package/dist/ui/frame.js +27 -0
- package/dist/ui/index.js +136 -0
- package/dist/ui/screen.js +599 -0
- package/dist/ui/session.js +151 -0
- package/dist/ui/thinking.js +17 -0
- package/dist/ui/tool.js +72 -0
- package/dist/ui/view.js +292 -0
- package/index.js +8 -0
- package/package.json +75 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
- Recovery delivers a call's task when an earlier execution ended before its
|
|
6
|
+
subagent received it (for example, an orchestrator restart while the call
|
|
7
|
+
waited for a provider slot). It used to send only "Continue the task", and
|
|
8
|
+
the fresh subagent had to guess what the task was.
|
|
9
|
+
|
|
10
|
+
## 1.0.2
|
|
11
|
+
|
|
12
|
+
The first published release (1.0.0 and 1.0.1 were prepared but never
|
|
13
|
+
published).
|
|
14
|
+
|
|
15
|
+
- Durable subagent workflows for pi. Requests, executions and results are
|
|
16
|
+
journaled; a crash of pi, the orchestrator or the machine resumes the same
|
|
17
|
+
sessions without running a finished call again.
|
|
18
|
+
- `subagents` tool for the main agent: `agents`, `run` (single call, `tasks`,
|
|
19
|
+
`chain`, or a workflow script with `runs.run` / `runs.all` / `emit` / `args` /
|
|
20
|
+
`runs.input`), `send` (steer a running subagent, follow up a finished one,
|
|
21
|
+
answer, switch model; `replaces` supersedes an earlier send), `stop`,
|
|
22
|
+
`revise`, `resume`, `drain`, `status`. Each verb has one meaning; every
|
|
23
|
+
refusal names what would work (agent names, call addresses). The
|
|
24
|
+
completion notice carries each subagent's result.
|
|
25
|
+
- Questions (`ask`) and structured reports (`report`) inside subagents;
|
|
26
|
+
hibernation releases slots while a question waits; generations continue an
|
|
27
|
+
ended subagent's session.
|
|
28
|
+
- Model pools, provider slots and memory admission that are never exceeded;
|
|
29
|
+
active-time timeouts; per-call and workflow usage budgets; worktree
|
|
30
|
+
isolation, fork context, gates and output artifacts.
|
|
31
|
+
- Quitting pi (Ctrl+D, `/quit`, a closed terminal) pauses that session's
|
|
32
|
+
running workflows so nothing more is spent; `resume` continues them in the
|
|
33
|
+
same sessions. A crash or `kill -9` lets them run on. `"onQuit": "continue"`
|
|
34
|
+
keeps them running after a quit too.
|
|
35
|
+
- TUI: summary line and dock above the editor, a framed list (`↓` or
|
|
36
|
+
`/subagents`) with a live preview per agent that doubles as a control surface
|
|
37
|
+
(steer, follow-up, stop, model, answer, resume from the list), watch view with
|
|
38
|
+
the streaming response, steering, model and thinking switches; interaction
|
|
39
|
+
cards in the main transcript.
|
|
40
|
+
- CLI: `smoke`, `chaos` (nine offline fault scenarios), `status`, `events`,
|
|
41
|
+
`tail`, `start`, `resume`, `drain`, `stop`, `stop-all`, `prune`, `doctor`,
|
|
42
|
+
`install-service`, `uninstall-service`.
|
|
43
|
+
- Compatible with pi-subagents 0.75.0 scripts and agent files (builtin agents
|
|
44
|
+
adapted under MIT); `researcher` and `evidence-auditor` use whichever web
|
|
45
|
+
extension is installed.
|
|
46
|
+
- Requires Node.js 22.19 or later and pi 1.0.x.
|
|
47
|
+
- Model and thinking menus search fuzzily, by id or display name (`bedrock opus`
|
|
48
|
+
finds `amazon-bedrock/claude-opus-4-5`). A requested model switch shows at
|
|
49
|
+
once ("old → new, at the end of this step") until the subagent applies it.
|
|
50
|
+
- Calls waiting for a provider slot show as queued, with the model they asked
|
|
51
|
+
for; the summary counts them apart from working ones.
|
|
52
|
+
- The dock is installed once per session: listed before another extension's
|
|
53
|
+
editor bar (such as a powerline bar) in `packages`, it sits above that bar.
|
|
54
|
+
`"ui": { "dockAt": "below" }` puts it below the editor.
|
|
55
|
+
- `/subagents` opens the list, like `↓` on an empty editor.
|
|
56
|
+
- A top-level `cwd` is the run's directory: relative workflow, input and call
|
|
57
|
+
paths resolve against it.
|
|
58
|
+
- Install from npm, or from GitHub without a build step:
|
|
59
|
+
`pi install git:github.com/purboo/pi-durable-subagents`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 purboo
|
|
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
CHANGED
|
@@ -1,3 +1,319 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Durable Subagents for pi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Subagents that never lose work, and never do it twice.**
|
|
4
|
+
|
|
5
|
+
Streams drop. Requests time out. Models return nothing. You quit pi. Your
|
|
6
|
+
laptop reboots. Durable Subagents keeps going: it picks every subagent up
|
|
7
|
+
where it stopped, in the same session. Every request is decided once and
|
|
8
|
+
every step is finished at most once (what a tool did to the outside world
|
|
9
|
+
before a crash is the one thing it cannot undo; see
|
|
10
|
+
[What we do not promise](#what-we-do-not-promise)).
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
$ npx pi-durable-subagents chaos
|
|
14
|
+
killed host ×1 · dropped streams ×1 · empty replies ×6 · out-of-order steers ×1
|
|
15
|
+
duplicate runs ........ 0
|
|
16
|
+
lost results .......... 0
|
|
17
|
+
restarted from scratch 0
|
|
18
|
+
AC4 wakes / reminders . pass
|
|
19
|
+
all 9 scenarios ....... pass
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You can run this yourself, offline, in about 2 minutes. It runs a three-step
|
|
23
|
+
writer → reviewer → integrator workflow through the real product (a real pi
|
|
24
|
+
main session, the orchestrator, real subagent pi processes and a scripted
|
|
25
|
+
model). It injects one fault per scenario, then checks the journals and
|
|
26
|
+
sessions: nothing ran twice, nothing was lost, and nothing restarted from
|
|
27
|
+
scratch.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pi install npm:pi-durable-subagents
|
|
33
|
+
# or straight from GitHub (no build step; runs the TypeScript sources)
|
|
34
|
+
pi install git:github.com/purboo/pi-durable-subagents
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This needs pi 1.0.x and Node.js 22.19 or later. It has been tested with
|
|
38
|
+
pi 1.0.2 on Linux. The CI configuration covers Linux and macOS.
|
|
39
|
+
|
|
40
|
+
The `pi-durable-subagents` command line (below) is optional. Run it without
|
|
41
|
+
installing through `npx pi-durable-subagents …`, or install it once with
|
|
42
|
+
`npm i -g pi-durable-subagents`. Use the global install if you want the
|
|
43
|
+
optional login service (`install-service`): a service must not point into
|
|
44
|
+
the npx cache, so `install-service` refuses to run from there.
|
|
45
|
+
|
|
46
|
+
## What happens when…
|
|
47
|
+
|
|
48
|
+
| Situation | What Durable Subagents does |
|
|
49
|
+
|---|---|
|
|
50
|
+
| The stream drops, or the model returns nothing | Continues the **same** session. Finished tool results are kept. |
|
|
51
|
+
| A step runs past its `timeoutMs` (even inside a silent tool) | Stops it cleanly as `timeout`. Only time spent working counts; waiting for you does not. |
|
|
52
|
+
| You quit pi (Ctrl+D, `/quit`, closing the terminal) while subagents run | That session's workflows pause: nothing more is spent, nothing is lost. When you come back, pi says so; `resume` (or `r` in the list) continues them in the same sessions. Set `"onQuit": "continue"` to let them run on instead. |
|
|
53
|
+
| pi crashes or is killed (`kill -9`) while subagents run | The work keeps running. When you come back, the session that started the work is told what needs you. |
|
|
54
|
+
| The machine or the orchestrator dies mid-run | The next pi you open resumes the work. Finished results are kept and nothing runs twice. |
|
|
55
|
+
| You steer a subagent while it is asking you a question | Your message reaches it, in order. Nothing is rejected or lost. |
|
|
56
|
+
| Two steers arrive out of order and the second replaces the first | Only the second one applies. |
|
|
57
|
+
| A step is refused, or a dependency fails | The workflow stops that branch cleanly. Nothing is retried in vain. |
|
|
58
|
+
| A subagent waits for an answer for a long time | It releases its model slot and memory, then resumes exactly once when you answer. |
|
|
59
|
+
|
|
60
|
+
## Use it
|
|
61
|
+
|
|
62
|
+
The main agent gets one tool, `subagents`. You ask in plain language, and
|
|
63
|
+
the agent calls it:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
subagents({ action: "agents" })
|
|
67
|
+
subagents({ agent: "worker", task: "Fix the flaky lease test" })
|
|
68
|
+
subagents({ tasks: [{ agent: "scout", task: "…" }, { agent: "reviewer", task: "…" }] })
|
|
69
|
+
subagents({ chain: [{ agent: "worker", task: "…" }, { agent: "reviewer", task: "Review: {previous}" }] })
|
|
70
|
+
subagents({ workflow: "./batch.js", args: { … }, usageBudget: { costUsd: 20 } })
|
|
71
|
+
subagents({ action: "send", to: "<wid>/<key>", kind: "steer", message: "Don't touch the tests yet" })
|
|
72
|
+
subagents({ action: "status" })
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Every run is asynchronous. The agent is woken once, when the workflow
|
|
76
|
+
finishes (the notice carries each subagent's result) or when a subagent asks
|
|
77
|
+
it something. Each verb means one thing, and a refusal says what would work:
|
|
78
|
+
|
|
79
|
+
| Verb | Applies to | Effect |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `run` | — | Start one subagent, `tasks` in parallel, a `chain`, or a workflow script. An unknown agent name is refused before anything starts, with the list of agents. |
|
|
82
|
+
| `send steer` | a running subagent | Reaches it at its next safe point. To a finished one: refused, use `follow-up`. |
|
|
83
|
+
| `send follow-up` | a finished subagent | Continues the same session as a new generation (`key@2`). |
|
|
84
|
+
| `send answer` | an open question | Answers it once. |
|
|
85
|
+
| `send model` | any subagent | Switches its model at the next request. |
|
|
86
|
+
| `stop` | a subagent or a workflow | Final: `stopped`, usage kept, edits left as they are. |
|
|
87
|
+
| `drain` / `resume` | existing workflows | A reversible hold; runs started later are not held. |
|
|
88
|
+
|
|
89
|
+
### Workflow scripts
|
|
90
|
+
|
|
91
|
+
A workflow is a plain script. These are the globals it can use:
|
|
92
|
+
|
|
93
|
+
| Global | Meaning |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `runs.run(key, spec)` | Run one subagent |
|
|
96
|
+
| `runs.all([...])` | Run several |
|
|
97
|
+
| `emit(value)` | Report progress |
|
|
98
|
+
| `args` | The workflow's arguments |
|
|
99
|
+
| `runs.input(name)` | A declared input file |
|
|
100
|
+
| `now()` / `random()` | Logged, so the run can be replayed |
|
|
101
|
+
|
|
102
|
+
The script's `return` value is the workflow result. A workflow script is a
|
|
103
|
+
single file: it cannot `import` or `require` other modules.
|
|
104
|
+
|
|
105
|
+
`spec` fields:
|
|
106
|
+
|
|
107
|
+
- `agent`, `task`, `model` (`provider/id[:thinking]` or a pool name), `cwd`;
|
|
108
|
+
- `timeoutMs` (active time), `output` (a relative path becomes an artifact);
|
|
109
|
+
- `schema` (a structured `report`);
|
|
110
|
+
- `gate` (a command, or `{command, output: "json", schema, timeoutMs}`);
|
|
111
|
+
- `isolation: "worktree"`, `context: "fork"`, `budget`.
|
|
112
|
+
|
|
113
|
+
The result has `ok`, `status`, the full `output` text and the structured
|
|
114
|
+
`data`.
|
|
115
|
+
|
|
116
|
+
A script is replayed after a crash. Finished calls are not run again, and a
|
|
117
|
+
changed script is detected rather than silently mixed. Keep scripts
|
|
118
|
+
deterministic: use `now()`/`random()`, not `Date`/`Math.random`.
|
|
119
|
+
|
|
120
|
+
### Watch any subagent like the main agent
|
|
121
|
+
|
|
122
|
+
While subagents work, a small dock sits above the editor: one quiet row per
|
|
123
|
+
working subagent (what it is doing and for how long; it spins while there is
|
|
124
|
+
fresh activity and stops when the agent goes quiet), a question first and
|
|
125
|
+
highlighted, and a summary line (`1 asking · 3 working · 12/40 done · ↓ subagents`).
|
|
126
|
+
When the work ends it shrinks to one sentence and leaves after ten minutes. Set
|
|
127
|
+
`"ui": { "dock": "line" }` (one line) or `"off"` in `~/.pi/durable-subagents/config.json`;
|
|
128
|
+
`"ui": { "dockAt": "below" }` puts it below the editor instead. pi stacks the
|
|
129
|
+
lines above the editor in extension load order, so to keep the dock above
|
|
130
|
+
another extension's editor bar (a powerline bar, for example), list
|
|
131
|
+
pi-durable-subagents before that extension in `packages`.
|
|
132
|
+
|
|
133
|
+
Press `↓` on an empty editor, or type `/subagents`, to open the list, a floating panel: this
|
|
134
|
+
session's workflows (sessions are independent), newest first, every
|
|
135
|
+
subagent with its model, what it is doing and for how long, and its latest
|
|
136
|
+
line. Finished ones stay there,
|
|
137
|
+
dimmed, with their conclusion.
|
|
138
|
+
|
|
139
|
+
The list is also where you act. The footer shows the keys for the selected
|
|
140
|
+
row: `Enter` watch, `s` steer, `f` follow-up, `x` stop (asks `y` first),
|
|
141
|
+
`m` model, `a` answer. A one-line input opens at the bottom (paste works),
|
|
142
|
+
and the result shows right there: `✓ applied` or the reason it was not.
|
|
143
|
+
|
|
144
|
+
`Enter` opens a subagent full screen: its task, thinking, tool calls and
|
|
145
|
+
output, rendered with pi's own components. `←`/`→` switch between the
|
|
146
|
+
subagents of one workflow. Scrolling up pauses following; pi's
|
|
147
|
+
`↓ Jump to latest message · End` badge (or `End`, or a click) brings you back.
|
|
148
|
+
|
|
149
|
+
Typing steers the subagent you are watching (`Alt+Enter` queues a
|
|
150
|
+
follow-up instead), or answers it if it is asking you something. `/model`
|
|
151
|
+
switches its model. Steers, answers and model switches are journaled as
|
|
152
|
+
coming from you, and the main agent sees a note at its next turn.
|
|
153
|
+
|
|
154
|
+
### Quiet by design
|
|
155
|
+
|
|
156
|
+
The main agent is interrupted only when there is something to decide:
|
|
157
|
+
|
|
158
|
+
- a question;
|
|
159
|
+
- a finished workflow;
|
|
160
|
+
- a stalled subagent;
|
|
161
|
+
- an unknown outcome;
|
|
162
|
+
- a reached budget.
|
|
163
|
+
|
|
164
|
+
Each one arrives once. A reminder that was already resolved is shown as
|
|
165
|
+
resolved, never as open.
|
|
166
|
+
|
|
167
|
+
## Your pi-subagents scripts, unchanged
|
|
168
|
+
|
|
169
|
+
Agent files, discovery and precedence follow `pi-subagents` 0.75.0. That
|
|
170
|
+
covers user, project and package agents, `model:thinking`, `tools` and
|
|
171
|
+
`skills`. The same builtin agents are included; an agent file of the same name
|
|
172
|
+
in your user or project agents overrides one.
|
|
173
|
+
|
|
174
|
+
| Agent | Use it when you want... |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `scout` | Fast local codebase recon: relevant files, entry points, data flow, risks. |
|
|
177
|
+
| `researcher` | Web/docs research with sources and a concise brief. |
|
|
178
|
+
| `evidence-auditor` | An independent check that important research claims are supported by their sources. |
|
|
179
|
+
| `worker` | Implementation: edits files, validates, asks instead of guessing on unapproved decisions. |
|
|
180
|
+
| `reviewer` | Code review and small fixes against the task, tests, edge cases and simplicity. |
|
|
181
|
+
| `oracle` | A second opinion before acting; challenges assumptions without editing. |
|
|
182
|
+
| `delegate` | A lightweight general delegate that behaves close to the parent session. |
|
|
183
|
+
|
|
184
|
+
`researcher` and `evidence-auditor` search with whatever web extension your pi
|
|
185
|
+
has installed (for example [pi-web-access](https://www.npmjs.com/package/pi-web-access)).
|
|
186
|
+
Without one they can still read given URLs with `curl`, and say that search was
|
|
187
|
+
unavailable.
|
|
188
|
+
|
|
189
|
+
| pi-subagents | Durable Subagents |
|
|
190
|
+
|---|---|
|
|
191
|
+
| `subagent({workflow: './x.js', async: true})` | `subagents({action: 'run', workflow: './x.js'})`; always asynchronous |
|
|
192
|
+
| `runs.run`, `runs.all`, `emit`, `args`, `return` | the same |
|
|
193
|
+
| `tasks: [...]`, `chain: [...]` | the same |
|
|
194
|
+
| `action: 'steer'`, supervisor `reply` | `send` (`steer`, `answer`) |
|
|
195
|
+
| `resume` an ended subagent | `send` to it: a new generation continues the same session |
|
|
196
|
+
| `contact_supervisor` in the subagent | `ask` |
|
|
197
|
+
| `outputSchema` | `schema` (the subagent calls `report`) |
|
|
198
|
+
| `context: 'fork'`, `gate`, `worktree: true` | `context: 'fork'`, `gate`, `isolation: 'worktree'` |
|
|
199
|
+
| `usageBudget`, `maxSubagentSpawnsPerRun` | `usageBudget`, `maxCalls` |
|
|
200
|
+
|
|
201
|
+
**Not supported:** external CLI agents, missions, schedules, intercom,
|
|
202
|
+
`acceptance` policies (use `gate`), and nested subagents.
|
|
203
|
+
|
|
204
|
+
A real rolling-DAG batch generated by a production template ran here
|
|
205
|
+
unchanged, with zero edited lines.
|
|
206
|
+
|
|
207
|
+
## Command line
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
pi-durable-subagents smoke check this machine and this pi (offline, < 60 s)
|
|
211
|
+
pi-durable-subagents chaos run the fault suite (offline, about 2 minutes)
|
|
212
|
+
pi-durable-subagents status [wid] [--json]
|
|
213
|
+
pi-durable-subagents events <wid> [--json] the meaningful timeline of one workflow
|
|
214
|
+
pi-durable-subagents tail [wid] [--json]
|
|
215
|
+
pi-durable-subagents start start the orchestrator if work is pending; sends nothing
|
|
216
|
+
pi-durable-subagents resume [wid] continue unfinished or parked work (undoes drain / stop-all)
|
|
217
|
+
pi-durable-subagents drain hold existing workflows: running calls finish, nothing new starts in them
|
|
218
|
+
pi-durable-subagents stop <wid|call>
|
|
219
|
+
pi-durable-subagents stop-all pause every existing workflow now; journals stay resumable
|
|
220
|
+
(runs you start afterwards are not held)
|
|
221
|
+
pi-durable-subagents prune [wid] [--older-than <days>]
|
|
222
|
+
delete finished workflows (done, failed, stopped); prints count and bytes freed
|
|
223
|
+
pi-durable-subagents doctor [--json] read-only health check; exits 1 when something needs you
|
|
224
|
+
pi-durable-subagents install-service optional: run `start` at login and every 30 s (systemd / launchd)
|
|
225
|
+
pi-durable-subagents uninstall-service
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The service only runs `start`: it never resumes work you drained or
|
|
229
|
+
stopped. Install the CLI globally (`npm i -g pi-durable-subagents`) before
|
|
230
|
+
`install-service`.
|
|
231
|
+
|
|
232
|
+
### Housekeeping
|
|
233
|
+
|
|
234
|
+
Journals are never compacted, so state only grows. `prune` removes finished
|
|
235
|
+
workflows: the named one, or all of them (only those that ended more than
|
|
236
|
+
`--older-than` days ago, if given). Parked and running workflows, and
|
|
237
|
+
workflows with a follow-up still open, are never pruned; naming one prints
|
|
238
|
+
why. The ledger keeps a one-line record of each pruned workflow, and it
|
|
239
|
+
never comes back. `doctor` shows disk use, workflows by status, the largest
|
|
240
|
+
journals, parked work, old open questions, and leftovers; each finding
|
|
241
|
+
comes with one command to fix it.
|
|
242
|
+
|
|
243
|
+
## Configuration
|
|
244
|
+
|
|
245
|
+
State lives in `~/.pi/durable-subagents`; set `DSA_HOME` to move it.
|
|
246
|
+
`config.json` there is optional:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"defaultModel": "provider/id",
|
|
251
|
+
"onQuit": "pause",
|
|
252
|
+
"pools": { "fast": ["anthropic/claude-haiku-4-5", "openai/gpt-5-mini"] },
|
|
253
|
+
"providers": { "anthropic": { "slots": 4 } },
|
|
254
|
+
"memory": { "reserveMb": 2048, "perChildMb": 300 }
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
- **Pools:** a model can name a pool. The first candidate with a free slot is
|
|
259
|
+
used, and a candidate that keeps failing is skipped for 10 minutes.
|
|
260
|
+
- **Provider slots:** never exceeded, including while a model switch is in
|
|
261
|
+
progress.
|
|
262
|
+
- **Memory:** new subagents wait while memory is short. Running ones are
|
|
263
|
+
never stopped for memory.
|
|
264
|
+
- **onQuit:** `"pause"` (default) pauses a session's running workflows when
|
|
265
|
+
you quit that pi; `"continue"` lets them run on in the background.
|
|
266
|
+
|
|
267
|
+
## Switching back
|
|
268
|
+
|
|
269
|
+
Durable Subagents registers the tool `subagents`, so it can be installed
|
|
270
|
+
next to `pi-subagents` (tool `subagent`). To switch back:
|
|
271
|
+
|
|
272
|
+
1. Optionally, run `pi-durable-subagents drain` (running work finishes) or
|
|
273
|
+
`pi-durable-subagents stop-all` (pauses everything; resumable later).
|
|
274
|
+
2. Optionally, run `pi-durable-subagents uninstall-service`.
|
|
275
|
+
3. In `~/.pi/agent/settings.json`, replace `npm:pi-durable-subagents` with
|
|
276
|
+
`npm:pi-subagents` under `packages`. New sessions use it.
|
|
277
|
+
|
|
278
|
+
Journals and pending questions stay on disk. If you install Durable
|
|
279
|
+
Subagents again later, `resume` picks the work up.
|
|
280
|
+
|
|
281
|
+
## Survives pi upgrades
|
|
282
|
+
|
|
283
|
+
It uses only pi's public CLI, RPC and extension API, through root exports.
|
|
284
|
+
On load, it checks the pi exports and API methods it uses.
|
|
285
|
+
|
|
286
|
+
- If an execution surface is missing, Durable Subagents disables itself
|
|
287
|
+
with one exact message. Running work is untouched. A subagent that
|
|
288
|
+
starts on such a pi exits with that message, and its step fails after
|
|
289
|
+
the usual retries instead of hanging.
|
|
290
|
+
- If a UI surface is missing, only the watch view is disabled.
|
|
291
|
+
|
|
292
|
+
`smoke` runs the same checks inside your pi.
|
|
293
|
+
|
|
294
|
+
## What we do not promise
|
|
295
|
+
|
|
296
|
+
- Call specs are checked strictly when a call is first proposed: an unknown or
|
|
297
|
+
misspelled field makes that call fail with a message naming it, instead of
|
|
298
|
+
being ignored. A `revise` of an older, looser script therefore fails those
|
|
299
|
+
calls loudly; calls already finished before the revision are kept as they
|
|
300
|
+
were.
|
|
301
|
+
- A subagent whose processes cannot be killed (for example stuck in the
|
|
302
|
+
kernel) keeps its model slot and memory reservation until a later sweep
|
|
303
|
+
proves it gone, because it may still be calling the provider. You get one
|
|
304
|
+
"outcome unknown" notice; other work keeps running.
|
|
305
|
+
- A tool that already ran inside a subagent may run again after a crash, if
|
|
306
|
+
its result never reached the session. Make external side effects
|
|
307
|
+
idempotent, or mark the step `once: true` (it then stops as `unknown`
|
|
308
|
+
instead of repeating).
|
|
309
|
+
- After a crash, the model call that was in flight is paid for again.
|
|
310
|
+
- Process containment uses process tags plus a 1-second tracker. A process
|
|
311
|
+
that clears its tag and leaves the process tree within its first second
|
|
312
|
+
cannot be found.
|
|
313
|
+
- Model and tool behaviour belong to the models and tools you use.
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT © purboo. The builtin agent definitions are adapted from
|
|
318
|
+
[pi-subagents](https://github.com/nicobailon/pi-subagents) (MIT, © Nico
|
|
319
|
+
Bailon); see `agents/LICENSE`.
|
package/agents/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nico Bailon
|
|
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.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools; changes stay uncommitted
|
|
4
|
+
name: delegate
|
|
5
|
+
description: Lightweight subagent that inherits the parent model with no default reads
|
|
6
|
+
systemPromptMode: append
|
|
7
|
+
inheritProjectContext: true
|
|
8
|
+
inheritSkills: false
|
|
9
|
+
tools: read, grep, find, ls, bash, edit, write, ask, report
|
|
10
|
+
---
|
|
11
|
+
Execute the assigned task using the provided tools. Be direct and efficient;
|
|
12
|
+
keep the response focused on the requested work. Stay within the assigned scope.
|
|
13
|
+
Leave your changes uncommitted in the working tree for the user to review: do
|
|
14
|
+
not commit, amend, stash, reset, push or switch branches unless the task asks.
|
|
15
|
+
If blocked on a decision, call ask with one focused question and wait for the
|
|
16
|
+
answer. Call report when done if a schema is given; otherwise finish with your
|
|
17
|
+
final answer.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools; works with whichever web extension is installed
|
|
4
|
+
name: evidence-auditor
|
|
5
|
+
description: Independent evidence reviewer checking whether important research claims are supported by sources
|
|
6
|
+
tools: read, grep, find, ls, bash, ask, report, web_search, fetch_content, get_search_content, source_check, web_fetch, fetch_markdown, pdf_extract
|
|
7
|
+
thinking: high
|
|
8
|
+
systemPromptMode: replace
|
|
9
|
+
inheritProjectContext: true
|
|
10
|
+
inheritSkills: false
|
|
11
|
+
---
|
|
12
|
+
You are an evidence-auditing subagent. Independently audit the small set of claims
|
|
13
|
+
that could change a research conclusion. Do not redo the whole research or treat
|
|
14
|
+
a supplied URL as proof: fetch and inspect the underlying source. Use the web
|
|
15
|
+
tools you have (from an installed web extension such as pi-web-access:
|
|
16
|
+
fetch_content, source_check, web_search; or web_fetch, fetch_markdown,
|
|
17
|
+
pdf_extract); without them, read pages with `curl -sL` through bash and say that
|
|
18
|
+
no web tool was available. If essential evidence is inaccessible, call ask with
|
|
19
|
+
one focused question or explicitly mark the claim unverified.
|
|
20
|
+
|
|
21
|
+
Prioritize decision-critical claims. Distinguish evidence, source interpretation
|
|
22
|
+
and inference. Check whether sources support the wording and level of certainty.
|
|
23
|
+
Prefer primary sources and flag stale, weak, secondary or circular evidence.
|
|
24
|
+
Preserve contradictions and uncertainty. Keep verification bounded and name any
|
|
25
|
+
important claims left unverified.
|
|
26
|
+
|
|
27
|
+
Return verified, contradicted, weak or unclear claims; source-quality concerns;
|
|
28
|
+
missing evidence; material contradictions; and implications for the conclusion.
|
|
29
|
+
For each claim provide sources, reasoning and confidence. Explicitly label
|
|
30
|
+
interpretation and inference. Call report when done if a schema is given;
|
|
31
|
+
otherwise finish with your final answer.
|
package/agents/oracle.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools
|
|
4
|
+
name: oracle
|
|
5
|
+
description: High-context decision-consistency oracle that protects inherited state and prevents drift
|
|
6
|
+
tools: read, grep, find, ls, bash, ask, report
|
|
7
|
+
thinking: high
|
|
8
|
+
systemPromptMode: replace
|
|
9
|
+
inheritProjectContext: true
|
|
10
|
+
inheritSkills: false
|
|
11
|
+
defaultContext: fork
|
|
12
|
+
---
|
|
13
|
+
You are the oracle: a decision-consistency subagent. Protect inherited decisions
|
|
14
|
+
and constraints from hidden drift. You advise; you are not the primary executor
|
|
15
|
+
or a second decision authority.
|
|
16
|
+
|
|
17
|
+
First reconstruct the key decisions, constraints and unresolved questions from
|
|
18
|
+
provided context, source files and the task. Preserve that baseline unless strong
|
|
19
|
+
evidence warrants changing it. Match search scope to the question. Prefer source
|
|
20
|
+
for runtime behavior and report discrepancies with documentation.
|
|
21
|
+
|
|
22
|
+
Surface contradictions, hidden assumptions and context lost by the main agent.
|
|
23
|
+
When recommending a different direction, identify exactly which prior assumption
|
|
24
|
+
must change and why. Prefer narrow corrections. Do not edit files, propose new
|
|
25
|
+
worker trees or expand scope without explicit authorization. Use bash only for
|
|
26
|
+
read-only inspection and verification.
|
|
27
|
+
|
|
28
|
+
If an unknown or unapproved decision would make the recommendation speculative,
|
|
29
|
+
call ask with one focused blocking question and wait. Keep consultation bounded.
|
|
30
|
+
Return inherited decisions, diagnosis, contradictions, recommendation, risks and
|
|
31
|
+
any next dependency. Include an implementation handoff only if warranted.
|
|
32
|
+
Call report when done if a schema is given; otherwise finish with your final answer.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools; works with whichever web extension is installed
|
|
4
|
+
name: researcher
|
|
5
|
+
description: Autonomous researcher who evaluates sources and synthesizes a focused research brief
|
|
6
|
+
tools: read, grep, find, ls, bash, write, ask, report, web_search, fetch_content, get_search_content, source_check, web_fetch, fetch_markdown, pdf_extract
|
|
7
|
+
thinking: medium
|
|
8
|
+
systemPromptMode: replace
|
|
9
|
+
inheritProjectContext: true
|
|
10
|
+
inheritSkills: false
|
|
11
|
+
---
|
|
12
|
+
You are a research subagent. Produce a concise, well-sourced brief that answers
|
|
13
|
+
the supplied question directly.
|
|
14
|
+
|
|
15
|
+
Web access comes from whatever web extension is installed in pi (for example
|
|
16
|
+
pi-web-access: web_search, fetch_content, get_search_content, source_check; or
|
|
17
|
+
tools such as web_fetch, fetch_markdown, pdf_extract). Use the ones you have:
|
|
18
|
+
search with several focused queries, then fetch the original pages. If you have
|
|
19
|
+
no search tool, say so at the top of your answer ("No web search tool was
|
|
20
|
+
available"), read the supplied URLs with `curl -sL` through bash, and do not
|
|
21
|
+
present memory as sourced evidence. If essential sources cannot be accessed,
|
|
22
|
+
call ask with one focused blocking question or explicitly report the gap.
|
|
23
|
+
|
|
24
|
+
Break the question into two to four focused research angles. Prefer primary,
|
|
25
|
+
official and directly relevant sources. Treat search summaries as discovery aids;
|
|
26
|
+
inspect original sources for important, disputed or decision-critical claims.
|
|
27
|
+
Keep a small set of strong sources and reject stale, redundant or low-quality
|
|
28
|
+
material. Distinguish direct evidence, source interpretation and your inference.
|
|
29
|
+
Never invent dates, quotations, citations or unsupported precision.
|
|
30
|
+
|
|
31
|
+
Record contradictions and missing evidence. If the first pass leaves a material
|
|
32
|
+
gap, perform a tighter follow-up, then report remaining uncertainty and stop.
|
|
33
|
+
Return a direct summary, findings with source and confidence, contradictions,
|
|
34
|
+
missing evidence, kept and rejected sources, and useful next steps.
|
|
35
|
+
Call report when done if a schema is given; otherwise finish with your final answer.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools
|
|
4
|
+
name: reviewer
|
|
5
|
+
description: Versatile review specialist for code diffs, plans, proposed solutions, codebase health, and PR/issue validation
|
|
6
|
+
tools: read, grep, find, ls, bash, ask, report
|
|
7
|
+
thinking: high
|
|
8
|
+
systemPromptMode: replace
|
|
9
|
+
inheritProjectContext: true
|
|
10
|
+
inheritSkills: false
|
|
11
|
+
---
|
|
12
|
+
You are a disciplined review subagent. Inspect, evaluate and report findings
|
|
13
|
+
with evidence. Verify claims from the code, tests, documents or requirements.
|
|
14
|
+
|
|
15
|
+
For code changes, start with the exact diff and named source paths. Use bash only
|
|
16
|
+
for read-only inspection, including git diff and git status. Distinguish working
|
|
17
|
+
tree changes from committed ranges. Check behavior against intent, edge cases,
|
|
18
|
+
tests, regressions and unrelated changes. Report any test commands that the main
|
|
19
|
+
agent must run. Do not edit files or mutate the repository.
|
|
20
|
+
|
|
21
|
+
For plans, check feasibility, missing steps, dependencies and scope. For proposed
|
|
22
|
+
solutions, check correctness, tradeoffs and simpler alternatives. For codebase
|
|
23
|
+
health, report concrete drift, defects or maintainability risks. For a PR or issue,
|
|
24
|
+
verify that the proposed fix addresses the underlying problem without regressions.
|
|
25
|
+
|
|
26
|
+
Search specific symbols and paths first. Do not invent issues or flag unrelated
|
|
27
|
+
local progress files as noise. Each finding must cite a concrete path and line,
|
|
28
|
+
explain the impact, and recommend the smallest correction. For diff reviews,
|
|
29
|
+
show how the named change causes or exposes the problem. Use P0 for merge blockers,
|
|
30
|
+
P1 for issues required before release, and P2 for informational findings.
|
|
31
|
+
|
|
32
|
+
If blocked by a material decision, call ask with one focused question and wait.
|
|
33
|
+
Return verified findings and a merge verdict: BLOCK, OK, or OK with notes. Say
|
|
34
|
+
"No issues found." when no concrete issue qualifies. Call report when done if a
|
|
35
|
+
schema is given; otherwise finish with your final answer.
|
package/agents/scout.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools
|
|
4
|
+
name: scout
|
|
5
|
+
description: Fast codebase recon that returns compressed context for handoff
|
|
6
|
+
tools: read, grep, find, ls, bash, write, ask, report
|
|
7
|
+
thinking: low
|
|
8
|
+
systemPromptMode: replace
|
|
9
|
+
inheritProjectContext: true
|
|
10
|
+
inheritSkills: false
|
|
11
|
+
---
|
|
12
|
+
You are a scouting subagent. Return the minimum reliable context another agent
|
|
13
|
+
needs to act. Move quickly, but do not guess.
|
|
14
|
+
|
|
15
|
+
Start from task-provided paths, symbols, types and likely source roots. Use find
|
|
16
|
+
for paths and targeted grep and read for content. Reserve broad searches for
|
|
17
|
+
exhaustive verification after a scoped pass. Use bash only for non-interactive
|
|
18
|
+
inspection. Identify entry points, key interfaces, data flow, likely change
|
|
19
|
+
locations, constraints, risks and open questions.
|
|
20
|
+
|
|
21
|
+
Cite exact paths and line numbers. Structure the result as retrieved files,
|
|
22
|
+
critical code, architecture and the recommended starting file. If instructed to
|
|
23
|
+
write an artifact, use the supplied path and keep the final response concise.
|
|
24
|
+
For a blocking decision, call ask with one focused question and wait.
|
|
25
|
+
Call report when done if a schema is given; otherwise finish with your final answer.
|
package/agents/worker.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Adapted from pi-subagents (MIT, (c) nicobailon) — https://github.com/nicobailon/pi-subagents
|
|
3
|
+
# adapted: tool references changed to pi-durable-subagents tools; changes stay uncommitted
|
|
4
|
+
name: worker
|
|
5
|
+
description: Implementation agent for normal tasks and approved oracle handoffs
|
|
6
|
+
thinking: high
|
|
7
|
+
systemPromptMode: replace
|
|
8
|
+
inheritProjectContext: true
|
|
9
|
+
inheritSkills: false
|
|
10
|
+
tools: read, grep, find, ls, bash, edit, write, ask, report
|
|
11
|
+
defaultContext: fresh
|
|
12
|
+
---
|
|
13
|
+
You are the implementation subagent and the single writer for your assigned task.
|
|
14
|
+
The main agent and user remain the decision authority.
|
|
15
|
+
|
|
16
|
+
Read supplied context, files, plans and named source paths first. Validate the
|
|
17
|
+
approved direction against the actual code, then implement narrow, coherent
|
|
18
|
+
changes. Preserve unrelated work. Prefer specific symbols and paths for search;
|
|
19
|
+
use broad searches only to verify or expand from that starting point.
|
|
20
|
+
|
|
21
|
+
Follow existing patterns and verify the changed behavior, including relevant
|
|
22
|
+
failure paths. Do not introduce speculative scaffolding, placeholders or silent
|
|
23
|
+
scope changes. Keep requested progress records accurate. Use bash for inspection,
|
|
24
|
+
implementation and verification, respecting the assigned ownership.
|
|
25
|
+
Leave your changes uncommitted in the working tree for the user to review: do
|
|
26
|
+
not commit, amend, stash, reset, push or switch branches unless the task asks.
|
|
27
|
+
|
|
28
|
+
If implementation requires an unapproved product, architecture or scope decision,
|
|
29
|
+
call ask with one focused blocking question and wait for the answer. Do not
|
|
30
|
+
substitute an implicit decision or return a success summary without making the
|
|
31
|
+
requested edits.
|
|
32
|
+
|
|
33
|
+
When done, report what changed, the exact validation performed, remaining risks
|
|
34
|
+
and the next dependency. Call report when a schema is given; otherwise finish
|
|
35
|
+
with your final answer.
|