@osolmaz/pi-workflows 0.12.0 → 0.13.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 (257) hide show
  1. package/README.md +56 -31
  2. package/dist/builtins/autodoc.workflow.d.ts +4 -4
  3. package/dist/builtins/autoimplement.workflow.d.ts +797 -142
  4. package/dist/builtins/autoimplement.workflow.js +17 -105
  5. package/dist/builtins/autoimplement.workflow.js.map +1 -1
  6. package/dist/builtins/autoplan.workflow.d.ts +126 -13
  7. package/dist/builtins/autoplan.workflow.js +200 -29
  8. package/dist/builtins/autoplan.workflow.js.map +1 -1
  9. package/dist/builtins/catalog.js +7 -5
  10. package/dist/builtins/catalog.js.map +1 -1
  11. package/dist/builtins/index.d.ts +4 -2
  12. package/dist/builtins/index.js +3 -1
  13. package/dist/builtins/index.js.map +1 -1
  14. package/dist/builtins/monitor.workflow.d.ts +56 -23
  15. package/dist/builtins/monitor.workflow.js +508 -329
  16. package/dist/builtins/monitor.workflow.js.map +1 -1
  17. package/dist/builtins/pi-agent-group.d.ts +72 -0
  18. package/dist/builtins/pi-agent-group.js +1087 -0
  19. package/dist/builtins/pi-agent-group.js.map +1 -0
  20. package/dist/builtins/plain-summary.workflow.d.ts +32 -0
  21. package/dist/builtins/plain-summary.workflow.js +134 -0
  22. package/dist/builtins/plain-summary.workflow.js.map +1 -0
  23. package/dist/builtins/plan-approval.workflow.d.ts +39 -5
  24. package/dist/builtins/plan-approval.workflow.js +92 -14
  25. package/dist/builtins/plan-approval.workflow.js.map +1 -1
  26. package/dist/builtins/plan-change.workflow.d.ts +449 -0
  27. package/dist/builtins/plan-change.workflow.js +256 -0
  28. package/dist/builtins/plan-change.workflow.js.map +1 -0
  29. package/dist/builtins/plan-presentation.js +2 -2
  30. package/dist/builtins/plan-presentation.js.map +1 -1
  31. package/dist/builtins/sanity-check.workflow.d.ts +50 -6
  32. package/dist/builtins/sanity-check.workflow.js +150 -28
  33. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  34. package/dist/controllers/effects.d.ts +3 -2
  35. package/dist/controllers/effects.js +8 -1
  36. package/dist/controllers/effects.js.map +1 -1
  37. package/dist/controllers/index.d.ts +1 -1
  38. package/dist/controllers/index.js +1 -1
  39. package/dist/controllers/index.js.map +1 -1
  40. package/dist/controllers/manager.d.ts +1 -0
  41. package/dist/controllers/manager.js +41 -17
  42. package/dist/controllers/manager.js.map +1 -1
  43. package/dist/controllers/sqlite.d.ts +107 -85
  44. package/dist/controllers/sqlite.js +1611 -1486
  45. package/dist/controllers/sqlite.js.map +1 -1
  46. package/dist/controllers/store.d.ts +9 -8
  47. package/dist/controllers/store.js +1 -31
  48. package/dist/controllers/store.js.map +1 -1
  49. package/dist/controllers/types.d.ts +3 -0
  50. package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
  51. package/dist/controllers/workflow-engine-scheduler.js +3 -5
  52. package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
  53. package/dist/controllers/workflows.d.ts +2 -2
  54. package/dist/controllers/workflows.js +11 -10
  55. package/dist/controllers/workflows.js.map +1 -1
  56. package/dist/extension/controller-host.js +2 -2
  57. package/dist/extension/controller-host.js.map +1 -1
  58. package/dist/extension/decision-channels.d.ts +4 -2
  59. package/dist/extension/decision-channels.js +333 -146
  60. package/dist/extension/decision-channels.js.map +1 -1
  61. package/dist/extension/executor.d.ts +9 -2
  62. package/dist/extension/executor.js +89 -2
  63. package/dist/extension/executor.js.map +1 -1
  64. package/dist/extension/herdr-viewer.d.ts +0 -1
  65. package/dist/extension/herdr-viewer.js +0 -4
  66. package/dist/extension/herdr-viewer.js.map +1 -1
  67. package/dist/extension/index.js +209 -127
  68. package/dist/extension/index.js.map +1 -1
  69. package/dist/extension/recorder.d.ts +3 -10
  70. package/dist/extension/recorder.js +13 -22
  71. package/dist/extension/recorder.js.map +1 -1
  72. package/dist/extension/session-events.d.ts +2 -2
  73. package/dist/extension/step-message.d.ts +7 -2
  74. package/dist/extension/step-message.js +94 -2
  75. package/dist/extension/step-message.js.map +1 -1
  76. package/dist/extension/widget.js +29 -3
  77. package/dist/extension/widget.js.map +1 -1
  78. package/dist/host/rpc-executor.d.ts +3 -0
  79. package/dist/host/rpc-executor.js +2 -0
  80. package/dist/host/rpc-executor.js.map +1 -1
  81. package/dist/host/runner.d.ts +3 -6
  82. package/dist/host/runner.js +83 -32
  83. package/dist/host/runner.js.map +1 -1
  84. package/dist/render/graph-render.js +15 -10
  85. package/dist/render/graph-render.js.map +1 -1
  86. package/dist/state/database.d.ts +35 -0
  87. package/dist/state/database.js +287 -0
  88. package/dist/state/database.js.map +1 -0
  89. package/dist/state/index.d.ts +4 -0
  90. package/dist/state/index.js +5 -0
  91. package/dist/state/index.js.map +1 -0
  92. package/dist/state/json.d.ts +6 -0
  93. package/dist/state/json.js +38 -0
  94. package/dist/state/json.js.map +1 -0
  95. package/dist/state/mutation.d.ts +57 -0
  96. package/dist/state/mutation.js +255 -0
  97. package/dist/state/mutation.js.map +1 -0
  98. package/dist/state/schema.d.ts +6 -0
  99. package/dist/state/schema.js +473 -0
  100. package/dist/state/schema.js.map +1 -0
  101. package/dist/viewer/cli.d.ts +2 -2
  102. package/dist/viewer/cli.js +142 -122
  103. package/dist/viewer/cli.js.map +1 -1
  104. package/dist/viewer/render.d.ts +4 -4
  105. package/dist/viewer/render.js +9 -23
  106. package/dist/viewer/render.js.map +1 -1
  107. package/dist/viewer/session-reducer.d.ts +1 -1
  108. package/dist/viewer/session-reducer.js +1 -1
  109. package/dist/viewer/tui.d.ts +3 -3
  110. package/dist/viewer/tui.js +15 -13
  111. package/dist/viewer/tui.js.map +1 -1
  112. package/dist/viewer/watch.d.ts +2 -5
  113. package/dist/viewer/watch.js +13 -13
  114. package/dist/viewer/watch.js.map +1 -1
  115. package/dist/workflows/catalog.js +7 -2
  116. package/dist/workflows/catalog.js.map +1 -1
  117. package/dist/workflows/composition.js +20 -2
  118. package/dist/workflows/composition.js.map +1 -1
  119. package/dist/workflows/decision-presentation.d.ts +1 -1
  120. package/dist/workflows/decision-presentation.js +51 -38
  121. package/dist/workflows/decision-presentation.js.map +1 -1
  122. package/dist/workflows/definition.d.ts +6 -2
  123. package/dist/workflows/definition.js +17 -0
  124. package/dist/workflows/definition.js.map +1 -1
  125. package/dist/workflows/engine.d.ts +7 -7
  126. package/dist/workflows/engine.js +196 -115
  127. package/dist/workflows/engine.js.map +1 -1
  128. package/dist/workflows/errors.d.ts +16 -3
  129. package/dist/workflows/errors.js +18 -3
  130. package/dist/workflows/errors.js.map +1 -1
  131. package/dist/workflows/human-decision.d.ts +45 -8
  132. package/dist/workflows/human-decision.js +641 -274
  133. package/dist/workflows/human-decision.js.map +1 -1
  134. package/dist/workflows/index.d.ts +5 -6
  135. package/dist/workflows/index.js +4 -5
  136. package/dist/workflows/index.js.map +1 -1
  137. package/dist/workflows/progress.d.ts +1 -0
  138. package/dist/workflows/progress.js +15 -3
  139. package/dist/workflows/progress.js.map +1 -1
  140. package/dist/workflows/schema.js +27 -1
  141. package/dist/workflows/schema.js.map +1 -1
  142. package/dist/workflows/store.d.ts +83 -103
  143. package/dist/workflows/store.js +907 -951
  144. package/dist/workflows/store.js.map +1 -1
  145. package/dist/workflows/types.d.ts +88 -126
  146. package/docs/CONTROLLERS.md +10 -8
  147. package/docs/DEFERRED_TURNS.md +2 -2
  148. package/docs/DESIGN_PHILOSOPHY.md +4 -2
  149. package/docs/HUMAN_DECISIONS.md +36 -47
  150. package/docs/HUMAN_DECISION_PRESENTATIONS.md +14 -24
  151. package/docs/MONITOR.md +179 -237
  152. package/docs/SQLITE_STATE.md +219 -0
  153. package/docs/WORKFLOW_COMPOSITION.md +27 -26
  154. package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
  155. package/docs/WORKFLOW_UPDATES.md +10 -9
  156. package/docs/development.md +9 -9
  157. package/docs/live-replay-protocol.md +28 -37
  158. package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
  159. package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
  160. package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
  161. package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +322 -0
  162. package/docs/plans/2026-08-21-sanity-check-plan.md +217 -95
  163. package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
  164. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
  165. package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
  166. package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
  167. package/docs/plans/session-event-replay-implementation-plan.md +1 -1
  168. package/docs/plans/tui-viewer-implementation-plan.md +1 -1
  169. package/docs/session-event-journal.md +63 -434
  170. package/docs/tui-viewer.md +13 -15
  171. package/docs/workflows.md +127 -53
  172. package/examples/workflows/approved-plan.workflow.ts +19 -46
  173. package/examples/workflows/plain-summary.workflow.ts +1 -0
  174. package/herdr-plugin.toml +1 -1
  175. package/package.json +7 -7
  176. package/plugins/herdr/viewer.mjs +1 -11
  177. package/schemas/human-decision-accepted-v1.schema.json +15 -3
  178. package/schemas/human-decision-continuation-v1.schema.json +10 -1
  179. package/schemas/human-decision-delivery-v1.schema.json +8 -0
  180. package/schemas/human-decision-receipt-v1.schema.json +8 -0
  181. package/schemas/human-decision-request-v1.schema.json +24 -4
  182. package/skills/autoimplement/SKILL.md +27 -0
  183. package/skills/autoplan/SKILL.md +5 -4
  184. package/skills/monitor/SKILL.md +91 -135
  185. package/skills/pi-workflows/SKILL.md +9 -8
  186. package/skills/sanity-check/SKILL.md +44 -0
  187. package/src/builtins/autoimplement.workflow.ts +19 -118
  188. package/src/builtins/autoplan.workflow.ts +290 -40
  189. package/src/builtins/catalog.ts +7 -5
  190. package/src/builtins/index.ts +18 -1
  191. package/src/builtins/monitor.workflow.ts +673 -382
  192. package/src/builtins/pi-agent-group.ts +1407 -0
  193. package/src/builtins/plain-summary.workflow.ts +185 -0
  194. package/src/builtins/plan-approval.workflow.ts +157 -24
  195. package/src/builtins/plan-change.workflow.ts +321 -0
  196. package/src/builtins/plan-presentation.ts +2 -2
  197. package/src/builtins/sanity-check.workflow.ts +248 -48
  198. package/src/controllers/effects.ts +7 -0
  199. package/src/controllers/index.ts +0 -6
  200. package/src/controllers/manager.ts +72 -32
  201. package/src/controllers/sqlite.ts +2420 -1948
  202. package/src/controllers/store.ts +17 -38
  203. package/src/controllers/types.ts +3 -0
  204. package/src/controllers/workflow-engine-scheduler.ts +4 -8
  205. package/src/controllers/workflows.ts +45 -21
  206. package/src/extension/controller-host.ts +1 -2
  207. package/src/extension/decision-channels.ts +456 -203
  208. package/src/extension/executor.ts +105 -2
  209. package/src/extension/herdr-viewer.ts +0 -5
  210. package/src/extension/index.ts +251 -151
  211. package/src/extension/recorder.ts +13 -22
  212. package/src/extension/session-events.ts +2 -2
  213. package/src/extension/step-message.ts +106 -4
  214. package/src/extension/widget.ts +32 -5
  215. package/src/host/rpc-executor.ts +4 -0
  216. package/src/host/runner.ts +93 -41
  217. package/src/render/graph-render.ts +12 -6
  218. package/src/state/database.ts +375 -0
  219. package/src/state/index.ts +29 -0
  220. package/src/state/json.ts +42 -0
  221. package/src/state/mutation.ts +435 -0
  222. package/src/state/schema.ts +475 -0
  223. package/src/viewer/cli.ts +151 -144
  224. package/src/viewer/render.ts +19 -30
  225. package/src/viewer/session-reducer.ts +1 -1
  226. package/src/viewer/tui.ts +18 -17
  227. package/src/viewer/watch.ts +13 -17
  228. package/src/workflows/catalog.ts +7 -2
  229. package/src/workflows/composition.ts +21 -3
  230. package/src/workflows/decision-presentation.ts +56 -43
  231. package/src/workflows/definition.ts +36 -3
  232. package/src/workflows/engine.ts +228 -130
  233. package/src/workflows/errors.ts +27 -3
  234. package/src/workflows/human-decision.ts +921 -349
  235. package/src/workflows/index.ts +20 -30
  236. package/src/workflows/progress.ts +18 -3
  237. package/src/workflows/schema.ts +36 -1
  238. package/src/workflows/store.ts +1300 -1163
  239. package/src/workflows/types.ts +100 -137
  240. package/dist/builtins/sanity-check-session.d.ts +0 -17
  241. package/dist/builtins/sanity-check-session.js +0 -168
  242. package/dist/builtins/sanity-check-session.js.map +0 -1
  243. package/dist/workflows/artifacts.d.ts +0 -40
  244. package/dist/workflows/artifacts.js +0 -155
  245. package/dist/workflows/artifacts.js.map +0 -1
  246. package/dist/workflows/migrate-sources.d.ts +0 -42
  247. package/dist/workflows/migrate-sources.js +0 -133
  248. package/dist/workflows/migrate-sources.js.map +0 -1
  249. package/docs/run-bundles.md +0 -481
  250. package/schemas/human-decision-accepted-v2.schema.json +0 -50
  251. package/schemas/human-decision-delivery-v2.schema.json +0 -36
  252. package/schemas/human-decision-receipt-v2.schema.json +0 -39
  253. package/schemas/human-decision-request-v2.schema.json +0 -69
  254. package/schemas/human-decision-resolution-v2.schema.json +0 -27
  255. package/src/builtins/sanity-check-session.ts +0 -205
  256. package/src/workflows/artifacts.ts +0 -188
  257. package/src/workflows/migrate-sources.ts +0 -178
@@ -1,5 +1,6 @@
1
1
  export {
2
2
  agent,
3
+ assistantMessage,
3
4
  action,
4
5
  checkpoint,
5
6
  compute,
@@ -23,8 +24,8 @@ export {
23
24
  decisionPresentationFingerprint,
24
25
  digestCanonical,
25
26
  humanDecisionChannelRequest,
26
- legacyDecisionPresentation,
27
27
  normalizeDecisionPresentation,
28
+ valueDecisionPresentation,
28
29
  validateHumanDecisionRequestIntegrity,
29
30
  type DecisionDocumentSegment,
30
31
  } from "./decision-presentation.js";
@@ -38,7 +39,7 @@ export {
38
39
  digest,
39
40
  humanDecision,
40
41
  humanDecisionEdge,
41
- humanDecisionStateRoot,
42
+ humanDecisionDatabasePath,
42
43
  textInput,
43
44
  validateHumanDecisionResponse,
44
45
  validateHumanDecisionSubmission,
@@ -112,42 +113,37 @@ export {
112
113
  validateWorkflowUpdate,
113
114
  } from "./updates.js";
114
115
  export { sanitizeText, stripAnsi } from "./text.js";
115
- export {
116
- ARTIFACT_THRESHOLD_BYTES,
117
- ArtifactWriter,
118
- decodeValueWith,
119
- encodeValue,
120
- isArtifactValue,
121
- resolveArtifacts,
122
- } from "./artifacts.js";
123
116
  export {
124
117
  DEFINITION_SNAPSHOT_SCHEMA,
125
- RUN_BUNDLE_SCHEMA,
126
118
  RUN_STATE_SCHEMA,
127
119
  SESSION_BINDING_SCHEMA,
128
- TRACE_EVENT_SCHEMA,
129
120
  WorkflowRunStore,
130
121
  createDefinitionSnapshot,
131
122
  createRunId,
132
- listRunBundles,
133
- readRunBundle,
134
- workflowRunsBaseDir,
135
- type LoadedRunBundle,
136
- type ReadRunBundleOptions,
123
+ listWorkflowRuns,
124
+ readLastTraceEvent,
125
+ readWorkflowRun,
126
+ workflowStateDatabasePath,
127
+ type LoadedWorkflowRun,
128
+ type ReadWorkflowRunOptions,
129
+ type RunWriteAuthority,
137
130
  } from "./store.js";
138
131
  export type {
139
132
  AcceptedHumanDecision,
140
- AcceptedHumanDecisionV1,
141
- AcceptedHumanDecisionV2,
133
+ DefaultedHumanDecision,
134
+ ResolvedHumanDecision,
142
135
  AgentNodeDefinition,
136
+ AgentExpectedOutput,
137
+ AgentStepCompletion,
143
138
  AgentStepContract,
139
+ AssistantAgentNodeDefinition,
140
+ AssistantMessageOutput,
141
+ AssistantMessageReceipt,
144
142
  AgentStepExecutor,
145
143
  AgentStepPresentation,
146
144
  AgentStepRequest,
147
145
  AgentStepSubmission,
148
146
  ActionNodeDefinition,
149
- ArtifactRef,
150
- ArtifactValue,
151
147
  CheckpointNodeDefinition,
152
148
  ConversationRange,
153
149
  ComputeNodeDefinition,
@@ -167,26 +163,21 @@ export type {
167
163
  HumanDecisionChoiceMap,
168
164
  HumanDecisionContinuationRecord,
169
165
  HumanDecisionDeliveryRecord,
170
- HumanDecisionDeliveryRecordV1,
171
- HumanDecisionDeliveryRecordV2,
172
166
  HumanDecisionNodeContract,
173
167
  HumanDecisionPrompt,
174
168
  HumanDecisionReceipt,
175
- HumanDecisionReceiptV1,
176
- HumanDecisionReceiptV2,
177
169
  HumanDecisionRequest,
178
- HumanDecisionRequestV1,
179
- HumanDecisionRequestV2,
180
170
  HumanDecisionResponse,
181
171
  HumanDecisionSettlementRecord,
182
172
  HumanDecisionSubmission,
183
173
  HumanDecisionTextInput,
184
- LegacyHumanDecisionPrompt,
174
+ HumanDecisionTimeout,
175
+ HumanDecisionTimeoutPolicy,
185
176
  MaybePromise,
186
177
  NotifyNodeDefinition,
187
- PresentedHumanDecisionPrompt,
188
178
  ShellActionExecution,
189
179
  ShellActionNodeDefinition,
180
+ SubmittedAgentNodeDefinition,
190
181
  ShellActionResult,
191
182
  WorkflowActionContext,
192
183
  WorkflowActionReceipt,
@@ -216,7 +207,6 @@ export type {
216
207
  WorkflowPresentationContext,
217
208
  WorkflowProgressData,
218
209
  WorkflowProgressStatus,
219
- WorkflowRunManifest,
220
210
  WorkflowRunResult,
221
211
  WorkflowRunState,
222
212
  WorkflowRunStatus,
@@ -18,6 +18,7 @@ export type ProgressEstimate = {
18
18
  confidence?: ProgressConfidence;
19
19
  sourceEstimatedFinishAt?: string;
20
20
  unavailableReason?: string;
21
+ elapsedMs?: number;
21
22
  };
22
23
 
23
24
  export type ProgressSample = {
@@ -42,7 +43,16 @@ export function estimateProgress(
42
43
  for (const sample of samples) validateProgressData(sample.data as Record<string, unknown>);
43
44
  const latest = samples.at(-1) as ProgressSample;
44
45
  const data = latest.data;
45
- const base: ProgressEstimate = { key, data, sampleCount: 1 };
46
+ const firstAt = Date.parse(samples[0]!.at);
47
+ const endAt = TERMINAL.has(data.status) ? Date.parse(latest.at) : now.getTime();
48
+ const elapsedMs =
49
+ Number.isFinite(firstAt) && Number.isFinite(endAt) ? Math.max(0, endAt - firstAt) : undefined;
50
+ const base: ProgressEstimate = {
51
+ key,
52
+ data,
53
+ sampleCount: 1,
54
+ ...(elapsedMs !== undefined ? { elapsedMs } : {}),
55
+ };
46
56
  if (TERMINAL.has(data.status)) return base;
47
57
  const sourceFinish = validSourceFinish(latest, now);
48
58
  if (sourceFinish !== undefined) base.sourceEstimatedFinishAt = sourceFinish;
@@ -212,10 +222,15 @@ export function formatProgressLine(estimate: ProgressEstimate, now = new Date())
212
222
  ? `${formatRemaining(estimate.remainingLowMs)}–${formatRemaining(estimate.remainingHighMs)}`
213
223
  : formatRemaining(estimate.remainingMedianMs);
214
224
  eta = `ETA ${range}`;
215
- } else if (!TERMINAL.has(data.status)) {
225
+ } else if (!TERMINAL.has(data.status) && data.phase === undefined) {
216
226
  eta = `ETA unavailable${estimate.unavailableReason ? ` (${estimate.unavailableReason})` : ""}`;
217
227
  }
218
- return [label, count, eta].filter(Boolean).join(" ");
228
+ const phase = data.phase === undefined ? "" : sanitizeText(data.phase);
229
+ const elapsed =
230
+ data.phase === undefined || estimate.elapsedMs === undefined
231
+ ? ""
232
+ : `elapsed ${formatRemaining(estimate.elapsedMs)}`;
233
+ return [label, count, phase, elapsed, eta].filter(Boolean).join(" ");
219
234
  }
220
235
 
221
236
  export function formatProgressReport(
@@ -51,7 +51,25 @@ export function assertValidAgentNode(node: AgentNodeDefinition, nodeId = "agent"
51
51
  fail(`node ${nodeId} requires a prompt function`);
52
52
  }
53
53
  if (node.expectedOutput !== undefined && typeof node.expectedOutput !== "string") {
54
- fail(`node ${nodeId} expectedOutput must be a string`);
54
+ const output = node.expectedOutput as { kind?: unknown; maxChars?: unknown };
55
+ if (output === null || typeof output !== "object" || output.kind !== "assistant-message") {
56
+ fail(`node ${nodeId} expectedOutput must be a string or assistantMessage()`);
57
+ }
58
+ const unknown = Object.keys(output).filter((key) => key !== "kind" && key !== "maxChars");
59
+ if (unknown.length > 0) {
60
+ fail(`node ${nodeId} assistantMessage has unknown field ${JSON.stringify(unknown[0])}`);
61
+ }
62
+ if (
63
+ output.maxChars !== undefined &&
64
+ (typeof output.maxChars !== "number" ||
65
+ !Number.isInteger(output.maxChars) ||
66
+ output.maxChars <= 0)
67
+ ) {
68
+ fail(`node ${nodeId} assistantMessage maxChars must be a positive integer`);
69
+ }
70
+ if (node.validate !== undefined) {
71
+ fail(`node ${nodeId} cannot use validate with assistantMessage()`);
72
+ }
55
73
  }
56
74
  assertOptionalFunction(node.validate, `node ${nodeId} validate`);
57
75
  assertCommonNodeFields(node, nodeId);
@@ -151,6 +169,23 @@ export function assertValidCheckpointNode(
151
169
  if (typeof node.humanDecision.request !== "function") {
152
170
  fail(`node ${nodeId} humanDecision request must be a function`);
153
171
  }
172
+ if (
173
+ node.humanDecision.onTimeout !== undefined &&
174
+ typeof node.humanDecision.onTimeout !== "function"
175
+ ) {
176
+ assertRecord(node.humanDecision.onTimeout, `node ${nodeId} humanDecision onTimeout`);
177
+ if (
178
+ typeof node.humanDecision.onTimeout.afterMs !== "number" ||
179
+ !Number.isFinite(node.humanDecision.onTimeout.afterMs) ||
180
+ node.humanDecision.onTimeout.afterMs <= 0
181
+ ) {
182
+ fail(`node ${nodeId} humanDecision onTimeout afterMs must be a finite positive number`);
183
+ }
184
+ assertRecord(
185
+ node.humanDecision.onTimeout.response,
186
+ `node ${nodeId} humanDecision onTimeout response`,
187
+ );
188
+ }
154
189
  }
155
190
  assertCommonNodeFields(node, nodeId);
156
191
  }