@deepseek-ai/dsh-workflow-worker-thread 0.0.1-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@deepseek-ai/dsh-workflow-worker-thread`.
4
+ * @module @deepseek-ai/dsh-workflow-worker-thread/invariant
5
+ */
6
+ const PACKAGE_NAME = "@deepseek-ai/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 };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Host side of one workflow run. The first worker result, unexpected death, or
3
+ * cancellation-grace expiry owns settlement and closes message admission.
4
+ * Pending starts share one abort signal; published children share idempotent
5
+ * cleanup, and quiescence waits for both while synthesizing any missing end events.
6
+ * @module @deepseek-ai/dsh-workflow-worker-thread/host
7
+ */
8
+ import type { Context } from '@deepseek-ai/cordis';
9
+ import type { Agent } from '@deepseek-ai/dsh-agent';
10
+ import type SubagentRuntime from '@deepseek-ai/dsh-subagent';
11
+ import type { WorkflowMeta, WorkflowResult, WorkflowRun, WorkflowRunId } from '@deepseek-ai/dsh-workflow';
12
+ import type { ExecutionObserver } from './runtime.ts';
13
+ import type { WorkerInit } from './types.ts';
14
+ /**
15
+ * One live worker-engine run — the seam's {@link WorkflowRun}, returned by
16
+ * `start()` directly. Owns the Worker, the child registry, and the result
17
+ * settlement; `result` never rejects. `meta` is trusted same-process data
18
+ * borrowed as immutable by the handle and lifecycle events. The holder-bound
19
+ * SubagentRuntime handle is captured before the
20
+ * engine returns this run, so unloading the engine removes only the ability to
21
+ * start another workflow; this run can still start and clean up its children.
22
+ */
23
+ export declare class WorkerRun implements WorkflowRun {
24
+ private readonly ctx;
25
+ private readonly subagents;
26
+ readonly id: WorkflowRunId;
27
+ readonly meta: WorkflowMeta;
28
+ private readonly parent;
29
+ private readonly provider;
30
+ private readonly disposeGraceMs;
31
+ private readonly observer;
32
+ /** Settles exactly once with the run's outcome; never rejects. */
33
+ readonly result: Promise<WorkflowResult>;
34
+ private settleResolve;
35
+ private settled;
36
+ /** A Result/death/grace outcome atomically won before teardown callbacks. */
37
+ private terminalClaimed;
38
+ /** The first death signal closes worker-message admission and owns failure-time cleanup. */
39
+ private workerDeathObserved;
40
+ private cancelReason;
41
+ private graceTimer;
42
+ private readonly worker;
43
+ /** Set on `exit`: the thread is gone, so posting has nowhere to go. */
44
+ private workerGone;
45
+ /** Accepted `child-start` messages — the terminate-path `agentsStarted` (see module doc). */
46
+ private hostStarted;
47
+ /** Published children by callId; an entry leaves only after disposal settles. */
48
+ private readonly children;
49
+ /** Provider starts that have not yet fulfilled or rejected. */
50
+ private readonly pendingStarts;
51
+ /** Started-but-not-ended agents by seq — the pairing ledger the HOST guarantees (see {@link endAgent}). */
52
+ private readonly liveAgents;
53
+ private readonly quiescenceWaiters;
54
+ /** The per-run abort fanout every child start request carries. */
55
+ private readonly controller;
56
+ /** External start signal and the exact callback installed on it, retained only until first settle/teardown. */
57
+ private inputSignal;
58
+ private inputSignalAbort;
59
+ private disposed;
60
+ constructor(ctx: Context, subagents: SubagentRuntime, id: WorkflowRunId, meta: WorkflowMeta, parent: Agent, init: WorkerInit, provider: string, disposeGraceMs: number, observer: ExecutionObserver, signal: AbortSignal | undefined);
61
+ /**
62
+ * Cancel the run: the worker is told (its hooks start throwing and the
63
+ * script dies at its next await), the required signal shared by every child
64
+ * start is aborted, and the grace timer
65
+ * arms: a run still unsettled `disposeGraceMs` later force-settles
66
+ * `cancelled` and its worker is TERMINATED. Idempotent; the first reason
67
+ * wins.
68
+ * @param reason - human-readable cause (default `'workflow cancelled'`).
69
+ */
70
+ cancel(reason?: string): void;
71
+ /**
72
+ * Cancel + bounded settle + termination. Host-drives every registered
73
+ * child's disposal IMMEDIATELY — a wedged worker can relay no dispose RPC,
74
+ * and deferring child teardown to the post-terminate reap would spend the
75
+ * whole grace waiting for a quiescence that cannot start, then return with
76
+ * the disposals still in flight — so child disposal overlaps the same
77
+ * grace the worker gets to settle (the worker's own dispose RPCs join the
78
+ * shared per-child disposal). Waits (at most the grace) for the result and
79
+ * child quiescence, then terminates the worker unconditionally — the
80
+ * thread never outlives its run — and reaps whatever children remain
81
+ * (their disposal is contained, not awaited past the grace, the same
82
+ * abandonment the seam documents for a slow-disposing child). Idempotent;
83
+ * safe on every path.
84
+ * @returns resolves when the run's resources are released or abandoned.
85
+ */
86
+ dispose(): Promise<void>;
87
+ /** Post one message to the worker (payload looked up from the tag's map entry), tolerating a thread that is already gone. */
88
+ private post;
89
+ private onMessage;
90
+ /** Why a ready provider result may no longer be admitted to the worker. */
91
+ private childAdmissionFailure;
92
+ private onChildStart;
93
+ /** Await one provider-owned startup transaction and publish only while admitted. */
94
+ private startChild;
95
+ private onChildDispose;
96
+ /**
97
+ * Start (or join) one registered child's disposal; the registry entry
98
+ * leaves when it settles. Memoized per callId: the worker's dispose RPC,
99
+ * the dispose() host drive, and the reap can all land on the same child —
100
+ * the child's `dispose()` runs once and every caller awaits that one
101
+ * settlement. A rejection is contained (the subagent seam's dispose() is
102
+ * not supposed to reject, but a backend that does anyway must not break
103
+ * quiescence): logged, and the child still leaves the registry.
104
+ * @param callId - the child's registry key.
105
+ * @param record - the registered child (the caller looked it up).
106
+ * @returns resolves when the disposal settled either way; never rejects.
107
+ */
108
+ private disposeChild;
109
+ /** Drop a child record and release quiescence waiters when all work ends. */
110
+ private finishChild;
111
+ /** Retire one provider startup transaction. */
112
+ private finishPendingStart;
113
+ /** Release waiters only after both pending starts and published children end. */
114
+ private notifyChildQuiescence;
115
+ /** Resolves once every pending start and published child has reached quiescence. */
116
+ private childQuiescence;
117
+ /** Abort + dispose every registered child (worker death / final teardown); disposal is contained, not awaited. */
118
+ private reapChildren;
119
+ /** Abort the one canonical signal shared by pending and published children. */
120
+ private abortChildren;
121
+ private onResult;
122
+ /** Process an error/messageerror/exit signal; `exit` also performs the final disposal sweep. */
123
+ private onWorkerDeath;
124
+ /**
125
+ * The single agent-end emission gate: forwards `end` iff its start is still
126
+ * unpaired in the ledger, so every forwarded `workflow/agent-start` gets
127
+ * EXACTLY one `workflow/agent-end` — the worker's own report where it can
128
+ * speak, a host-synthesized one where it cannot ({@link endStrandedAgents}).
129
+ * @param end - the settlement to emit (worker-reported or synthesized).
130
+ */
131
+ private endAgent;
132
+ /**
133
+ * Synthesize the missing `agent-end` for every started-but-unpaired agent,
134
+ * outcome `'cancelled'`: the reap cancels every child, and a real
135
+ * settlement racing the force-settle loses to that already-started external
136
+ * cancellation. The atomic terminal boundaries in {@link onResult} and
137
+ * {@link onWorkerDeath} deliberately exclude teardown callbacks as contenders.
138
+ * Called where the worker can no longer speak (the grace force-settle,
139
+ * worker death, physical exit). When grace/death is the terminal source it
140
+ * runs before settleResult, so already-known pairs precede `workflow/end`;
141
+ * after an earlier Result, exit cleanup may close a survivor afterward.
142
+ * The ledger preserves exactly-once pairing in both orders.
143
+ */
144
+ private endStrandedAgents;
145
+ private cancelledResult;
146
+ /** Remove the exact abort callback installed on the caller's start signal. */
147
+ private detachInputSignal;
148
+ /** First settle wins; disarms the grace timer and releases the caller signal. */
149
+ private settleResult;
150
+ }
151
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Worker-thread workflow engine. Each run executes its model-written script in
3
+ * an escapable vm context on a fresh worker and bridges `agent()` calls to host
4
+ * subagents. The thread prevents synchronous script work from blocking the host
5
+ * and permits forced termination, but it is containment rather than a security boundary.
6
+ * @module @deepseek-ai/dsh-workflow-worker-thread
7
+ */
8
+ import type { Context } from '@deepseek-ai/cordis';
9
+ import z from '@deepseek-ai/schemastery';
10
+ import WorkflowEngine from '@deepseek-ai/dsh-workflow';
11
+ import type { WorkflowRun, WorkflowStartRequest } from '@deepseek-ai/dsh-workflow';
12
+ export { validateMeta } from './meta.ts';
13
+ export { materializeFromRealm, MaterializeError } from './realm.ts';
14
+ export type { ChildHandle, ChildPort, ChildResult, ChildStartRequest, WorkerInit, WorkerLimits, } from './types.ts';
15
+ /** Plugin config (all optional — `static Config` supplies the defaults). */
16
+ export interface Config {
17
+ /** The `ctx.subagents` provider children run on (default `spawn`). */
18
+ provider?: string;
19
+ /** Concurrent `agent()` ceiling; `0` (the default) auto-resolves to `min(16, max(1, cores - 2))`. */
20
+ maxConcurrentAgents?: number;
21
+ /** Total `agent()` calls one run may start — the runaway-loop backstop (default 1000). */
22
+ maxTotalAgents?: number;
23
+ /** Items accepted by a single `parallel()`/`pipeline()` call (default 4096). */
24
+ maxItemsPerCall?: number;
25
+ /** vm timeout for the script's initial synchronous slice, inside the worker (default 5000 ms). */
26
+ syncTimeoutMs?: number;
27
+ /**
28
+ * How long after a cancellation an unsettled script may keep running before
29
+ * the run force-settles `cancelled` and its worker is TERMINATED (default
30
+ * 5000 ms); also bounds `dispose()`.
31
+ */
32
+ disposeGraceMs?: number;
33
+ }
34
+ /**
35
+ * The worker-thread engine service. `start()` validates the script up front
36
+ * (meta + a host-side body parse) and returns a {@link WorkflowRun} whose
37
+ * `result` never rejects; the `workflow/*` events fire around the run per
38
+ * the seam contract.
39
+ */
40
+ declare class WorkerThreadWorkflowEngine extends WorkflowEngine {
41
+ static inject: string[];
42
+ static Config: z<Config>;
43
+ private readonly config;
44
+ constructor(ctx: Context, config: Config);
45
+ /**
46
+ * Validate and execute a workflow script in a fresh worker thread. Throws
47
+ * {@link WorkflowError} synchronously (`META_INVALID` for a malformed meta
48
+ * block, `SCRIPT_PARSE` for a body that does not compile) for a request
49
+ * that cannot begin; once a run is returned, every failure resolves through
50
+ * `result.stopReason` instead.
51
+ * @param request - the script body, its meta data and `args`, the parent
52
+ * agent, and an optional cancel signal.
53
+ * @returns the live run (its `result` resolves when the script settles).
54
+ */
55
+ start(request: WorkflowStartRequest): WorkflowRun;
56
+ }
57
+ export default WorkerThreadWorkflowEngine;
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@deepseek-ai/dsh-workflow-worker-thread`.
3
+ * @module @deepseek-ai/dsh-workflow-worker-thread/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/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
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Meta validation checks caller-provided DATA against the {@link WorkflowMeta}
3
+ * contract and rejects every violation by name. Meta arrives as schema-checked
4
+ * JSON data, never evaluated script text; evaluating it on the host could run getters outside the
5
+ * worker timeout that exists to isolate model-written code.
6
+ * @module @deepseek-ai/dsh-workflow-worker-thread/meta
7
+ */
8
+ import type { WorkflowMeta } from '@deepseek-ai/dsh-workflow';
9
+ /**
10
+ * Validate a caller-provided meta value against the {@link WorkflowMeta}
11
+ * contract. Throws `META_INVALID` naming every violation (unknown fields,
12
+ * missing/mistyped `name`/`description`, malformed `phases`); the returned
13
+ * meta is a NORMALIZED copy built from the validated fields, so the engine
14
+ * never aliases the caller's object.
15
+ * @param value - the meta data from the start request (plain JSON by the seam contract).
16
+ * @returns the validated, normalized meta block.
17
+ */
18
+ export declare function validateMeta(value: unknown): WorkflowMeta;
19
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1,132 @@
1
+ /**
2
+ * The host⇄worker wire protocol: one string-valued enum of message tags per direction, a
3
+ * payload map giving each tag its parameters (the single source of truth), and the message
4
+ * unions derived from them. Payloads are plain JSON by construction for structured clone. Both
5
+ * directions are closed engine protocols whose receivers use `assertNever`; generic typed senders
6
+ * make tag/payload mismatches compile-time errors rather than silently skipped messages.
7
+ * @module @deepseek-ai/dsh-workflow-worker-thread/protocol
8
+ */
9
+ import type { WorkflowAgentEndInfo, WorkflowAgentInfo, WorkflowResult } from '@deepseek-ai/dsh-workflow';
10
+ import type { ChildResult, ChildStartRequest } from './types.ts';
11
+ /** Message tags the worker sends the host (the wire values are the tag strings). */
12
+ export declare enum WorkerToHostType {
13
+ /** The startup handshake: the session is listening and awaits {@link HostToWorkerType.Go}. */
14
+ Ready = "ready",
15
+ /** Observer narration: a `phase(title)` call. */
16
+ Phase = "phase",
17
+ /** Observer narration: a `log(message)` call. */
18
+ Log = "log",
19
+ /** Observer lifecycle: one `agent()` call started a child. */
20
+ AgentStart = "agent-start",
21
+ /** Observer lifecycle: one `agent()` call settled. */
22
+ AgentEnd = "agent-end",
23
+ /** Child RPC: start a child on the host (answered by ChildStarted or ChildStartError). */
24
+ ChildStart = "child-start",
25
+ /** Child RPC: dispose a started child (answered by ChildDisposed). */
26
+ ChildDispose = "child-dispose",
27
+ /** The run's single terminal result. */
28
+ Result = "result"
29
+ }
30
+ /** The payload each worker→host tag carries. */
31
+ export interface WorkerToHostPayloads {
32
+ /** Ready carries nothing. */
33
+ [WorkerToHostType.Ready]: Record<never, never>;
34
+ /** The phase title, verbatim. */
35
+ [WorkerToHostType.Phase]: {
36
+ title: string;
37
+ };
38
+ /** The logged message, verbatim. */
39
+ [WorkerToHostType.Log]: {
40
+ message: string;
41
+ };
42
+ /** The call's sequence number, label, phase, and child id. */
43
+ [WorkerToHostType.AgentStart]: {
44
+ info: WorkflowAgentInfo;
45
+ };
46
+ /** The call identity plus its outcome. */
47
+ [WorkerToHostType.AgentEnd]: {
48
+ info: WorkflowAgentEndInfo;
49
+ };
50
+ /** The RPC correlation id and the prompt plus validated options. */
51
+ [WorkerToHostType.ChildStart]: {
52
+ callId: number;
53
+ request: ChildStartRequest;
54
+ };
55
+ /** The RPC correlation id of the child to dispose. */
56
+ [WorkerToHostType.ChildDispose]: {
57
+ callId: number;
58
+ };
59
+ /** The run's terminal outcome. */
60
+ [WorkerToHostType.Result]: {
61
+ result: WorkflowResult;
62
+ };
63
+ }
64
+ /** Message tags the host sends the worker (the wire values are the tag strings). */
65
+ export declare enum HostToWorkerType {
66
+ /** Releases the startup gate: run the script body. */
67
+ Go = "go",
68
+ /** Cancel the run: hooks start throwing and the script dies at its next await. */
69
+ Cancel = "cancel",
70
+ /** Child RPC reply: the provider fulfilled with a published run (exactly one start reply per ChildStart). */
71
+ ChildStarted = "child-started",
72
+ /** Child RPC reply: the provider's asynchronous start failed. */
73
+ ChildStartError = "child-start-error",
74
+ /** Child RPC: a started child's result RESOLVED (its JSON projection). */
75
+ ChildSettled = "child-settled",
76
+ /** Child RPC: a started child's result REJECTED (an infrastructure fault, rendered). */
77
+ ChildFailed = "child-failed",
78
+ /** Child RPC reply: a requested disposal completed. */
79
+ ChildDisposed = "child-disposed"
80
+ }
81
+ /** The payload each host→worker tag carries. */
82
+ export interface HostToWorkerPayloads {
83
+ /** Go carries nothing. */
84
+ [HostToWorkerType.Go]: Record<never, never>;
85
+ /** The cancel reason, canonical for the whole run. */
86
+ [HostToWorkerType.Cancel]: {
87
+ reason: string;
88
+ };
89
+ /** The RPC correlation id and the child agent's id (minted by the subagent seam). */
90
+ [HostToWorkerType.ChildStarted]: {
91
+ callId: number;
92
+ childId: string;
93
+ };
94
+ /** The RPC correlation id and the rendered start failure. */
95
+ [HostToWorkerType.ChildStartError]: {
96
+ callId: number;
97
+ rendered: string;
98
+ };
99
+ /** The RPC correlation id and the child's terminal result projection. */
100
+ [HostToWorkerType.ChildSettled]: {
101
+ callId: number;
102
+ result: ChildResult;
103
+ };
104
+ /** The RPC correlation id and the rendered infrastructure fault. */
105
+ [HostToWorkerType.ChildFailed]: {
106
+ callId: number;
107
+ rendered: string;
108
+ };
109
+ /** The RPC correlation id of the completed disposal. */
110
+ [HostToWorkerType.ChildDisposed]: {
111
+ callId: number;
112
+ };
113
+ }
114
+ /**
115
+ * One worker→host message of tag `T`; unparameterized, the closed union over
116
+ * every tag (a discriminated union — `switch` on `type` narrows).
117
+ */
118
+ export type WorkerToHostMessage<T extends WorkerToHostType = WorkerToHostType> = {
119
+ [K in T]: {
120
+ type: K;
121
+ } & WorkerToHostPayloads[K];
122
+ }[T];
123
+ /**
124
+ * One host→worker message of tag `T`; unparameterized, the closed union over
125
+ * every tag (a discriminated union — `switch` on `type` narrows).
126
+ */
127
+ export type HostToWorkerMessage<T extends HostToWorkerType = HostToWorkerType> = {
128
+ [K in T]: {
129
+ type: K;
130
+ } & HostToWorkerPayloads[K];
131
+ }[T];
132
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Materializes values leaving the script vm into plain JSON before they cross the worker
3
+ * boundary, and renders thrown script values without rejecting the run. The walk rejects
4
+ * values that JSON cannot preserve but trusts model-written workflow scripts: getters and proxy traps may
5
+ * run, and the vm is not a security boundary. The worker provides host-loop isolation and
6
+ * forced termination, not hostile-value containment. See
7
+ * .agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md for the isolation rationale.
8
+ * @module @deepseek-ai/dsh-workflow-worker-thread/realm
9
+ */
10
+ /** Thrown by {@link materializeFromRealm}; the caller wraps it into the right `WorkflowError` code. */
11
+ export declare class MaterializeError extends Error {
12
+ readonly path: string;
13
+ readonly reason: string;
14
+ constructor(path: string, reason: string);
15
+ }
16
+ /**
17
+ * Render a thrown value to failure text without ever throwing: prefer the
18
+ * `stack` (host or realm — a realm error's `stack` is a plain string read),
19
+ * fall back to `message`, then `String()`. Reading those properties MAY run
20
+ * script code (a getter, `toString`) — accepted under the module's trust
21
+ * premise; if that code itself throws, a fixed label is returned instead.
22
+ * @param error - any value thrown in the host or worker realm.
23
+ * @returns human-readable text for the failure report; prefers the stack.
24
+ */
25
+ export declare function renderThrown(error: unknown): string;
26
+ /**
27
+ * Copy `value` (typically from the vm realm) into plain host JSON data. Root `undefined` is
28
+ * returned unchanged; nested `undefined` and values JSON cannot represent losslessly fail
29
+ * with the offending path. Property accessors run normally, and a throwing read is wrapped
30
+ * with its rendered failure.
31
+ *
32
+ * @param value - the realm value to materialize.
33
+ * @param root - the path label for the root value (error messages).
34
+ * @returns the host-realm copy (plain objects/arrays/scalars only).
35
+ * @throws {@link MaterializeError} for unsupported values, cycles, sparse arrays, exotic
36
+ * prototypes, or property reads that throw.
37
+ */
38
+ export declare function materializeFromRealm(value: unknown, root?: string): unknown;
39
+ //# sourceMappingURL=realm.d.ts.map
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Per-run worker-side vm hooks, child RPC, concurrency/caps, cancellation, and result serialization; it
3
+ * never touches Cordis. Script values leaving the realm are materialized as plain JSON before
4
+ * messaging. Values entering the trusted model-written realm are passed directly; `args` alone is
5
+ * cloned so script mutation cannot alter initialization data. See `./realm.ts` for the trust model.
6
+ *
7
+ * Fatal workflow errors—bad hook arguments, unsupported schemas/options, caps, start failures, and
8
+ * cancellation—propagate through combinators. Only child failures and ordinary stage errors become
9
+ * per-item nulls. Every returned promise has a rejection consumer so dropped script promises cannot
10
+ * kill the worker. A cancelled script that never settles emits nothing; the host force-settles the
11
+ * run within grace and terminates the thread.
12
+ * @module @deepseek-ai/dsh-workflow-worker-thread/runtime
13
+ */
14
+ import type { WorkflowAgentEndInfo, WorkflowAgentInfo, WorkflowMeta, WorkflowResult } from '@deepseek-ai/dsh-workflow';
15
+ import type { ChildPort, WorkerLimits } from './types.ts';
16
+ /** The observers the execution reports progress through (the session posts them to the host). */
17
+ export interface ExecutionObserver {
18
+ phase(title: string): void;
19
+ log(message: string): void;
20
+ agentStart(info: WorkflowAgentInfo): void;
21
+ agentEnd(info: WorkflowAgentEndInfo): void;
22
+ }
23
+ /**
24
+ * One live script execution inside the worker. Constructed per run by the
25
+ * session; `drive()` is called exactly once and NEVER rejects — every failure
26
+ * becomes a {@link WorkflowResult} with a non-`completed` stop reason. The
27
+ * host owns cancellation and cleanup of any dropped child work.
28
+ */
29
+ export declare class WorkflowExecution {
30
+ private readonly limits;
31
+ private readonly observer;
32
+ private readonly children;
33
+ /** 1-based count of `agent()` calls started (the `agentsStarted` result field). */
34
+ private started;
35
+ private activeSlots;
36
+ private readonly slotWaiters;
37
+ private cancelReason;
38
+ private cancelError;
39
+ private currentPhase;
40
+ private readonly context;
41
+ private readonly compiled;
42
+ constructor(meta: WorkflowMeta, body: string, args: unknown, limits: WorkerLimits, observer: ExecutionObserver, children: ChildPort);
43
+ /**
44
+ * Whether the run has been cancelled. A METHOD, not an inline property
45
+ * read: `cancel()` mutates `cancelReason` concurrently (the session's
46
+ * message handler), and an inline read after an `await` gets narrowed by
47
+ * control flow into an always-false comparison.
48
+ */
49
+ private isCancelled;
50
+ /**
51
+ * Shared hook entry guard: after {@link cancel}, EVERY hook throws
52
+ * `CANCELLED` at its next call — cancellation is the next HOOK boundary,
53
+ * not just the next `agent()`, so a script that caught one cancelled
54
+ * rejection cannot keep emitting progress through `phase`/`log` or enter a
55
+ * combinator.
56
+ */
57
+ private throwIfCancelled;
58
+ /**
59
+ * Cancel the run: waiting `agent()` slots reject and every future hook call
60
+ * throws `CANCELLED` — the script dies at its next await. A script that
61
+ * never settles anyway (parked on a promise no hook owns) is the HOST's
62
+ * problem: its grace timer force-settles the run and terminates the
63
+ * worker. Idempotent; the first reason wins.
64
+ * @param reason - human-readable cause carried on the CANCELLED error. The
65
+ * host independently aborts the required signal shared by every child.
66
+ */
67
+ cancel(reason: string): void;
68
+ /**
69
+ * Run the script to settlement. Resolves — never rejects — with the run's
70
+ * {@link WorkflowResult}: the materialized return value on `completed`, the
71
+ * failure message on `error`, and `cancelled` when the script died of
72
+ * cancellation. This method only chooses the result; the session publishes
73
+ * it and the host owns terminal child cancellation.
74
+ * @returns the settled outcome — this promise NEVER rejects (the seam's
75
+ * `result`-never-rejects contract); every failure maps to a variant.
76
+ */
77
+ drive(): Promise<WorkflowResult>;
78
+ /**
79
+ * Attach a no-op rejection consumer WITHOUT changing what the caller
80
+ * receives: if the script drops the promise (no await), cancellation cannot
81
+ * become an unhandled rejection (which would kill the worker thread); if
82
+ * the script does await it, it still observes the rejection.
83
+ */
84
+ private contain;
85
+ private cancelledError;
86
+ /** Materialize the script's return value; violations become RESULT_UNSERIALIZABLE. */
87
+ private materializeResult;
88
+ /**
89
+ * Acquire one concurrency slot (FIFO). Cancellation rejects QUEUED waiters
90
+ * (see {@link cancel}); the callers guard their own entry and post-acquire
91
+ * windows, so no cancelled-precheck is duplicated here.
92
+ */
93
+ private acquireSlot;
94
+ private releaseSlot;
95
+ /** The `agent(prompt, opts)` hook. */
96
+ private agent;
97
+ /** Materialize + validate the `agent()` options bag from the realm. */
98
+ private readAgentOptions;
99
+ /** The `parallel(thunks)` hook: each thunk caught → `null`; fatal errors propagate. */
100
+ private parallel;
101
+ /** The `pipeline(items, ...stages)` hook: per-item stage chains, NO cross-stage barrier. */
102
+ private pipeline;
103
+ private assertItemCap;
104
+ /** The `phase(title)` hook: sets the current label for subsequent `agent()` calls and notifies observers. */
105
+ private phase;
106
+ /** The `log(message)` hook: narration to observers. */
107
+ private log;
108
+ }
109
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The worker-side half of the engine: {@link runWorkerSession} wires one MessagePort to one
3
+ * {@link WorkflowExecution} — hook progress and child starts go out as messages, run control
4
+ * and child lifecycle come back in — and posts the run's terminal result exactly once. Keeping it
5
+ * separate from `worker.ts` lets unit tests drive the session over a MessageChannel, because main
6
+ * process coverage cannot observe code inside a real Worker.
7
+ *
8
+ * The session announces ready and waits for `go`, so cancellation racing startup can prevent even
9
+ * the script's synchronous prefix. A cancel in place of `go` releases the gate into a cancelled
10
+ * drive without executing the body.
11
+ * @module @deepseek-ai/dsh-workflow-worker-thread/session
12
+ */
13
+ import type { MessagePort } from 'node:worker_threads';
14
+ import type { WorkerInit } from './types.ts';
15
+ /**
16
+ * Narrow the nullable `parentPort` the bootstrap reads from
17
+ * `node:worker_threads`.
18
+ * @param port - `parentPort` as imported (null on the main thread).
19
+ * @returns the port, non-null.
20
+ */
21
+ export declare function requireParentPort(port: MessagePort | null): MessagePort;
22
+ /**
23
+ * Run one workflow script to settlement against `port`, posting the terminal result message
24
+ * exactly once; resolves after that post (stray children may still be winding down through the
25
+ * port — the host owns their teardown and ultimately terminates the thread). It never rejects:
26
+ * constructor failure becomes an error result. Host pre-parse makes syntax failure here a likely
27
+ * Node-version skew, but the session still reports it instead of dying silently.
28
+ * @param port - the channel to the host (the real `parentPort`, or one side
29
+ * of an in-process `MessageChannel` in tests).
30
+ * @param init - the run payload the host provided as `workerData`.
31
+ */
32
+ export declare function runWorkerSession(port: MessagePort, init: WorkerInit): Promise<void>;
33
+ //# sourceMappingURL=session.d.ts.map