@quintinshaw/pi-dynamic-workflows 1.9.0 → 1.9.1
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 +89 -66
- package/package.json +16 -3
package/README.md
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
# pi-dynamic-workflows
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@quintinshaw/pi-dynamic-workflows)
|
|
4
|
+
[](#license)
|
|
5
|
+
[](https://github.com/earendil-works/pi)
|
|
6
|
+
[](#development)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
> **Claude-Code-style dynamic workflows for [Pi](https://github.com/earendil-works/pi).** One assistant turn fans out into dozens of isolated subagents, cross-checks itself, and hands you a synthesized result.
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
Instead of one model grinding through a task step by step, Pi writes a small JavaScript **orchestration script** that spawns many subagents in parallel, holds the intermediate results in script variables (not the chat context), and returns only the answer. You get the structure of a pipeline with the flexibility of plain code.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
Perfect for **codebase-wide audits, multi-perspective review, large refactors, and cross-checked research** — anything where one context window isn't enough.
|
|
13
|
+
|
|
14
|
+
Inspired by Anthropic's [dynamic workflows in Claude Code](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code).
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ✨ Highlights
|
|
19
|
+
|
|
20
|
+
- 🚀 **Fan-out orchestration** — `agent()`, `parallel()`, `pipeline()`, `phase()` in a sandboxed script. Up to 16 concurrent / 1000 total subagents.
|
|
21
|
+
- 🧭 **Interactive `/workflows` TUI** — drill through runs → phases → agents → agent detail with the keyboard, just like Claude Code. Pause, stop, and save runs without leaving the view.
|
|
22
|
+
- 📊 **Real token & cost accounting** — read straight from each subagent's session (input / output / cost), not estimated. Your `budget` gates on the real total.
|
|
23
|
+
- 🧠 **Real per-agent / per-phase model routing** — send the cheap work to a small model and the hard synthesis to a big one, resolved against your authenticated models.
|
|
24
|
+
- ⏯️ **Resume** — interrupted runs replay completed agents from a journal (no re-run, no tokens) and only run what's left or what you changed.
|
|
25
|
+
- 🌲 **Git worktree isolation** — `isolation: "worktree"` gives an agent its own branch so parallel agents can edit the same files without clobbering each other.
|
|
26
|
+
- 🔭 **Bundled `/deep-research`** — fans out **real** web searches, fetches sources, keeps only multi-source-supported claims, and writes a cited report. Plus `/adversarial-review` for skeptic-vetted findings.
|
|
27
|
+
- 🧩 **Saved & nested workflows** — turn any run into a `/<name>` slash command; compose saved workflows from inside other scripts.
|
|
28
|
+
- 🪟 **Background + live task panel** — run workflows in the background, watch a "Workflows running" panel under your input, and get the result delivered back into the chat when it finishes.
|
|
29
|
+
|
|
30
|
+
> **This is a heavily extended fork.** The [upstream project](https://github.com/Michaelliv/pi-dynamic-workflows) shipped the core script runtime; here, every advertised capability is actually **implemented, real-tested against the Pi SDK, and shipped** — see the [comparison](#whats-different-from-upstream) below.
|
|
31
|
+
|
|
32
|
+
---
|
|
10
33
|
|
|
11
34
|
## Install
|
|
12
35
|
|
|
@@ -14,7 +37,7 @@ Fork of [Michaelliv/pi-dynamic-workflows](https://github.com/Michaelliv/pi-dynam
|
|
|
14
37
|
pi install @quintinshaw/pi-dynamic-workflows
|
|
15
38
|
```
|
|
16
39
|
|
|
17
|
-
Then `/reload` in Pi. The extension registers
|
|
40
|
+
Then `/reload` in Pi. The extension registers the `workflow` tool and the `/workflows`, `/deep-research`, and `/adversarial-review` commands.
|
|
18
41
|
|
|
19
42
|
<details>
|
|
20
43
|
<summary>From source (for development)</summary>
|
|
@@ -25,55 +48,68 @@ pi install /path/to/pi-dynamic-workflows
|
|
|
25
48
|
```
|
|
26
49
|
</details>
|
|
27
50
|
|
|
28
|
-
##
|
|
51
|
+
## 30-second demo
|
|
29
52
|
|
|
30
|
-
|
|
53
|
+
Just ask for a workflow in plain language:
|
|
31
54
|
|
|
32
55
|
```text
|
|
33
|
-
Run a workflow to
|
|
56
|
+
Run a workflow to audit every route under src/routes/ for missing auth checks.
|
|
34
57
|
```
|
|
35
58
|
|
|
36
|
-
|
|
59
|
+
Pi writes the script and streams compact progress inline:
|
|
37
60
|
|
|
38
61
|
```text
|
|
39
|
-
◆ Workflow:
|
|
62
|
+
◆ Workflow: auth_audit (5/5 done · 48,210 tokens · $0.0131)
|
|
40
63
|
✓ Scan 1/1
|
|
41
|
-
#1 ✓
|
|
42
|
-
✓
|
|
43
|
-
#2 ✓
|
|
44
|
-
#3 ✓
|
|
64
|
+
#1 ✓ enumerate routes
|
|
65
|
+
✓ Review 3/3
|
|
66
|
+
#2 ✓ routes/users.ts
|
|
67
|
+
#3 ✓ routes/admin.ts
|
|
68
|
+
#4 ✓ routes/billing.ts
|
|
69
|
+
✓ Verify 1/1
|
|
70
|
+
#5 ✓ adversarial recheck
|
|
45
71
|
```
|
|
46
72
|
|
|
47
|
-
Press `Esc` to cancel
|
|
73
|
+
Press `Esc` to cancel; active subagents are aborted and surfaced as skipped.
|
|
48
74
|
|
|
49
|
-
|
|
75
|
+
## What's different from upstream
|
|
50
76
|
|
|
51
|
-
|
|
77
|
+
This fork turns the original's roadmap into working, tested features:
|
|
52
78
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
79
|
+
| Capability | Upstream | This fork |
|
|
80
|
+
| --- | :---: | :---: |
|
|
81
|
+
| Core `agent`/`parallel`/`pipeline` runtime | ✅ | ✅ |
|
|
82
|
+
| Structured (JSON-Schema) subagent output | ✅ | ✅ |
|
|
83
|
+
| **Token & cost accounting** | estimate | ✅ real, from the SDK session |
|
|
84
|
+
| **Per-agent / per-phase model routing** | prose-only* | ✅ actually switches models |
|
|
85
|
+
| **`/workflows` command + interactive TUI** | — | ✅ full keyboard navigator |
|
|
86
|
+
| **Resume an interrupted run** | — | ✅ journaled, replays the prefix |
|
|
87
|
+
| **Git worktree isolation** | — | ✅ real worktrees, auto-cleanup |
|
|
88
|
+
| **`/deep-research` with real web access** | — | ✅ live search + cross-checking |
|
|
89
|
+
| **Saved workflows as `/<name>`** | — | ✅ |
|
|
90
|
+
| **Nested `workflow()`** | — | ✅ shares the global caps |
|
|
91
|
+
| **Background runs + live task panel + result delivery** | — | ✅ |
|
|
92
|
+
| Test suite | minimal | ✅ 43 tests + real Pi end-to-end |
|
|
62
93
|
|
|
63
|
-
|
|
94
|
+
<sub>*Upstream injected the requested model as a text line in the prompt; it never changed the subagent's actual model.</sub>
|
|
95
|
+
|
|
96
|
+
## Commands
|
|
64
97
|
|
|
65
98
|
```text
|
|
66
|
-
/
|
|
67
|
-
/
|
|
68
|
-
|
|
99
|
+
/workflows # open the interactive navigator (plain list in print mode)
|
|
100
|
+
/workflows status <id> # watch a running run live; prints the result when it finishes
|
|
101
|
+
/workflows save <name> # save the latest run's script as a reusable /<name> command
|
|
102
|
+
/workflows pause|resume|stop|rm <id>
|
|
69
103
|
|
|
70
|
-
|
|
104
|
+
/deep-research <question> # web-researched, source-cross-checked report
|
|
105
|
+
/adversarial-review <task> # findings cross-checked by skeptical reviewers
|
|
106
|
+
```
|
|
71
107
|
|
|
72
|
-
|
|
108
|
+
In the **interactive navigator**: `↑/↓` (or `j/k`) select · `enter`/`→` open · `esc`/`←` back · `j/k` scroll detail · `p` pause/resume · `x` stop · `s` save · `q` quit.
|
|
73
109
|
|
|
74
|
-
##
|
|
110
|
+
## Writing a workflow
|
|
75
111
|
|
|
76
|
-
A workflow is plain JavaScript
|
|
112
|
+
A workflow is plain JavaScript whose first statement exports literal metadata:
|
|
77
113
|
|
|
78
114
|
```js
|
|
79
115
|
export const meta = {
|
|
@@ -102,7 +138,7 @@ return { inventory, summary }
|
|
|
102
138
|
| `workflow(name, args)` | Run a saved workflow inline and return its result (one level deep; shares the global caps). |
|
|
103
139
|
| `log(message)` | Append a workflow-level log line. |
|
|
104
140
|
| `args` | Optional JSON value passed via the tool's `args` parameter. |
|
|
105
|
-
| `budget` | `{ total, spent(), remaining() }` token-budget tracker. |
|
|
141
|
+
| `budget` | `{ total, spent(), remaining() }` token-budget tracker (real tokens). |
|
|
106
142
|
| `cwd`, `process.cwd()` | Working directory for subagents. |
|
|
107
143
|
|
|
108
144
|
### Agent options
|
|
@@ -111,16 +147,16 @@ return { inventory, summary }
|
|
|
111
147
|
| --- | --- | --- |
|
|
112
148
|
| `label` | string | Human-readable label for progress display |
|
|
113
149
|
| `phase` | string | Override the current phase for this agent |
|
|
114
|
-
| `schema` | object | JSON Schema
|
|
150
|
+
| `schema` | object | JSON Schema → the subagent returns a validated object |
|
|
115
151
|
| `model` | string | Run this agent on a specific model — `provider/modelId` or a bare `modelId` |
|
|
116
152
|
| `isolation` | `"worktree"` | Run this agent in its own throwaway git worktree (parallel edits without conflict) |
|
|
117
153
|
| `timeoutMs` | number | Override the default 5-minute agent timeout |
|
|
118
154
|
|
|
119
|
-
Models can also be set per phase via `meta.phases[].model`. Precedence
|
|
155
|
+
Models can also be set per phase via `meta.phases[].model`. Precedence: `opts.model` > phase model > session default; an unknown model logs a warning and falls back.
|
|
120
156
|
|
|
121
157
|
### Structured output
|
|
122
158
|
|
|
123
|
-
Pass a JSON Schema
|
|
159
|
+
Pass a JSON Schema and the subagent returns a validated object instead of prose:
|
|
124
160
|
|
|
125
161
|
```js
|
|
126
162
|
const finding = await agent('Find security-sensitive files.', {
|
|
@@ -136,51 +172,38 @@ const finding = await agent('Find security-sensitive files.', {
|
|
|
136
172
|
})
|
|
137
173
|
```
|
|
138
174
|
|
|
139
|
-
Backed by a Pi `structured_output` tool with `terminate: true`, so the subagent ends on that call.
|
|
175
|
+
Backed by a Pi `structured_output` tool with `terminate: true`, so the subagent ends on that call — no wasted follow-up turn.
|
|
140
176
|
|
|
141
|
-
### Determinism
|
|
177
|
+
### Determinism
|
|
142
178
|
|
|
143
|
-
Scripts run inside a Node `vm` sandbox. Intentionally unavailable: `Date.now()`, `new Date()`, `Math.random()`, `require`/`import`/`fs`/network, and (inside `meta`) spreads, computed keys, template interpolation, and function calls. This keeps `meta` parseable and runs reproducible.
|
|
144
|
-
|
|
145
|
-
## What works today
|
|
146
|
-
|
|
147
|
-
- **Core runtime** — `agent` / `parallel` / `pipeline` / `phase` / `log` / `budget` in a sandboxed script
|
|
148
|
-
- **Structured output** — JSON-Schema-validated subagent results
|
|
149
|
-
- **Real token & cost accounting** — read from each subagent's SDK session (input / output / total / cost), with a character estimate only as fallback when a provider reports no usage; `budget` gates on the real total
|
|
150
|
-
- **Real per-agent / per-phase model routing** — `opts.model` and `meta.phases[].model` actually select the model (resolved against your authed model registry), with graceful fallback
|
|
151
|
-
- **`/workflows` interactive navigator** — `/workflows` opens a focused TUI you drill through with the keyboard (runs → phases → agents → agent detail): `↑/↓` (or `j/k`) select, `enter`/`→` open, `esc`/`←` back, `j/k` scroll detail, `p` pause/resume, `x` stop, `s` save, `q` quit. In print/RPC mode it falls back to plain text
|
|
152
|
-
- **Live task panel + background delivery** — while a `background: true` run is going, a "Workflows running" panel sits below the input (focus it and press `enter` to open the navigator); when the run finishes, its result is delivered back into the conversation so your paused task continues
|
|
153
|
-
- **Bundled `/deep-research` & `/adversarial-review`** — `/deep-research` runs real web searches (via built-in `web_search` / `web_fetch` tools), extracts claims, cross-checks them across sources, and reports only what survived; `/adversarial-review` investigates a task then has independent skeptics try to refute each finding, keeping only those that clear an agreement threshold
|
|
154
|
-
- **Saved workflows as `/<name>`** — save a run's script with `/workflows save <name>` and it becomes a reusable slash command; arguments are parsed (`key=value` and positionals) and passed through as `args`
|
|
155
|
-
- **Nested `workflow()`** — call `await workflow('saved-name', args)` inside a script to run a saved workflow inline; nesting is one level deep and shares the parent's concurrency limiter, agent counter, and token budget so the global caps hold
|
|
156
|
-
- **Resume** — each agent result is journaled by a deterministic call index; resuming replays the unchanged prefix from cache (no re-run, no tokens) and runs only new or edited calls live
|
|
157
|
-
- **Worktree isolation** — `isolation: "worktree"` runs an agent in its own git worktree on a throwaway branch, so parallel agents can edit the same files without conflict; the worktree is torn down after (results are not auto-merged), and it falls back to a logged no-op outside a git repo
|
|
158
|
-
- **Safety limits** — 1000-agent cap (`maxAgents`), per-agent timeout (`agentTimeoutMs`), recoverable-vs-fatal error classification
|
|
159
|
-
- **Live progress + token/cost display**, `Esc` to abort
|
|
160
|
-
- **Log persistence** to `.pi/workflows/runs/`
|
|
179
|
+
Scripts run inside a Node `vm` sandbox. Intentionally unavailable: `Date.now()`, `new Date()`, `Math.random()`, `require`/`import`/`fs`/network, and (inside `meta`) spreads, computed keys, template interpolation, and function calls. This keeps `meta` parseable and runs **reproducible** — which is what makes resume reliable.
|
|
161
180
|
|
|
162
181
|
## How it works
|
|
163
182
|
|
|
164
183
|
```text
|
|
165
184
|
user prompt
|
|
166
|
-
→ Pi
|
|
167
|
-
→ workflow tool parses + runs it in a vm sandbox
|
|
168
|
-
→ script calls agent() / parallel() / pipeline()
|
|
185
|
+
→ Pi writes a workflow script
|
|
186
|
+
→ the workflow tool parses + runs it in a vm sandbox
|
|
187
|
+
→ the script calls agent() / parallel() / pipeline()
|
|
169
188
|
→ each agent() spawns a fresh in-memory Pi subagent session
|
|
170
|
-
→ snapshots stream back as compact progress
|
|
171
|
-
→ final structured result returns to the parent assistant
|
|
189
|
+
→ results are journaled; snapshots stream back as compact progress
|
|
190
|
+
→ the final structured result returns to the parent assistant
|
|
172
191
|
```
|
|
173
192
|
|
|
174
|
-
Subagents run in fresh in-memory Pi sessions with the standard coding tools (read, bash, edit, write, grep, find, ls), so they work exactly like a normal Pi turn.
|
|
193
|
+
Subagents run in fresh in-memory Pi sessions with the standard coding tools (read, bash, edit, write, grep, find, ls), so they work exactly like a normal Pi turn — and inherit your provider/model settings.
|
|
175
194
|
|
|
176
195
|
## Development
|
|
177
196
|
|
|
178
197
|
```bash
|
|
179
198
|
npm install
|
|
180
|
-
npm test # biome check + tsc + unit tests
|
|
199
|
+
npm test # biome check + tsc + 43 unit tests
|
|
181
200
|
```
|
|
182
201
|
|
|
183
|
-
|
|
202
|
+
Tests live in `tests/`. Each feature is also verified end-to-end against a real Pi subagent session before release.
|
|
203
|
+
|
|
204
|
+
## Credits
|
|
205
|
+
|
|
206
|
+
Fork of [Michaelliv/pi-dynamic-workflows](https://github.com/Michaelliv/pi-dynamic-workflows), rebuilt on `@earendil-works/*` packages with the advertised feature set implemented and a subagent settings-inheritance fix. Inspired by [Claude Code dynamic workflows](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code).
|
|
184
207
|
|
|
185
208
|
## License
|
|
186
209
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quintinshaw/pi-dynamic-workflows",
|
|
3
|
-
"version": "1.9.
|
|
4
|
-
"description": "Claude-Code-style dynamic
|
|
3
|
+
"version": "1.9.1",
|
|
4
|
+
"description": "Claude-Code-style dynamic workflows for Pi — fan a task out across 100s of subagents with real model routing, token/cost accounting, resume, git-worktree isolation, an interactive /workflows TUI, and a real /deep-research.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -33,8 +33,21 @@
|
|
|
33
33
|
"keywords": [
|
|
34
34
|
"pi-package",
|
|
35
35
|
"pi",
|
|
36
|
+
"pi-coding-agent",
|
|
36
37
|
"workflow",
|
|
37
|
-
"
|
|
38
|
+
"workflows",
|
|
39
|
+
"dynamic-workflows",
|
|
40
|
+
"orchestration",
|
|
41
|
+
"subagents",
|
|
42
|
+
"multi-agent",
|
|
43
|
+
"agents",
|
|
44
|
+
"ai-agents",
|
|
45
|
+
"parallel",
|
|
46
|
+
"fan-out",
|
|
47
|
+
"claude-code",
|
|
48
|
+
"deep-research",
|
|
49
|
+
"code-review",
|
|
50
|
+
"llm"
|
|
38
51
|
],
|
|
39
52
|
"pi": {
|
|
40
53
|
"extensions": [
|