@deepseek-ai/dsh-workflow 0.1.1-rc.2 → 0.1.2-alpha.2

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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/workflow/workflow/README.md
5
- README.md: cc2c24f62512273ea1657542d0d904b0b870e236
6
- README.zh.md: 0b02cea896b3cb64559ce110c0da2478728f513c
5
+ README.md: 80b9f1a912f9f58432d2fff1fc76615c04cd2751
6
+ README.zh.md: e692081d99021b7ed6059af61527e551517c9eea
package/README.md CHANGED
@@ -1,61 +1,143 @@
1
+ ---
2
+ description: "The workflow orchestration capability: run a model-written script that fans out subagents, for users and maintainers choosing or building on ctx.workflowEngine."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-workflow
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- The workflow seam (`ctx.workflowEngine`) executes a model-written orchestration script that can fan out subagents. The seam defines the script, run, result, error, and event contracts; an engine decides how to isolate and execute the script.
10
+ ## Summary
11
+
12
+ `dsh-workflow` runs a plain-JavaScript orchestration script and gives the caller a live run whose result resolves with the script's final JSON value. The script can fan out subagents with `agent()`, combine independent work with `parallel()` and `pipeline()`, and narrate progress with `phase()` and `log()`; agents normally drive this through the `workflow` tool from `dsh-tool-workflow`. A run is holder-owned: its result never rejects, cancellation and disposal are bounded, and every child is attributed to the invoking agent. The package ships no execution engine — `dsh-workflow-worker-thread` is the current one — so a different isolation strategy can replace it without changing what callers or the model see.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Run a workflow when a task decomposes into many independent pieces that one script should coordinate — an audit across many files, a migration, multi-angle research — and the model explicitly asks for workflow-style orchestration. For one or two delegations, prefer a plain subagent call.
29
+
30
+ ### The model-facing path
31
+
32
+ The model reaches the capability through the `workflow` tool from `dsh-tool-workflow`, which owns the call schema and result envelope; the engine supplies the execution underneath. A tool call submits `meta`, `script`, and optional `args` and returns `{ runId, agentsStarted, result }` when the run completes. The tool blocks the parent turn until the whole workflow settles, so the model sees one final outcome, never intermediate child messages.
33
+
34
+ ### Running a workflow script
35
+
36
+ An orchestration script is a plain JavaScript body (not TypeScript) that runs with top-level `await` and ends with `return <json-value>`. The `meta` identity block and any `args` arrive as plain JSON data — never evaluated code. During execution the script calls the provided hooks: `agent(prompt, opts)` starts one subagent and resolves with its final text or, with a schema, a validated structured value; `parallel()` and `pipeline()` combine independent work; `phase()` and `log()` narrate progress for observers.
37
+
38
+ ```text
39
+ // Script body — runs with top-level await, ends with a JSON return value:
40
+ const reviews = await parallel([
41
+ () => agent('Review src/a.ts for correctness'),
42
+ () => agent('Review src/b.ts for correctness'),
43
+ ])
44
+ return { reviewed: reviews.length }
45
+ ```
46
+
47
+ When the script settles, the run's result resolves with the returned value, the stop reason, and the number of children started. A script that returns nothing yields `null`.
48
+
49
+ ### Programmatic runs
50
+
51
+ Plugin consumers can start a run directly: `ctx.workflowEngine.start({ script, meta, args?, parent, signal? })`. `parent` attributes every child to the invoking agent; `signal` cancels the run when aborted. `start()` validates the meta block and parses the script before a run exists, so a malformed request fails immediately with a violation list.
6
52
 
7
- `@deepseek-ai/dsh-workflow-worker-thread` is the current engine and `@deepseek-ai/dsh-tool-workflow` is the model-facing consumer. A future process or sandbox engine can replace the implementation without changing the tool.
53
+ A returned run exposes `id`, `meta`, `result`, `cancel(reason?)`, and `dispose()`. The result never rejects: a script failure resolves with `stopReason: 'error'`, cancellation with `'cancelled'`. The caller owns the run — call `dispose()` on every path; it cancels remaining work and waits for script and children to settle within a bounded grace.
8
54
 
9
- The package root is the Host face. The browser-safe `@deepseek-ai/dsh-workflow/types` subpath contains run identities, metadata, results, and observe-only lifecycle payloads without importing `Agent`, Cordis services, or Host context declarations; Host-only `WorkflowStartRequest` and `WorkflowRun` live behind the package root.
55
+ ### Failures and recovery
10
56
 
11
- ## Service and run contract
57
+ A script that does not parse, a malformed meta block, an unavailable provider route, or an unsupported per-run limit is rejected synchronously before a run exists; the `workflow` tool reports these as errors the model can correct from. During execution, hook misuse — bad arguments, unknown options, unsupported schemas, tripped caps — kills the script loudly rather than dissolving into a per-item `null`. An ordinary child failure is not an infrastructure error: `agent()` resolves `null` and the script decides how to handle it.
12
58
 
13
- `WorkflowEngine.start(request): WorkflowRun` validates enough synchronously to reject a malformed meta block, unparseable script, unavailable provider route, or unsupported per-run limit before a run exists. Once returned, `WorkflowRun.result` never rejects: execution failures resolve with `stopReason: 'error'`, and cancellation resolves with `cancelled` within the engine's bounded grace.
59
+ -----
14
60
 
15
- A run is holder-owned. Engine-plugin unload prevents new starts but does not revoke accepted runs. The holder must call `dispose()` on every path; disposal cancels remaining work and reaches or abandons quiescence within the documented bound.
61
+ <a id="understand-the-implementation"></a>
62
+ ## Understand the implementation
16
63
 
17
- `WorkflowStartRequest` contains `{ meta, script, args?, subagentProvider?, maxTotalAgents?, parent, signal? }`. `parent` attributes every child agent to the invoking agent. `subagentProvider` optionally routes every child in that run without exposing provider choice to the script; omission uses the engine's configured provider. `maxTotalAgents` optionally lowers the engine's deployment ceiling for one run and is likewise invisible to the script. An implementation rejects invalid routes and limits synchronously. `meta` and `args` are plain data, not script fragments.
64
+ <details>
65
+ <summary>Implementation internals — click to expand</summary>
18
66
 
19
- `WorkflowRun` exposes `{ id, meta, result, cancel(reason?), dispose() }`. `WorkflowResult` contains `{ value, stopReason, error?, agentsStarted }`; `value` is plain JSON data or `null`.
67
+ This section explains how the capability is split and where the contracts live; observable behavior is fully covered in [Use this package](#use-this-package).
20
68
 
21
- ## Events
69
+ ### Design concept
22
70
 
23
- Workflow events are observe-only. They carry `WorkflowRunInfo` (`id` plus `meta`) rather than the live run, so listeners cannot acquire cancellation or disposal authority.
71
+ The package separates the script, run, result, and event contracts from execution: any engine can implement `ctx.workflowEngine` behind the same vocabulary, and one engine serves a context at a time — loading a second engine fails loud, so swapping engines means changing which engine plugin the composition loads. The `workflow/*` events are observe-only: payloads carry run identity snapshots, never the live run, so listeners cannot acquire cancellation or disposal authority.
24
72
 
25
- - `workflow/start` / `workflow/end` pair the run.
26
- - `workflow/phase` and `workflow/log` expose script narration.
27
- - `workflow/agent-start` / `workflow/agent-end` pair each child call by `seq`; a child whose async provider start rejects emits neither.
73
+ ### Source map
28
74
 
29
- Same-process event payloads are borrowed immutable values. Every listener is independently contained: a synchronous throw or rejected returned promise is logged without starving peers or changing execution.
75
+ | File | Role |
76
+ |---|---|
77
+ | [`src/index.ts`](src/index.ts) | Service definition, `workflow/*` event declarations, `WorkflowError` and its fatal flag |
78
+ | [`src/types.ts`](src/types.ts) | Browser-safe vocabulary: `WorkflowMeta`, `WorkflowResult`, run and agent event info |
79
+ | [`src/runtime-types.ts`](src/runtime-types.ts) | Host-only `WorkflowStartRequest` and `WorkflowRun` handles |
80
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: event pairing and identity checks |
30
81
 
31
- ## Failure discipline
82
+ ### Lifecycle and ownership
32
83
 
33
- `WorkflowError` carries a code and a `fatal` flag. Fatal errors always escape `parallel()` and `pipeline()` instead of becoming an ordinary per-item `null`:
84
+ A run is holder-owned: engine-plugin unload prevents new starts but does not revoke accepted runs, and the caller must dispose every run it starts. `dispose()` cancels if needed and awaits script and child quiescence within the engine's documented bound, so a consumer awaiting `result` is never wedged past a cancellation.
34
85
 
35
- - `SCRIPT_PARSE` / `META_INVALID` the workflow cannot start.
36
- - `INVALID_ARGUMENT` / `UNSUPPORTED_OPTION` / `UNSUPPORTED_SCHEMA` — a hook call violates the engine contract.
37
- - `AGENT_CAP` / `ITEM_CAP` — configured safety limits were exceeded.
38
- - `AGENT_START` — the provider's async start rejected.
39
- - `AGENT_RESULT` — a published child's result rejected with an infrastructure fault.
40
- - `RESULT_UNSERIALIZABLE` — a script/worker value is not plain JSON data.
41
- - `CANCELLED` — cancellation owns the run and pending/future hooks reject.
86
+ `workflow/start` and `workflow/end` pair the run; `workflow/phase` and `workflow/log` carry script narration; `workflow/agent-start` and `workflow/agent-end` pair each child call by `seq`. Every listener is independently contained: a throwing listener is logged without starving peers or changing execution, and each receives its own payload clone.
42
87
 
43
- A child that resolves normally with a non-completed stop reason is not an infrastructure exception: `agent()` returns `null`, allowing the script to handle an ordinary child failure.
88
+ ### Failure discipline
44
89
 
90
+ `WorkflowError` carries a machine-routable code and a `fatal` flag; every code is fatal, and `parallel()` and `pipeline()` re-throw fatal errors instead of mapping the item to `null` — a typo'd option must kill the script loudly. Codes cover start failures, contract violations, exceeded caps, provider and result faults, unserializable values, and cancellation; the exact set and meanings live in [`src/index.ts`](src/index.ts).
91
+
92
+ The per-item `null` is reserved for child-run failures and ordinary in-stage script errors, so a child that resolves normally with a non-completed stop reason is not an infrastructure exception: `agent()` returns `null`, letting the script handle an ordinary child failure.
93
+
94
+ </details>
95
+
96
+ -----
97
+
98
+ <a id="further-exploration"></a>
99
+ ## Further Exploration
100
+
101
+ Read these pages when the package-level contract is not enough. They move from the shared workflow model to the current engine and the model-facing consumers.
102
+
103
+ - [Workflow subsystem](../../../docs/subsystems/workflow.md) — the full type vocabulary, start request, and event payloads.
104
+ - [Group map](../README.md) — the workflow capability family and its packages.
105
+ - [workflow tool](../tool-workflow/README.md) — the model-facing consumer that owns the call schema and result envelope.
106
+ - [Worker-thread engine](../workflow-worker-thread/README.md) — the current execution engine and its isolation boundary.
107
+ - [Dynamic workflows Agent Note](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md) — the seam design and its decisions.
108
+
109
+ -----
110
+
111
+ <a id="model-experience"></a>
45
112
  ## Model Experience
46
113
 
47
- Indirectly, through `dsh-tool-workflow` and a workflow engine, which create child-agent requests and return a retained parent tool result.
114
+ Indirectly, through its consumer `dsh-tool-workflow` and a workflow engine, which render the parent tool result and the child-agent requests.
48
115
 
49
116
  #### KV Cache effect
50
117
 
51
- No direct invalidation; the named consumer owns any request-prefix changes.
118
+ No direct invalidation; the named consumer and engine own any request-prefix changes.
52
119
 
53
120
  ## Known Limitations and Deferred Work
54
121
 
122
+ <a id="known-limitations-and-deferred-work"></a>
123
+
124
+
125
+ These limits define what the capability does not yet support. They are current constraints, not a task backlog.
126
+
55
127
  - **Foreground collection only** — the caller owns one live run and awaits it; background start/poll, spill handles, and detached collection are deferred.
56
128
  - **No journaling or resume** — scripts, child progress, and intermediate values are not checkpointed, so a process restart cannot continue a run.
57
- - **No saved or nested workflows** — the seam starts caller-supplied scripts only, and a workflow script receives no `workflow()` hook for recursive orchestration.
58
- - **No token-budget vocabulary** — engines cap concurrency, items, and children, but neither the request nor result accounts for model tokens across children.
129
+ - **No saved or nested workflows** — the capability starts caller-supplied scripts only, and a workflow script receives no `workflow()` hook for recursive orchestration.
130
+ - **No token-budget vocabulary** — engines cap concurrency, items, and children, but neither the request nor the result accounts for model tokens across children.
59
131
  - **Runs are holder-owned, not service-tracked** — unloading the engine does not discover independent live handles; every consumer must dispose the run it started.
60
132
 
61
- See the [dynamic-workflows Agent Note](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md) for the deferred workflow API.
133
+ <a id="dev-note"></a>
134
+ ### Dev Note
135
+
136
+ <details>
137
+ <summary>Working context for maintainers — click to expand</summary>
138
+
139
+ This Dev Note is working context for maintainers: open directions that are not decided. It is explicitly non-authoritative — shipped behavior, limits, and accepted rationale live in the sections above, the package code, and the linked Agent Notes.
140
+
141
+ Deferred directions: a background start/poll API with spill handles and detached collection; saved and nested workflows; a token-budget vocabulary across children; and the seam's promise that a future process or sandbox engine can replace the worker-thread engine without changing the model-facing surface.
142
+
143
+ </details>
package/README.zh.md CHANGED
@@ -1,61 +1,143 @@
1
+ ---
2
+ description: "工作流编排能力:运行由模型编写的、扇出 subagent 的脚本,供选择或构建在 ctx.workflowEngine 之上的用户与维护者阅读。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-workflow
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 工作流 seam(扩展点,`ctx.workflowEngine`)执行由模型编写、可扇出 subagent 的编排脚本。该 seam 定义脚本、运行、结果、错误和事件契约;引擎负责决定如何隔离并执行脚本。
10
+ ## 概述
11
+
12
+ `dsh-workflow` 运行一段纯 JavaScript 编排脚本,并交给调用方一个活动运行,其 result 在脚本结算时以脚本的最终 JSON 值兑现。脚本可以用 `agent()` 扇出 subagent,用 `parallel()` 和 `pipeline()` 组合独立工作,用 `phase()` 和 `log()` 叙述进度;agent 通常通过 `dsh-tool-workflow` 的 `workflow` 工具驱动这一切。运行由持有方负责:其 result 绝不拒绝,取消与 dispose(资源释放)有界,每个子 agent 都归属于调用它的 agent。本包不附带执行引擎——当前引擎是 `dsh-workflow-worker-thread`——因此可以用不同的隔离策略替换它,而不改变调用方或模型看到的内容。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 当任务分解为许多独立部分、适合用一段脚本统一协调——例如跨多个文件的审计、一次迁移、多角度研究——且模型明确要求工作流式编排时,运行工作流。一两项委派时,优先使用普通 subagent 调用。
29
+
30
+ ### 模型侧路径
31
+
32
+ 模型通过 `dsh-tool-workflow` 的 `workflow` 工具触达该能力;该工具拥有调用 schema 与结果包络,引擎提供其下的执行。一次工具调用提交 `meta`、`script` 与可选 `args`,运行完成时返回 `{ runId, agentsStarted, result }`。工具会阻塞父级轮次直到整个工作流结算,因此模型只看到最终结果,永远不会看到中间子 agent 消息。
33
+
34
+ ### 运行工作流脚本
35
+
36
+ 编排脚本是纯 JavaScript 脚本体(不是 TypeScript),以顶层 `await` 运行并以 `return <json-value>` 结尾。`meta` 身份块与任何 `args` 都以普通 JSON 数据到达——绝不作为代码求值。执行期间脚本调用提供的钩子:`agent(prompt, opts)` 启动一个 subagent,并以其最终文本、或在提供 schema 时以经过校验的结构化值兑现;`parallel()` 与 `pipeline()` 组合独立工作;`phase()` 与 `log()` 为观察者叙述进度。
37
+
38
+ ```text
39
+ // Script body — runs with top-level await, ends with a JSON return value:
40
+ const reviews = await parallel([
41
+ () => agent('Review src/a.ts for correctness'),
42
+ () => agent('Review src/b.ts for correctness'),
43
+ ])
44
+ return { reviewed: reviews.length }
45
+ ```
46
+
47
+ 脚本结算时,运行的 result 以返回值、结束原因和已启动的子 agent 数量兑现。脚本不返回值时得到 `null`。
48
+
49
+ ### 编程方式运行
50
+
51
+ 插件消费方可以直接启动运行:`ctx.workflowEngine.start({ script, meta, args?, parent, signal? })`。`parent` 把每个子 agent 归属于调用它的 agent;`signal` 在中止时取消运行。`start()` 在运行存在之前校验 meta 块并解析脚本,因此格式错误的请求会立即以违规清单失败。
6
52
 
7
- `@deepseek-ai/dsh-workflow-worker-thread` 是当前引擎,`@deepseek-ai/dsh-tool-workflow` 是面向模型的消费方。未来的进程或沙箱引擎可以替换实现,而无需更改工具。
53
+ 返回的运行公开 `id`、`meta`、`result`、`cancel(reason?)` `dispose()`。result 绝不拒绝:脚本失败以 `stopReason: 'error'` 兑现,取消以 `'cancelled'` 兑现。调用方拥有该运行——每条路径都要调用 `dispose()`;它会取消剩余工作,并在有界宽限期内等待脚本与子 agent 完全停稳。
8
54
 
9
- 包根是 Host face。浏览器安全的 `@deepseek-ai/dsh-workflow/types` 子路径包含运行身份、元数据、结果和仅供观察的生命周期 payload,不导入 `Agent`、Cordis service 或 Host Context 声明;Host 专用的 `WorkflowStartRequest` 与 `WorkflowRun` 只从包根提供。
55
+ ### 失败与恢复
10
56
 
11
- ## 服务与运行契约
57
+ 无法解析的脚本、格式错误的 meta 块、不可用的提供方路由或不受支持的单次运行限制,都会在运行存在之前被同步拒绝;`workflow` 工具把这些报告为模型可以修正的错误。执行期间,钩子误用——错误参数、未知选项、不支持的 schema、超出上限——会响亮地终止脚本,而不会溶解为逐项 `null`。普通子 agent 失败不是基础设施错误:`agent()` 以 `null` 兑现,由脚本决定如何处理。
12
58
 
13
- `WorkflowEngine.start(request): WorkflowRun` 会同步完成足够多的校验,在运行创建前拒绝格式错误的 meta 块、无法解析的脚本、不可用的提供方路由或不受支持的单次运行限制。返回后,`WorkflowRun.result` 绝不拒绝:执行失败以 `stopReason: 'error'` 兑现,取消则在引擎有限的宽限时间内以 `cancelled` 兑现。
59
+ -----
14
60
 
15
- 运行由持有方负责。引擎插件卸载会阻止新的启动,但不会撤销已接受的运行。持有方必须在每条路径上调用 `dispose()`;dispose(资源释放)会取消剩余工作,并在文档规定的期限内达到或放弃完全停稳。
61
+ <a id="understand-the-implementation"></a>
62
+ ## 理解实现
16
63
 
17
- `WorkflowStartRequest` 包含 `{ meta, script, args?, subagentProvider?, maxTotalAgents?, parent, signal? }`。`parent` 把每个子 agent(智能体)归属于调用 agent。`subagentProvider` 可以为该次运行的所有子 agent 指定路由,同时不向脚本公开提供方选择;省略时使用引擎配置的提供方。`maxTotalAgents` 可以为一次运行降低引擎的部署上限,同样对脚本不可见。实现会同步拒绝无效路由和限制。`meta` 与 `args` 是普通数据,不是脚本片段。
64
+ <details>
65
+ <summary>实现细节——点击展开</summary>
18
66
 
19
- `WorkflowRun` 公开 `{ id, meta, result, cancel(reason?), dispose() }`。`WorkflowResult` 包含 `{ value, stopReason, error?, agentsStarted }`;`value` 是普通 JSON 数据或 `null`。
67
+ 本节解释能力如何拆分、契约位于何处;可观察行为已在[使用本包](#use-this-package)中完整说明。
20
68
 
21
- ## 事件
69
+ ### 设计理念
22
70
 
23
- 工作流事件只供观察。它们携带 `WorkflowRunInfo`(`id` `meta`),而不是活动运行,因此监听器无法取得取消或 dispose 权限。
71
+ 本包把脚本、运行、结果与事件契约同执行分开:任何引擎都可以在同一词汇背后实现 `ctx.workflowEngine`,一个上下文同时只有一个引擎——加载第二个引擎会立即失败,因此更换引擎意味着更改组合所加载的引擎插件。`workflow/*` 事件只供观察:payload 携带运行身份快照,绝不携带活动运行,因此监听器无法取得取消或 dispose 权限。
24
72
 
25
- - `workflow/start` / `workflow/end` 为运行配对;
26
- - `workflow/phase` 和 `workflow/log` 公开脚本叙述;
27
- - `workflow/agent-start` / `workflow/agent-end` 按 `seq` 为每次子 agent 调用配对;提供方的异步启动调用被拒绝时,该子 agent 不会发出其中任何一个事件。
73
+ ### 源码地图
28
74
 
29
- 同进程事件 payload 是以不可变方式借用的值。每个监听器都独立隔离:同步抛出异常或返回的 promise 被拒绝时,只会记录日志,不会阻塞同级监听器或改变执行。
75
+ | 文件 | 职责 |
76
+ |---|---|
77
+ | [`src/index.ts`](src/index.ts) | 服务定义、`workflow/*` 事件声明、`WorkflowError` 及其 fatal 标志 |
78
+ | [`src/types.ts`](src/types.ts) | 浏览器安全词汇:`WorkflowMeta`、`WorkflowResult`、运行与 agent 事件信息 |
79
+ | [`src/runtime-types.ts`](src/runtime-types.ts) | 仅宿主的 `WorkflowStartRequest` 与 `WorkflowRun` 句柄 |
80
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:事件配对与身份校验 |
30
81
 
31
- ## 失败纪律
82
+ ### 生命周期与归属
32
83
 
33
- `WorkflowError` 携带一个代码和 `fatal` 标志。致命错误总会逸出 `parallel()` `pipeline()`,而不会变成普通的逐项 `null`:
84
+ 运行由持有方负责:引擎插件卸载会阻止新的启动,但不会撤销已接受的运行,调用方必须 dispose 自己启动的每个运行。`dispose()` 在需要时取消,并在引擎文档规定的期限内等待脚本与子 agent 完全停稳,因此等待 `result` 的消费方绝不会因取消而卡死。
34
85
 
35
- - `SCRIPT_PARSE` / `META_INVALID`:工作流无法启动;
36
- - `INVALID_ARGUMENT` / `UNSUPPORTED_OPTION` / `UNSUPPORTED_SCHEMA`:钩子调用违反引擎契约;
37
- - `AGENT_CAP` / `ITEM_CAP`:超过已配置的安全上限;
38
- - `AGENT_START`:提供方的异步启动调用被拒绝;
39
- - `AGENT_RESULT`:已发布子 agent 的结果因基础设施故障而被拒绝;
40
- - `RESULT_UNSERIALIZABLE`:脚本/worker 值不是普通 JSON 数据;
41
- - `CANCELLED`:取消会接管该运行,待处理和未来的钩子都会拒绝。
86
+ `workflow/start` `workflow/end` 为运行配对;`workflow/phase` `workflow/log` 携带脚本叙述;`workflow/agent-start` 与 `workflow/agent-end` 按 `seq` 为每次子 agent 调用配对。每个监听器都独立隔离:抛错的监听器只记录日志,不会饿死同级监听器或改变执行,并且每个监听器都会收到自己的 payload 副本。
42
87
 
43
- agent 若以非完成的结束原因正常兑现,并不属于基础设施异常:`agent()` 返回 `null`,使脚本可以处理普通的子 agent 失败。
88
+ ### 失败纪律
44
89
 
90
+ `WorkflowError` 携带机器可路由的 code 与 `fatal` 标志;每个 code 都是致命的,`parallel()` 与 `pipeline()` 会重新抛出致命错误,而不是把条目映射为 `null`——拼错的选项必须响亮地终止脚本。code 覆盖启动失败、契约违规、超出上限、提供方与结果故障、不可序列化值与取消;完整集合与含义见 [`src/index.ts`](src/index.ts)。
91
+
92
+ 逐项 `null` 只保留给子运行失败与阶段内普通脚本错误,因此以非完成结束原因正常结算的子 agent 不属于基础设施异常:`agent()` 返回 `null`,让脚本处理普通子 agent 失败。
93
+
94
+ </details>
95
+
96
+ -----
97
+
98
+ <a id="further-exploration"></a>
99
+ ## 进一步探索
100
+
101
+ 当包级契约不够用时阅读以下页面。它们从共享工作流模型逐步进入当前引擎与面向模型的消费方。
102
+
103
+ - [工作流子系统](../../../docs/subsystems/workflow.zh.md)——完整类型词汇、启动请求与事件载荷。
104
+ - [组地图](../README.zh.md)——工作流能力家族及其包。
105
+ - [workflow 工具](../tool-workflow/README.zh.md)——拥有调用 schema 与结果包络的模型侧消费方。
106
+ - [worker-thread 引擎](../workflow-worker-thread/README.zh.md)——当前执行引擎及其隔离边界。
107
+ - [动态工作流 Agent Note](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.zh.md)——seam 设计及其决策。
108
+
109
+ -----
110
+
111
+ <a id="model-experience"></a>
45
112
  ## 模型体验
46
113
 
47
- 通过 `dsh-tool-workflow` 和工作流引擎间接产生影响;两者创建子 agent 请求,并返回保留在父级的工具结果。
114
+ 间接地,通过其消费方 `dsh-tool-workflow` 与一个工作流引擎,由它们渲染父级工具结果与子 agent 请求。
48
115
 
49
116
  #### KV Cache 影响
50
117
 
51
- 不会直接导致 KV Cache 失效;请求前缀的任何变化均由上述消费方负责。
118
+ 不会直接导致失效;请求前缀的任何变化均由上述消费方与引擎负责。
119
+
120
+ ## 已知限制与延期工作
121
+
122
+ <a id="known-limitations-and-deferred-work"></a>
123
+
124
+
125
+ 这些限制说明该能力尚未支持什么。它们是当前约束,不是任务积压。
126
+
127
+ - **仅支持前台收集**——调用方拥有一个活动运行并等待它;后台启动/轮询、spill 句柄与分离收集均暂缓。
128
+ - **没有日志化或恢复**——脚本、子 agent 进度与中间值均不设检查点,因此进程重启后无法继续运行。
129
+ - **没有已保存或嵌套工作流**——该能力只启动调用方提供的脚本,工作流脚本不会收到用于递归编排的 `workflow()` 钩子。
130
+ - **没有 token 预算词汇**——引擎限制并发、条目与子 agent,但请求与结果都不会统计跨子 agent 的模型 token。
131
+ - **运行由持有方负责,不由服务跟踪**——卸载引擎不会发现独立的活动句柄;每个消费方都必须 dispose 自己启动的运行。
132
+
133
+ <a id="dev-note"></a>
134
+ ### 开发备注
135
+
136
+ <details>
137
+ <summary>维护者的工作上下文——点击展开</summary>
52
138
 
53
- ## 已知限制与暂缓事项
139
+ 本开发备注是维护者的工作上下文:尚未决定的开放方向。它明确不具权威性——已交付的行为、限制与既定理由以上文、包代码与相关 Agent Note 为准。
54
140
 
55
- - **仅支持前台收集**:调用方负责一个活动运行并等待它;后台启动/轮询、spill 句柄和分离收集均暂缓处理。
56
- - **没有日志化或恢复**:脚本、子 agent 进度和中间值均不设检查点,因此进程重启后无法继续运行。
57
- - **没有已保存或嵌套工作流**:该 seam 只启动调用方提供的脚本,工作流脚本不会收到用于递归编排的 `workflow()` 钩子。
58
- - **没有 token 预算词汇**:引擎会限制并发、条目和子 agent,但请求与结果都不会统计跨子 agent 的模型 token。
59
- - **运行由持有方负责,不由服务跟踪**:卸载引擎不会发现独立的活动句柄;每个消费方都必须 dispose 自己启动的运行。
141
+ 暂缓的方向:带 spill 句柄与分离收集的后台启动/轮询 API;已保存与嵌套工作流;跨子 agent 的 token 预算词汇;以及该 seam 的承诺——未来的进程或沙箱引擎可以在不改变模型侧表面的前提下替换 worker-thread 引擎。
60
142
 
61
- 暂缓实现的工作流接口见[动态工作流 Agent Note(agent 决策记录)](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.zh.md)。
143
+ </details>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-workflow",
3
3
  "description": "Workflow capability seam: ctx.workflowEngine service, run vocabulary, and workflow/* events",
4
- "version": "0.1.1-rc.2",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -37,19 +37,19 @@
37
37
  ],
38
38
  "license": "MIT",
39
39
  "peerDependencies": {
40
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
41
- "@deepseek-ai/dsh-brand": "^0.1.1-rc.2",
42
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
43
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
44
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
45
- "@deepseek-ai/cordis": "^4.0.1"
40
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
41
+ "@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
42
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
43
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
44
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
45
+ "@deepseek-ai/cordis": "^4.0.2"
46
46
  },
47
47
  "devDependencies": {
48
- "@deepseek-ai/dsh-brand": "^0.1.1-rc.2",
49
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
50
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
51
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
52
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
53
- "@deepseek-ai/cordis": "^4.0.1"
48
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
49
+ "@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
50
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
51
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
52
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
53
+ "@deepseek-ai/cordis": "^4.0.2"
54
54
  }
55
55
  }