pi-taskflow 0.0.15 → 0.0.17

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/DESIGN.md DELETED
@@ -1,338 +0,0 @@
1
- # pi-taskflow — 设计与可行性方案
2
-
3
- > 轻量工作流编排框架 for [pi coding agent](https://pi.dev)
4
- > 灵感来自 Claude Code Dynamic Workflows(2026-05-28 发布),适配 pi extension 生态。
5
-
6
- ---
7
-
8
- ## 0. 一句话定位
9
-
10
- **让 LLM(或用户)用声明式 DSL 描述一个多阶段工作流,由确定性 runtime 编排 subagent 执行,中间结果不污染主 context,最终只回收结论;工作流可保存为命令、可复用、可恢复。**
11
-
12
- ---
13
-
14
- ## 1. 市场调研结论
15
-
16
- ### 1.1 命名
17
-
18
- | 名字 | 状态 | 说明 |
19
- |------|------|------|
20
- | `pi-workflow` | ❌ 已占 | VSCode GUI 扩展(聊天面板/侧栏),**非编排框架**,不冲突 |
21
- | **`pi-taskflow`** | ✅ 可用 | 本项目 |
22
-
23
- ### 1.2 竞品分析(pi 生态无同类)
24
-
25
- | 包 | 模式 | 与 pi-taskflow 差异 |
26
- |----|------|------|
27
- | `pi-pipeline` | SPEC→PLAN→TASKS→VERIFY 固定流水线 | 固定流程,非动态可定义 DSL |
28
- | `pi-agent-flow` | fork subagent 并行调用器(scout/audit…) | 一次性并行调用,无 DAG / 无保存 / 无恢复 |
29
- | `pi-crew` | 重型多 agent 编排 + worktree + 异步 | 太重,用户已弃用 |
30
- | `pi-loop` | planner-worker-judge 固定循环 | 固定架构 |
31
- | `pi-subagents`(官方) | single/parallel/chain 即时调用 | 无持久化工作流定义、无 fan-out scale、无恢复 |
32
-
33
- **结论:声明式、可保存、可恢复、支持动态 fan-out 的轻量编排框架在 pi 生态是空白。**
34
-
35
- ### 1.3 Claude Code Dynamic Workflows 借鉴要点
36
-
37
- | 特性 | Claude Code | pi-taskflow 对应 |
38
- |------|-------------|------------------|
39
- | 计划进代码 | Claude 写 JS 脚本 | LLM 产出 **声明式 JSON DSL**(更轻、可审、更安全) |
40
- | 中间结果隔离 | 脚本变量 | runtime 内存 Map,不进 context |
41
- | 规模 | 16 并发 / 1000 agent | 可配置并发上限 + `map` 动态 fan-out |
42
- | 可复用 | 保存为 `/command` | 保存到 `.pi/taskflows/`,注册为 `/tf:<name>` |
43
- | 可恢复 | 同 session 缓存 | run 状态落盘,**跨 session 可恢复**(超越 CC) |
44
- | 质量模式 | 对抗式 review | `gate` / `review` 阶段类型 |
45
-
46
- ---
47
-
48
- ## 2. 深度可行性验证(逐项对照 pi 真实 API)
49
-
50
- > 全部基于阅读 `@earendil-works/pi-coding-agent` 的 extensions.md / packages.md / json.md / skills.md / prompt-templates.md / development.md + 现有 `~/.pi/agent/extensions/subagent/` 源码。
51
-
52
- ### ✅ V1. 生成隔离上下文的 subagent,并拿到结构化输出
53
- - **机制**:`spawn("pi", ["--mode","json","-p","--no-session", ...])`,逐行解析 JSON 事件(`message_end` / `tool_result_end`)。
54
- - **证据**:现有 subagent extension 的 `runSingleAgent()` 已完整实现,含 usage 统计、stopReason、错误处理、abort 信号。
55
- - **结论**:**直接复用**,零风险。
56
-
57
- ### ✅ V2. 并发控制(matching CC 的 scale)
58
- - **机制**:`mapWithConcurrencyLimit(items, concurrency, fn)`。
59
- - **证据**:subagent extension 已有该函数(worker pool 实现)。
60
- - **结论**:复用 + 提高默认上限(CC=16),新增 `map` 阶段做动态 fan-out。
61
-
62
- ### ✅ V3. 中间结果不进 context window
63
- - **机制**:phase 结果存 runtime 内存 `Map<phaseName, PhaseResult>`;只有最终 phase 的 output 写进 tool `content`;完整轨迹放 `details`(默认不送 LLM,仅 TUI 渲染)。
64
- - **证据**:tool result 的 `content` vs `details` 分离(json.md / 现有 subagent)。
65
- - **结论**:可行,这是相对"裸 subagent 串联"的核心优势。
66
-
67
- ### ⚠️ V4. 后台执行(session 保持响应)—— 已知约束 + 取舍
68
- - **pi 现实**:工具调用在一个 agent turn 内是**同步阻塞**的;没有 CC 那种独立 workflow runtime 进程。
69
- - **可用手段**:
70
- - 工具 `onUpdate(partial)` 回调可**实时流式**推进度(subagent parallel 模式已验证)。
71
- - `ctx.ui.setStatus()` / `ctx.ui.setWidget()` footer/widget 进度。
72
- - **取舍**:
73
- - **v1(采用)**:工作流作为**单次长工具调用**执行,期间实时流式进度。session 在该 turn 内"忙",但有完整 phase 进度可视化 —— 与 subagent 现有体验一致,符合"轻量"。
74
- - **v2(路线图)**:detached 子进程 + 文件状态轮询 + `/tf status` 命令实现**真后台**。复杂度高,非首版。
75
- - **结论**:v1 可行,体验对标 subagent;真后台留作演进。诚实记录此约束。
76
-
77
- ### ✅ V5. 保存工作流 → 可复用命令
78
- - **三条可用路径**(均已读文档确认):
79
- 1. `pi.registerCommand()` —— 文档明确支持**运行时注册**(与 registerTool 同源刷新)。
80
- 2. `resources_discover` 事件 —— 动态贡献 prompt/skill 路径(dynamic-resources 示例验证)。
81
- 3. prompt templates(`.pi/prompts/*.md`)—— `/name` 展开为文本。
82
- - **采用方案**:
83
- - 工作流定义存 `.pi/taskflows/<name>.json`(项目级)/ `~/.pi/agent/taskflows/<name>.json`(用户级)。
84
- - `session_start` 时扫描目录,为每个工作流 `registerCommand("tf:<name>")`。
85
- - 始终提供通用 `taskflow` 工具(LLM 调用)+ `/tf run <name> [args]` 命令(用户调用)。
86
- - 保存新工作流后 `registerCommand` 立即生效(同 session 可用),无需 reload。
87
- - **结论**:可行,比 prompt-template 方案更强(命令直接驱动 runtime)。
88
-
89
- ### ✅ V6. 状态持久化 / 恢复
90
- - **机制**:
91
- - `pi.appendEntry(customType, data)` —— 会话内持久化(survive reload)。
92
- - run 状态额外落盘 `.pi/taskflows/runs/<runId>.json` —— **跨 session 恢复**。
93
- - 恢复逻辑:按 `phaseName + inputHash` 缓存结果;重跑跳过已完成 phase(与 CC "cached results" 一致)。
94
- - **证据**:todo.ts 示例(从 session entries 重建状态);appendEntry API(extensions.md)。
95
- - **结论**:可行,且跨 session 恢复**超越 CC**(CC 仅同 session)。
96
-
97
- ### ✅ V7. 进度可视化(TUI)
98
- - **机制**:复用 subagent 的 `renderCall` / `renderResult`;新增 phase 进度条 / DAG 状态。`ctx.ui.custom()` 做全屏 run 视图(todo.ts 模式)。
99
- - **结论**:可行,有现成范式。
100
-
101
- ### ✅ V8. 打包发布
102
- - **机制**:`package.json` + `pi` manifest + `pi-package` keyword;pi 核心走 `peerDependencies`;`extensions/` 约定目录。`pi install npm:pi-taskflow`。
103
- - **证据**:packages.md。
104
- - **结论**:可行。
105
-
106
- ### ✅ V9. Agent 复用
107
- - **机制**:复用 `discoverAgents(cwd, scope, overrides)`,从 `~/.pi/agent/agents/*.md` + `.pi/agents/*.md` 加载;工作流按 agent 名引用;支持 settings.json 的 `subagents.agentOverrides`。
108
- - **结论**:与现有 subagent 体系无缝衔接。
109
-
110
- ### 可行性总评
111
-
112
- | 项 | 结论 |
113
- |----|------|
114
- | 核心编排(spawn/并发/隔离) | ✅ 复用现成代码,零风险 |
115
- | 保存/命令/恢复 | ✅ API 齐全 |
116
- | 真·后台执行 | ⚠️ v1 用流式长调用替代,v2 演进 |
117
- | TUI/打包/agent | ✅ 有范式 |
118
-
119
- **整体:高度可行。唯一妥协是"真后台"留 v2,v1 用流式长工具调用,体验对标现有 subagent。**
120
-
121
- ---
122
-
123
- ## 3. 架构设计
124
-
125
- ### 3.1 包结构
126
-
127
- ```
128
- pi-taskflow/
129
- ├── package.json # pi manifest + peerDeps + pi-package keyword
130
- ├── tsconfig.json
131
- ├── README.md
132
- ├── DESIGN.md # 本文件
133
- ├── extensions/
134
- │ ├── index.ts # 入口:注册 tool + commands + 事件
135
- │ ├── runtime.ts # 编排引擎(DAG 解析 + 调度 + 恢复)
136
- │ ├── runner.ts # subagent spawn(复用/移植 runSingleAgent)
137
- │ ├── agents.ts # agent discovery(移植自 subagent/agents.ts)
138
- │ ├── schema.ts # Taskflow DSL typebox schema + 校验
139
- │ ├── store.ts # 工作流定义/run 状态读写(.pi/taskflows/)
140
- │ ├── interpolate.ts # 模板插值 {steps.x.output} / {args.y}
141
- │ └── render.ts # TUI renderCall/renderResult + 进度视图
142
- ├── skills/
143
- │ └── taskflow/
144
- │ └── SKILL.md # 教 LLM 何时/如何写 taskflow 定义
145
- └── examples/
146
- ├── audit-endpoints.json
147
- ├── deep-research.json
148
- └── migrate-files.json
149
- ```
150
-
151
- ### 3.2 DSL(声明式工作流定义)
152
-
153
- ```jsonc
154
- {
155
- "name": "audit-endpoints",
156
- "description": "审计 src/routes/ 下所有 API 端点的认证检查",
157
- "version": 1,
158
- "args": { // 调用时传入,{args.dir}
159
- "dir": { "default": "src/routes" }
160
- },
161
- "concurrency": 8, // 默认并发上限
162
- "phases": [
163
- {
164
- "id": "discover",
165
- "type": "agent", // 单 agent
166
- "agent": "analyst",
167
- "task": "列出 {args.dir} 下所有 API 端点,输出 JSON 数组 [{file, route}]",
168
- "output": "json" // 解析为结构化数据供 map 用
169
- },
170
- {
171
- "id": "audit",
172
- "type": "map", // ★ 动态 fan-out(scale 核心)
173
- "over": "{steps.discover.output}", // 对数组每项起一个 agent
174
- "as": "item",
175
- "agent": "analyst",
176
- "task": "审计端点 {item.route}(文件 {item.file})的认证检查,列出风险",
177
- "dependsOn": ["discover"]
178
- },
179
- {
180
- "id": "review",
181
- "type": "gate", // ★ 对抗式质量门
182
- "agent": "reviewer",
183
- "task": "复核以下审计结果,剔除误报,标注置信度:\n{steps.audit.output}",
184
- "dependsOn": ["audit"]
185
- },
186
- {
187
- "id": "report",
188
- "type": "agent",
189
- "agent": "planner",
190
- "task": "汇总成最终报告:\n{steps.review.output}",
191
- "dependsOn": ["review"],
192
- "final": true // 该 phase 输出回收到主 session
193
- }
194
- ]
195
- }
196
- ```
197
-
198
- ### 3.3 Phase 类型
199
-
200
- | type | 语义 | 并发 |
201
- |------|------|------|
202
- | `agent` | 单 subagent 调用 | 1 |
203
- | `parallel` | 静态多任务并行(固定 task 列表) | ≤concurrency |
204
- | `map` | 对上游数组**动态 fan-out**,每项一个 agent | ≤concurrency |
205
- | `gate` | 质量门 / 对抗 review(可决定是否继续) | 1+ |
206
- | `reduce` | 把多结果聚合为一(synthesize) | 1 |
207
- | `approval` | **人在环**:暂停等待 approve / reject / edit | 1 |
208
- | `flow` | 把一个**已保存的 taskflow** 当作单个 phase 运行(组合复用) | 子流程并发 |
209
-
210
- ### 3.3b 控制流 / 可靠性字段(任意 phase)
211
-
212
- | 字段 | 语义 |
213
- |------|------|
214
- | `when` | 条件守卫:表达式为假则 skip 该 phase。支持 `{refs}`、`== != < > <= >=`、`&& \|\| !`、括号、字符串/数字字面量。解析失败 fail-open(仍运行) |
215
- | `join` | 依赖 join:`all`(默认,等全部 dep)/ `any`(OR-join,任一 dep 完成即运行) |
216
- | `retry` | `{max, backoffMs, factor}`:失败重试,延迟 = `backoffMs * factor^attempt` |
217
- | `use` / `with` | `flow` 子流程的名字与入参(入参字符串值会插值) |
218
-
219
- 顶层 `budget: {maxUSD, maxTokens}`:累计成本/token 超限即停(剩余 phase skip,运行态 `blocked`)。
220
-
221
- ### 3.4 模板插值
222
-
223
- | 占位符 | 含义 |
224
- |--------|------|
225
- | `{args.X}` | 调用参数 |
226
- | `{steps.ID.output}` | 某 phase 的最终输出(字符串) |
227
- | `{steps.ID.json}` | 某 phase 输出解析为 JSON |
228
- | `{item}` / `{item.field}` | map 阶段当前项 |
229
- | `{previous.output}` | 上一 phase 输出(链式简写) |
230
-
231
- ### 3.5 执行引擎(runtime.ts)
232
-
233
- ```
234
- 1. 校验 DSL(schema.ts)
235
- 2. 拓扑排序 phases(dependsOn 建 DAG,检测环)
236
- 3. 按层调度:
237
- - 同层无依赖 phase 并行
238
- - map 阶段展开为 N 子任务,受 concurrency 限流
239
- 4. 每个 phase:
240
- - 插值 task
241
- - 命中缓存(phaseName+inputHash 在 run 状态里)→ 跳过
242
- - 否则 spawn subagent(runner.ts),流式 onUpdate
243
- - 存结果到内存 Map + 落盘 run 状态
244
- 5. gate 阶段可返回 {continue:false} 中止
245
- 6. final phase(或最后一个)输出 → tool content 回主 session
246
- 7. 全程 details 累积完整轨迹供 TUI
247
- ```
248
-
249
- ### 3.6 对外接口
250
-
251
- **(a) LLM 工具:`taskflow`**
252
- ```jsonc
253
- // 内联定义直接跑(LLM 动态生成工作流 —— 对标 CC "Claude 写脚本")
254
- { "define": { /* 完整 DSL */ }, "args": { "dir": "src/api" } }
255
-
256
- // 跑已保存的工作流
257
- { "run": "audit-endpoints", "args": { "dir": "src/api" } }
258
-
259
- // 保存定义为可复用命令
260
- { "save": "audit-endpoints", "define": { /* DSL */ } }
261
-
262
- // 从中断处恢复
263
- { "resume": "<runId>" }
264
- ```
265
-
266
- **(b) 用户命令**
267
- | 命令 | 作用 |
268
- |------|------|
269
- | `/tf list` | 列出已保存工作流 + 最近 run |
270
- | `/tf run <name> [args]` | 运行 |
271
- | `/tf:<name> [args]` | 每个保存的工作流自动注册的快捷命令 |
272
- | `/tf resume <runId>` | 恢复中断的 run |
273
- | `/tf show <name>` | 查看定义 |
274
- | `/tf runs` | 全屏 run 历史/状态视图(ctx.ui.custom) |
275
-
276
- **(c) 编程接口(供其他 extension)**
277
- ```ts
278
- export async function runTaskflow(def, args, ctx): Promise<TaskflowResult>
279
- ```
280
-
281
- ### 3.7 存储布局
282
-
283
- ```
284
- .pi/taskflows/ # 项目级定义(可入库共享)
285
- audit-endpoints.json
286
- ~/.pi/agent/taskflows/ # 用户级定义
287
- deep-research.json
288
- .pi/taskflows/runs/ # run 状态(恢复用,gitignore)
289
- <runId>.json # {def, args, phases:{id:{status,output,usage,hash}}}
290
- ```
291
-
292
- ---
293
-
294
- ## 4. 与现有 subagent 的关系
295
-
296
- - **不替代,是上层编排**。subagent = 即时调用;taskflow = 可定义/保存/恢复的编排。
297
- - 复用其 spawn / 并发 / usage / TUI 代码(移植进 `runner.ts`,避免硬依赖一个非 npm 的本地扩展)。
298
- - 共享 agent 体系(`~/.pi/agent/agents/*.md` + settings `subagents.agentOverrides`)。
299
-
300
- ---
301
-
302
- ## 5. 路线图
303
-
304
- | 版本 | 范围 | 状态 |
305
- |------|------|------|
306
- | **v0.1** | DSL + schema + runtime(agent/parallel/map/reduce)+ `taskflow` 工具 + `/tf run` + 内存隔离 + 流式进度 | ✅ 已发布 (npm 0.0.1) |
307
- | **v0.2** | 保存/动态命令注册 + 跨 session 恢复 + `gate` 真门控 + run 历史交互 TUI | ✅ 已完成 (npm 0.0.3) |
308
- | **v0.3** | examples + SKILL.md(教 LLM 写定义)+ YAML 支持 + 发布 npm | 🚧 examples/SKILL/npm 已做;YAML 待办 |
309
- | **v0.6** | 控制流 & 可靠性:`when` 条件分支 + `join:any` OR-join + 声明式 `retry` + `approval` 人在环 + `flow` 子流程组合 + `budget` 成本上限 | ✅ 已完成 |
310
- | **v0.7+** | 真·后台执行(detached + 轮询)+ 事件/cron 触发 + 成本**预估** + mermaid DAG 导出 + 内置 `deep-research` 工作流 | ⏳ 待办 |
311
-
312
- ---
313
-
314
- ## 6. 风险与缓解
315
-
316
- | 风险 | 缓解 |
317
- |------|------|
318
- | 真后台执行 v1 缺失 | 流式长调用 + 明确文档;v4 补 |
319
- | map 依赖上游输出结构化 JSON | `output:"json"` + 容错解析 + schema 提示 agent |
320
- | spawn pi 路径解析(bun/node/standalone) | 移植 subagent 的 `getPiInvocation()`(已处理三种运行时) |
321
- | 并发过高耗 token/限流 | concurrency 上限 + 成本预估(v4) |
322
- | 运行时命令注册兼容性 | session_start 扫描注册兜底;保存即注册为增强 |
323
- | DSL 过度复杂 | 保持声明式、5 种 phase 封顶;JS 逃生舱不做(保持"轻量") |
324
-
325
- ---
326
-
327
- ## 7. 下一步
328
-
329
- 1. 创建 `package.json` + `tsconfig.json` + 骨架目录
330
- 2. 实现 `schema.ts`(DSL 校验)+ `interpolate.ts`
331
- 3. 移植 `runner.ts` / `agents.ts`(自 subagent)
332
- 4. 实现 `runtime.ts`(DAG 调度 + map fan-out)
333
- 5. `index.ts` 接线 tool + `/tf` 命令
334
- 6. 本地 `pi -e ./extensions/index.ts` 联调
335
- 7. examples + SKILL.md + README
336
- 8. 发布 `npm publish` → `pi install npm:pi-taskflow`
337
- </content>
338
- </invoke>