taskflow-core 0.1.7 → 0.2.0

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.
Files changed (126) hide show
  1. package/README.md +80 -25
  2. package/dist/agents.js.map +1 -1
  3. package/dist/cache.d.ts.map +1 -1
  4. package/dist/compile.js.map +1 -1
  5. package/dist/context-store.js.map +1 -1
  6. package/dist/deterministic.d.ts +8 -0
  7. package/dist/deterministic.d.ts.map +1 -1
  8. package/dist/deterministic.js +23 -1
  9. package/dist/deterministic.js.map +1 -1
  10. package/dist/exec/driver.d.ts +47 -0
  11. package/dist/exec/driver.d.ts.map +1 -0
  12. package/dist/exec/driver.js +397 -0
  13. package/dist/exec/driver.js.map +1 -0
  14. package/dist/exec/events.d.ts +76 -0
  15. package/dist/exec/events.d.ts.map +1 -0
  16. package/dist/exec/events.js +108 -0
  17. package/dist/exec/events.js.map +1 -0
  18. package/dist/exec/fold.d.ts +45 -0
  19. package/dist/exec/fold.d.ts.map +1 -0
  20. package/dist/exec/fold.js +122 -0
  21. package/dist/exec/fold.js.map +1 -0
  22. package/dist/exec/index.d.ts +17 -0
  23. package/dist/exec/index.d.ts.map +1 -0
  24. package/dist/exec/index.js +17 -0
  25. package/dist/exec/index.js.map +1 -0
  26. package/dist/exec/kernel-policy.d.ts +35 -0
  27. package/dist/exec/kernel-policy.d.ts.map +1 -0
  28. package/dist/exec/kernel-policy.js +184 -0
  29. package/dist/exec/kernel-policy.js.map +1 -0
  30. package/dist/exec/step-kinds.d.ts +41 -0
  31. package/dist/exec/step-kinds.d.ts.map +1 -0
  32. package/dist/exec/step-kinds.js +574 -0
  33. package/dist/exec/step-kinds.js.map +1 -0
  34. package/dist/exec/step.d.ts +93 -0
  35. package/dist/exec/step.d.ts.map +1 -0
  36. package/dist/exec/step.js +436 -0
  37. package/dist/exec/step.js.map +1 -0
  38. package/dist/flowir/canonical-hash.d.ts +101 -0
  39. package/dist/flowir/canonical-hash.d.ts.map +1 -0
  40. package/dist/flowir/canonical-hash.js +219 -0
  41. package/dist/flowir/canonical-hash.js.map +1 -0
  42. package/dist/flowir/compile.d.ts +49 -0
  43. package/dist/flowir/compile.d.ts.map +1 -0
  44. package/dist/flowir/compile.js +219 -0
  45. package/dist/flowir/compile.js.map +1 -0
  46. package/dist/flowir/cond.d.ts +76 -0
  47. package/dist/flowir/cond.d.ts.map +1 -0
  48. package/dist/flowir/cond.js +214 -0
  49. package/dist/flowir/cond.js.map +1 -0
  50. package/dist/flowir/index.d.ts +20 -23
  51. package/dist/flowir/index.d.ts.map +1 -1
  52. package/dist/flowir/index.js +47 -35
  53. package/dist/flowir/index.js.map +1 -1
  54. package/dist/flowir/meta.d.ts +4 -4
  55. package/dist/flowir/meta.d.ts.map +1 -1
  56. package/dist/flowir/phasefp.d.ts.map +1 -1
  57. package/dist/flowir/phasefp.js +13 -1
  58. package/dist/flowir/phasefp.js.map +1 -1
  59. package/dist/flowir/schema.d.ts +260 -0
  60. package/dist/flowir/schema.d.ts.map +1 -0
  61. package/dist/flowir/schema.js +234 -0
  62. package/dist/flowir/schema.js.map +1 -0
  63. package/dist/flowir/translate.d.ts.map +1 -1
  64. package/dist/flowir/translate.js +3 -0
  65. package/dist/flowir/translate.js.map +1 -1
  66. package/dist/frontmatter.d.ts.map +1 -1
  67. package/dist/host/runner-types.d.ts +3 -0
  68. package/dist/host/runner-types.d.ts.map +1 -1
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -0
  72. package/dist/index.js.map +1 -1
  73. package/dist/interpolate.js.map +1 -1
  74. package/dist/peek.js.map +1 -1
  75. package/dist/rates.d.ts +121 -0
  76. package/dist/rates.d.ts.map +1 -0
  77. package/dist/rates.js +187 -0
  78. package/dist/rates.js.map +1 -0
  79. package/dist/reflexion.js.map +1 -1
  80. package/dist/replay.d.ts +43 -50
  81. package/dist/replay.d.ts.map +1 -1
  82. package/dist/replay.js +629 -19
  83. package/dist/replay.js.map +1 -1
  84. package/dist/runner-core.d.ts +24 -0
  85. package/dist/runner-core.d.ts.map +1 -1
  86. package/dist/runner-core.js +225 -32
  87. package/dist/runner-core.js.map +1 -1
  88. package/dist/runtime/phases/approval.d.ts +23 -0
  89. package/dist/runtime/phases/approval.d.ts.map +1 -0
  90. package/dist/runtime/phases/approval.js +38 -0
  91. package/dist/runtime/phases/approval.js.map +1 -0
  92. package/dist/runtime/phases/expand.d.ts +29 -0
  93. package/dist/runtime/phases/expand.d.ts.map +1 -0
  94. package/dist/runtime/phases/expand.js +126 -0
  95. package/dist/runtime/phases/expand.js.map +1 -0
  96. package/dist/runtime/phases/parallel.d.ts +26 -0
  97. package/dist/runtime/phases/parallel.d.ts.map +1 -0
  98. package/dist/runtime/phases/parallel.js +15 -0
  99. package/dist/runtime/phases/parallel.js.map +1 -0
  100. package/dist/runtime/phases/race.d.ts +31 -0
  101. package/dist/runtime/phases/race.d.ts.map +1 -0
  102. package/dist/runtime/phases/race.js +220 -0
  103. package/dist/runtime/phases/race.js.map +1 -0
  104. package/dist/runtime/phases/script.d.ts +38 -0
  105. package/dist/runtime/phases/script.d.ts.map +1 -0
  106. package/dist/runtime/phases/script.js +139 -0
  107. package/dist/runtime/phases/script.js.map +1 -0
  108. package/dist/runtime.d.ts +29 -16
  109. package/dist/runtime.d.ts.map +1 -1
  110. package/dist/runtime.js +554 -292
  111. package/dist/runtime.js.map +1 -1
  112. package/dist/schema.d.ts +44 -12
  113. package/dist/schema.d.ts.map +1 -1
  114. package/dist/schema.js +91 -10
  115. package/dist/schema.js.map +1 -1
  116. package/dist/scorers.d.ts.map +1 -1
  117. package/dist/scorers.js.map +1 -1
  118. package/dist/store.d.ts +6 -0
  119. package/dist/store.d.ts.map +1 -1
  120. package/dist/store.js.map +1 -1
  121. package/dist/trace.d.ts +4 -1
  122. package/dist/trace.d.ts.map +1 -1
  123. package/dist/trace.js +33 -26
  124. package/dist/trace.js.map +1 -1
  125. package/dist/workspace.d.ts.map +1 -1
  126. package/package.json +5 -4
@@ -0,0 +1,47 @@
1
+ /**
2
+ * exec/driver — event-sourced schedule loop for all phase kinds (S2).
3
+ *
4
+ * **Default OFF.** Engaged when `deps.eventKernel === true` or
5
+ * `PI_TASKFLOW_EVENT_KERNEL=1`, and only when {@link canUseEventKernel} admits
6
+ * the def (no unsupported advanced features).
7
+ */
8
+ import type { RunState } from "../store.ts";
9
+ import { type Budget, type Taskflow } from "../schema.ts";
10
+ import type { TraceSink } from "../trace.ts";
11
+ import { EVENT_KERNEL_PHASE_TYPES, type KernelApprovalDecision, type KernelApprovalRequest, type RunTaskFn } from "./step.ts";
12
+ import type { AgentConfig } from "../agents.ts";
13
+ import type { UsageStats } from "../usage.ts";
14
+ import { kernelUnsupportedReason } from "./kernel-policy.ts";
15
+ export { EVENT_KERNEL_PHASE_TYPES, kernelUnsupportedReason };
16
+ export interface EventKernelDeps {
17
+ cwd: string;
18
+ agents: AgentConfig[];
19
+ runTask: RunTaskFn;
20
+ signal?: AbortSignal;
21
+ globalThinking?: string;
22
+ usageAccounting?: "available" | "tokens-only" | "unavailable";
23
+ trace?: TraceSink;
24
+ persist?: (state: RunState) => void;
25
+ onProgress?: (state: RunState) => void;
26
+ eventKernel?: boolean;
27
+ requestApproval?: (req: KernelApprovalRequest) => Promise<KernelApprovalDecision>;
28
+ loadFlow?: (name: string) => Taskflow | undefined;
29
+ _stack?: string[];
30
+ }
31
+ export interface EventKernelResult {
32
+ state: RunState;
33
+ finalOutput: string;
34
+ ok: boolean;
35
+ totalUsage: UsageStats;
36
+ }
37
+ /** True when types are known AND no advanced features force imperative fall-back. */
38
+ export declare function canUseEventKernel(def: Taskflow, loadFlow?: (name: string) => Taskflow | undefined, seen?: Set<string>, inheritedBudget?: Budget): boolean;
39
+ export declare function eventKernelEnabled(deps: {
40
+ eventKernel?: boolean;
41
+ }): boolean;
42
+ /**
43
+ * Run a Taskflow on the event kernel.
44
+ * Caller must have checked {@link canUseEventKernel}.
45
+ */
46
+ export declare function runEventKernel(state: RunState, deps: EventKernelDeps): Promise<EventKernelResult>;
47
+ //# sourceMappingURL=driver.d.ts.map
@@ -0,0 +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,EAAE,MAAM,cAAc,CAAC;AAE/G,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;AAC9C,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,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;CACvB;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,CA+QvG"}
@@ -0,0 +1,397 @@
1
+ /**
2
+ * exec/driver — event-sourced schedule loop for all phase kinds (S2).
3
+ *
4
+ * **Default OFF.** Engaged when `deps.eventKernel === true` or
5
+ * `PI_TASKFLOW_EVENT_KERNEL=1`, and only when {@link canUseEventKernel} admits
6
+ * the def (no unsupported advanced features).
7
+ */
8
+ import { dependenciesOf, resolveArgs, topoLayers } from "../schema.js";
9
+ import { aggregateUsage, emptyUsage } from "../usage.js";
10
+ import { overBudget as overBudgetCheck } from "../deterministic.js";
11
+ import { safeParse } from "../interpolate.js";
12
+ import { EVENT_KERNEL_PHASE_TYPES, stepPhase, } from "./step.js";
13
+ import { foldEvents } from "./fold.js";
14
+ import { EVENT_SCHEMA_VERSION } from "./events.js";
15
+ import { clampSubFlowBudget, containsInterpolationPlaceholder, depsSatisfied, kernelUnsupportedReason, } from "./kernel-policy.js";
16
+ export { EVENT_KERNEL_PHASE_TYPES, kernelUnsupportedReason };
17
+ /** True when types are known AND no advanced features force imperative fall-back. */
18
+ export function canUseEventKernel(def, loadFlow, seen = new Set(), inheritedBudget) {
19
+ if (seen.has(def.name))
20
+ return false;
21
+ const nextSeen = new Set(seen).add(def.name);
22
+ const typesOk = (def.phases ?? []).every((p) => {
23
+ const t = p.type ?? "agent";
24
+ return EVENT_KERNEL_PHASE_TYPES.includes(t);
25
+ });
26
+ if (!typesOk)
27
+ return false;
28
+ // A parent run-wide budget also governs every nested call. Admission must
29
+ // evaluate the child with that inherited ceiling; otherwise a parent whose
30
+ // only phase is `flow` can smuggle a budgeted map/parallel/loop/tournament
31
+ // into the kernel and fail only after execution has already started.
32
+ const effectiveBudget = def.budget ?? inheritedBudget;
33
+ const effectiveDef = effectiveBudget === def.budget ? def : { ...def, budget: effectiveBudget };
34
+ if (kernelUnsupportedReason(effectiveDef) !== undefined)
35
+ return false;
36
+ for (const phase of def.phases ?? []) {
37
+ if ((phase.type ?? "agent") !== "flow")
38
+ continue;
39
+ let child;
40
+ const raw = phase.def;
41
+ if (raw !== undefined) {
42
+ if (typeof raw === "string") {
43
+ // Interpolated/runtime-generated definitions cannot be admitted statically.
44
+ if (containsInterpolationPlaceholder(raw))
45
+ return false;
46
+ try {
47
+ const parsed = JSON.parse(raw);
48
+ if (Array.isArray(parsed))
49
+ child = { name: `${phase.id}-inline`, phases: parsed };
50
+ else if (parsed && typeof parsed === "object" && Array.isArray(parsed.phases))
51
+ child = parsed;
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ else if (Array.isArray(raw)) {
58
+ child = { name: `${phase.id}-inline`, phases: raw };
59
+ }
60
+ else if (raw && typeof raw === "object" && Array.isArray(raw.phases)) {
61
+ child = raw;
62
+ }
63
+ }
64
+ else if (phase.use && loadFlow) {
65
+ child = loadFlow(phase.use);
66
+ }
67
+ if (!child || !canUseEventKernel(child, loadFlow, nextSeen, effectiveBudget))
68
+ return false;
69
+ }
70
+ return true;
71
+ }
72
+ export function eventKernelEnabled(deps) {
73
+ if (deps.eventKernel === true)
74
+ return true;
75
+ if (deps.eventKernel === false)
76
+ return false;
77
+ return process.env.PI_TASKFLOW_EVENT_KERNEL === "1" || process.env.PI_TASKFLOW_EVENT_KERNEL === "true";
78
+ }
79
+ function safeTraceEmit(deps, event) {
80
+ try {
81
+ deps.trace?.emit(event);
82
+ }
83
+ catch {
84
+ /* fail-open */
85
+ }
86
+ }
87
+ function safeTraceFlush(deps, phaseId) {
88
+ try {
89
+ deps.trace?.flush(phaseId);
90
+ }
91
+ catch {
92
+ /* fail-open */
93
+ }
94
+ }
95
+ function runOverBudget(state) {
96
+ const budget = state.def.budget;
97
+ if (!budget)
98
+ return { over: false, reason: "" };
99
+ return overBudgetCheck({
100
+ maxUSD: budget.maxUSD,
101
+ maxTokens: budget.maxTokens,
102
+ usages: Object.values(state.phases).map((p) => p.usage ?? emptyUsage()),
103
+ });
104
+ }
105
+ function emitLifecycle(deps, allEvents, runId, phase, status, error) {
106
+ const start = {
107
+ v: EVENT_SCHEMA_VERSION,
108
+ ts: Date.now(),
109
+ runId,
110
+ phaseId: phase.id,
111
+ kind: "phase-start",
112
+ dependencies: dependenciesOf(phase),
113
+ optional: phase.optional === true,
114
+ };
115
+ const end = {
116
+ v: EVENT_SCHEMA_VERSION,
117
+ ts: Date.now(),
118
+ runId,
119
+ phaseId: phase.id,
120
+ kind: "phase-end",
121
+ status,
122
+ error,
123
+ };
124
+ allEvents.push(start, end);
125
+ safeTraceEmit(deps, start);
126
+ safeTraceEmit(deps, end);
127
+ safeTraceFlush(deps, phase.id);
128
+ }
129
+ /**
130
+ * Run a Taskflow on the event kernel.
131
+ * Caller must have checked {@link canUseEventKernel}.
132
+ */
133
+ export async function runEventKernel(state, deps) {
134
+ const def = state.def;
135
+ const layers = topoLayers(def.phases);
136
+ const steps = {};
137
+ const args = resolveArgs(def, state.args);
138
+ const byId = new Map(def.phases.map((p) => [p.id, p]));
139
+ state.status = "running";
140
+ const allEvents = [];
141
+ let gateBlocked = false;
142
+ let gateReason = "";
143
+ let budgetBlocked = false;
144
+ let budgetReason = "";
145
+ const runNested = async (opts) => {
146
+ if (deps.usageAccounting === "unavailable" && (opts.def.budget || def.budget)) {
147
+ return {
148
+ finalOutput: `Usage accounting is unavailable; refusing budgeted nested flow '${opts.def.name}'`,
149
+ ok: false,
150
+ usage: emptyUsage(),
151
+ events: [],
152
+ blocked: false,
153
+ };
154
+ }
155
+ const effectiveBudget = opts.def.budget ?? def.budget;
156
+ if (deps.usageAccounting === "tokens-only" && effectiveBudget?.maxUSD !== undefined) {
157
+ throw new Error("This host reports tokens but not cost, so budget.maxUSD cannot be enforced. " +
158
+ "Use budget.maxTokens or a host with cost accounting.");
159
+ }
160
+ const parentSpent = aggregateUsage(Object.values(state.phases).map((p) => p.usage ?? emptyUsage()));
161
+ const effectiveDef = clampSubFlowBudget(opts.def, def.budget, parentSpent);
162
+ // Re-admit nested defs — parent admission must not smuggle race/expand
163
+ // or score/retry/… into the kernel path (silent semantic drift).
164
+ if (!canUseEventKernel(effectiveDef, deps.loadFlow)) {
165
+ const reason = kernelUnsupportedReason(effectiveDef) ??
166
+ "nested flow contains phase kinds or features the event kernel cannot execute";
167
+ return {
168
+ finalOutput: `Nested flow rejected by event kernel: ${reason}`,
169
+ ok: false,
170
+ usage: emptyUsage(),
171
+ events: [],
172
+ blocked: false,
173
+ };
174
+ }
175
+ const childState = {
176
+ // No `/` — validateRunId rejects path separators if ever persisted.
177
+ runId: `${state.runId}-n-${effectiveDef.name.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 40)}`,
178
+ flowName: effectiveDef.name,
179
+ def: effectiveDef,
180
+ args: opts.args,
181
+ status: "running",
182
+ phases: {},
183
+ createdAt: Date.now(),
184
+ updatedAt: Date.now(),
185
+ cwd: deps.cwd,
186
+ };
187
+ const child = await runEventKernel(childState, {
188
+ ...deps,
189
+ // A trace file belongs to exactly one runId. Nested flow events are
190
+ // intentionally isolated; the parent flow phase is marked unreplayable
191
+ // by the imperative path rather than polluting the parent's event log.
192
+ trace: undefined,
193
+ _stack: opts.stack,
194
+ });
195
+ const childErr = Object.values(child.state.phases)
196
+ .map((p) => p.error)
197
+ .find((e) => !!e);
198
+ return {
199
+ finalOutput: child.ok ? child.finalOutput : childErr || child.finalOutput || "sub-flow failed",
200
+ ok: child.ok,
201
+ usage: child.totalUsage,
202
+ events: [],
203
+ blocked: child.state.status === "blocked",
204
+ };
205
+ };
206
+ const stepDeps = {
207
+ cwd: deps.cwd,
208
+ agents: deps.agents,
209
+ runTask: deps.runTask,
210
+ signal: deps.signal,
211
+ globalThinking: deps.globalThinking,
212
+ requestApproval: deps.requestApproval,
213
+ loadFlow: deps.loadFlow,
214
+ stack: deps._stack ?? [],
215
+ runNested,
216
+ };
217
+ for (const layer of layers) {
218
+ if (deps.signal?.aborted)
219
+ break;
220
+ for (const phase of layer) {
221
+ if (deps.signal?.aborted)
222
+ break;
223
+ let skipReason;
224
+ if (gateBlocked)
225
+ skipReason = `Gate blocked${gateReason ? `: ${gateReason}` : ""}`;
226
+ else if (budgetBlocked)
227
+ skipReason = `Budget exceeded${budgetReason ? `: ${budgetReason}` : ""}`;
228
+ else {
229
+ const dep = depsSatisfied(phase, state.phases, byId);
230
+ if (!dep.ok)
231
+ skipReason = dep.skipReason;
232
+ }
233
+ if (skipReason) {
234
+ if (skipReason.startsWith("Budget exceeded")) {
235
+ budgetBlocked = true;
236
+ const be = {
237
+ v: EVENT_SCHEMA_VERSION,
238
+ ts: Date.now(),
239
+ runId: state.runId,
240
+ phaseId: phase.id,
241
+ kind: "decision",
242
+ decision: { type: "budget-hit", value: budgetReason || "budget", reason: skipReason },
243
+ };
244
+ allEvents.push(be);
245
+ safeTraceEmit(deps, be);
246
+ }
247
+ const startedAt = Date.now();
248
+ emitLifecycle(deps, allEvents, state.runId, phase, "skipped", skipReason);
249
+ state.phases[phase.id] = {
250
+ id: phase.id,
251
+ status: "skipped",
252
+ error: skipReason,
253
+ startedAt,
254
+ endedAt: Date.now(),
255
+ usage: emptyUsage(),
256
+ };
257
+ continue;
258
+ }
259
+ const startedAt = Date.now();
260
+ state.phases[phase.id] = { id: phase.id, status: "running", startedAt };
261
+ const ctx = { state, deps: stepDeps, steps, args };
262
+ const result = await stepPhase(phase, ctx);
263
+ if (!result) {
264
+ state.phases[phase.id] = {
265
+ id: phase.id,
266
+ status: "failed",
267
+ error: `event kernel cannot handle type ${phase.type}`,
268
+ endedAt: Date.now(),
269
+ usage: emptyUsage(),
270
+ };
271
+ continue;
272
+ }
273
+ for (const e of result.events) {
274
+ allEvents.push(e);
275
+ safeTraceEmit(deps, e);
276
+ }
277
+ safeTraceFlush(deps, phase.id);
278
+ const st = result.status === "skipped"
279
+ ? "skipped"
280
+ : result.status === "failed" || result.status === "timedOut"
281
+ ? "failed"
282
+ : "done";
283
+ const phaseJson = phase.output === "json" ? safeParse(result.output ?? "") : undefined;
284
+ state.phases[phase.id] = {
285
+ id: phase.id,
286
+ status: st,
287
+ output: result.output,
288
+ json: phaseJson,
289
+ error: result.error,
290
+ startedAt,
291
+ endedAt: Date.now(),
292
+ usage: result.usage ?? emptyUsage(),
293
+ attempts: result.attempts,
294
+ gate: result.gate,
295
+ approval: result.approval,
296
+ warnings: result.warnings,
297
+ // Match the imperative audit marker: an idempotent:false phase
298
+ // records that its side effect may have fired, unless its guard skipped
299
+ // all execution.
300
+ ...(phase.idempotent === false && result.status !== "skipped" ? { sideEffect: true } : {}),
301
+ ...(result.status === "timedOut" ? { timedOut: true } : {}),
302
+ };
303
+ if (result.status === "done" && result.output !== undefined) {
304
+ steps[phase.id] = {
305
+ output: result.output,
306
+ // Always best-effort parse so {steps.X.json.field} works for JSON agents
307
+ json: phaseJson ?? safeParse(result.output),
308
+ };
309
+ }
310
+ if (result.gate?.verdict === "block") {
311
+ gateBlocked = true;
312
+ gateReason = result.gate.reason || "Gate blocked";
313
+ }
314
+ const ob = runOverBudget(state);
315
+ if (ob.over) {
316
+ budgetBlocked = true;
317
+ budgetReason = ob.reason;
318
+ const be = {
319
+ v: EVENT_SCHEMA_VERSION,
320
+ ts: Date.now(),
321
+ runId: state.runId,
322
+ phaseId: phase.id,
323
+ kind: "decision",
324
+ decision: { type: "budget-hit", value: "budget", reason: ob.reason },
325
+ };
326
+ allEvents.push(be);
327
+ safeTraceEmit(deps, be);
328
+ // stepPhase already flushed this phase's lifecycle batch.
329
+ safeTraceFlush(deps, phase.id);
330
+ }
331
+ try {
332
+ deps.persist?.(state);
333
+ }
334
+ catch {
335
+ /* fail-open */
336
+ }
337
+ try {
338
+ deps.onProgress?.(state);
339
+ }
340
+ catch {
341
+ /* fail-open */
342
+ }
343
+ }
344
+ }
345
+ // Soft fold drift check
346
+ const folded = foldEvents(allEvents);
347
+ for (const [id, ps] of Object.entries(state.phases)) {
348
+ const f = folded.phases[id];
349
+ if (!f || f.status === "pending" || f.status === "running")
350
+ continue;
351
+ if (ps.timedOut && f.status === "timedOut")
352
+ continue;
353
+ if (String(ps.status) === String(f.status))
354
+ continue;
355
+ if (ps.status === "done" && f.status === "blocked")
356
+ continue; // fold gate intermediate
357
+ console.warn(`[taskflow] event-kernel fold status drift phase=${id} state=${ps.status} fold=${f.status}`);
358
+ }
359
+ const anyFailed = Object.entries(state.phases).some(([id, p]) => p.status === "failed" && !byId.get(id)?.optional);
360
+ const finals = def.phases.filter((p) => p.final);
361
+ const finalPhase = finals[finals.length - 1] ?? def.phases[def.phases.length - 1];
362
+ let finalState = finalPhase ? state.phases[finalPhase.id] : undefined;
363
+ if (!finalState || finalState.status !== "done") {
364
+ const doneInOrder = def.phases.map((p) => state.phases[p.id]).filter((p) => p?.status === "done");
365
+ if (doneInOrder.length)
366
+ finalState = doneInOrder[doneInOrder.length - 1];
367
+ }
368
+ let finalOutput = finalState?.output ?? "";
369
+ if (gateBlocked) {
370
+ finalOutput = `Gate blocked the workflow.${gateReason ? `\nReason: ${gateReason}` : ""}${finalOutput ? `\n\n${finalOutput}` : ""}`;
371
+ }
372
+ else if (budgetBlocked) {
373
+ finalOutput = `Budget exceeded — run halted.${budgetReason ? `\nReason: ${budgetReason}` : ""}${finalOutput ? `\n\n${finalOutput}` : ""}`;
374
+ }
375
+ // Match imperative priority: aborted → gate/budget blocked → failed → completed
376
+ state.status = deps.signal?.aborted
377
+ ? "paused"
378
+ : gateBlocked || budgetBlocked
379
+ ? "blocked"
380
+ : anyFailed
381
+ ? "failed"
382
+ : "completed";
383
+ const totalUsage = aggregateUsage(Object.values(state.phases).map((p) => p.usage ?? emptyUsage()));
384
+ try {
385
+ deps.persist?.(state);
386
+ }
387
+ catch {
388
+ /* ignore */
389
+ }
390
+ return {
391
+ state,
392
+ finalOutput,
393
+ ok: state.status === "completed",
394
+ totalUsage,
395
+ };
396
+ }
397
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/exec/driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Event Log Schema — the future event-sourced kernel.
3
+ *
4
+ * This module defines the **append-only event log** schema that the batch-2
5
+ * event-sourced driver (Q8) will write to. It is a **versioned extension** of
6
+ * the current `TraceEvent` shape (`../trace.ts`): `Event = TraceEvent & { v }`.
7
+ *
8
+ * **Why this exists**: The batch-2 event-sourced kernel needs an explicit,
9
+ * versioned event schema that (a) can subsume trace.ts, (b) carries a `v`
10
+ * field so future schema migrations are unambiguous on disk, and (c) provides
11
+ * a back-compat reader that upgrades legacy trace.jsonl lines on the fly.
12
+ *
13
+ * **Single source of truth**: `Event` / `EventDecision` / `EventKind` are
14
+ * type aliases over `TraceEvent` / `TraceDecision` — never a parallel copy —
15
+ * so adding a decision variant or field in `trace.ts` automatically lands
16
+ * here (no dual-schema drift).
17
+ *
18
+ * **F3 dissolution**: the 5 currently-unemitted trace decisions
19
+ * (gate-score, budget-hit, cache-hit, when-guard, unreplayable) dissolve here:
20
+ * the event-sourced driver (batch 2) will emit *every* decision by
21
+ * construction — this module is the log schema + version + back-compat.
22
+ * Once batch 2 lands, this module subsumes trace.ts entirely (see §0.2.0 Roadmap).
23
+ *
24
+ * Pure types + parser: no IO, no randomness. Missing `ts` on upgrade uses `0`
25
+ * (not `Date.now()`) so upgrade is deterministic for replay.
26
+ */
27
+ import type { TraceEvent, TraceDecision } from "../trace.ts";
28
+ /** Current event log schema version. Incremented on breaking changes. */
29
+ export declare const EVENT_SCHEMA_VERSION = 1;
30
+ /**
31
+ * Discriminated event kind — identical to TraceEvent's `kind` union.
32
+ * A versioned Event carries a `v` field so a consumer can detect schema
33
+ * drift without inspecting fields.
34
+ */
35
+ export type EventKind = TraceEvent["kind"];
36
+ /** Discriminated record of a runtime decision — alias of TraceDecision. */
37
+ export type EventDecision = TraceDecision;
38
+ /**
39
+ * A single event in the append-only event log. Structurally identical to
40
+ * {@link TraceEvent} with an explicit `v` field for schema versioning.
41
+ *
42
+ * The batch-2 event-sourced driver (Q8) will emit these directly; legacy
43
+ * trace.jsonl lines are upgraded via {@link upgradeTraceEvent}.
44
+ */
45
+ export type Event = TraceEvent & {
46
+ /** Schema version (see {@link EVENT_SCHEMA_VERSION}). */
47
+ v: number;
48
+ };
49
+ /**
50
+ * Accept any object shape that overlaps with the legacy TraceEvent fields
51
+ * and stamp `v=` {@link EVENT_SCHEMA_VERSION} onto it. This is deliberately
52
+ * lenient — a legacy trace.jsonl line may have extra / missing fields.
53
+ *
54
+ * **Design note (§8 back-compat)**: old trace.jsonl files have no `v` field.
55
+ * This shim stamps the current schema version onto any missing event so that
56
+ * the batch-2 event-sourced consumer can read both old and new records
57
+ * through the same `Event` interface. When the schema version bumps, this
58
+ * function is where the migration logic lives.
59
+ *
60
+ * **Determinism**: missing `ts` becomes `0`, never `Date.now()` — the same
61
+ * corrupt line upgrades to the same bytes every time (replay-safe).
62
+ */
63
+ export declare function upgradeTraceEvent(old: Record<string, unknown>): Event;
64
+ /**
65
+ * Parse an event log JSONL text into an array of {@link Event}s.
66
+ *
67
+ * **Partial-line tolerance**: any line that fails JSON.parse is silently
68
+ * skipped (fail-open), matching trace.ts's `readTrace` behaviour. This
69
+ * handles crash-truncated final records gracefully.
70
+ *
71
+ * **Versionless line upgrade**: any line whose parsed object lacks a `v`
72
+ * field is routed through {@link upgradeTraceEvent} to stamp the current
73
+ * schema version — so old trace.jsonl data is readable without migration.
74
+ */
75
+ export declare function readEvents(text: string): Event[];
76
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/exec/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAM7D,yEAAyE;AACzE,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAMtC;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAE3C,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG;IAChC,yDAAyD;IACzD,CAAC,EAAE,MAAM,CAAC;CACV,CAAC;AAMF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAqBrE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,CAqBhD"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Event Log Schema — the future event-sourced kernel.
3
+ *
4
+ * This module defines the **append-only event log** schema that the batch-2
5
+ * event-sourced driver (Q8) will write to. It is a **versioned extension** of
6
+ * the current `TraceEvent` shape (`../trace.ts`): `Event = TraceEvent & { v }`.
7
+ *
8
+ * **Why this exists**: The batch-2 event-sourced kernel needs an explicit,
9
+ * versioned event schema that (a) can subsume trace.ts, (b) carries a `v`
10
+ * field so future schema migrations are unambiguous on disk, and (c) provides
11
+ * a back-compat reader that upgrades legacy trace.jsonl lines on the fly.
12
+ *
13
+ * **Single source of truth**: `Event` / `EventDecision` / `EventKind` are
14
+ * type aliases over `TraceEvent` / `TraceDecision` — never a parallel copy —
15
+ * so adding a decision variant or field in `trace.ts` automatically lands
16
+ * here (no dual-schema drift).
17
+ *
18
+ * **F3 dissolution**: the 5 currently-unemitted trace decisions
19
+ * (gate-score, budget-hit, cache-hit, when-guard, unreplayable) dissolve here:
20
+ * the event-sourced driver (batch 2) will emit *every* decision by
21
+ * construction — this module is the log schema + version + back-compat.
22
+ * Once batch 2 lands, this module subsumes trace.ts entirely (see §0.2.0 Roadmap).
23
+ *
24
+ * Pure types + parser: no IO, no randomness. Missing `ts` on upgrade uses `0`
25
+ * (not `Date.now()`) so upgrade is deterministic for replay.
26
+ */
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+ // Schema version
29
+ // ─────────────────────────────────────────────────────────────────────────────
30
+ /** Current event log schema version. Incremented on breaking changes. */
31
+ export const EVENT_SCHEMA_VERSION = 1;
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+ // Back-compat: upgrading legacy TraceEvent → Event
34
+ // ─────────────────────────────────────────────────────────────────────────────
35
+ /**
36
+ * Accept any object shape that overlaps with the legacy TraceEvent fields
37
+ * and stamp `v=` {@link EVENT_SCHEMA_VERSION} onto it. This is deliberately
38
+ * lenient — a legacy trace.jsonl line may have extra / missing fields.
39
+ *
40
+ * **Design note (§8 back-compat)**: old trace.jsonl files have no `v` field.
41
+ * This shim stamps the current schema version onto any missing event so that
42
+ * the batch-2 event-sourced consumer can read both old and new records
43
+ * through the same `Event` interface. When the schema version bumps, this
44
+ * function is where the migration logic lives.
45
+ *
46
+ * **Determinism**: missing `ts` becomes `0`, never `Date.now()` — the same
47
+ * corrupt line upgrades to the same bytes every time (replay-safe).
48
+ */
49
+ export function upgradeTraceEvent(old) {
50
+ return {
51
+ v: EVENT_SCHEMA_VERSION,
52
+ ts: typeof old.ts === "number" ? old.ts : 0,
53
+ runId: typeof old.runId === "string" ? old.runId : "",
54
+ phaseId: typeof old.phaseId === "string" ? old.phaseId : "",
55
+ kind: ["phase-start", "phase-end", "subagent-call", "decision"].includes(old.kind)
56
+ ? old.kind
57
+ : "phase-start",
58
+ dependencies: Array.isArray(old.dependencies)
59
+ ? old.dependencies.filter((x) => typeof x === "string")
60
+ : undefined,
61
+ optional: old.optional === true,
62
+ input: old.input,
63
+ output: old.output,
64
+ decision: old.decision,
65
+ status: old.status,
66
+ error: typeof old.error === "string" ? old.error : undefined,
67
+ };
68
+ }
69
+ // ─────────────────────────────────────────────────────────────────────────────
70
+ // Reader (partial-line tolerant, upgrades versionless lines)
71
+ // ─────────────────────────────────────────────────────────────────────────────
72
+ /**
73
+ * Parse an event log JSONL text into an array of {@link Event}s.
74
+ *
75
+ * **Partial-line tolerance**: any line that fails JSON.parse is silently
76
+ * skipped (fail-open), matching trace.ts's `readTrace` behaviour. This
77
+ * handles crash-truncated final records gracefully.
78
+ *
79
+ * **Versionless line upgrade**: any line whose parsed object lacks a `v`
80
+ * field is routed through {@link upgradeTraceEvent} to stamp the current
81
+ * schema version — so old trace.jsonl data is readable without migration.
82
+ */
83
+ export function readEvents(text) {
84
+ const out = [];
85
+ const lines = text.split("\n");
86
+ for (const line of lines) {
87
+ const trimmed = line.trim();
88
+ if (!trimmed)
89
+ continue;
90
+ try {
91
+ const parsed = JSON.parse(trimmed);
92
+ if (typeof parsed.v === "number") {
93
+ // Already versioned — trust schema (double-cast via `unknown` since a
94
+ // JSON-parsed record can't be proven to overlap with `Event`).
95
+ out.push(parsed);
96
+ }
97
+ else {
98
+ // Legacy line — upgrade via back-compat shim.
99
+ out.push(upgradeTraceEvent(parsed));
100
+ }
101
+ }
102
+ catch {
103
+ // Partial / corrupt line — skip (fail-open).
104
+ }
105
+ }
106
+ return out;
107
+ }
108
+ //# sourceMappingURL=events.js.map