taskflow-core 0.1.8 → 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.
- package/README.md +80 -25
- package/dist/deterministic.d.ts +8 -0
- package/dist/deterministic.d.ts.map +1 -1
- package/dist/deterministic.js +23 -1
- package/dist/deterministic.js.map +1 -1
- package/dist/exec/driver.d.ts +47 -0
- package/dist/exec/driver.d.ts.map +1 -0
- package/dist/exec/driver.js +397 -0
- package/dist/exec/driver.js.map +1 -0
- package/dist/exec/events.d.ts +76 -0
- package/dist/exec/events.d.ts.map +1 -0
- package/dist/exec/events.js +108 -0
- package/dist/exec/events.js.map +1 -0
- package/dist/exec/fold.d.ts +45 -0
- package/dist/exec/fold.d.ts.map +1 -0
- package/dist/exec/fold.js +122 -0
- package/dist/exec/fold.js.map +1 -0
- package/dist/exec/index.d.ts +17 -0
- package/dist/exec/index.d.ts.map +1 -0
- package/dist/exec/index.js +17 -0
- package/dist/exec/index.js.map +1 -0
- package/dist/exec/kernel-policy.d.ts +35 -0
- package/dist/exec/kernel-policy.d.ts.map +1 -0
- package/dist/exec/kernel-policy.js +184 -0
- package/dist/exec/kernel-policy.js.map +1 -0
- package/dist/exec/step-kinds.d.ts +41 -0
- package/dist/exec/step-kinds.d.ts.map +1 -0
- package/dist/exec/step-kinds.js +574 -0
- package/dist/exec/step-kinds.js.map +1 -0
- package/dist/exec/step.d.ts +93 -0
- package/dist/exec/step.d.ts.map +1 -0
- package/dist/exec/step.js +436 -0
- package/dist/exec/step.js.map +1 -0
- package/dist/flowir/canonical-hash.d.ts +101 -0
- package/dist/flowir/canonical-hash.d.ts.map +1 -0
- package/dist/flowir/canonical-hash.js +219 -0
- package/dist/flowir/canonical-hash.js.map +1 -0
- package/dist/flowir/compile.d.ts +49 -0
- package/dist/flowir/compile.d.ts.map +1 -0
- package/dist/flowir/compile.js +219 -0
- package/dist/flowir/compile.js.map +1 -0
- package/dist/flowir/cond.d.ts +76 -0
- package/dist/flowir/cond.d.ts.map +1 -0
- package/dist/flowir/cond.js +214 -0
- package/dist/flowir/cond.js.map +1 -0
- package/dist/flowir/index.d.ts +20 -23
- package/dist/flowir/index.d.ts.map +1 -1
- package/dist/flowir/index.js +47 -35
- package/dist/flowir/index.js.map +1 -1
- package/dist/flowir/meta.d.ts +4 -4
- package/dist/flowir/meta.d.ts.map +1 -1
- package/dist/flowir/phasefp.d.ts.map +1 -1
- package/dist/flowir/phasefp.js +13 -1
- package/dist/flowir/phasefp.js.map +1 -1
- package/dist/flowir/schema.d.ts +260 -0
- package/dist/flowir/schema.d.ts.map +1 -0
- package/dist/flowir/schema.js +234 -0
- package/dist/flowir/schema.js.map +1 -0
- package/dist/flowir/translate.d.ts.map +1 -1
- package/dist/flowir/translate.js +3 -0
- package/dist/flowir/translate.js.map +1 -1
- package/dist/host/runner-types.d.ts +3 -0
- package/dist/host/runner-types.d.ts.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/rates.d.ts +121 -0
- package/dist/rates.d.ts.map +1 -0
- package/dist/rates.js +187 -0
- package/dist/rates.js.map +1 -0
- package/dist/replay.d.ts +43 -50
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +629 -19
- package/dist/replay.js.map +1 -1
- package/dist/runner-core.d.ts +24 -0
- package/dist/runner-core.d.ts.map +1 -1
- package/dist/runner-core.js +225 -32
- package/dist/runner-core.js.map +1 -1
- package/dist/runtime/phases/approval.d.ts +23 -0
- package/dist/runtime/phases/approval.d.ts.map +1 -0
- package/dist/runtime/phases/approval.js +38 -0
- package/dist/runtime/phases/approval.js.map +1 -0
- package/dist/runtime/phases/expand.d.ts +29 -0
- package/dist/runtime/phases/expand.d.ts.map +1 -0
- package/dist/runtime/phases/expand.js +126 -0
- package/dist/runtime/phases/expand.js.map +1 -0
- package/dist/runtime/phases/parallel.d.ts +26 -0
- package/dist/runtime/phases/parallel.d.ts.map +1 -0
- package/dist/runtime/phases/parallel.js +15 -0
- package/dist/runtime/phases/parallel.js.map +1 -0
- package/dist/runtime/phases/race.d.ts +31 -0
- package/dist/runtime/phases/race.d.ts.map +1 -0
- package/dist/runtime/phases/race.js +220 -0
- package/dist/runtime/phases/race.js.map +1 -0
- package/dist/runtime/phases/script.d.ts +38 -0
- package/dist/runtime/phases/script.d.ts.map +1 -0
- package/dist/runtime/phases/script.js +139 -0
- package/dist/runtime/phases/script.js.map +1 -0
- package/dist/runtime.d.ts +29 -16
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +554 -292
- package/dist/runtime.js.map +1 -1
- package/dist/schema.d.ts +36 -4
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +86 -10
- package/dist/schema.js.map +1 -1
- package/dist/store.d.ts +6 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/trace.d.ts +4 -1
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js +33 -26
- package/dist/trace.js.map +1 -1
- package/package.json +5 -4
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/exec/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AA4BtC,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAA4B;IAC7D,OAAO;QACN,CAAC,EAAE,oBAAoB;QACvB,EAAE,EAAE,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACrD,OAAO,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QAC3D,IAAI,EAAG,CAAC,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,CAAW,CAAC,QAAQ,CAClF,GAAG,CAAC,IAAiB,CACrB;YACA,CAAC,CAAE,GAAG,CAAC,IAAkB;YACzB,CAAC,CAAC,aAAa;QAChB,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAC5C,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACpE,CAAC,CAAC,SAAS;QACZ,QAAQ,EAAE,GAAG,CAAC,QAAQ,KAAK,IAAI;QAC/B,KAAK,EAAE,GAAG,CAAC,KAAuB;QAClC,MAAM,EAAE,GAAG,CAAC,MAAyB;QACrC,QAAQ,EAAE,GAAG,CAAC,QAAqC;QACnD,MAAM,EAAE,GAAG,CAAC,MAAyB;QACrC,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KAC5D,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,6DAA6D;AAC7D,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;YAC9D,IAAI,OAAO,MAAM,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAClC,sEAAsE;gBACtE,+DAA+D;gBAC/D,GAAG,CAAC,IAAI,CAAC,MAA0B,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACP,8CAA8C;gBAC9C,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;YACrC,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,6CAA6C;QAC9C,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fold(event log) → RunState-shaped phase snapshot (RFC §6.4, S1).
|
|
3
|
+
*
|
|
4
|
+
* Pure reduce over {@link Event} / legacy TraceEvent-compatible records.
|
|
5
|
+
* Does **not** spawn processes or touch disk. Used by:
|
|
6
|
+
* - S1 differential: assert fold(log) matches phase statuses the imperative
|
|
7
|
+
* runtime would have left in RunState
|
|
8
|
+
* - S3 replay: re-fold under alternate knobs (thresholds/budget) without
|
|
9
|
+
* re-entering the driver
|
|
10
|
+
*
|
|
11
|
+
* Never throws.
|
|
12
|
+
*/
|
|
13
|
+
import type { Event, EventDecision } from "./events.ts";
|
|
14
|
+
import type { UsageStats } from "../usage.ts";
|
|
15
|
+
/** Per-phase folded snapshot (subset of PhaseState the runtime persists). */
|
|
16
|
+
export interface FoldedPhase {
|
|
17
|
+
phaseId: string;
|
|
18
|
+
status: "pending" | "running" | "done" | "failed" | "blocked" | "skipped" | "timedOut";
|
|
19
|
+
/** Last recorded text output (subagent or decision summary). */
|
|
20
|
+
output?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
/** Accumulated usage from subagent-call events. */
|
|
23
|
+
usage: UsageStats;
|
|
24
|
+
/** Last decision event for this phase (gate / when / cache / …). */
|
|
25
|
+
decision?: EventDecision;
|
|
26
|
+
/** Number of subagent-call events seen. */
|
|
27
|
+
subagentCalls: number;
|
|
28
|
+
startedAt?: number;
|
|
29
|
+
endedAt?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Whole-run fold result. */
|
|
32
|
+
export interface FoldedRun {
|
|
33
|
+
runId: string;
|
|
34
|
+
phases: Record<string, FoldedPhase>;
|
|
35
|
+
/** Events that could not be associated with a phaseId (malformed). */
|
|
36
|
+
orphans: number;
|
|
37
|
+
/** Total events folded. */
|
|
38
|
+
eventCount: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reduce an ordered event list into a per-phase snapshot.
|
|
42
|
+
* Accepts {@link Event} (with `v`) or plain TraceEvent-shaped records.
|
|
43
|
+
*/
|
|
44
|
+
export declare function foldEvents(events: readonly Event[]): FoldedRun;
|
|
45
|
+
//# sourceMappingURL=fold.d.ts.map
|