taskflow-core 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/agents.d.ts +2 -2
- package/dist/agents.d.ts.map +1 -1
- package/dist/build-info.json +2 -2
- package/dist/compile.d.ts +8 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +75 -9
- package/dist/compile.js.map +1 -1
- package/dist/detached-control.d.ts +52 -0
- package/dist/detached-control.d.ts.map +1 -0
- package/dist/detached-control.js +251 -0
- package/dist/detached-control.js.map +1 -0
- package/dist/detached-runner.js +183 -30
- package/dist/detached-runner.js.map +1 -1
- package/dist/exec/driver.d.ts +5 -0
- package/dist/exec/driver.d.ts.map +1 -1
- package/dist/exec/driver.js +98 -52
- package/dist/exec/driver.js.map +1 -1
- package/dist/exec/kernel-policy.d.ts.map +1 -1
- package/dist/exec/kernel-policy.js +20 -20
- package/dist/exec/kernel-policy.js.map +1 -1
- package/dist/exec/step-kinds.d.ts.map +1 -1
- package/dist/exec/step-kinds.js +59 -22
- package/dist/exec/step-kinds.js.map +1 -1
- package/dist/exec/step.d.ts.map +1 -1
- package/dist/exec/step.js +44 -10
- package/dist/exec/step.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/runner-core.d.ts.map +1 -1
- package/dist/runner-core.js +10 -0
- package/dist/runner-core.js.map +1 -1
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +81 -38
- package/dist/runtime.js.map +1 -1
- package/dist/store.d.ts +41 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +489 -180
- package/dist/store.js.map +1 -1
- package/dist/verifiers/discover.d.ts +44 -0
- package/dist/verifiers/discover.d.ts.map +1 -0
- package/dist/verifiers/discover.js +152 -0
- package/dist/verifiers/discover.js.map +1 -0
- package/dist/verifiers/index.d.ts +12 -0
- package/dist/verifiers/index.d.ts.map +1 -0
- package/dist/verifiers/index.js +12 -0
- package/dist/verifiers/index.js.map +1 -0
- package/dist/verifiers/script-lint.d.ts +24 -0
- package/dist/verifiers/script-lint.d.ts.map +1 -0
- package/dist/verifiers/script-lint.js +311 -0
- package/dist/verifiers/script-lint.js.map +1 -0
- package/dist/verify.d.ts +55 -3
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +201 -2
- package/dist/verify.js.map +1 -1
- package/package.json +1 -1
package/dist/detached-runner.js
CHANGED
|
@@ -16,17 +16,85 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
16
16
|
}
|
|
17
17
|
return path;
|
|
18
18
|
};
|
|
19
|
-
import { readFileSync, rmdirSync, unlinkSync } from "node:fs";
|
|
20
|
-
import {
|
|
19
|
+
import { existsSync, lstatSync, readFileSync, realpathSync, rmdirSync, unlinkSync } from "node:fs";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { basename, dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
21
22
|
import { discoverAgents, readSubagentSettings } from "./agents.js";
|
|
22
23
|
import { executeTaskflow } from "./runtime.js";
|
|
23
24
|
import { cwdBridgeModeFromEnv } from "./cwd-bridge.js";
|
|
24
|
-
import { getFlow, loadRun, saveRun, DEFAULT_KEPT_RUNS, DEFAULT_RUN_AGE_DAYS } from "./store.js";
|
|
25
|
+
import { bumpReuseInSidecar, getFlow, loadRun, runsDir, saveRun, traceFilePath, DEFAULT_KEPT_RUNS, DEFAULT_RUN_AGE_DAYS, } from "./store.js";
|
|
26
|
+
import { clearDetachedCancelRequest, clearDetachedProcessRegistry, DETACHED_CONTROL_CWD_ENV, DETACHED_CONTROL_INSTANCE_ENV, DETACHED_CONTROL_OWNER_PID_ENV, DETACHED_CONTROL_RUN_ID_ENV, DETACHED_CONTROL_SIGNAL_READY_ENV, heartbeatDetachedProcessRegistry, terminateDetachedProcessTrees, watchDetachedCancel, } from "./detached-control.js";
|
|
27
|
+
import { FileTraceSink } from "./trace.js";
|
|
28
|
+
const START_GATE_TIMEOUT_MS = 5_000;
|
|
29
|
+
/**
|
|
30
|
+
* The spawn-only entry consumes and deletes its context file. Refuse arbitrary
|
|
31
|
+
* command-line paths so a direct or malformed invocation cannot turn that
|
|
32
|
+
* one-shot cleanup into an unlink primitive outside Taskflow's private temp
|
|
33
|
+
* directory.
|
|
34
|
+
*/
|
|
35
|
+
function isPrivateDetachContextPath(candidate) {
|
|
36
|
+
if (!isAbsolute(candidate) || basename(candidate) !== "context.json")
|
|
37
|
+
return false;
|
|
38
|
+
const parent = dirname(candidate);
|
|
39
|
+
if (!basename(parent).startsWith("taskflow-detach-"))
|
|
40
|
+
return false;
|
|
41
|
+
try {
|
|
42
|
+
const tempRoot = realpathSync(tmpdir());
|
|
43
|
+
const realParent = realpathSync(parent);
|
|
44
|
+
const rel = relative(tempRoot, realParent);
|
|
45
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const parentStat = lstatSync(parent);
|
|
49
|
+
const fileStat = lstatSync(candidate);
|
|
50
|
+
if (!parentStat.isDirectory() || parentStat.isSymbolicLink())
|
|
51
|
+
return false;
|
|
52
|
+
if (!fileStat.isFile() || fileStat.isSymbolicLink())
|
|
53
|
+
return false;
|
|
54
|
+
if (typeof process.getuid === "function") {
|
|
55
|
+
const uid = process.getuid();
|
|
56
|
+
if (parentStat.uid !== uid || fileStat.uid !== uid)
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function waitForStartGate(contextDir) {
|
|
66
|
+
const startPath = join(contextDir, "start");
|
|
67
|
+
const deadline = Date.now() + START_GATE_TIMEOUT_MS;
|
|
68
|
+
while (Date.now() < deadline) {
|
|
69
|
+
if (existsSync(startPath)) {
|
|
70
|
+
try {
|
|
71
|
+
unlinkSync(startPath);
|
|
72
|
+
}
|
|
73
|
+
catch { /* consumed concurrently */ }
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
function cleanupContextDir(contextPath) {
|
|
81
|
+
const parent = dirname(contextPath);
|
|
82
|
+
if (basename(parent).startsWith("taskflow-detach-")) {
|
|
83
|
+
try {
|
|
84
|
+
rmdirSync(parent);
|
|
85
|
+
}
|
|
86
|
+
catch { /* not empty / already gone */ }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
25
89
|
const contextPath = process.argv[2];
|
|
26
90
|
if (!contextPath) {
|
|
27
91
|
console.error("[detached-runner] Missing context file path argument");
|
|
28
92
|
process.exit(1);
|
|
29
93
|
}
|
|
94
|
+
if (!isPrivateDetachContextPath(contextPath)) {
|
|
95
|
+
console.error("[detached-runner] Refusing context outside a private taskflow-detach temp directory");
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
30
98
|
let ctx;
|
|
31
99
|
try {
|
|
32
100
|
ctx = JSON.parse(readFileSync(contextPath, "utf-8"));
|
|
@@ -42,37 +110,67 @@ finally {
|
|
|
42
110
|
unlinkSync(contextPath);
|
|
43
111
|
}
|
|
44
112
|
catch { /* best-effort one-shot file cleanup */ }
|
|
45
|
-
const parent = dirname(contextPath);
|
|
46
|
-
// Remove only an empty Taskflow temp directory. Recursive deletion here would
|
|
47
|
-
// make this public spawn entry capable of deleting unrelated argv-selected
|
|
48
|
-
// files merely because their parent happened to share the expected prefix.
|
|
49
|
-
if (basename(parent).startsWith("taskflow-detach-")) {
|
|
50
|
-
try {
|
|
51
|
-
rmdirSync(parent);
|
|
52
|
-
}
|
|
53
|
-
catch { /* not empty / already gone */ }
|
|
54
|
-
}
|
|
55
113
|
}
|
|
56
|
-
if (!ctx)
|
|
114
|
+
if (!ctx) {
|
|
115
|
+
cleanupContextDir(contextPath);
|
|
57
116
|
process.exit(1);
|
|
117
|
+
}
|
|
58
118
|
const cleanupConfig = { maxKeep: DEFAULT_KEPT_RUNS, maxAgeDays: DEFAULT_RUN_AGE_DAYS };
|
|
119
|
+
if (ctx.waitForStart && !(await waitForStartGate(dirname(contextPath)))) {
|
|
120
|
+
try {
|
|
121
|
+
const state = loadRun(ctx.cwd, ctx.runId);
|
|
122
|
+
if (state?.status === "running") {
|
|
123
|
+
state.status = "failed";
|
|
124
|
+
state.phases["__detach__"] = {
|
|
125
|
+
id: "__detach__",
|
|
126
|
+
status: "failed",
|
|
127
|
+
endedAt: Date.now(),
|
|
128
|
+
error: `Detached launch gate was not released within ${START_GATE_TIMEOUT_MS}ms.`,
|
|
129
|
+
};
|
|
130
|
+
saveRun(state, cleanupConfig);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch { /* best-effort terminalization */ }
|
|
134
|
+
cleanupContextDir(contextPath);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
cleanupContextDir(contextPath);
|
|
59
138
|
try {
|
|
60
139
|
const state = loadRun(ctx.cwd, ctx.runId);
|
|
61
140
|
if (!state) {
|
|
62
141
|
console.error(`[detached-runner] Run not found: ${ctx.runId}`);
|
|
63
142
|
process.exit(1);
|
|
64
143
|
}
|
|
65
|
-
|
|
144
|
+
process.env.TASKFLOW_DETACHED_RUNNER = "1";
|
|
145
|
+
let heartbeatTimer;
|
|
146
|
+
if (ctx.detachedInstanceId) {
|
|
147
|
+
process.env[DETACHED_CONTROL_CWD_ENV] = ctx.cwd;
|
|
148
|
+
process.env[DETACHED_CONTROL_RUN_ID_ENV] = ctx.runId;
|
|
149
|
+
process.env[DETACHED_CONTROL_INSTANCE_ENV] = ctx.detachedInstanceId;
|
|
150
|
+
process.env[DETACHED_CONTROL_OWNER_PID_ENV] = String(process.pid);
|
|
151
|
+
heartbeatDetachedProcessRegistry(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
152
|
+
heartbeatTimer = setInterval(() => {
|
|
153
|
+
try {
|
|
154
|
+
heartbeatDetachedProcessRegistry(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
155
|
+
}
|
|
156
|
+
catch { /* best-effort lease */ }
|
|
157
|
+
}, 1_000);
|
|
158
|
+
heartbeatTimer.unref();
|
|
159
|
+
}
|
|
160
|
+
// Prefer the execution context frozen by the parent. Legacy callers without
|
|
161
|
+
// a snapshot retain the old discovery fallback.
|
|
66
162
|
const settings = readSubagentSettings();
|
|
67
|
-
cleanupConfig.maxKeep = settings.taskflow.maxKeptRuns;
|
|
68
|
-
cleanupConfig.maxAgeDays = settings.taskflow.maxRunAgeDays;
|
|
69
|
-
const
|
|
70
|
-
const
|
|
163
|
+
cleanupConfig.maxKeep = ctx.maxKeptRuns ?? state.detachedRetention?.maxKeep ?? settings.taskflow.maxKeptRuns;
|
|
164
|
+
cleanupConfig.maxAgeDays = ctx.maxRunAgeDays ?? state.detachedRetention?.maxAgeDays ?? settings.taskflow.maxRunAgeDays;
|
|
165
|
+
const legacyDefaultScope = ctx.runnerFactoryExport ? "user" : "both";
|
|
166
|
+
const scope = ctx.agentScope ?? state.def.agentScope ?? legacyDefaultScope;
|
|
167
|
+
const agents = ctx.agents ?? discoverAgents(ctx.cwd, scope, settings.modelRoles, settings.taskflow).agents;
|
|
71
168
|
// The host adapter injects its subagent runner. Core is host-neutral and
|
|
72
169
|
// CANNOT spawn pi/codex itself, so without this every phase would fail with
|
|
73
170
|
// "No subagent runner injected". Resolve the runner via a dynamic import of
|
|
74
171
|
// the module path the host serialized into the context file.
|
|
75
|
-
let
|
|
172
|
+
let injectedRunner;
|
|
173
|
+
let runnerLoadError;
|
|
76
174
|
if (ctx.runnerModule) {
|
|
77
175
|
try {
|
|
78
176
|
const runnerMod = await import(__rewriteRelativeImportExtension(ctx.runnerModule));
|
|
@@ -82,14 +180,15 @@ try {
|
|
|
82
180
|
? exported(ctx.runnerConfig)
|
|
83
181
|
: exported;
|
|
84
182
|
if (runner && typeof runner.runTask === "function") {
|
|
85
|
-
|
|
183
|
+
injectedRunner = runner;
|
|
86
184
|
}
|
|
87
185
|
else {
|
|
88
186
|
console.error(`[detached-runner] '${exportName}' on '${ctx.runnerModule}' is not a SubagentRunner (missing runTask)`);
|
|
89
187
|
}
|
|
90
188
|
}
|
|
91
189
|
catch (e) {
|
|
92
|
-
|
|
190
|
+
runnerLoadError = e instanceof Error ? e.message : String(e);
|
|
191
|
+
console.error(`[detached-runner] Failed to load runner module '${ctx.runnerModule}': ${runnerLoadError}`);
|
|
93
192
|
}
|
|
94
193
|
}
|
|
95
194
|
else {
|
|
@@ -100,30 +199,73 @@ try {
|
|
|
100
199
|
// stub — burying the real cause (a bad module path, a compile-time specifier
|
|
101
200
|
// bug, a missing export). Exiting non-zero here routes the real stderr
|
|
102
201
|
// message into the host's early-exit crash guard, which persists it on the
|
|
103
|
-
// run's synthetic __detach__ phase where it is pollable and debuggable.
|
|
104
|
-
|
|
202
|
+
// run's synthetic __detach__ phase where it is pollable and debuggable. The
|
|
203
|
+
// non-zero exit then lets the parent guard observe that terminal record
|
|
204
|
+
// without overwriting it; detached stdio itself is intentionally ignored.
|
|
205
|
+
if (ctx.runnerModule && !injectedRunner) {
|
|
105
206
|
state.status = "failed";
|
|
106
207
|
state.phases["__detach__"] = {
|
|
107
208
|
id: "__detach__",
|
|
108
209
|
status: "failed",
|
|
109
210
|
endedAt: Date.now(),
|
|
110
|
-
error: `Runner module failed to load: '${ctx.runnerModule}' (export '${ctx.runnerFactoryExport ?? ctx.runnerExport ?? "piSubagentRunner"}')
|
|
211
|
+
error: `Runner module failed to load: '${ctx.runnerModule}' (export '${ctx.runnerFactoryExport ?? ctx.runnerExport ?? "piSubagentRunner"}'): ${runnerLoadError ?? "export is not a SubagentRunner"}`,
|
|
111
212
|
};
|
|
112
213
|
saveRun(state, cleanupConfig);
|
|
214
|
+
if (heartbeatTimer)
|
|
215
|
+
clearInterval(heartbeatTimer);
|
|
216
|
+
if (ctx.detachedInstanceId)
|
|
217
|
+
clearDetachedProcessRegistry(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
113
218
|
process.exit(1);
|
|
114
219
|
}
|
|
115
|
-
const
|
|
220
|
+
const abortController = new AbortController();
|
|
221
|
+
const stopCancelWatch = watchDetachedCancel(ctx.cwd, ctx.runId, abortController, undefined, (request) => {
|
|
222
|
+
state.detachedCancel = request;
|
|
223
|
+
});
|
|
224
|
+
const abortForSignal = () => abortController.abort({ reason: "detached-process-signal" });
|
|
225
|
+
process.once("SIGTERM", abortForSignal);
|
|
226
|
+
process.once("SIGINT", abortForSignal);
|
|
227
|
+
process.once("SIGHUP", abortForSignal);
|
|
228
|
+
process.env[DETACHED_CONTROL_SIGNAL_READY_ENV] = "1";
|
|
229
|
+
const deps = {
|
|
116
230
|
cwd: ctx.cwd,
|
|
117
231
|
cwdBridgeMode: cwdBridgeModeFromEnv(),
|
|
118
232
|
agents,
|
|
119
|
-
globalThinking: settings.globalThinking,
|
|
233
|
+
globalThinking: ctx.globalThinking ?? settings.globalThinking,
|
|
120
234
|
persist: (s) => saveRun(s, cleanupConfig),
|
|
121
|
-
runTask,
|
|
235
|
+
runTask: injectedRunner?.runTask,
|
|
236
|
+
usageAccounting: injectedRunner?.usageAccounting,
|
|
237
|
+
signal: abortController.signal,
|
|
238
|
+
trace: new FileTraceSink(traceFilePath(runsDir(ctx.cwd), state.flowName, state.runId)),
|
|
122
239
|
// No requestApproval — approval phases auto-reject in detached/CI mode
|
|
123
240
|
// (safety: approval gates are never bypassed; the run records the rejection).
|
|
124
241
|
loadFlow: (name) => getFlow(ctx.cwd, name)?.def,
|
|
125
|
-
}
|
|
126
|
-
|
|
242
|
+
};
|
|
243
|
+
if (ctx.incremental === true)
|
|
244
|
+
deps.cacheScopeDefault = "cross-run";
|
|
245
|
+
try {
|
|
246
|
+
const result = await executeTaskflow(state, deps);
|
|
247
|
+
result.state.finalOutput = result.finalOutput;
|
|
248
|
+
result.state.outputSourcePhaseId = result.outputSourcePhaseId;
|
|
249
|
+
saveRun(result.state, cleanupConfig);
|
|
250
|
+
if (result.ok && ctx.reusedSavedName) {
|
|
251
|
+
try {
|
|
252
|
+
bumpReuseInSidecar(ctx.cwd, ctx.reusedSavedName);
|
|
253
|
+
}
|
|
254
|
+
catch { /* best-effort */ }
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
finally {
|
|
258
|
+
stopCancelWatch();
|
|
259
|
+
if (heartbeatTimer)
|
|
260
|
+
clearInterval(heartbeatTimer);
|
|
261
|
+
clearDetachedCancelRequest(ctx.cwd, ctx.runId);
|
|
262
|
+
if (ctx.detachedInstanceId)
|
|
263
|
+
clearDetachedProcessRegistry(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
264
|
+
delete process.env[DETACHED_CONTROL_SIGNAL_READY_ENV];
|
|
265
|
+
process.removeListener("SIGTERM", abortForSignal);
|
|
266
|
+
process.removeListener("SIGINT", abortForSignal);
|
|
267
|
+
process.removeListener("SIGHUP", abortForSignal);
|
|
268
|
+
}
|
|
127
269
|
}
|
|
128
270
|
catch (e) {
|
|
129
271
|
// Top-level catch: persist failure so the host can poll the terminal state.
|
|
@@ -133,12 +275,23 @@ catch (e) {
|
|
|
133
275
|
const state = loadRun(ctx.cwd, ctx.runId);
|
|
134
276
|
if (state && state.status === "running") {
|
|
135
277
|
state.status = "failed";
|
|
278
|
+
state.phases["__detach__"] = {
|
|
279
|
+
id: "__detach__",
|
|
280
|
+
status: "failed",
|
|
281
|
+
endedAt: Date.now(),
|
|
282
|
+
error: message.slice(0, 2_000),
|
|
283
|
+
};
|
|
136
284
|
saveRun(state, cleanupConfig);
|
|
137
285
|
}
|
|
138
286
|
}
|
|
139
287
|
catch {
|
|
140
288
|
// Best-effort — if we can't even load the state, there's nothing to persist.
|
|
141
289
|
}
|
|
290
|
+
if (ctx.detachedInstanceId)
|
|
291
|
+
terminateDetachedProcessTrees(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
292
|
+
clearDetachedCancelRequest(ctx.cwd, ctx.runId);
|
|
293
|
+
if (ctx.detachedInstanceId)
|
|
294
|
+
clearDetachedProcessRegistry(ctx.cwd, ctx.runId, ctx.detachedInstanceId);
|
|
142
295
|
process.exit(1);
|
|
143
296
|
}
|
|
144
297
|
//# sourceMappingURL=detached-runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detached-runner.js","sourceRoot":"","sources":["../src/detached-runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"detached-runner.js","sourceRoot":"","sources":["../src/detached-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/exec/driver.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { TraceSink } from "../trace.ts";
|
|
|
11
11
|
import { EVENT_KERNEL_PHASE_TYPES, type KernelApprovalDecision, type KernelApprovalRequest, type RunTaskFn } from "./step.ts";
|
|
12
12
|
import type { AgentConfig } from "../agents.ts";
|
|
13
13
|
import type { UsageStats } from "../usage.ts";
|
|
14
|
+
import type { TaskflowVerifier } from "../verify.ts";
|
|
14
15
|
import { kernelUnsupportedReason } from "./kernel-policy.ts";
|
|
15
16
|
export { EVENT_KERNEL_PHASE_TYPES, kernelUnsupportedReason };
|
|
16
17
|
export interface EventKernelDeps {
|
|
@@ -26,6 +27,10 @@ export interface EventKernelDeps {
|
|
|
26
27
|
eventKernel?: boolean;
|
|
27
28
|
requestApproval?: (req: KernelApprovalRequest) => Promise<KernelApprovalDecision>;
|
|
28
29
|
loadFlow?: (name: string) => Taskflow | undefined;
|
|
30
|
+
/** Caller-supplied zero-token verifiers (see verify.ts). Run in runNested's
|
|
31
|
+
* plugin-error preflight before every child-flow dispatch on this engine, and
|
|
32
|
+
* recursed via the ...deps spread. */
|
|
33
|
+
verifiers?: TaskflowVerifier[];
|
|
29
34
|
_stack?: string[];
|
|
30
35
|
_dynamic?: boolean;
|
|
31
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/exec/driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAA2C,KAAK,MAAM,EAAc,KAAK,QAAQ,EAAoB,MAAM,cAAc,CAAC;AAGjI,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EACN,wBAAwB,EAExB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,KAAK,SAAS,EAGd,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/exec/driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAA2C,KAAK,MAAM,EAAc,KAAK,QAAQ,EAAoB,MAAM,cAAc,CAAC;AAGjI,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EACN,wBAAwB,EAExB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,KAAK,SAAS,EAGd,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAIN,uBAAuB,EACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;IAC9D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAClF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,CAAC;IAClD;;2CAEuC;IACvC,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;IACvB;;;qEAGiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,QAAQ,EACb,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,EACjD,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,EAC7B,eAAe,CAAC,EAAE,MAAM,GACtB,OAAO,CAyCT;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAI3E;AA4DD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkXvG"}
|
package/dist/exec/driver.js
CHANGED
|
@@ -13,6 +13,7 @@ import { safeParse } from "../interpolate.js";
|
|
|
13
13
|
import { EVENT_KERNEL_PHASE_TYPES, stepPhase, } from "./step.js";
|
|
14
14
|
import { foldEvents } from "./fold.js";
|
|
15
15
|
import { EVENT_SCHEMA_VERSION } from "./events.js";
|
|
16
|
+
import { pluginVerifierErrors } from "../verify.js";
|
|
16
17
|
import { clampSubFlowBudget, containsInterpolationPlaceholder, depsSatisfied, kernelUnsupportedReason, } from "./kernel-policy.js";
|
|
17
18
|
export { EVENT_KERNEL_PHASE_TYPES, kernelUnsupportedReason };
|
|
18
19
|
/** True when types are known AND no advanced features force imperative fall-back. */
|
|
@@ -189,6 +190,34 @@ export async function runEventKernel(state, deps) {
|
|
|
189
190
|
blocked: false,
|
|
190
191
|
};
|
|
191
192
|
}
|
|
193
|
+
// Plugin-error verifier preflight (no-spend gate, zero-token). runNested is
|
|
194
|
+
// the single funnel for BOTH inline-def and saved-use child dispatch on this
|
|
195
|
+
// engine, so centralizing here covers every child flow (review of #84, issue
|
|
196
|
+
// 1). It runs BEFORE childState is created, so a blocked child never
|
|
197
|
+
// dispatches. Verifiers see the DECLARED child def (opts.def), not the
|
|
198
|
+
// budget-clamped effectiveDef, matching what the imperative path's verify
|
|
199
|
+
// sites observe: a budget/concurrency policy verifier must see the same
|
|
200
|
+
// declaration on both engines, or the event kernel would silently let a child
|
|
201
|
+
// it blocks on the imperative path go on to spend.
|
|
202
|
+
//
|
|
203
|
+
// Built-in graph detectors (dead-ends, unreachable, …) are intentionally NOT
|
|
204
|
+
// run here: this is a plugin-only gate, matching the top-level preflight's
|
|
205
|
+
// advisory treatment of built-ins. It costs nothing reachable — the only
|
|
206
|
+
// error-severity built-ins are `unreachable` and self-dependency, and neither
|
|
207
|
+
// can reach a dispatching event-kernel child. A flow nesting an unreachable
|
|
208
|
+
// child is itself kernel-ineligible (concurrent DAG layers), so it runs on the
|
|
209
|
+
// imperative path where the built-in detectors still run; a self-dependency is
|
|
210
|
+
// rejected by validateTaskflow above. (Pinned in verify-pluggable.test.ts.)
|
|
211
|
+
const pluginErrors = pluginVerifierErrors({ name: opts.def.name, phases: opts.def.phases, budget: opts.def.budget, concurrency: opts.def.concurrency }, deps.verifiers);
|
|
212
|
+
if (pluginErrors) {
|
|
213
|
+
return {
|
|
214
|
+
finalOutput: `Nested flow '${effectiveDef.name}' failed verifier preflight: ${pluginErrors.join("; ")}`,
|
|
215
|
+
ok: false,
|
|
216
|
+
usage: emptyUsage(),
|
|
217
|
+
events: [],
|
|
218
|
+
blocked: false,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
192
221
|
const childState = {
|
|
193
222
|
// No `/` — validateRunId rejects path separators if ever persisted.
|
|
194
223
|
runId: `${state.runId}-n-${effectiveDef.name.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 40)}`,
|
|
@@ -235,20 +264,12 @@ export async function runEventKernel(state, deps) {
|
|
|
235
264
|
for (const layer of layers) {
|
|
236
265
|
if (deps.signal?.aborted)
|
|
237
266
|
break;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
else if (budgetBlocked)
|
|
245
|
-
skipReason = `Budget exceeded${budgetReason ? `: ${budgetReason}` : ""}`;
|
|
246
|
-
else {
|
|
247
|
-
const dep = depsSatisfied(phase, state.phases, byId);
|
|
248
|
-
if (!dep.ok)
|
|
249
|
-
skipReason = dep.skipReason;
|
|
250
|
-
}
|
|
251
|
-
if (skipReason) {
|
|
267
|
+
// --- Pre-layer gate/budget check: skip the entire layer if blocked ---
|
|
268
|
+
if (gateBlocked || budgetBlocked) {
|
|
269
|
+
for (const phase of layer) {
|
|
270
|
+
const skipReason = gateBlocked
|
|
271
|
+
? `Gate blocked${gateReason ? `: ${gateReason}` : ""}`
|
|
272
|
+
: `Budget exceeded${budgetReason ? `: ${budgetReason}` : ""}`;
|
|
252
273
|
if (skipReason.startsWith("Budget exceeded")) {
|
|
253
274
|
budgetBlocked = true;
|
|
254
275
|
const be = {
|
|
@@ -262,24 +283,50 @@ export async function runEventKernel(state, deps) {
|
|
|
262
283
|
allEvents.push(be);
|
|
263
284
|
safeTraceEmit(deps, be);
|
|
264
285
|
}
|
|
265
|
-
const startedAt = Date.now();
|
|
266
286
|
emitLifecycle(deps, allEvents, state.runId, phase, "skipped", skipReason);
|
|
267
287
|
state.phases[phase.id] = {
|
|
268
288
|
id: phase.id,
|
|
269
289
|
status: "skipped",
|
|
270
290
|
error: skipReason,
|
|
271
|
-
startedAt,
|
|
291
|
+
startedAt: Date.now(),
|
|
272
292
|
endedAt: Date.now(),
|
|
273
293
|
usage: emptyUsage(),
|
|
274
294
|
};
|
|
275
|
-
continue;
|
|
276
295
|
}
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
const plans = layer.map((phase) => {
|
|
299
|
+
const dep = depsSatisfied(phase, state.phases, byId);
|
|
300
|
+
return { phase, skipReason: dep.ok ? undefined : dep.skipReason };
|
|
301
|
+
});
|
|
302
|
+
// Emit skips for dep-unsatisfied phases (sequential, cheap).
|
|
303
|
+
for (const { phase, skipReason } of plans) {
|
|
304
|
+
if (!skipReason)
|
|
305
|
+
continue;
|
|
306
|
+
emitLifecycle(deps, allEvents, state.runId, phase, "skipped", skipReason);
|
|
307
|
+
state.phases[phase.id] = {
|
|
308
|
+
id: phase.id,
|
|
309
|
+
status: "skipped",
|
|
310
|
+
error: skipReason,
|
|
311
|
+
startedAt: Date.now(),
|
|
312
|
+
endedAt: Date.now(),
|
|
313
|
+
usage: emptyUsage(),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
// --- Execute runnable phases concurrently within the layer ---
|
|
317
|
+
const runnable = plans.filter((p) => !p.skipReason);
|
|
318
|
+
if (runnable.length === 0)
|
|
319
|
+
continue;
|
|
320
|
+
const outcomes = await Promise.all(runnable.map(async ({ phase }) => {
|
|
277
321
|
const startedAt = Date.now();
|
|
278
|
-
state.phases[phase.id] = { id: phase.id, status: "running", startedAt };
|
|
279
322
|
const readRefs = [];
|
|
280
323
|
const promptCalls = [];
|
|
281
324
|
const ctx = { state, deps: stepDeps, steps, args, readRefs, promptCalls };
|
|
282
325
|
const result = await stepPhase(phase, ctx);
|
|
326
|
+
return { phase, result, startedAt, readRefs, promptCalls };
|
|
327
|
+
}));
|
|
328
|
+
// --- Atomic layer commit: fold all outcomes into state ---
|
|
329
|
+
for (const { phase, result, startedAt, readRefs } of outcomes) {
|
|
283
330
|
if (!result) {
|
|
284
331
|
state.phases[phase.id] = {
|
|
285
332
|
id: phase.id,
|
|
@@ -318,18 +365,13 @@ export async function runEventKernel(state, deps) {
|
|
|
318
365
|
approval: result.approval,
|
|
319
366
|
warnings: result.warnings,
|
|
320
367
|
...(observedReads.length ? { reads: observedReads } : {}),
|
|
321
|
-
// Prompt-size diagnostics (parity with imperative PhaseState.promptStats).
|
|
322
368
|
...(result.promptStats ? { promptStats: result.promptStats } : {}),
|
|
323
|
-
// Match the imperative audit marker: an idempotent:false phase
|
|
324
|
-
// records that its side effect may have fired, unless its guard skipped
|
|
325
|
-
// all execution.
|
|
326
369
|
...(phase.idempotent === false && result.status !== "skipped" ? { sideEffect: true } : {}),
|
|
327
370
|
...(result.status === "timedOut" ? { timedOut: true } : {}),
|
|
328
371
|
};
|
|
329
372
|
if (result.status === "done" && result.output !== undefined) {
|
|
330
373
|
steps[phase.id] = {
|
|
331
374
|
output: result.output,
|
|
332
|
-
// Always best-effort parse so {steps.X.json.field} works for JSON agents
|
|
333
375
|
json: phaseJson ?? safeParse(result.output),
|
|
334
376
|
};
|
|
335
377
|
}
|
|
@@ -339,35 +381,37 @@ export async function runEventKernel(state, deps) {
|
|
|
339
381
|
gateOutput = result.output ?? "";
|
|
340
382
|
gatePhaseId = phase.id;
|
|
341
383
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
384
|
+
}
|
|
385
|
+
// --- Post-layer budget check ---
|
|
386
|
+
const ob = runOverBudget(state);
|
|
387
|
+
if (ob.over) {
|
|
388
|
+
budgetBlocked = true;
|
|
389
|
+
budgetReason = ob.reason;
|
|
390
|
+
// Attribute the budget-hit to the last phase in the layer.
|
|
391
|
+
const lastPhase = layer[layer.length - 1];
|
|
392
|
+
const be = {
|
|
393
|
+
v: EVENT_SCHEMA_VERSION,
|
|
394
|
+
ts: Date.now(),
|
|
395
|
+
runId: state.runId,
|
|
396
|
+
phaseId: lastPhase.id,
|
|
397
|
+
kind: "decision",
|
|
398
|
+
decision: { type: "budget-hit", value: "budget", reason: ob.reason },
|
|
399
|
+
};
|
|
400
|
+
allEvents.push(be);
|
|
401
|
+
safeTraceEmit(deps, be);
|
|
402
|
+
safeTraceFlush(deps, lastPhase.id);
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
deps.persist?.(state);
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
/* fail-open */
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
deps.onProgress?.(state);
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
/* fail-open */
|
|
371
415
|
}
|
|
372
416
|
}
|
|
373
417
|
// Soft fold drift check
|
|
@@ -401,6 +445,8 @@ export async function runEventKernel(state, deps) {
|
|
|
401
445
|
budget: budgetBlocked,
|
|
402
446
|
budgetReason,
|
|
403
447
|
});
|
|
448
|
+
state.finalOutput = finalOutput;
|
|
449
|
+
state.outputSourcePhaseId = outputSourcePhaseId;
|
|
404
450
|
const totalUsage = aggregateUsage(Object.values(state.phases).map((p) => p.usage ?? emptyUsage()));
|
|
405
451
|
try {
|
|
406
452
|
deps.persist?.(state);
|