@osolmaz/pi-workflows 0.1.0 → 0.3.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 +107 -26
- package/dist/builtins/monitor.workflow.d.ts +71 -0
- package/dist/builtins/monitor.workflow.js +234 -0
- package/dist/builtins/monitor.workflow.js.map +1 -0
- package/dist/controllers/conditions.d.ts +6 -0
- package/dist/controllers/conditions.js +68 -0
- package/dist/controllers/conditions.js.map +1 -0
- package/dist/controllers/definition.d.ts +6 -0
- package/dist/controllers/definition.js +45 -0
- package/dist/controllers/definition.js.map +1 -0
- package/dist/controllers/effects.d.ts +14 -0
- package/dist/controllers/effects.js +104 -0
- package/dist/controllers/effects.js.map +1 -0
- package/dist/controllers/errors.d.ts +12 -0
- package/dist/controllers/errors.js +25 -0
- package/dist/controllers/errors.js.map +1 -0
- package/dist/controllers/index.d.ts +13 -0
- package/dist/controllers/index.js +13 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/json.d.ts +5 -0
- package/dist/controllers/json.js +57 -0
- package/dist/controllers/json.js.map +1 -0
- package/dist/controllers/loader.d.ts +23 -0
- package/dist/controllers/loader.js +74 -0
- package/dist/controllers/loader.js.map +1 -0
- package/dist/controllers/manager.d.ts +58 -0
- package/dist/controllers/manager.js +399 -0
- package/dist/controllers/manager.js.map +1 -0
- package/dist/controllers/results.d.ts +5 -0
- package/dist/controllers/results.js +32 -0
- package/dist/controllers/results.js.map +1 -0
- package/dist/controllers/sqlite.d.ts +212 -0
- package/dist/controllers/sqlite.js +1009 -0
- package/dist/controllers/sqlite.js.map +1 -0
- package/dist/controllers/store.d.ts +112 -0
- package/dist/controllers/store.js +32 -0
- package/dist/controllers/store.js.map +1 -0
- package/dist/controllers/types.d.ts +159 -0
- package/dist/controllers/types.js +2 -0
- package/dist/controllers/types.js.map +1 -0
- package/dist/controllers/workflow-engine-scheduler.d.ts +25 -0
- package/dist/controllers/workflow-engine-scheduler.js +93 -0
- package/dist/controllers/workflow-engine-scheduler.js.map +1 -0
- package/dist/controllers/workflows.d.ts +27 -0
- package/dist/controllers/workflows.js +109 -0
- package/dist/controllers/workflows.js.map +1 -0
- package/dist/extension/controller-host.d.ts +47 -0
- package/dist/extension/controller-host.js +110 -0
- package/dist/extension/controller-host.js.map +1 -0
- package/dist/extension/executor.d.ts +14 -1
- package/dist/extension/executor.js +12 -2
- package/dist/extension/executor.js.map +1 -1
- package/dist/extension/index.d.ts +7 -0
- package/dist/extension/index.js +1118 -89
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +91 -0
- package/dist/extension/recorder.js +537 -0
- package/dist/extension/recorder.js.map +1 -0
- package/dist/extension/session-events.d.ts +134 -0
- package/dist/extension/session-events.js +60 -0
- package/dist/extension/session-events.js.map +1 -0
- package/dist/extension/widget.js +25 -24
- package/dist/extension/widget.js.map +1 -1
- package/dist/extension/workflow-tool.d.ts +28 -0
- package/dist/extension/workflow-tool.js +33 -0
- package/dist/extension/workflow-tool.js.map +1 -0
- package/dist/host/processes.d.ts +24 -0
- package/dist/host/processes.js +114 -0
- package/dist/host/processes.js.map +1 -0
- package/dist/host/rpc-bridge.d.ts +9 -0
- package/dist/host/rpc-bridge.js +39 -0
- package/dist/host/rpc-bridge.js.map +1 -0
- package/dist/host/rpc-executor.d.ts +38 -0
- package/dist/host/rpc-executor.js +254 -0
- package/dist/host/rpc-executor.js.map +1 -0
- package/dist/host/runner.d.ts +49 -0
- package/dist/host/runner.js +350 -0
- package/dist/host/runner.js.map +1 -0
- package/dist/render/canvas.d.ts +1 -1
- package/dist/render/canvas.js +5 -0
- package/dist/render/canvas.js.map +1 -1
- package/dist/render/graph-render.d.ts +5 -0
- package/dist/render/graph-render.js +211 -48
- package/dist/render/graph-render.js.map +1 -1
- package/dist/viewer/cli.d.ts +7 -3
- package/dist/viewer/cli.js +150 -19
- package/dist/viewer/cli.js.map +1 -1
- package/dist/viewer/render.js +19 -3
- package/dist/viewer/render.js.map +1 -1
- package/dist/viewer/session-reducer.d.ts +45 -0
- package/dist/viewer/session-reducer.js +266 -0
- package/dist/viewer/session-reducer.js.map +1 -0
- package/dist/workflows/artifacts.d.ts +40 -0
- package/dist/workflows/artifacts.js +155 -0
- package/dist/workflows/artifacts.js.map +1 -0
- package/dist/workflows/engine.d.ts +38 -0
- package/dist/workflows/engine.js +281 -20
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +23 -0
- package/dist/workflows/errors.js +38 -0
- package/dist/workflows/errors.js.map +1 -1
- package/dist/workflows/graph.js +0 -5
- package/dist/workflows/graph.js.map +1 -1
- package/dist/workflows/index.d.ts +3 -2
- package/dist/workflows/index.js +2 -1
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/loader.d.ts +5 -3
- package/dist/workflows/loader.js +10 -1
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/schema.js +1 -1
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.d.ts +98 -10
- package/dist/workflows/store.js +921 -46
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +136 -3
- package/docs/CONTROLLERS.md +215 -0
- package/docs/development.md +51 -24
- package/docs/live-replay-protocol.md +155 -0
- package/docs/plans/2026-08-04-controller-runtime-plan.md +169 -0
- package/docs/plans/2026-08-05-always-on-workflows-plan.md +125 -0
- package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +184 -0
- package/docs/plans/piw-viewer-experience-implementation-plan.md +674 -0
- package/docs/plans/replayable-run-bundles-implementation-plan.md +65 -0
- package/docs/plans/session-event-replay-implementation-plan.md +494 -0
- package/docs/plans/tui-viewer-implementation-plan.md +64 -0
- package/docs/run-bundles.md +359 -55
- package/docs/session-event-journal.md +470 -0
- package/docs/tui-viewer.md +218 -0
- package/docs/workflows.md +131 -11
- package/examples/controllers/pull-request.controller.ts +215 -0
- package/package.json +11 -2
- package/src/builtins/monitor.workflow.ts +278 -0
- package/src/controllers/conditions.ts +110 -0
- package/src/controllers/definition.ts +65 -0
- package/src/controllers/effects.ts +123 -0
- package/src/controllers/errors.ts +27 -0
- package/src/controllers/index.ts +90 -0
- package/src/controllers/json.ts +62 -0
- package/src/controllers/loader.ts +104 -0
- package/src/controllers/manager.ts +533 -0
- package/src/controllers/results.ts +46 -0
- package/src/controllers/sqlite.ts +1427 -0
- package/src/controllers/store.ts +160 -0
- package/src/controllers/types.ts +183 -0
- package/src/controllers/workflow-engine-scheduler.ts +145 -0
- package/src/controllers/workflows.ts +152 -0
- package/src/extension/controller-host.ts +163 -0
- package/src/extension/executor.ts +29 -2
- package/src/extension/index.ts +1315 -109
- package/src/extension/recorder.ts +662 -0
- package/src/extension/session-events.ts +119 -0
- package/src/extension/widget.ts +26 -24
- package/src/extension/workflow-tool.ts +59 -0
- package/src/host/processes.ts +119 -0
- package/src/host/rpc-bridge.ts +44 -0
- package/src/host/rpc-executor.ts +299 -0
- package/src/host/runner.ts +406 -0
- package/src/render/canvas.ts +19 -1
- package/src/render/graph-render.ts +277 -44
- package/src/viewer/cli.ts +167 -21
- package/src/viewer/render.ts +21 -3
- package/src/viewer/session-reducer.ts +347 -0
- package/src/workflows/artifacts.ts +188 -0
- package/src/workflows/engine.ts +365 -19
- package/src/workflows/errors.ts +45 -0
- package/src/workflows/graph.ts +0 -5
- package/src/workflows/index.ts +15 -0
- package/src/workflows/loader.ts +13 -3
- package/src/workflows/schema.ts +1 -1
- package/src/workflows/store.ts +1157 -48
- package/src/workflows/types.ts +151 -3
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
function payloadString(payload, key) {
|
|
2
|
+
const value = payload[key];
|
|
3
|
+
return typeof value === "string" ? value : undefined;
|
|
4
|
+
}
|
|
5
|
+
function payloadIndex(payload) {
|
|
6
|
+
const value = payload.contentIndex;
|
|
7
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : undefined;
|
|
8
|
+
}
|
|
9
|
+
function ensureBlock(message, contentIndex, kind) {
|
|
10
|
+
const existing = message.blocks.get(contentIndex);
|
|
11
|
+
if (existing) {
|
|
12
|
+
return existing;
|
|
13
|
+
}
|
|
14
|
+
const block = { contentIndex, kind, text: "" };
|
|
15
|
+
message.blocks.set(contentIndex, block);
|
|
16
|
+
return block;
|
|
17
|
+
}
|
|
18
|
+
function entryIds(entries) {
|
|
19
|
+
return new Set(entries.flatMap((record) => {
|
|
20
|
+
const id = record.entry.id;
|
|
21
|
+
return typeof id === "string" ? [id] : [];
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
function foldSessionEvents(entries, events, throughSeq, initial) {
|
|
25
|
+
const messages = new Map();
|
|
26
|
+
const messageOrder = [];
|
|
27
|
+
for (const message of initial?.messages ?? []) {
|
|
28
|
+
messages.set(message.messageId, {
|
|
29
|
+
...message,
|
|
30
|
+
blocks: new Map(message.blocks.map((block) => [block.contentIndex, { ...block }])),
|
|
31
|
+
});
|
|
32
|
+
messageOrder.push(message.messageId);
|
|
33
|
+
}
|
|
34
|
+
const tools = new Map();
|
|
35
|
+
const toolOrder = [];
|
|
36
|
+
for (const tool of initial?.tools ?? []) {
|
|
37
|
+
tools.set(tool.toolCallId, { ...tool });
|
|
38
|
+
toolOrder.push(tool.toolCallId);
|
|
39
|
+
}
|
|
40
|
+
const settledEntryIds = [...(initial?.settledEntryIds ?? [])];
|
|
41
|
+
const knownEntries = entryIds(entries);
|
|
42
|
+
const diagnostics = [...(initial?.diagnostics ?? [])];
|
|
43
|
+
let expectedSeq = (initial?.throughSeq ?? 0) + 1;
|
|
44
|
+
let lastSeq = initial?.throughSeq ?? 0;
|
|
45
|
+
for (const event of events) {
|
|
46
|
+
if (event.seq <= lastSeq) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (event.seq > throughSeq) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (event.seq !== expectedSeq) {
|
|
53
|
+
diagnostics.push(`session event sequence gap at ${expectedSeq}`);
|
|
54
|
+
expectedSeq = event.seq;
|
|
55
|
+
}
|
|
56
|
+
expectedSeq += 1;
|
|
57
|
+
lastSeq = event.seq;
|
|
58
|
+
switch (event.type) {
|
|
59
|
+
case "message_started": {
|
|
60
|
+
if (!event.messageId) {
|
|
61
|
+
diagnostics.push(`message_started ${event.seq} has no messageId`);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
if (!messages.has(event.messageId)) {
|
|
65
|
+
messages.set(event.messageId, {
|
|
66
|
+
messageId: event.messageId,
|
|
67
|
+
role: payloadString(event.payload, "role") ?? "unknown",
|
|
68
|
+
status: "streaming",
|
|
69
|
+
blocks: new Map(),
|
|
70
|
+
});
|
|
71
|
+
messageOrder.push(event.messageId);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "assistant_event": {
|
|
76
|
+
if (!event.messageId) {
|
|
77
|
+
diagnostics.push(`assistant_event ${event.seq} has no messageId`);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const message = messages.get(event.messageId);
|
|
81
|
+
if (!message) {
|
|
82
|
+
diagnostics.push(`assistant_event ${event.seq} precedes message_started`);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
const assistantType = payloadString(event.payload, "type");
|
|
86
|
+
const contentIndex = payloadIndex(event.payload);
|
|
87
|
+
if (contentIndex !== undefined &&
|
|
88
|
+
(assistantType === "text_start" ||
|
|
89
|
+
assistantType === "thinking_start" ||
|
|
90
|
+
assistantType === "toolcall_start")) {
|
|
91
|
+
ensureBlock(message, contentIndex, assistantType === "text_start"
|
|
92
|
+
? "text"
|
|
93
|
+
: assistantType === "thinking_start"
|
|
94
|
+
? "thinking"
|
|
95
|
+
: "toolCall");
|
|
96
|
+
}
|
|
97
|
+
else if (contentIndex !== undefined &&
|
|
98
|
+
(assistantType === "text_delta" ||
|
|
99
|
+
assistantType === "thinking_delta" ||
|
|
100
|
+
assistantType === "toolcall_delta")) {
|
|
101
|
+
const block = ensureBlock(message, contentIndex, assistantType === "text_delta"
|
|
102
|
+
? "text"
|
|
103
|
+
: assistantType === "thinking_delta"
|
|
104
|
+
? "thinking"
|
|
105
|
+
: "toolCall");
|
|
106
|
+
block.text += payloadString(event.payload, "delta") ?? "";
|
|
107
|
+
}
|
|
108
|
+
else if (contentIndex !== undefined &&
|
|
109
|
+
(assistantType === "text_end" || assistantType === "thinking_end")) {
|
|
110
|
+
const block = ensureBlock(message, contentIndex, assistantType === "text_end" ? "text" : "thinking");
|
|
111
|
+
const content = payloadString(event.payload, "content") ?? "";
|
|
112
|
+
if (block.text !== content) {
|
|
113
|
+
diagnostics.push(`${assistantType} mismatch for ${event.messageId}:${contentIndex}`);
|
|
114
|
+
block.text = content;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else if (contentIndex !== undefined && assistantType === "toolcall_end") {
|
|
118
|
+
const block = ensureBlock(message, contentIndex, "toolCall");
|
|
119
|
+
block.value = event.payload.toolCall;
|
|
120
|
+
}
|
|
121
|
+
else if (assistantType === "done") {
|
|
122
|
+
message.status = "finished";
|
|
123
|
+
}
|
|
124
|
+
else if (assistantType === "error") {
|
|
125
|
+
message.status = "error";
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case "message_finished": {
|
|
130
|
+
if (!event.messageId) {
|
|
131
|
+
diagnostics.push(`message_finished ${event.seq} has no messageId`);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
const message = messages.get(event.messageId);
|
|
135
|
+
if (!message) {
|
|
136
|
+
diagnostics.push(`message_finished ${event.seq} precedes message_started`);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
const settled = event.payload.settled === true;
|
|
140
|
+
const entryId = payloadString(event.payload, "entryId");
|
|
141
|
+
if (settled && entryId) {
|
|
142
|
+
message.status = "settled";
|
|
143
|
+
message.entryId = entryId;
|
|
144
|
+
settledEntryIds.push(entryId);
|
|
145
|
+
if (!knownEntries.has(entryId)) {
|
|
146
|
+
diagnostics.push(`settled entry ${entryId} is missing`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
message.status = "unsettled";
|
|
151
|
+
}
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "tool_execution_started": {
|
|
155
|
+
if (!event.toolCallId || !event.messageId) {
|
|
156
|
+
diagnostics.push(`tool_execution_started ${event.seq} is uncorrelated`);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
const tool = {
|
|
160
|
+
toolCallId: event.toolCallId,
|
|
161
|
+
messageId: event.messageId,
|
|
162
|
+
toolName: payloadString(event.payload, "toolName") ?? "tool",
|
|
163
|
+
status: "running",
|
|
164
|
+
updates: 0,
|
|
165
|
+
...(event.payload.args === undefined ? {} : { args: event.payload.args }),
|
|
166
|
+
};
|
|
167
|
+
tools.set(event.toolCallId, tool);
|
|
168
|
+
toolOrder.push(event.toolCallId);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case "tool_execution_updated": {
|
|
172
|
+
const tool = event.toolCallId ? tools.get(event.toolCallId) : undefined;
|
|
173
|
+
if (tool) {
|
|
174
|
+
tool.updates += 1;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
diagnostics.push(`tool_execution_updated ${event.seq} precedes start`);
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case "tool_execution_finished": {
|
|
182
|
+
const tool = event.toolCallId ? tools.get(event.toolCallId) : undefined;
|
|
183
|
+
if (!tool) {
|
|
184
|
+
diagnostics.push(`tool_execution_finished ${event.seq} precedes start`);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
tool.status = event.payload.isError === true ? "failed" : "finished";
|
|
188
|
+
if (event.payload.result !== undefined) {
|
|
189
|
+
tool.result = event.payload.result;
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case "turn_started":
|
|
194
|
+
case "turn_finished":
|
|
195
|
+
break;
|
|
196
|
+
default:
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
throughSeq: lastSeq,
|
|
202
|
+
messages: messageOrder.map((messageId) => {
|
|
203
|
+
const message = messages.get(messageId);
|
|
204
|
+
return {
|
|
205
|
+
messageId: message.messageId,
|
|
206
|
+
role: message.role,
|
|
207
|
+
status: message.status,
|
|
208
|
+
...(message.entryId === undefined ? {} : { entryId: message.entryId }),
|
|
209
|
+
blocks: [...message.blocks.values()].toSorted((left, right) => left.contentIndex - right.contentIndex),
|
|
210
|
+
};
|
|
211
|
+
}),
|
|
212
|
+
tools: toolOrder.map((toolCallId) => tools.get(toolCallId)),
|
|
213
|
+
settledEntryIds,
|
|
214
|
+
diagnostics,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/** Fold the durable semantic journal through one sequence position. */
|
|
218
|
+
export function reduceSessionEvents(entries, events, throughSeq = Number.MAX_SAFE_INTEGER) {
|
|
219
|
+
return foldSessionEvents(entries, events, throughSeq);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* In-memory seek index. Checkpoints are viewer-only cache state and are never
|
|
223
|
+
* persisted into a run bundle.
|
|
224
|
+
*/
|
|
225
|
+
export class SessionReplayIndex {
|
|
226
|
+
entries;
|
|
227
|
+
events;
|
|
228
|
+
checkpoints = [];
|
|
229
|
+
timestamps;
|
|
230
|
+
constructor(entries, events, checkpointInterval = 256) {
|
|
231
|
+
this.entries = entries;
|
|
232
|
+
this.events = events;
|
|
233
|
+
let lastTimestamp = Number.NEGATIVE_INFINITY;
|
|
234
|
+
this.timestamps = events.map((event) => {
|
|
235
|
+
const parsed = Date.parse(event.at);
|
|
236
|
+
lastTimestamp = Math.max(lastTimestamp, Number.isFinite(parsed) ? parsed : lastTimestamp);
|
|
237
|
+
return { at: lastTimestamp, seq: event.seq };
|
|
238
|
+
});
|
|
239
|
+
let state = foldSessionEvents(entries, events, 0);
|
|
240
|
+
this.checkpoints.push({ seq: 0, state });
|
|
241
|
+
for (let end = checkpointInterval - 1; end < events.length; end += checkpointInterval) {
|
|
242
|
+
const seq = events[end]?.seq ?? state.throughSeq;
|
|
243
|
+
state = foldSessionEvents(entries, events, seq, state);
|
|
244
|
+
this.checkpoints.push({ seq, state });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
stateAtSeq(throughSeq) {
|
|
248
|
+
const checkpoint = this.checkpoints.findLast(({ seq }) => seq <= throughSeq);
|
|
249
|
+
return foldSessionEvents(this.entries, this.events, throughSeq, checkpoint?.state);
|
|
250
|
+
}
|
|
251
|
+
seqAtOrBefore(timestampMs) {
|
|
252
|
+
let low = 0;
|
|
253
|
+
let high = this.timestamps.length;
|
|
254
|
+
while (low < high) {
|
|
255
|
+
const middle = (low + high) >>> 1;
|
|
256
|
+
if ((this.timestamps[middle]?.at ?? Number.POSITIVE_INFINITY) <= timestampMs) {
|
|
257
|
+
low = middle + 1;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
high = middle;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return low === 0 ? 0 : (this.timestamps[low - 1]?.seq ?? 0);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=session-reducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-reducer.js","sourceRoot":"","sources":["../../src/viewer/session-reducer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ArtifactRef, ArtifactValue } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Value externalization for run bundles (see docs/run-bundles.md): string
|
|
4
|
+
* leaves larger than the threshold are written once, content-addressed, under
|
|
5
|
+
* `artifacts/` and replaced by `{ "$artifact": ref }`. Because artifacts are
|
|
6
|
+
* immutable and deduplicated by hash, the same output appearing in `outputs`,
|
|
7
|
+
* `results`, `steps`, and the trace costs one file plus small references.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ARTIFACT_THRESHOLD_BYTES = 4096;
|
|
10
|
+
export declare const ARTIFACTS_DIR = "artifacts";
|
|
11
|
+
export declare function isArtifactValue(value: unknown): value is ArtifactValue;
|
|
12
|
+
/**
|
|
13
|
+
* Writes externalized string leaves for one run bundle. Instances serialize
|
|
14
|
+
* their writes and deduplicate by content hash, so encoding the same large
|
|
15
|
+
* string in several value positions touches the filesystem once.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ArtifactWriter {
|
|
18
|
+
private readonly runDir;
|
|
19
|
+
private readonly written;
|
|
20
|
+
private chain;
|
|
21
|
+
private dirCreated;
|
|
22
|
+
constructor(runDir: string);
|
|
23
|
+
/** True once any artifact exists for this run. */
|
|
24
|
+
get hasArtifacts(): boolean;
|
|
25
|
+
externalize(text: string): Promise<ArtifactValue>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Encode a persisted value: externalize large string leaves and escape
|
|
29
|
+
* single-key `$artifact`/`$escaped` objects so the sentinel stays
|
|
30
|
+
* unambiguous. Returns the original value when nothing changed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function encodeValue(value: unknown, writer: ArtifactWriter, thresholdBytes?: number): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Walk a persisted value, replacing every `$artifact` sentinel via `resolve`
|
|
35
|
+
* and unwrapping `$escaped` objects. `resolve` may return the artifact
|
|
36
|
+
* contents or a placeholder; it receives the reference untouched.
|
|
37
|
+
*/
|
|
38
|
+
export declare function decodeValueWith(value: unknown, resolve: (ref: ArtifactRef) => unknown): unknown;
|
|
39
|
+
/** Resolve every artifact reference in `value` by reading the bundle files. */
|
|
40
|
+
export declare function resolveArtifacts(value: unknown, runDir: string): Promise<unknown>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Value externalization for run bundles (see docs/run-bundles.md): string
|
|
6
|
+
* leaves larger than the threshold are written once, content-addressed, under
|
|
7
|
+
* `artifacts/` and replaced by `{ "$artifact": ref }`. Because artifacts are
|
|
8
|
+
* immutable and deduplicated by hash, the same output appearing in `outputs`,
|
|
9
|
+
* `results`, `steps`, and the trace costs one file plus small references.
|
|
10
|
+
*/
|
|
11
|
+
export const ARTIFACT_THRESHOLD_BYTES = 4096;
|
|
12
|
+
export const ARTIFACTS_DIR = "artifacts";
|
|
13
|
+
const ARTIFACT_KEY = "$artifact";
|
|
14
|
+
const ESCAPED_KEY = "$escaped";
|
|
15
|
+
export function isArtifactValue(value) {
|
|
16
|
+
return (typeof value === "object" &&
|
|
17
|
+
value !== null &&
|
|
18
|
+
!Array.isArray(value) &&
|
|
19
|
+
Object.keys(value).length === 1 &&
|
|
20
|
+
ARTIFACT_KEY in value);
|
|
21
|
+
}
|
|
22
|
+
function isEscapedValue(value) {
|
|
23
|
+
return (typeof value === "object" &&
|
|
24
|
+
value !== null &&
|
|
25
|
+
!Array.isArray(value) &&
|
|
26
|
+
Object.keys(value).length === 1 &&
|
|
27
|
+
ESCAPED_KEY in value);
|
|
28
|
+
}
|
|
29
|
+
/** True for a single-key object that would be misread as a sentinel. */
|
|
30
|
+
function needsEscape(value) {
|
|
31
|
+
const keys = Object.keys(value);
|
|
32
|
+
return keys.length === 1 && (keys[0] === ARTIFACT_KEY || keys[0] === ESCAPED_KEY);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Writes externalized string leaves for one run bundle. Instances serialize
|
|
36
|
+
* their writes and deduplicate by content hash, so encoding the same large
|
|
37
|
+
* string in several value positions touches the filesystem once.
|
|
38
|
+
*/
|
|
39
|
+
export class ArtifactWriter {
|
|
40
|
+
runDir;
|
|
41
|
+
written = new Set();
|
|
42
|
+
chain = Promise.resolve();
|
|
43
|
+
dirCreated = false;
|
|
44
|
+
constructor(runDir) {
|
|
45
|
+
this.runDir = runDir;
|
|
46
|
+
}
|
|
47
|
+
/** True once any artifact exists for this run. */
|
|
48
|
+
get hasArtifacts() {
|
|
49
|
+
return this.written.size > 0;
|
|
50
|
+
}
|
|
51
|
+
async externalize(text) {
|
|
52
|
+
const bytes = Buffer.from(text, "utf8");
|
|
53
|
+
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
54
|
+
const relativePath = `${ARTIFACTS_DIR}/sha256-${sha256}.txt`;
|
|
55
|
+
const task = this.chain.then(async () => {
|
|
56
|
+
if (this.written.has(sha256)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!this.dirCreated) {
|
|
60
|
+
await fs.mkdir(path.join(this.runDir, ARTIFACTS_DIR), { recursive: true, mode: 0o700 });
|
|
61
|
+
this.dirCreated = true;
|
|
62
|
+
}
|
|
63
|
+
const filePath = path.join(this.runDir, relativePath);
|
|
64
|
+
// Content-addressed files are immutable; an existing file is complete
|
|
65
|
+
// unless a previous crash left a partial write, which the temp-rename
|
|
66
|
+
// pattern prevents.
|
|
67
|
+
const tempPath = `${filePath}.${process.pid}.tmp`;
|
|
68
|
+
await fs.writeFile(tempPath, bytes, { mode: 0o600 });
|
|
69
|
+
await fs.rename(tempPath, filePath);
|
|
70
|
+
this.written.add(sha256);
|
|
71
|
+
});
|
|
72
|
+
this.chain = task.catch(() => undefined);
|
|
73
|
+
await task;
|
|
74
|
+
return {
|
|
75
|
+
$artifact: {
|
|
76
|
+
path: relativePath,
|
|
77
|
+
mediaType: "text/plain",
|
|
78
|
+
bytes: bytes.byteLength,
|
|
79
|
+
sha256,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Encode a persisted value: externalize large string leaves and escape
|
|
86
|
+
* single-key `$artifact`/`$escaped` objects so the sentinel stays
|
|
87
|
+
* unambiguous. Returns the original value when nothing changed.
|
|
88
|
+
*/
|
|
89
|
+
export async function encodeValue(value, writer, thresholdBytes = ARTIFACT_THRESHOLD_BYTES) {
|
|
90
|
+
if (typeof value === "string") {
|
|
91
|
+
if (Buffer.byteLength(value, "utf8") <= thresholdBytes) {
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
return await writer.externalize(value);
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
const encoded = await Promise.all(value.map((item) => encodeValue(item, writer, thresholdBytes)));
|
|
98
|
+
return encoded.some((item, index) => item !== value[index]) ? encoded : value;
|
|
99
|
+
}
|
|
100
|
+
if (typeof value === "object" && value !== null) {
|
|
101
|
+
const record = value;
|
|
102
|
+
const entries = await Promise.all(Object.entries(record).map(async ([key, item]) => [key, await encodeValue(item, writer, thresholdBytes)]));
|
|
103
|
+
const changed = entries.some(([key, item]) => item !== record[key]);
|
|
104
|
+
const encoded = changed ? Object.fromEntries(entries) : record;
|
|
105
|
+
return needsEscape(record) ? { [ESCAPED_KEY]: encoded } : encoded;
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Walk a persisted value, replacing every `$artifact` sentinel via `resolve`
|
|
111
|
+
* and unwrapping `$escaped` objects. `resolve` may return the artifact
|
|
112
|
+
* contents or a placeholder; it receives the reference untouched.
|
|
113
|
+
*/
|
|
114
|
+
export function decodeValueWith(value, resolve) {
|
|
115
|
+
if (isArtifactValue(value)) {
|
|
116
|
+
return resolve(value.$artifact);
|
|
117
|
+
}
|
|
118
|
+
if (isEscapedValue(value)) {
|
|
119
|
+
// The unwrapped object is user data: process its children but do not
|
|
120
|
+
// re-test the object itself as a sentinel.
|
|
121
|
+
return decodeChildren(value.$escaped, resolve);
|
|
122
|
+
}
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
return value.map((item) => decodeValueWith(item, resolve));
|
|
125
|
+
}
|
|
126
|
+
if (typeof value === "object" && value !== null) {
|
|
127
|
+
return decodeChildren(value, resolve);
|
|
128
|
+
}
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
function decodeChildren(record, resolve) {
|
|
132
|
+
return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeValueWith(item, resolve)]));
|
|
133
|
+
}
|
|
134
|
+
/** Resolve every artifact reference in `value` by reading the bundle files. */
|
|
135
|
+
export async function resolveArtifacts(value, runDir) {
|
|
136
|
+
const refs = [];
|
|
137
|
+
decodeValueWith(value, (ref) => {
|
|
138
|
+
refs.push(ref);
|
|
139
|
+
return null;
|
|
140
|
+
});
|
|
141
|
+
const contents = new Map();
|
|
142
|
+
for (const ref of refs) {
|
|
143
|
+
if (contents.has(ref.path)) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const resolved = path.resolve(runDir, ref.path);
|
|
147
|
+
// A reference must never escape the bundle directory.
|
|
148
|
+
if (!resolved.startsWith(path.resolve(runDir) + path.sep)) {
|
|
149
|
+
throw new Error(`Artifact path escapes the bundle: ${ref.path}`);
|
|
150
|
+
}
|
|
151
|
+
contents.set(ref.path, await fs.readFile(resolved, "utf8"));
|
|
152
|
+
}
|
|
153
|
+
return decodeValueWith(value, (ref) => contents.get(ref.path) ?? null);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/workflows/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,14 +11,23 @@ export declare class WorkflowEngine {
|
|
|
11
11
|
private readonly defaultNodeTimeoutMs;
|
|
12
12
|
private readonly maxSteps;
|
|
13
13
|
private readonly onEvent?;
|
|
14
|
+
private readonly onRunStarted?;
|
|
15
|
+
private readonly onRunFinishing?;
|
|
14
16
|
private activeAbort;
|
|
15
17
|
private cancelled;
|
|
18
|
+
private parked;
|
|
16
19
|
private paused;
|
|
17
20
|
private wakePause;
|
|
18
21
|
constructor(options: WorkflowEngineOptions);
|
|
19
22
|
get outputRoot(): string;
|
|
20
23
|
/** Abort the currently running node and mark the run cancelled. */
|
|
21
24
|
cancel(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Stop without a terminal event so another runner can claim and resume
|
|
27
|
+
* the run. The active node aborts; its partial attempt is never recorded,
|
|
28
|
+
* so resume reruns that node from its last persisted boundary.
|
|
29
|
+
*/
|
|
30
|
+
park(): void;
|
|
22
31
|
/**
|
|
23
32
|
* Request a pause. The current step finishes normally; the engine then
|
|
24
33
|
* holds before dispatching the next node until `resume` (or `cancel`).
|
|
@@ -30,7 +39,36 @@ export declare class WorkflowEngine {
|
|
|
30
39
|
get pauseRequested(): boolean;
|
|
31
40
|
run(workflow: WorkflowDefinition, input: unknown, options?: {
|
|
32
41
|
workflowPath?: string;
|
|
42
|
+
workflowHash?: string;
|
|
43
|
+
runId?: string;
|
|
44
|
+
}): Promise<WorkflowRunResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Resume an interrupted run at the node it stopped on. The caller must
|
|
47
|
+
* hold the run's queue claim. Completed nodes replay from the recorded
|
|
48
|
+
* state; only the interrupted node and everything downstream rerun.
|
|
49
|
+
*/
|
|
50
|
+
resumeRun(workflow: WorkflowDefinition, runId: string, options?: {
|
|
51
|
+
workflowHash?: string;
|
|
52
|
+
force?: boolean;
|
|
33
53
|
}): Promise<WorkflowRunResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Start a continuation run from a checkpointed parent. The new run gets a
|
|
56
|
+
* fresh bundle and trace, carries forward the parent's outputs, results,
|
|
57
|
+
* and step accounting, and continues routing after the checkpoint.
|
|
58
|
+
*/
|
|
59
|
+
continueRun(workflow: WorkflowDefinition, parentRunId: string, input: unknown, options?: {
|
|
60
|
+
workflowPath?: string;
|
|
61
|
+
workflowHash?: string;
|
|
62
|
+
runId?: string;
|
|
63
|
+
force?: boolean;
|
|
64
|
+
}): Promise<WorkflowRunResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Find where a resumed run continues. An in-flight node reruns; otherwise
|
|
67
|
+
* routing continues from the last recorded step. A null nodeId means the
|
|
68
|
+
* graph was already done when the crash hit.
|
|
69
|
+
*/
|
|
70
|
+
private resumePointFor;
|
|
71
|
+
private finishAfterError;
|
|
34
72
|
/**
|
|
35
73
|
* Resolve the run title inside a cancellation and timeout boundary. This
|
|
36
74
|
* runs before any node abort controller exists, so without it a hung async
|