@osolmaz/pi-workflows 0.1.0 → 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 +36 -21
- package/dist/extension/executor.d.ts +14 -1
- package/dist/extension/executor.js +11 -1
- package/dist/extension/executor.js.map +1 -1
- package/dist/extension/index.js +79 -7
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +85 -0
- package/dist/extension/recorder.js +525 -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/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/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 +2 -0
- package/dist/workflows/engine.js +38 -7
- package/dist/workflows/engine.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/store.d.ts +53 -9
- package/dist/workflows/store.js +523 -43
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +126 -3
- package/docs/development.md +43 -19
- package/docs/live-replay-protocol.md +155 -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 +320 -55
- package/docs/session-event-journal.md +470 -0
- package/docs/tui-viewer.md +218 -0
- package/package.json +2 -1
- package/src/extension/executor.ts +28 -1
- package/src/extension/index.ts +87 -7
- package/src/extension/recorder.ts +633 -0
- package/src/extension/session-events.ts +119 -0
- package/src/extension/widget.ts +26 -24
- package/src/render/canvas.ts +19 -1
- package/src/render/graph-render.ts +277 -44
- 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 +39 -7
- package/src/workflows/index.ts +15 -0
- package/src/workflows/store.ts +649 -49
- package/src/workflows/types.ts +141 -3
package/src/workflows/types.ts
CHANGED
|
@@ -153,6 +153,34 @@ export type WorkflowDefinition = {
|
|
|
153
153
|
|
|
154
154
|
export type WorkflowNodeOutcome = "ok" | "timed_out" | "failed" | "cancelled";
|
|
155
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Reference to a content-addressed file under the bundle's `artifacts/`
|
|
158
|
+
* directory. Large string leaves inside persisted values are replaced by
|
|
159
|
+
* `{ "$artifact": ArtifactRef }` at write time (see `docs/run-bundles.md`).
|
|
160
|
+
*/
|
|
161
|
+
export type ArtifactRef = {
|
|
162
|
+
/** Bundle-relative path, `artifacts/sha256-<64 hex>.txt`. */
|
|
163
|
+
path: string;
|
|
164
|
+
mediaType: string;
|
|
165
|
+
bytes: number;
|
|
166
|
+
/** Hex digest of the artifact bytes. */
|
|
167
|
+
sha256: string;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/** The sentinel wrapper that replaces an externalized value. */
|
|
171
|
+
export type ArtifactValue = { $artifact: ArtifactRef };
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Explicit linkage from a workflow attempt to the Pi conversation slice it
|
|
175
|
+
* produced. Ids address entries in `session/entries.ndjson` by Pi entry id.
|
|
176
|
+
*/
|
|
177
|
+
export type ConversationRange = {
|
|
178
|
+
/** First Pi session entry id of the attempt. */
|
|
179
|
+
firstEntryId: string;
|
|
180
|
+
/** Last Pi session entry id of the attempt, inclusive. */
|
|
181
|
+
lastEntryId: string;
|
|
182
|
+
};
|
|
183
|
+
|
|
156
184
|
export type WorkflowNodeResult = {
|
|
157
185
|
attemptId: string;
|
|
158
186
|
nodeId: string;
|
|
@@ -182,10 +210,16 @@ export type WorkflowStepRecord = {
|
|
|
182
210
|
outcome: WorkflowNodeOutcome;
|
|
183
211
|
startedAt: string;
|
|
184
212
|
finishedAt: string;
|
|
185
|
-
|
|
213
|
+
/**
|
|
214
|
+
* Full prompt text for agent steps, `null` for other node types. In a
|
|
215
|
+
* persisted bundle a large prompt may be an `ArtifactValue`.
|
|
216
|
+
*/
|
|
217
|
+
prompt: string | ArtifactValue | null;
|
|
186
218
|
output: unknown;
|
|
187
219
|
error?: string;
|
|
188
220
|
action?: WorkflowActionReceipt;
|
|
221
|
+
/** For agent steps recorded inside a Pi conversation. */
|
|
222
|
+
conversation?: ConversationRange;
|
|
189
223
|
};
|
|
190
224
|
|
|
191
225
|
export type WorkflowRunStatus =
|
|
@@ -197,6 +231,13 @@ export type WorkflowRunStatus =
|
|
|
197
231
|
| "cancelled";
|
|
198
232
|
|
|
199
233
|
export type WorkflowRunState = {
|
|
234
|
+
schema: "pi-workflows.run-state.v1";
|
|
235
|
+
/**
|
|
236
|
+
* `seq` of the trace event this projection reflects. `trace.ndjson` is the
|
|
237
|
+
* source of truth; a state whose `traceSeq` is older than the trace tail is
|
|
238
|
+
* a stale projection.
|
|
239
|
+
*/
|
|
240
|
+
traceSeq: number;
|
|
200
241
|
runId: string;
|
|
201
242
|
workflowName: string;
|
|
202
243
|
runTitle?: string;
|
|
@@ -211,7 +252,6 @@ export type WorkflowRunState = {
|
|
|
211
252
|
steps: WorkflowStepRecord[];
|
|
212
253
|
currentNode?: string;
|
|
213
254
|
currentAttemptId?: string;
|
|
214
|
-
currentNodeType?: WorkflowNodeDefinition["nodeType"];
|
|
215
255
|
currentNodeStartedAt?: string;
|
|
216
256
|
statusDetail?: string;
|
|
217
257
|
/** True while the run is held at a step boundary by a pause request. */
|
|
@@ -241,7 +281,7 @@ export type WorkflowDefinitionSnapshot = {
|
|
|
241
281
|
export type WorkflowTraceEvent = {
|
|
242
282
|
seq: number;
|
|
243
283
|
at: string;
|
|
244
|
-
scope: "run" | "node" | "agent" | "action";
|
|
284
|
+
scope: "run" | "node" | "agent" | "action" | "session";
|
|
245
285
|
type: string;
|
|
246
286
|
runId: string;
|
|
247
287
|
nodeId?: string;
|
|
@@ -249,6 +289,77 @@ export type WorkflowTraceEvent = {
|
|
|
249
289
|
payload: Record<string, unknown>;
|
|
250
290
|
};
|
|
251
291
|
|
|
292
|
+
/** `session/binding.json`: written once when a run binds to a conversation. */
|
|
293
|
+
export type WorkflowSessionBinding = {
|
|
294
|
+
schema: "pi-workflows.session-binding.v1";
|
|
295
|
+
runId: string;
|
|
296
|
+
/** Pi session UUID. */
|
|
297
|
+
piSessionId: string;
|
|
298
|
+
/**
|
|
299
|
+
* Absolute path of the Pi session file; provenance only, never read back.
|
|
300
|
+
* Absent for in-memory sessions.
|
|
301
|
+
*/
|
|
302
|
+
piSessionFile?: string;
|
|
303
|
+
/** Working directory of the conversation. */
|
|
304
|
+
cwd: string;
|
|
305
|
+
boundAt: string;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* One line of `session/entries.ndjson`: a verbatim Pi session entry recorded
|
|
310
|
+
* while the run was active. The inner entry shape is owned by Pi.
|
|
311
|
+
*/
|
|
312
|
+
export type WorkflowSessionEntryRecord = {
|
|
313
|
+
/** Starts at 1, increases by exactly 1 within the file. */
|
|
314
|
+
seq: number;
|
|
315
|
+
/** When the entry was recorded into the bundle. */
|
|
316
|
+
at: string;
|
|
317
|
+
/** Verbatim Pi session entry (has its own id/parentId/timestamp). */
|
|
318
|
+
entry: Record<string, unknown>;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
export type WorkflowSessionEventType =
|
|
322
|
+
| "turn_started"
|
|
323
|
+
| "turn_finished"
|
|
324
|
+
| "message_started"
|
|
325
|
+
| "assistant_event"
|
|
326
|
+
| "message_finished"
|
|
327
|
+
| "tool_execution_started"
|
|
328
|
+
| "tool_execution_updated"
|
|
329
|
+
| "tool_execution_finished";
|
|
330
|
+
|
|
331
|
+
/** One normalized temporal Pi event in `session/events.ndjson`. */
|
|
332
|
+
export type WorkflowSessionEventRecord = {
|
|
333
|
+
/** Starts at 1 and increases by exactly 1 within the file. */
|
|
334
|
+
seq: number;
|
|
335
|
+
/** Time when the extension received the public Pi event. */
|
|
336
|
+
at: string;
|
|
337
|
+
nodeId: string;
|
|
338
|
+
attemptId: string;
|
|
339
|
+
turnId?: string;
|
|
340
|
+
messageId?: string;
|
|
341
|
+
toolCallId?: string;
|
|
342
|
+
type: WorkflowSessionEventType;
|
|
343
|
+
payload: Record<string, unknown>;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
export type WorkflowSessionCaptureFailure = {
|
|
347
|
+
failedAt: string;
|
|
348
|
+
code: string;
|
|
349
|
+
message: string;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
/** Atomic integrity projection for the temporal session journal. */
|
|
353
|
+
export type WorkflowSessionCapture = {
|
|
354
|
+
schema: "pi-workflows.session-capture.v1";
|
|
355
|
+
eventSchema: "pi-workflows.session-event.v1";
|
|
356
|
+
status: "recording" | "complete" | "failed";
|
|
357
|
+
eventCount: number;
|
|
358
|
+
entryCount: number;
|
|
359
|
+
lastEventSeq: number;
|
|
360
|
+
failure?: WorkflowSessionCaptureFailure;
|
|
361
|
+
};
|
|
362
|
+
|
|
252
363
|
export type WorkflowTraceEventDraft = Omit<WorkflowTraceEvent, "seq" | "at" | "runId">;
|
|
253
364
|
|
|
254
365
|
export type WorkflowRunManifest = {
|
|
@@ -265,6 +376,10 @@ export type WorkflowRunManifest = {
|
|
|
265
376
|
workflow: string;
|
|
266
377
|
state: string;
|
|
267
378
|
trace: string;
|
|
379
|
+
/** Bundle-relative session directory, present once a session is bound. */
|
|
380
|
+
session?: string;
|
|
381
|
+
/** Bundle-relative artifacts directory, present once a value was externalized. */
|
|
382
|
+
artifacts?: string;
|
|
268
383
|
};
|
|
269
384
|
};
|
|
270
385
|
|
|
@@ -294,6 +409,11 @@ export type AgentStepRequest = {
|
|
|
294
409
|
|
|
295
410
|
export type AgentStepSubmission = {
|
|
296
411
|
output: unknown;
|
|
412
|
+
/**
|
|
413
|
+
* The Pi conversation slice this step produced, when the executor records
|
|
414
|
+
* one. Persisted verbatim into the step record and terminal node event.
|
|
415
|
+
*/
|
|
416
|
+
conversation?: ConversationRange;
|
|
297
417
|
};
|
|
298
418
|
|
|
299
419
|
/**
|
|
@@ -309,6 +429,24 @@ export type WorkflowEngineOptions = {
|
|
|
309
429
|
executor: AgentStepExecutor;
|
|
310
430
|
/** Root directory for run bundles. Defaults to `~/.pi/agent/workflows/runs`. */
|
|
311
431
|
outputRoot?: string;
|
|
432
|
+
/**
|
|
433
|
+
* Shared run store. Pass the same instance used by a session recorder so
|
|
434
|
+
* trace sequence numbers stay single-writer. Defaults to a new store on
|
|
435
|
+
* `outputRoot`.
|
|
436
|
+
*/
|
|
437
|
+
store?: import("./store.js").WorkflowRunStore;
|
|
438
|
+
/**
|
|
439
|
+
* Awaited after `run_started` is persisted, before any node executes. This
|
|
440
|
+
* is where a session recorder binds, so `session_bound` lands at the start
|
|
441
|
+
* of the trace and can never trail the terminal event.
|
|
442
|
+
*/
|
|
443
|
+
onRunStarted?: (runDir: string, state: WorkflowRunState) => MaybePromise<void>;
|
|
444
|
+
/**
|
|
445
|
+
* Awaited before the terminal snapshot is persisted. This is where a
|
|
446
|
+
* session recorder stops and drains, so the bundle is immutable the moment
|
|
447
|
+
* the terminal event exists. Errors are swallowed: finishing the run wins.
|
|
448
|
+
*/
|
|
449
|
+
onRunFinishing?: (runDir: string, state: WorkflowRunState) => MaybePromise<void>;
|
|
312
450
|
/** Default per-node timeout. Defaults to 15 minutes. */
|
|
313
451
|
defaultNodeTimeoutMs?: number;
|
|
314
452
|
/** Guard against unbounded graph loops. Defaults to 100 executed steps. */
|