@xneog/dsh-workflow-worker-thread 0.1.0 → 0.1.3-alpha.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.i18n.yaml +2 -2
- package/README.md +112 -53
- package/README.zh.md +121 -62
- package/lib/index.js +6 -3
- package/lib/types/host.d.ts +5 -1
- package/lib/worker.cjs +4 -4
- package/package.json +26 -30
- package/lib/invariant.js +0 -23
- package/lib/types/invariant.d.ts +0 -16
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-worker-thread/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 954682f166b7aa51f07d14dae3046bb40dbc52a6
|
|
6
|
+
README.zh.md: 2252616d4d58c3a543ead79246973037be498a8c
|
package/README.md
CHANGED
|
@@ -1,90 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "The worker-thread workflow engine: executes model-written orchestration scripts off the host event loop, for users and maintainers choosing or configuring execution isolation."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @xneog/dsh-workflow-worker-thread
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## Summary
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
`dsh-workflow-worker-thread` implements the workflow engine with one Node worker thread per run: the orchestration script executes inside a fresh worker while its `agent()` calls reach host subagents over a typed host/worker protocol. A synchronous script loop cannot block the harness event loop, and a script that ignores cancellation can be terminated with its worker. The isolation is containment, not a security boundary — a model-written script has the same trust premise as the model's existing bash access, and escaping the `node:vm` context recovers the worker's process authority. Mount this engine to give `ctx.workflowEngine` a concrete implementation; a composition that loads it with `dsh-tool-workflow` gives the model the `workflow` tool.
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## Table of Contents
|
|
10
15
|
|
|
11
|
-
|
|
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)
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
-----
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
- `worker.terminate()` gives disposal a real final stop.
|
|
19
|
-
- The worker starts with an empty environment, except unbuilt loader plumbing, so ambient credentials do not cross through `process.env`.
|
|
20
|
-
- Host/worker messages use structured-clone data, with plain-JSON validation at the script boundary.
|
|
28
|
+
Mount this engine when a composition needs the workflow capability: each orchestration script runs in its own worker thread, off the host event loop, and the `workflow` and `ralph` tools in the shipped composition execute on it. Do not use it as a sandbox for genuinely untrusted scripts — hostile code needs a separate-process or container engine.
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
### Minimal configuration
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
Loading the engine registers `ctx.workflowEngine`; adding `dsh-tool-workflow` on top gives the model the `workflow` tool. Every config field is optional:
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@xneog/dsh-workflow-worker-thread'
|
|
36
|
+
- name: '@xneog/dsh-tool-workflow'
|
|
37
|
+
```
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
| Field | Default | Meaning |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `provider` | `spawn` | Host-side subagent provider used by `agent()` calls. |
|
|
42
|
+
| `maxConcurrentAgents` | `0` | Concurrent `agent()` ceiling; `0` resolves from available CPU parallelism. |
|
|
43
|
+
| `maxTotalAgents` | `1000` | Total `agent()` calls one run may start — the runaway-loop backstop. |
|
|
44
|
+
| `maxItemsPerCall` | `4096` | Items accepted by one `parallel()` or `pipeline()` call. |
|
|
45
|
+
| `syncTimeoutMs` | `5000` | VM timeout for the script's initial synchronous slice, in milliseconds. |
|
|
46
|
+
| `disposeGraceMs` | `5000` | Bound before force-settlement and worker termination; also bounds `dispose()`. |
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
- `parallel(thunks)` runs thunks under the configured concurrency limit.
|
|
32
|
-
- `pipeline(items, ...stages)` passes `(previous, item, index)` without a cross-stage barrier.
|
|
33
|
-
- `phase(title)` and `log(message)` emit observer narration.
|
|
48
|
+
An owning consumer may set `WorkflowStartRequest.subagentProvider` and `WorkflowStartRequest.maxTotalAgents` for one run — engine-level policy, not script hooks; the ordinary `workflow` tool leaves both unset, and a per-run total-child cap may lower but never raise the configured ceiling. The generated [configuration catalog](../../../docs/config-catalog.md#xneogdsh-workflow-worker-thread) is the exhaustive source for every accepted field.
|
|
34
49
|
|
|
35
|
-
|
|
50
|
+
### What a run gives you
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
When a run starts, the script body executes in the worker with top-level `await` and the hooks `agent()`, `parallel()`, `pipeline()`, `phase()`, and `log()`; `meta` and `args` arrive as plain JSON data, never evaluated code. Every `agent()` call starts a host-side subagent under the configured provider, with the run's parent as the parent of every child. The run settles with the script's final JSON value; an ordinary child failure resolves `agent()` to `null` so the script can handle it.
|
|
38
53
|
|
|
39
|
-
|
|
54
|
+
A malformed meta block, a body that does not parse, an unavailable provider route, or a per-run cap above the ceiling is rejected synchronously before a worker exists, so the caller sees a violation list and can correct the call. During execution, hook misuse and tripped caps kill the script with a fatal workflow error. Cancellation is bounded: a script that ignores it is force-settled as cancelled and its worker terminated after `disposeGraceMs`.
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
### Trust expectations
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
2. The host calls the start request's provider override, or otherwise the configured provider, through async `SubagentRuntime.start`, passing the workflow's parent and one canonical per-run abort signal. Provider choice applies to every child in that run and is not visible to the script.
|
|
45
|
-
3. If start rejects, the host sends `child-start-error`; provider startup has already reached quiescence and no child lifecycle event is emitted.
|
|
46
|
-
4. If start fulfills while the workflow still admits work, the host records the run, observes `result`, then sends `child-started`. Even an already-settled result is forwarded afterward, preserving start-before-result order.
|
|
47
|
-
5. The worker emits paired `workflow/agent-start` and `workflow/agent-end` narration and requests child disposal after collection.
|
|
58
|
+
Script CPU work and synchronous spins stay off the host event loop, `worker.terminate()` gives disposal a real final stop, and the worker starts with a scrubbed environment — only platform temp paths and, in source mode, `TSX_TSCONFIG_PATH` — so ambient credentials do not cross through `process.env`. Host/worker messages use structured-clone data with plain-JSON validation at the script boundary.
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
None of this is a security boundary: no timers, filesystem API, or Node globals are intentionally injected, but escaped code can still reach Node with the worker's process authority.
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
-----
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
<a id="understand-the-implementation"></a>
|
|
65
|
+
## Understand the implementation
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
<details>
|
|
68
|
+
<summary>Implementation internals — click to expand</summary>
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
This section explains the engine's isolation design and run mechanics; observable behavior is fully covered in [Use this package](#use-this-package).
|
|
58
71
|
|
|
59
|
-
|
|
72
|
+
### Design concept
|
|
60
73
|
|
|
61
|
-
|
|
74
|
+
One worker thread per run keeps a misbehaving script from stalling the host and makes force termination possible: the script runs in an escapable `node:vm` context inside the worker, and `agent()` calls cross a typed host/worker protocol back to `ctx.subagents`. The vm context shapes the script's API surface; it is not a security sandbox.
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
### Source map
|
|
64
77
|
|
|
65
|
-
|
|
78
|
+
| File | Role |
|
|
79
|
+
|---|---|
|
|
80
|
+
| [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, up-front validation, `start()` wiring |
|
|
81
|
+
| [`src/host.ts`](src/host.ts) | Host side of a run: worker spawn, child orchestration, settlement, disposal |
|
|
82
|
+
| [`src/worker.ts`](src/worker.ts) | Worker entry: script execution, hook implementation, value materialization |
|
|
83
|
+
| [`src/runtime.ts`](src/runtime.ts) | Script runtime: hook contracts, `parallel()` and `pipeline()` combinators |
|
|
84
|
+
| [`src/realm.ts`](src/realm.ts) | Cross-realm materialization: plain-JSON acceptance and rejection rules |
|
|
85
|
+
| [`src/protocol.ts`](src/protocol.ts) | Typed host/worker message protocol |
|
|
86
|
+
| [`src/meta.ts`](src/meta.ts) | `meta` shape validation and normalization |
|
|
87
|
+
| [`src/session.ts`](src/session.ts) | Child run projection and snapshotting before crossing to the worker |
|
|
88
|
+
| — | No runtime invariant companion is published; this process-boundary implementation exposes no same-process event relation; worker protocol and built-worker tests cover it. |
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
### Run sequence
|
|
68
91
|
|
|
69
|
-
|
|
92
|
+
`start()` validates the meta block, parses the body, resolves the provider route, and resolves the per-run total-child cap before creating a worker or publishing `workflow/start`. A ready/go handshake prevents a start-signal cancellation racing worker boot from executing the script's initial synchronous slice; source mode installs TypeScript transforms through a data-URL bootstrap, while built mode passes the sibling `lib/worker.cjs` bundle.
|
|
70
93
|
|
|
71
|
-
|
|
94
|
+
For each `agent()` call the worker sends a `child-start`; the host starts the provider (the request's override, or the configured provider) through the subagent seam, attributes the child to the run's parent, and reports start or start-error back. Provider choice applies to every child in the run and is not visible to the script. Provider starts are tracked separately from published children, so a pending start is aborted by the shared signal when cancellation, worker death, or normal settlement closes admission.
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
### Value boundary
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
Values leaving the script pass through realm materialization, which accepts plain lossless JSON data and rejects exotic prototypes, functions, symbols, cycles, sparse arrays, non-finite numbers, and nested `undefined`. Child results are projected and snapshotted before crossing from host to worker — a real process-like serialization boundary, deliberately different from the borrowed immutable values of same-process workflow events.
|
|
76
99
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
### Cancellation and disposal
|
|
101
|
+
|
|
102
|
+
`cancel()` records the first reason, tells the worker to cancel, aborts the one signal shared by every pending and published child, and arms the `disposeGraceMs` timer; worker hooks then throw `CANCELLED` at their next await. If the run remains unsettled at the deadline, the host resolves it as cancelled, pairs stranded child lifecycle events, and terminates the worker.
|
|
103
|
+
|
|
104
|
+
`dispose()` is idempotent: it cancels the run, starts host-driven disposal immediately, waits for result and child quiescence up to the same grace, terminates the worker unconditionally, and performs a final survivor sweep. Per-child disposal is memoized so worker RPC, host cancellation, death cleanup, and public disposal all join one operation.
|
|
105
|
+
|
|
106
|
+
### Outcome and event guarantees
|
|
107
|
+
|
|
108
|
+
Terminal outcome is first-wins at host claim points: an accepted external cancellation overrides a later non-cancelled worker result, and a result or worker death that claims first cannot be rewritten by reentrant cleanup callbacks. Worker error, message failure, or premature exit closes message admission before cleanup, then resolves `error` unless cancellation already owns the run.
|
|
109
|
+
|
|
110
|
+
The host keeps a ledger of forwarded child starts; a graceful worker supplies their ends, while death or force termination synthesizes any missing end as cancelled — every forwarded `workflow/agent-start` is paired exactly once.
|
|
111
|
+
|
|
112
|
+
</details>
|
|
85
113
|
|
|
86
|
-
|
|
114
|
+
-----
|
|
87
115
|
|
|
116
|
+
<a id="further-exploration"></a>
|
|
117
|
+
## Further Exploration
|
|
118
|
+
|
|
119
|
+
Read these pages when the engine-level contract is not enough. They move from the seam contract to the model-facing consumers and the design decisions.
|
|
120
|
+
|
|
121
|
+
- [Workflow subsystem](../../../docs/subsystems/workflow.md) — the seam contract this engine implements.
|
|
122
|
+
- [Workflow seam](../workflow/README.md) — the run and result vocabulary behind `ctx.workflowEngine`.
|
|
123
|
+
- [workflow tool](../tool-workflow/README.md) — the model-facing consumer that runs scripts on this engine.
|
|
124
|
+
- [Group map](../README.md) — the workflow capability family and its packages.
|
|
125
|
+
- [Dynamic workflows Agent Note](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md) — the seam design and its decisions.
|
|
126
|
+
|
|
127
|
+
-----
|
|
128
|
+
|
|
129
|
+
<a id="model-experience"></a>
|
|
88
130
|
## Model Experience
|
|
89
131
|
|
|
90
132
|
### Child-agent requests
|
|
@@ -105,7 +147,7 @@ Independent of the parent request cache and of sibling children. Each child can
|
|
|
105
147
|
|
|
106
148
|
#### What the model sees
|
|
107
149
|
|
|
108
|
-
Through [`dsh-tool-workflow`](../tool-workflow/README.md), success exposes only the materialized final JSON value and child count in that consumer's wrapper. This engine supplies stable errors including `workflow script does not parse: <error>`, `invalid meta: <violations>`, `agent() requires a non-empty prompt string`, `agent() could not start a child: <error>`, `child agent run failed: <error>`,
|
|
150
|
+
Through [`dsh-tool-workflow`](../tool-workflow/README.md), success exposes only the materialized final JSON value and child count in that consumer's wrapper. This engine supplies stable errors including `workflow script does not parse: <error>`, `invalid meta: <violations>`, `agent() requires a non-empty prompt string`, `agent() could not start a child: <error>`, and `child agent run failed: <error>`, plus its exact `parallel()`, `pipeline()`, `phase()`, option, schema, and JSON-boundary validation messages. Intermediate child outputs are available to the script but not the parent model.
|
|
109
151
|
|
|
110
152
|
#### Token effect
|
|
111
153
|
|
|
@@ -117,8 +159,25 @@ Append-only; newly visible content follows the reusable request prefix and does
|
|
|
117
159
|
|
|
118
160
|
## Known Limitations and Deferred Work
|
|
119
161
|
|
|
120
|
-
|
|
162
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
These limits define when the engine is a poor fit or needs special operational care. They are current constraints, not a task backlog.
|
|
166
|
+
|
|
167
|
+
- **The worker and vm are not a security boundary** — model-written code can escape `node:vm` and reach the worker's process authority; a hostile-code deployment needs a separate-process or container engine.
|
|
121
168
|
- **One worker thread is paid per run** — there is no pool, warm runtime, or cross-run script cache.
|
|
122
|
-
- **No ambient timers, filesystem, or network are injected, but escaped code can still reach Node** — the missing globals are portability API, not containment.
|
|
169
|
+
- **No ambient timers, filesystem, or network are injected, but escaped code can still reach Node** — the missing globals are a portability API, not containment.
|
|
123
170
|
- **Termination can only report host-observed starts** — `agentsStarted` excludes worker-side calls still queued behind concurrency when a forced termination makes them unknowable.
|
|
124
171
|
- **Cross-realm errors fail `instanceof Error` inside scripts** — workflow authors must branch on stable fields such as `name` and `code`.
|
|
172
|
+
|
|
173
|
+
<a id="dev-note"></a>
|
|
174
|
+
### Dev Note
|
|
175
|
+
|
|
176
|
+
<details>
|
|
177
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
178
|
+
|
|
179
|
+
This Dev Note is working context for maintainers: measured artifacts and 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.
|
|
180
|
+
|
|
181
|
+
Open directions: a pooled or warm runtime and a cross-run script cache to avoid one worker per run; a genuine process or container engine for untrusted scripts behind the same seam. The built `./worker` entry ships as a CommonJS bundle because pkg's VFS hook expects CommonJS; source mode installs tsx transforms through a data-URL bootstrap.
|
|
182
|
+
|
|
183
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,111 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "worker-thread 工作流引擎:在宿主事件循环之外执行由模型编写的编排脚本,供选择或配置执行隔离的用户与维护者阅读。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @xneog/dsh-workflow-worker-thread
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
`dsh-workflow-worker-thread` 以每次运行一个 Node worker thread 的方式实现工作流引擎:编排脚本在一个全新 worker 内执行,其 `agent()` 调用通过带类型的宿主/worker 协议触达宿主 subagent。同步脚本循环不会阻塞 harness 事件循环,忽略取消的脚本可以连同其 worker 一起终止。这种隔离只是 containment(隔离),不是安全边界——由模型编写的脚本与模型已有的 bash 访问具有相同的信任前提,逃逸 `node:vm` 上下文即可重新取得 worker 的进程权限。挂载本引擎即为 `ctx.workflowEngine` 提供具体实现;与 `dsh-tool-workflow` 一起加载的组合会把 `workflow` 工具交给模型。
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## 目录
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
-----
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
- `worker.terminate()` 为 dispose(资源释放)提供真实的最终停止手段;
|
|
19
|
-
- 除未构建 loader 所需的衔接配置外,worker 以空环境启动,因此环境凭据不会通过 `process.env` 跨越边界;
|
|
20
|
-
- 宿主/worker 消息使用结构化克隆数据,并在脚本边界执行普通 JSON 校验。
|
|
28
|
+
当组合需要工作流能力时挂载本引擎:每个编排脚本都在独立 worker thread 中、宿主事件循环之外运行,已发布组合中的 `workflow` 与 `ralph` 工具都在其上执行。不要把它当作真正不可信脚本的沙箱——恶意代码需要独立进程或容器引擎。
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
### 最小配置
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
加载本引擎即注册 `ctx.workflowEngine`;在其上添加 `dsh-tool-workflow` 会把 `workflow` 工具交给模型。每个配置字段都是可选的:
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@xneog/dsh-workflow-worker-thread'
|
|
36
|
+
- name: '@xneog/dsh-tool-workflow'
|
|
37
|
+
```
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
| 字段 | 默认值 | 含义 |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `provider` | `spawn` | `agent()` 调用使用的宿主侧 subagent 提供方。 |
|
|
42
|
+
| `maxConcurrentAgents` | `0` | 并发 `agent()` 上限;`0` 会根据可用 CPU 并行度解析。 |
|
|
43
|
+
| `maxTotalAgents` | `1000` | 一次运行最多启动的 `agent()` 调用总数——失控循环的后备闸。 |
|
|
44
|
+
| `maxItemsPerCall` | `4096` | 一次 `parallel()` 或 `pipeline()` 调用接受的条目数。 |
|
|
45
|
+
| `syncTimeoutMs` | `5000` | 脚本最初同步片段的 VM 超时时间,单位为毫秒。 |
|
|
46
|
+
| `disposeGraceMs` | `5000` | 强制结算与终止 worker 前的期限;同时约束 `dispose()`。 |
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
- `parallel(thunks)` 在已配置的并发限制下运行 thunk;
|
|
32
|
-
- `pipeline(items, ...stages)` 在没有跨阶段屏障的情况下传递 `(previous, item, index)`;
|
|
33
|
-
- `phase(title)` 和 `log(message)` 发出观察器叙述。
|
|
48
|
+
负责该引擎的消费方可以为一次运行设置 `WorkflowStartRequest.subagentProvider` 与 `WorkflowStartRequest.maxTotalAgents`——这是引擎级策略,不是脚本钩子;普通 `workflow` 工具两者都不设置,单次运行的子 agent 总数上限可以降低、但绝不能提高已配置的上限。生成的[配置目录](../../../docs/config-catalog.zh.md#xneogdsh-workflow-worker-thread)是每个受支持字段的穷尽式真源。
|
|
34
49
|
|
|
35
|
-
|
|
50
|
+
### 运行会得到什么
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
运行启动后,脚本正文在 worker 中以顶层 `await` 执行,并可使用钩子 `agent()`、`parallel()`、`pipeline()`、`phase()` 与 `log()`;`meta` 与 `args` 以普通 JSON 数据到达,绝不作为代码求值。每次 `agent()` 调用都会在配置的提供方下启动一个宿主侧 subagent,并以运行的父级作为每个子 agent 的父级。运行以脚本的最终 JSON 值结算;普通子 agent 失败会把 `agent()` 兑现为 `null`,由脚本处理。
|
|
38
53
|
|
|
39
|
-
|
|
54
|
+
格式错误的 meta 块、无法解析的正文、不可用的提供方路由或高于上限的单次运行上限,都会在 worker 存在之前被同步拒绝,调用方因此看到违规清单并可以修正调用。执行期间,钩子误用与超出上限会用致命工作流错误终止脚本。取消是有界的:忽略取消的脚本会在 `disposeGraceMs` 后被强制以 cancelled 结算,其 worker 被终止。
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
### 信任预期
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
2. 宿主通过异步 `SubagentRuntime.start` 调用启动请求中指定的提供方,否则调用已配置的提供方;调用会传入工作流父级和该次运行共用的唯一中止信号。提供方选择应用于该次运行的每个子 agent,对脚本不可见。
|
|
45
|
-
3. 如果启动被拒绝,宿主会发送 `child-start-error`;提供方启动已经完全停稳,不会发出子 agent 生命周期事件。
|
|
46
|
-
4. 如果启动兑现时工作流仍接纳工作,宿主会记录该运行、观察 `result`,然后发送 `child-started`。即使结果已经结算,也只会随后转发,以保持先启动、后结果的顺序。
|
|
47
|
-
5. worker 发出成对的 `workflow/agent-start` 和 `workflow/agent-end` 叙述,并在收集后请求 dispose 子 agent。
|
|
58
|
+
脚本的 CPU 工作与同步自旋不会占用宿主事件循环,`worker.terminate()` 为 dispose(资源释放)提供真实的最终停止手段,worker 以清理后的环境启动——只注入平台临时路径以及(源码模式下)`TSX_TSCONFIG_PATH`——因此环境凭据不会通过 `process.env` 跨越边界。宿主/worker 消息使用结构化克隆数据,并在脚本边界执行普通 JSON 校验。
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
以上都不是安全边界:有意不注入 timer、文件系统 API 或 Node 全局变量,但逃逸代码仍可以 worker 的进程权限触达 Node。
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
-----
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
<a id="understand-the-implementation"></a>
|
|
65
|
+
## 理解实现
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
<details>
|
|
68
|
+
<summary>实现细节——点击展开</summary>
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
本节解释引擎的隔离设计与运行机制;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
58
71
|
|
|
59
|
-
|
|
72
|
+
### 设计理念
|
|
60
73
|
|
|
61
|
-
|
|
74
|
+
每次运行一个 worker thread,让行为异常的脚本无法拖垮宿主,并使强制终止成为可能:脚本在 worker 内可逃逸的 `node:vm` 上下文中运行,`agent()` 调用通过带类型的宿主/worker 协议回到 `ctx.subagents`。vm 上下文塑造脚本的 API 表面;它不是安全沙箱。
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
### 源码地图
|
|
64
77
|
|
|
65
|
-
|
|
78
|
+
| 文件 | 职责 |
|
|
79
|
+
|---|---|
|
|
80
|
+
| [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、前置校验、`start()` 接线 |
|
|
81
|
+
| [`src/host.ts`](src/host.ts) | 一次运行的宿主侧:worker 启动、子 agent 编排、结算、dispose |
|
|
82
|
+
| [`src/worker.ts`](src/worker.ts) | worker 入口:脚本执行、钩子实现、值物化 |
|
|
83
|
+
| [`src/runtime.ts`](src/runtime.ts) | 脚本运行时:钩子契约、`parallel()` 与 `pipeline()` 组合器 |
|
|
84
|
+
| [`src/realm.ts`](src/realm.ts) | 跨 realm 物化:普通 JSON 的接受与拒绝规则 |
|
|
85
|
+
| [`src/protocol.ts`](src/protocol.ts) | 带类型的宿主/worker 消息协议 |
|
|
86
|
+
| [`src/meta.ts`](src/meta.ts) | `meta` 形状校验与规范化 |
|
|
87
|
+
| [`src/session.ts`](src/session.ts) | 子 agent 运行在跨入 worker 前的投影与快照 |
|
|
88
|
+
| — | 不发布运行时不变式伴生入口;worker 测试覆盖该边界。 |
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
### 运行顺序
|
|
68
91
|
|
|
69
|
-
|
|
92
|
+
`start()` 在创建 worker 或发布 `workflow/start` 之前校验 meta 块、解析正文、解析提供方路由并解析单次运行的子 agent 总数上限。ready/go 握手可以避免启动信号取消与 worker 启动发生竞态、导致脚本最初的同步片段被执行;源代码模式通过 data URL bootstrap 安装 TypeScript 转换,构建模式则传入同级 `lib/worker.cjs` 包。
|
|
70
93
|
|
|
71
|
-
worker
|
|
94
|
+
每次 `agent()` 调用,worker 都会发送 `child-start`;宿主通过 subagent seam 启动提供方(请求的覆盖值,或配置的提供方),把子 agent 归属于运行的父级,并回报启动成功或启动错误。提供方选择应用于该运行的每个子 agent,对脚本不可见。提供方启动与已发布子 agent 分开跟踪,因此当取消、worker 死亡或正常结算关闭接纳时,待处理启动会被共享信号中止。
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
### 值边界
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
离开脚本的值会经过 realm 物化;该过程接受普通无损 JSON 数据,拒绝特殊原型、函数、symbol、循环、稀疏数组、非有限数与嵌套 `undefined`。子 agent 结果在从宿主跨入 worker 之前先投影并快照——这是真正近似进程的序列化边界,刻意区别于同进程工作流事件以不可变方式借用的值。
|
|
76
99
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
### 取消与 dispose
|
|
101
|
+
|
|
102
|
+
`cancel()` 记录第一个原因、通知 worker 取消、中止所有待处理与已发布子 agent 共享的唯一信号,并启动 `disposeGraceMs` 定时器;worker 钩子随后在下次 await 时抛出 `CANCELLED`。如果运行到期限仍未结算,宿主会将其以 cancelled 兑现、为悬空的子 agent 生命周期事件配对,并终止 worker。
|
|
103
|
+
|
|
104
|
+
`dispose()` 是幂等的:它取消运行、立即启动宿主驱动的 dispose、在同一宽限期内等待结果与子 agent 完全停稳、无条件终止 worker,并执行最后一次幸存项扫描。每个子 agent 的 dispose 都会记忆化,使 worker RPC、宿主取消、死亡清理与公开 dispose 都汇入同一操作。
|
|
105
|
+
|
|
106
|
+
### 结果与事件保证
|
|
107
|
+
|
|
108
|
+
在宿主的认领点,终态结果遵循先到者胜:已接受的外部取消会覆盖后到的非取消 worker 结果,先认领的结果或 worker 死亡不能被可重入清理回调改写。worker 错误、消息失败或提前退出会在清理前关闭消息接纳,然后以 `error` 兑现;除非取消已接管该运行。
|
|
109
|
+
|
|
110
|
+
宿主维护已转发子 agent 启动的台账;优雅退出的 worker 提供对应的结束事件,死亡或强制终止则把缺失的结束事件合成为已取消——每个已转发的 `workflow/agent-start` 都会且只会配对一次。
|
|
111
|
+
|
|
112
|
+
</details>
|
|
85
113
|
|
|
86
|
-
|
|
114
|
+
-----
|
|
87
115
|
|
|
116
|
+
<a id="further-exploration"></a>
|
|
117
|
+
## 进一步探索
|
|
118
|
+
|
|
119
|
+
当引擎级契约不够用时阅读以下页面。它们从 seam 契约逐步进入面向模型的消费方与设计决策。
|
|
120
|
+
|
|
121
|
+
- [工作流子系统](../../../docs/subsystems/workflow.zh.md)——本引擎实现的 seam 契约。
|
|
122
|
+
- [工作流 seam](../workflow/README.zh.md)——`ctx.workflowEngine` 背后的运行与结果词汇。
|
|
123
|
+
- [workflow 工具](../tool-workflow/README.zh.md)——在本引擎上运行脚本的模型侧消费方。
|
|
124
|
+
- [组地图](../README.zh.md)——工作流能力家族及其包。
|
|
125
|
+
- [动态工作流 Agent Note](../../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.zh.md)——seam 设计及其决策。
|
|
126
|
+
|
|
127
|
+
-----
|
|
128
|
+
|
|
129
|
+
<a id="model-experience"></a>
|
|
88
130
|
## 模型体验
|
|
89
131
|
|
|
90
132
|
### 子 agent 请求
|
|
91
133
|
|
|
92
|
-
####
|
|
134
|
+
#### 模型看到什么
|
|
93
135
|
|
|
94
|
-
脚本每次调用 `agent()`,都会把提示词原样发送给 subagent 提供方,并附带可选模型或结构化输出 schema。每个子 agent 看到该提供方自己的上下文;phase
|
|
136
|
+
脚本每次调用 `agent()`,都会把提示词原样发送给 subagent 提供方,并附带可选模型或结构化输出 schema。每个子 agent 看到该提供方自己的上下文;phase 与 log 叙述只留在观察器事件中。
|
|
95
137
|
|
|
96
138
|
#### Token 影响
|
|
97
139
|
|
|
98
|
-
可能需要为许多独立子 agent 上下文支付 token
|
|
140
|
+
可能需要为许多独立子 agent 上下文支付 token,数量受 `maxConcurrentAgents`、`maxTotalAgents` 与 `maxItemsPerCall` 限制;这些上下文绝不会直接加入父级历史。
|
|
99
141
|
|
|
100
142
|
#### KV Cache 影响
|
|
101
143
|
|
|
102
|
-
|
|
144
|
+
与父级请求缓存及同级子 agent 相互独立。每个子 agent 只能在其自身提供方、模型、提示词与 schema 下复用逐字节相同的前缀;其后续历史仅追加增长。
|
|
103
145
|
|
|
104
146
|
### 父级工具结果(间接)
|
|
105
147
|
|
|
106
|
-
####
|
|
148
|
+
#### 模型看到什么
|
|
107
149
|
|
|
108
|
-
通过 [`dsh-tool-workflow`](../tool-workflow/README.md),成功结果只会在该消费方的包装层中公开实体化的最终 JSON
|
|
150
|
+
通过 [`dsh-tool-workflow`](../tool-workflow/README.zh.md),成功结果只会在该消费方的包装层中公开实体化的最终 JSON 值与子 agent 数量。本引擎提供稳定错误,包括 `workflow script does not parse: <error>`、`invalid meta: <violations>`、`agent() requires a non-empty prompt string`、`agent() could not start a child: <error>` 与 `child agent run failed: <error>`,以及其精确的 `parallel()`、`pipeline()`、`phase()`、选项、schema 与 JSON 边界校验消息。中间子 agent 输出可供脚本使用,但不提供给父模型。
|
|
109
151
|
|
|
110
152
|
#### Token 影响
|
|
111
153
|
|
|
@@ -115,10 +157,27 @@ worker 错误、消息失败或提前退出会在清理前关闭消息接纳,
|
|
|
115
157
|
|
|
116
158
|
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
|
117
159
|
|
|
118
|
-
##
|
|
160
|
+
## 已知限制与延期工作
|
|
161
|
+
|
|
162
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
这些限制说明本引擎何时不合适,或何时需要特别的运维注意。它们是当前约束,不是任务积压。
|
|
166
|
+
|
|
167
|
+
- **worker 与 vm 不是安全边界**——模型编写的代码可以逃逸 `node:vm` 并取得 worker 的进程权限;不可信代码部署需要独立进程或容器引擎。
|
|
168
|
+
- **每次运行都要支付一个 worker thread**——没有池、预热运行时或跨运行脚本缓存。
|
|
169
|
+
- **不注入默认可用的定时器、文件系统或网络,但逃逸代码仍可触达 Node**——缺失的全局变量属于可移植性 API,而非隔离措施。
|
|
170
|
+
- **终止只能报告宿主观察到的启动**——`agentsStarted` 不包括因并发限制仍在 worker 侧排队、且在强制终止后无法得知的调用。
|
|
171
|
+
- **跨 realm 错误在脚本内无法通过 `instanceof Error`**——工作流作者必须根据 `name` 与 `code` 等稳定字段分支。
|
|
172
|
+
|
|
173
|
+
<a id="dev-note"></a>
|
|
174
|
+
### 开发备注
|
|
175
|
+
|
|
176
|
+
<details>
|
|
177
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
178
|
+
|
|
179
|
+
本开发备注是维护者的工作上下文:实测产物与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文、包代码与相关 Agent Note 为准。
|
|
180
|
+
|
|
181
|
+
开放方向:用池化或预热运行时与跨运行脚本缓存来避免每次运行一个 worker;在同一 seam 背后为不可信脚本提供真正的进程或容器引擎。构建产物 `./worker` 入口以 CommonJS 包形式发布,因为 pkg 的虚拟文件系统(VFS)钩子要求 CommonJS;源代码模式通过 data URL bootstrap 安装 tsx 转换。
|
|
119
182
|
|
|
120
|
-
|
|
121
|
-
- **每次运行都要支付一个 worker thread 的成本**:没有池、预热运行时或跨运行脚本缓存。
|
|
122
|
-
- **不注入默认可用的定时器、文件系统或网络,但逃逸代码仍可访问 Node**:这些缺失的全局变量属于可移植性 API 设计,而非隔离措施。
|
|
123
|
-
- **终止只能报告宿主观察到的启动**:`agentsStarted` 不包括因并发限制仍在 worker 侧排队、且在强制终止后无法得知的调用。
|
|
124
|
-
- **跨 realm 错误在脚本内无法通过 `instanceof Error`**:工作流作者必须根据 `name` 和 `code` 等稳定字段分支。
|
|
183
|
+
</details>
|
package/lib/index.js
CHANGED
|
@@ -5,8 +5,7 @@ import z from "@xneog/schemastery";
|
|
|
5
5
|
import WorkflowEngine, { WorkflowError, WorkflowRunId } from "@xneog/dsh-workflow";
|
|
6
6
|
import { Worker } from "node:worker_threads";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { assertNever } from "@xneog/dsh-
|
|
9
|
-
import { snapshotJsonValue } from "@xneog/dsh-session";
|
|
8
|
+
import { assertNever, snapshotJsonValue } from "@xneog/dsh-util-values";
|
|
10
9
|
//#region lib/types/realm.js
|
|
11
10
|
/**
|
|
12
11
|
* Materializes values leaving the script vm into plain JSON before they cross the worker
|
|
@@ -187,7 +186,11 @@ var HostToWorkerType;
|
|
|
187
186
|
* @module @xneog/dsh-workflow-worker-thread/host
|
|
188
187
|
*/
|
|
189
188
|
/**
|
|
190
|
-
* The scrubbed worker environment: no ambient credentials, no loader flags
|
|
189
|
+
* The scrubbed worker environment: no ambient credentials, no loader flags, and deliberately no
|
|
190
|
+
* proxy policy. A worker thread does not inherit the host's global dispatcher, so a workflow's own
|
|
191
|
+
* requests go direct — the alternative is handing the worker a proxy URL that may carry
|
|
192
|
+
* `user:password`, and this worker executes the model-authored script body. That is the same
|
|
193
|
+
* containment the code runtime keeps, and `docs/defensive-patterns.md` requires it.
|
|
191
194
|
* Windows derives `os.tmpdir()` from `TMP`/`TEMP` and falls back to the
|
|
192
195
|
* literal relative path `undefined\temp` when the environment is empty, so
|
|
193
196
|
* tsx's transform cache would land in a cwd-relative `undefined/temp`
|
package/lib/types/host.d.ts
CHANGED
|
@@ -12,7 +12,11 @@ import type { WorkflowMeta, WorkflowResult, WorkflowRun, WorkflowRunId } from '@
|
|
|
12
12
|
import type { ExecutionObserver } from './runtime.ts';
|
|
13
13
|
import type { WorkerInit } from './types.ts';
|
|
14
14
|
/**
|
|
15
|
-
* The scrubbed worker environment: no ambient credentials, no loader flags
|
|
15
|
+
* The scrubbed worker environment: no ambient credentials, no loader flags, and deliberately no
|
|
16
|
+
* proxy policy. A worker thread does not inherit the host's global dispatcher, so a workflow's own
|
|
17
|
+
* requests go direct — the alternative is handing the worker a proxy URL that may carry
|
|
18
|
+
* `user:password`, and this worker executes the model-authored script body. That is the same
|
|
19
|
+
* containment the code runtime keeps, and `docs/defensive-patterns.md` requires it.
|
|
16
20
|
* Windows derives `os.tmpdir()` from `TMP`/`TEMP` and falls back to the
|
|
17
21
|
* literal relative path `undefined\temp` when the environment is empty, so
|
|
18
22
|
* tsx's transform cache would land in a cwd-relative `undefined/temp`
|
package/lib/worker.cjs
CHANGED
|
@@ -21,10 +21,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
//#endregion
|
|
23
23
|
let node_worker_threads = require("node:worker_threads");
|
|
24
|
-
let
|
|
24
|
+
let _xneog_dsh_util_values = require("@xneog/dsh-util-values");
|
|
25
25
|
let node_vm = require("node:vm");
|
|
26
26
|
node_vm = __toESM(node_vm, 1);
|
|
27
|
-
let
|
|
27
|
+
let _xneog_dsh_brand = require("@xneog/dsh-brand");
|
|
28
28
|
let _xneog_dsh_tools = require("@xneog/dsh-tools");
|
|
29
29
|
let _xneog_dsh_workflow = require("@xneog/dsh-workflow");
|
|
30
30
|
//#region lib/types/protocol.js
|
|
@@ -433,7 +433,7 @@ var WorkflowExecution = class {
|
|
|
433
433
|
seq,
|
|
434
434
|
label,
|
|
435
435
|
...phase !== void 0 ? { phase } : {},
|
|
436
|
-
childId: (0,
|
|
436
|
+
childId: (0, _xneog_dsh_brand.brandString)(run.id)
|
|
437
437
|
};
|
|
438
438
|
this.observer.agentStart(info);
|
|
439
439
|
try {
|
|
@@ -763,7 +763,7 @@ async function runWorkerSession(port, init) {
|
|
|
763
763
|
children.onChildDisposed(message.callId);
|
|
764
764
|
break;
|
|
765
765
|
/* v8 ignore next 2 -- closed engine-owned union; the arm only makes adding a message type a compile error */
|
|
766
|
-
default: (0,
|
|
766
|
+
default: (0, _xneog_dsh_util_values.assertNever)(message, "host-to-worker message");
|
|
767
767
|
}
|
|
768
768
|
});
|
|
769
769
|
post(WorkerToHostType.Ready, {});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xneog/dsh-workflow-worker-thread",
|
|
3
3
|
"description": "worker-thread workflow engine: executes model-written orchestration scripts off the host event loop, bridging agent() calls back to ctx.subagents",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3-alpha.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -18,10 +18,6 @@
|
|
|
18
18
|
"types": "./lib/types/index.d.ts",
|
|
19
19
|
"default": "./lib/index.js"
|
|
20
20
|
},
|
|
21
|
-
"./invariant": {
|
|
22
|
-
"types": "./lib/types/invariant.d.ts",
|
|
23
|
-
"default": "./lib/invariant.js"
|
|
24
|
-
},
|
|
25
21
|
"./worker": {
|
|
26
22
|
"types": "./lib/types/worker.d.ts",
|
|
27
23
|
"default": "./lib/worker.cjs"
|
|
@@ -31,39 +27,39 @@
|
|
|
31
27
|
},
|
|
32
28
|
"files": [
|
|
33
29
|
"lib/index.js",
|
|
34
|
-
"lib/invariant.js",
|
|
35
30
|
"lib/worker.cjs",
|
|
36
31
|
"lib/types/**/*.d.ts"
|
|
37
32
|
],
|
|
38
33
|
"license": "MIT",
|
|
39
34
|
"peerDependencies": {
|
|
40
|
-
"@xneog/
|
|
41
|
-
"@xneog/dsh-
|
|
42
|
-
"@xneog/dsh-
|
|
43
|
-
"@xneog/dsh-
|
|
44
|
-
"@xneog/dsh-
|
|
45
|
-
"@xneog/dsh-
|
|
46
|
-
"@xneog/dsh-
|
|
47
|
-
"@xneog/dsh-workflow": "0.1.0",
|
|
48
|
-
"@xneog/cordis": "0.1.0"
|
|
35
|
+
"@xneog/cordis": "^4.0.2",
|
|
36
|
+
"@xneog/dsh-agent": "^0.1.3-alpha.1",
|
|
37
|
+
"@xneog/dsh-llm": "^0.1.3-alpha.1",
|
|
38
|
+
"@xneog/dsh-subagent": "^0.1.3-alpha.1",
|
|
39
|
+
"@xneog/dsh-workflow": "^0.1.3-alpha.1",
|
|
40
|
+
"@xneog/dsh-tools": "^0.1.3-alpha.1",
|
|
41
|
+
"@xneog/dsh-session": "^0.1.3-alpha.1"
|
|
49
42
|
},
|
|
50
43
|
"dependencies": {
|
|
51
|
-
"@xneog/
|
|
44
|
+
"@xneog/dsh-brand": "^0.1.3-alpha.1",
|
|
45
|
+
"@xneog/dsh-util-values": "^0.1.3-alpha.1",
|
|
46
|
+
"@xneog/schemastery": "^3.18.2"
|
|
52
47
|
},
|
|
53
48
|
"devDependencies": {
|
|
54
|
-
"
|
|
55
|
-
"@xneog/
|
|
56
|
-
"@xneog/dsh-agent
|
|
57
|
-
"@xneog/dsh-
|
|
58
|
-
"@xneog/dsh-
|
|
59
|
-
"@xneog/dsh-
|
|
60
|
-
"@xneog/dsh-
|
|
61
|
-
"@xneog/dsh-subagent": "0.1.
|
|
62
|
-
"@xneog/dsh-
|
|
63
|
-
"@xneog/dsh-
|
|
64
|
-
"@xneog/dsh-
|
|
65
|
-
"@xneog/dsh-
|
|
66
|
-
"@xneog/
|
|
67
|
-
"
|
|
49
|
+
"tsx": "^4.19.2",
|
|
50
|
+
"@xneog/cordis": "^4.0.2",
|
|
51
|
+
"@xneog/dsh-agent": "^0.1.3-alpha.1",
|
|
52
|
+
"@xneog/dsh-agent-loop-testkit": "^0.1.3-alpha.1",
|
|
53
|
+
"@xneog/dsh-llm": "^0.1.3-alpha.1",
|
|
54
|
+
"@xneog/dsh-session": "^0.1.3-alpha.1",
|
|
55
|
+
"@xneog/dsh-subagent": "^0.1.3-alpha.1",
|
|
56
|
+
"@xneog/dsh-subagent-spawn-in-process": "^0.1.3-alpha.1",
|
|
57
|
+
"@xneog/dsh-session-projection": "^0.1.3-alpha.1",
|
|
58
|
+
"@xneog/dsh-agent-loop": "^0.1.3-alpha.1",
|
|
59
|
+
"@xneog/dsh-invariants": "^0.1.3-alpha.1",
|
|
60
|
+
"@xneog/dsh-system-prompt": "^0.1.3-alpha.1",
|
|
61
|
+
"@xneog/dsh-tools": "^0.1.3-alpha.1",
|
|
62
|
+
"@xneog/dsh-workflow": "^0.1.3-alpha.1",
|
|
63
|
+
"@xneog/dsh-http-proxy": "^0.1.3-alpha.1"
|
|
68
64
|
}
|
|
69
65
|
}
|
package/lib/invariant.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
//#region lib/types/invariant.js
|
|
2
|
-
/**
|
|
3
|
-
* Package-owned invariant companion for `@xneog/dsh-workflow-worker-thread`.
|
|
4
|
-
* @module @xneog/dsh-workflow-worker-thread/invariant
|
|
5
|
-
*/
|
|
6
|
-
const PACKAGE_NAME = "@xneog/dsh-workflow-worker-thread";
|
|
7
|
-
/** Cordis companion plugin name. */
|
|
8
|
-
const name = "workflow-worker-thread-invariant";
|
|
9
|
-
/** Service required before the companion can reserve package ownership. */
|
|
10
|
-
const inject = ["invariants"];
|
|
11
|
-
/**
|
|
12
|
-
* No runtime invariant: this process-boundary implementation exposes no same-process event relation;
|
|
13
|
-
* worker protocol and built-worker tests cover it.
|
|
14
|
-
*/
|
|
15
|
-
const install = () => {};
|
|
16
|
-
/**
|
|
17
|
-
* Register this package's invariant companion.
|
|
18
|
-
* @param ctx - Cordis context carrying the invariant service.
|
|
19
|
-
* @returns the installed registration's disposer after setup succeeds.
|
|
20
|
-
*/
|
|
21
|
-
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
22
|
-
//#endregion
|
|
23
|
-
export { apply, inject, name };
|
package/lib/types/invariant.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package-owned invariant companion for `@xneog/dsh-workflow-worker-thread`.
|
|
3
|
-
* @module @xneog/dsh-workflow-worker-thread/invariant
|
|
4
|
-
*/
|
|
5
|
-
import type { Context } from '@xneog/cordis';
|
|
6
|
-
/** Cordis companion plugin name. */
|
|
7
|
-
export declare const name = "workflow-worker-thread-invariant";
|
|
8
|
-
/** Service required before the companion can reserve package ownership. */
|
|
9
|
-
export declare const inject: string[];
|
|
10
|
-
/**
|
|
11
|
-
* Register this package's invariant companion.
|
|
12
|
-
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
-
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
-
*/
|
|
15
|
-
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
-
//# sourceMappingURL=invariant.d.ts.map
|