@osolmaz/pi-workflows 0.15.3 → 0.16.1

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 (207) hide show
  1. package/README.md +24 -8
  2. package/dist/channels/adapter-entry.d.ts +3 -0
  3. package/dist/channels/adapter-entry.js +203 -0
  4. package/dist/channels/adapter-entry.js.map +1 -0
  5. package/dist/channels/config.d.ts +43 -0
  6. package/dist/channels/config.js +234 -0
  7. package/dist/channels/config.js.map +1 -0
  8. package/dist/channels/protocol.d.ts +94 -0
  9. package/dist/channels/protocol.js +219 -0
  10. package/dist/channels/protocol.js.map +1 -0
  11. package/dist/channels/telegram.d.ts +46 -0
  12. package/dist/channels/telegram.js +285 -0
  13. package/dist/channels/telegram.js.map +1 -0
  14. package/dist/client/activity.d.ts +2 -0
  15. package/dist/client/activity.js +6 -0
  16. package/dist/client/activity.js.map +1 -0
  17. package/dist/client/client.d.ts +102 -0
  18. package/dist/client/client.js +737 -0
  19. package/dist/client/client.js.map +1 -0
  20. package/dist/client/index.d.ts +3 -0
  21. package/dist/client/index.js +3 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client/materialize.d.ts +7 -0
  24. package/dist/client/materialize.js +177 -0
  25. package/dist/client/materialize.js.map +1 -0
  26. package/dist/client/protocol.d.ts +60 -0
  27. package/dist/client/protocol.js +275 -0
  28. package/dist/client/protocol.js.map +1 -0
  29. package/dist/client/resolver.d.ts +23 -0
  30. package/dist/client/resolver.js +2 -0
  31. package/dist/client/resolver.js.map +1 -0
  32. package/dist/client/view.d.ts +144 -0
  33. package/dist/client/view.js +3 -0
  34. package/dist/client/view.js.map +1 -0
  35. package/dist/controllers/index.d.ts +1 -1
  36. package/dist/controllers/index.js.map +1 -1
  37. package/dist/controllers/sqlite.d.ts +47 -157
  38. package/dist/controllers/sqlite.js +230 -406
  39. package/dist/controllers/sqlite.js.map +1 -1
  40. package/dist/extension/index.d.ts +23 -1
  41. package/dist/extension/index.js +734 -555
  42. package/dist/extension/index.js.map +1 -1
  43. package/dist/extension/recorder.d.ts +95 -0
  44. package/dist/extension/recorder.js +530 -0
  45. package/dist/extension/recorder.js.map +1 -0
  46. package/dist/extension/remote-recorder-store.d.ts +25 -0
  47. package/dist/extension/remote-recorder-store.js +81 -0
  48. package/dist/extension/remote-recorder-store.js.map +1 -0
  49. package/dist/extension/session-events.d.ts +134 -0
  50. package/dist/extension/session-events.js +60 -0
  51. package/dist/extension/session-events.js.map +1 -0
  52. package/dist/extension/session-view.d.ts +9 -2
  53. package/dist/extension/session-view.js +117 -51
  54. package/dist/extension/session-view.js.map +1 -1
  55. package/dist/extension/step-message.d.ts +6 -4
  56. package/dist/extension/step-message.js +12 -6
  57. package/dist/extension/step-message.js.map +1 -1
  58. package/dist/extension/widget.d.ts +3 -2
  59. package/dist/extension/widget.js +41 -24
  60. package/dist/extension/widget.js.map +1 -1
  61. package/dist/extension/workflow-message-coordinator.d.ts +27 -0
  62. package/dist/extension/workflow-message-coordinator.js +294 -0
  63. package/dist/extension/workflow-message-coordinator.js.map +1 -0
  64. package/dist/host/channel-effects.d.ts +72 -0
  65. package/dist/host/channel-effects.js +271 -0
  66. package/dist/host/channel-effects.js.map +1 -0
  67. package/dist/host/channel-supervisor.d.ts +21 -0
  68. package/dist/host/channel-supervisor.js +54 -0
  69. package/dist/host/channel-supervisor.js.map +1 -0
  70. package/dist/host/child-worker-supervisor.js +1 -1
  71. package/dist/host/child-worker-supervisor.js.map +1 -1
  72. package/dist/host/resolver-entry.d.ts +2 -23
  73. package/dist/host/resolver-entry.js +1 -1
  74. package/dist/host/resolver-entry.js.map +1 -1
  75. package/dist/host/runner.d.ts +54 -8
  76. package/dist/host/runner.js +1997 -305
  77. package/dist/host/runner.js.map +1 -1
  78. package/dist/host/state.d.ts +25 -19
  79. package/dist/host/state.js +303 -89
  80. package/dist/host/state.js.map +1 -1
  81. package/dist/host/view.d.ts +83 -0
  82. package/dist/host/view.js +975 -0
  83. package/dist/host/view.js.map +1 -0
  84. package/dist/host/worker-protocol.js +1 -1
  85. package/dist/host/worker-protocol.js.map +1 -1
  86. package/dist/state/database.d.ts +1 -0
  87. package/dist/state/database.js +15 -0
  88. package/dist/state/database.js.map +1 -1
  89. package/dist/state/prune.d.ts +3 -1
  90. package/dist/state/prune.js +9 -33
  91. package/dist/state/prune.js.map +1 -1
  92. package/dist/state/schema.js +88 -98
  93. package/dist/state/schema.js.map +1 -1
  94. package/dist/state/workflow-messages.d.ts +96 -0
  95. package/dist/state/workflow-messages.js +335 -0
  96. package/dist/state/workflow-messages.js.map +1 -0
  97. package/dist/viewer/backup.d.ts +2 -0
  98. package/dist/viewer/backup.js +28 -0
  99. package/dist/viewer/backup.js.map +1 -0
  100. package/dist/viewer/cli.d.ts +4 -0
  101. package/dist/viewer/cli.js +150 -170
  102. package/dist/viewer/cli.js.map +1 -1
  103. package/dist/viewer/render.js +1 -1
  104. package/dist/viewer/render.js.map +1 -1
  105. package/dist/viewer/tui.d.ts +5 -7
  106. package/dist/viewer/tui.js +245 -108
  107. package/dist/viewer/tui.js.map +1 -1
  108. package/dist/workflows/human-decision.d.ts +2 -0
  109. package/dist/workflows/human-decision.js +8 -2
  110. package/dist/workflows/human-decision.js.map +1 -1
  111. package/dist/workflows/index.d.ts +1 -1
  112. package/dist/workflows/index.js.map +1 -1
  113. package/dist/workflows/settings.d.ts +1 -8
  114. package/dist/workflows/settings.js.map +1 -1
  115. package/dist/workflows/store.d.ts +67 -20
  116. package/dist/workflows/store.js +451 -378
  117. package/dist/workflows/store.js.map +1 -1
  118. package/dist/workflows/tool-input.d.ts +21 -0
  119. package/dist/workflows/tool-input.js +23 -1
  120. package/dist/workflows/tool-input.js.map +1 -1
  121. package/dist/workflows/types.d.ts +5 -5
  122. package/dist/workflows/workflow-message-content.d.ts +38 -0
  123. package/dist/workflows/workflow-message-content.js +157 -0
  124. package/dist/workflows/workflow-message-content.js.map +1 -0
  125. package/docs/2026-08-18-herdr-piw-plan.md +2 -1
  126. package/docs/2026-08-20-durable-workflow-launch-plan.md +1 -1
  127. package/docs/2026-08-25-workflow-follow-ups.md +26 -50
  128. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
  129. package/docs/2026-09-01-restore-session-delivery-controls-plan.md +4 -0
  130. package/docs/2026-09-01-unified-workflow-client-plan.md +385 -0
  131. package/docs/2026-09-02-installed-live-e2e-plan.md +239 -0
  132. package/docs/2026-09-02-unify-workflow-messages-plan.md +562 -0
  133. package/docs/DEFERRED_TURNS.md +66 -294
  134. package/docs/HUMAN_DECISIONS.md +29 -30
  135. package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -11
  136. package/docs/SQLITE_STATE.md +31 -25
  137. package/docs/WORKFLOW_HOST.md +155 -77
  138. package/docs/WORKFLOW_STEP_MESSAGES.md +166 -75
  139. package/docs/development.md +2 -1
  140. package/docs/live-replay-protocol.md +74 -132
  141. package/docs/tui-viewer.md +12 -14
  142. package/docs/workflows.md +78 -28
  143. package/herdr-plugin.toml +1 -1
  144. package/package.json +9 -3
  145. package/plugins/herdr/viewer.mjs +14 -5
  146. package/protocol/client.v1.schema.json +137 -0
  147. package/protocol/fixtures/client-v1.json +23 -0
  148. package/src/channels/adapter-entry.ts +220 -0
  149. package/src/channels/config.ts +296 -0
  150. package/src/channels/protocol.ts +333 -0
  151. package/src/channels/telegram.ts +335 -0
  152. package/src/client/activity.ts +6 -0
  153. package/src/client/client.ts +939 -0
  154. package/src/client/index.ts +25 -0
  155. package/src/client/materialize.ts +228 -0
  156. package/src/client/protocol.ts +333 -0
  157. package/src/client/resolver.ts +26 -0
  158. package/src/client/view.ts +163 -0
  159. package/src/controllers/index.ts +0 -1
  160. package/src/controllers/sqlite.ts +339 -808
  161. package/src/extension/index.ts +853 -665
  162. package/src/extension/recorder.ts +687 -0
  163. package/src/extension/remote-recorder-store.ts +126 -0
  164. package/src/extension/session-events.ts +119 -0
  165. package/src/extension/session-view.ts +157 -51
  166. package/src/extension/step-message.ts +19 -9
  167. package/src/extension/widget.ts +53 -25
  168. package/src/extension/workflow-message-coordinator.ts +334 -0
  169. package/src/host/channel-effects.ts +465 -0
  170. package/src/host/channel-supervisor.ts +73 -0
  171. package/src/host/child-worker-supervisor.ts +1 -1
  172. package/src/host/resolver-entry.ts +11 -26
  173. package/src/host/runner.ts +2639 -450
  174. package/src/host/state.ts +404 -137
  175. package/src/host/view.ts +1212 -0
  176. package/src/host/worker-protocol.ts +1 -1
  177. package/src/state/database.ts +13 -0
  178. package/src/state/prune.ts +14 -42
  179. package/src/state/schema.ts +88 -98
  180. package/src/state/workflow-messages.ts +548 -0
  181. package/src/viewer/backup.ts +29 -0
  182. package/src/viewer/cli.ts +171 -185
  183. package/src/viewer/render.ts +1 -5
  184. package/src/viewer/tui.ts +261 -124
  185. package/src/workflows/human-decision.ts +18 -2
  186. package/src/workflows/index.ts +0 -1
  187. package/src/workflows/settings.ts +1 -20
  188. package/src/workflows/store.ts +650 -511
  189. package/src/workflows/tool-input.ts +36 -1
  190. package/src/workflows/types.ts +5 -5
  191. package/src/workflows/workflow-message-content.ts +197 -0
  192. package/dist/extension/decision-channels.d.ts +0 -134
  193. package/dist/extension/decision-channels.js +0 -1307
  194. package/dist/extension/decision-channels.js.map +0 -1
  195. package/dist/host/client.d.ts +0 -48
  196. package/dist/host/client.js +0 -216
  197. package/dist/host/client.js.map +0 -1
  198. package/dist/host/protocol.d.ts +0 -38
  199. package/dist/host/protocol.js +0 -156
  200. package/dist/host/protocol.js.map +0 -1
  201. package/dist/viewer/watch.d.ts +0 -6
  202. package/dist/viewer/watch.js +0 -46
  203. package/dist/viewer/watch.js.map +0 -1
  204. package/src/extension/decision-channels.ts +0 -1826
  205. package/src/host/client.ts +0 -293
  206. package/src/host/protocol.ts +0 -196
  207. package/src/viewer/watch.ts +0 -51
@@ -54,8 +54,7 @@ CREATE TABLE blobs (
54
54
  CREATE TABLE resources (
55
55
  resource_id TEXT PRIMARY KEY,
56
56
  resource_type TEXT NOT NULL CHECK (resource_type IN (
57
- 'run', 'session', 'decision', 'controller', 'effect', 'channel', 'notification', 'turn_intent',
58
- 'settings', 'follow_up_queue', 'follow_up'
57
+ 'run', 'session', 'decision', 'controller', 'effect', 'channel', 'settings', 'follow_up'
59
58
  )),
60
59
  aggregate_key TEXT NOT NULL,
61
60
  revision INTEGER NOT NULL DEFAULT 0 CHECK (revision >= 0),
@@ -113,6 +112,12 @@ CREATE TABLE runs (
113
112
  resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id) ON DELETE CASCADE,
114
113
  project_id TEXT REFERENCES projects(project_id),
115
114
  parent_run_id TEXT REFERENCES runs(run_id),
115
+ root_run_id TEXT NOT NULL REFERENCES runs(run_id),
116
+ lineage_kind TEXT CHECK (lineage_kind IS NULL OR lineage_kind IN ('continuation', 'restart')),
117
+ restart_number INTEGER NOT NULL DEFAULT 0 CHECK (restart_number >= 0),
118
+ parent_terminal_fingerprint BLOB CHECK (
119
+ parent_terminal_fingerprint IS NULL OR length(parent_terminal_fingerprint) = 32
120
+ ),
116
121
  definition_digest BLOB NOT NULL REFERENCES workflow_definitions(definition_digest),
117
122
  workflow_ref TEXT NOT NULL,
118
123
  launch_options_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
@@ -125,15 +130,35 @@ CREATE TABLE runs (
125
130
  input_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
126
131
  final_output_hash BLOB REFERENCES blobs(blob_hash),
127
132
  error_hash BLOB REFERENCES blobs(blob_hash),
133
+ presentation_prompt_hash BLOB REFERENCES blobs(blob_hash),
128
134
  created_at INTEGER NOT NULL,
129
135
  updated_at INTEGER NOT NULL,
130
136
  finished_at INTEGER,
131
- CHECK ((status IN ('waiting', 'completed', 'failed', 'timed_out', 'cancelled')) = (finished_at IS NOT NULL))
137
+ CHECK ((status IN ('waiting', 'completed', 'failed', 'timed_out', 'cancelled')) = (finished_at IS NOT NULL)),
138
+ CHECK ((parent_run_id IS NULL) = (lineage_kind IS NULL)),
139
+ CHECK (
140
+ (lineage_kind = 'restart' AND parent_terminal_fingerprint IS NOT NULL) OR
141
+ (lineage_kind IS NOT 'restart' AND parent_terminal_fingerprint IS NULL)
142
+ ),
143
+ CHECK (parent_run_id IS NOT NULL OR restart_number = 0)
132
144
  ) STRICT;
133
145
 
134
146
  CREATE INDEX runs_project_idx ON runs(project_id, created_at DESC);
135
147
  CREATE INDEX runs_status_idx ON runs(status, updated_at DESC);
136
148
  CREATE INDEX runs_parent_idx ON runs(parent_run_id);
149
+ CREATE UNIQUE INDEX runs_restart_parent_idx ON runs(parent_run_id)
150
+ WHERE lineage_kind = 'restart';
151
+
152
+ CREATE TABLE run_view_content (
153
+ run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
154
+ content_hash BLOB NOT NULL,
155
+ media_type TEXT NOT NULL CHECK (media_type IN ('application/json', 'text/plain')),
156
+ byte_length INTEGER NOT NULL CHECK (byte_length >= 0),
157
+ content BLOB NOT NULL,
158
+ created_at INTEGER NOT NULL,
159
+ PRIMARY KEY (run_id, content_hash, media_type),
160
+ CHECK (byte_length = length(content))
161
+ ) STRICT;
137
162
 
138
163
  CREATE TABLE viewer_runs (
139
164
  run_id TEXT PRIMARY KEY REFERENCES runs(run_id) ON DELETE CASCADE,
@@ -220,33 +245,10 @@ CREATE TABLE workflow_setting_changes (
220
245
  UNIQUE (scope_id, change_number)
221
246
  ) STRICT;
222
247
 
223
- CREATE TABLE workflow_follow_up_queues (
224
- run_id TEXT PRIMARY KEY REFERENCES runs(run_id) ON DELETE CASCADE,
225
- resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id) ON DELETE CASCADE,
226
- origin_session_id TEXT,
227
- presentation_state TEXT NOT NULL DEFAULT 'none' CHECK (presentation_state IN (
228
- 'none', 'not-needed', 'pending', 'settled', 'unavailable'
229
- )),
230
- presentation_entry_id TEXT,
231
- presentation_assistant_entry_id TEXT,
232
- presentation_reason_hash BLOB REFERENCES blobs(blob_hash),
233
- presentation_updated_at INTEGER,
234
- created_at INTEGER NOT NULL,
235
- updated_at INTEGER NOT NULL,
236
- CHECK (
237
- (presentation_state IN ('none', 'not-needed', 'pending') AND presentation_assistant_entry_id IS NULL AND presentation_reason_hash IS NULL)
238
- OR
239
- (presentation_state = 'unavailable' AND presentation_assistant_entry_id IS NULL AND presentation_reason_hash IS NOT NULL)
240
- OR
241
- (presentation_state = 'settled' AND presentation_entry_id IS NOT NULL AND presentation_assistant_entry_id IS NOT NULL AND presentation_reason_hash IS NULL)
242
- )
243
- ) STRICT;
244
-
245
248
  CREATE TABLE workflow_follow_ups (
246
249
  follow_up_id TEXT PRIMARY KEY,
247
250
  resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id) ON DELETE CASCADE,
248
- queue_resource_id TEXT NOT NULL REFERENCES resources(resource_id),
249
- run_id TEXT NOT NULL REFERENCES workflow_follow_up_queues(run_id) ON DELETE CASCADE,
251
+ run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
250
252
  request_id TEXT NOT NULL,
251
253
  order_number INTEGER NOT NULL CHECK (order_number > 0),
252
254
  target_session_id TEXT NOT NULL,
@@ -256,21 +258,17 @@ CREATE TABLE workflow_follow_ups (
256
258
  actor_id TEXT,
257
259
  source_type TEXT NOT NULL,
258
260
  prompt_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
259
- status TEXT NOT NULL CHECK (status IN (
260
- 'queued', 'pending_presentation', 'ready', 'sent', 'removed', 'cancelled'
261
- )),
262
- session_entry_id TEXT,
261
+ status TEXT NOT NULL CHECK (status IN ('queued', 'removed', 'cancelled')),
263
262
  reason_hash BLOB REFERENCES blobs(blob_hash),
264
263
  created_at INTEGER NOT NULL,
265
264
  updated_at INTEGER NOT NULL,
266
- sent_at INTEGER,
267
265
  UNIQUE (run_id, request_id),
268
266
  UNIQUE (run_id, order_number),
269
- CHECK ((status = 'sent') = (session_entry_id IS NOT NULL AND sent_at IS NOT NULL)),
270
267
  CHECK ((status IN ('removed', 'cancelled')) = (reason_hash IS NOT NULL))
271
268
  ) STRICT;
272
269
 
273
- CREATE INDEX workflow_follow_ups_delivery_idx ON workflow_follow_ups(target_session_id, status, order_number);
270
+ CREATE INDEX workflow_follow_ups_order_idx
271
+ ON workflow_follow_ups(target_session_id, run_id, order_number);
274
272
 
275
273
  CREATE TABLE run_queue (
276
274
  run_id TEXT PRIMARY KEY REFERENCES runs(run_id) ON DELETE CASCADE,
@@ -299,9 +297,11 @@ CREATE TABLE host_commands (
299
297
  operation TEXT NOT NULL CHECK (operation IN (
300
298
  'run.start', 'run.pause', 'run.resume', 'run.cancel', 'run.status', 'run.list',
301
299
  'checkpoint.answer', 'decision.answer', 'interaction.submit', 'interaction.update',
302
- 'notification.claim', 'notification.deliver', 'turn.claim', 'turn.resolve',
300
+ 'workflowMessage.reportBranch', 'workflowTurn.report', 'sessionView.clearTerminal',
301
+ 'run.restart', 'run.changeSettings', 'followUp.queue', 'followUp.remove', 'session.record',
302
+ 'channel.reload', 'channel.recover',
303
303
  'controller.list', 'controller.get', 'controller.apply', 'controller.reconcile', 'controller.delete',
304
- 'host.status', 'host.stop'
304
+ 'host.status', 'host.stop', 'state.backup', 'state.prune'
305
305
  )),
306
306
  idempotency_key TEXT NOT NULL,
307
307
  request_fingerprint BLOB NOT NULL CHECK (length(request_fingerprint) = 32),
@@ -505,24 +505,70 @@ CREATE TABLE interactive_requests (
505
505
  kind TEXT NOT NULL CHECK (kind IN ('agent', 'assistant', 'decision')),
506
506
  contract_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
507
507
  revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),
508
- status TEXT NOT NULL CHECK (status IN ('pending', 'presenting', 'settled', 'cancelled')),
509
- presenter_id TEXT,
510
- presentation_claim_expires_at INTEGER,
511
- presentation_session_entry_id TEXT,
508
+ status TEXT NOT NULL CHECK (status IN ('pending', 'settled', 'cancelled')),
509
+ unproductive_turn_ends INTEGER NOT NULL DEFAULT 0 CHECK (unproductive_turn_ends >= 0),
512
510
  accepted_submission_id TEXT,
513
511
  created_at INTEGER NOT NULL,
514
512
  updated_at INTEGER NOT NULL,
515
513
  settled_at INTEGER,
516
514
  consumed_at INTEGER,
517
515
  CHECK ((status = 'settled') = (accepted_submission_id IS NOT NULL AND settled_at IS NOT NULL)),
518
- CHECK ((presenter_id IS NULL) = (presentation_claim_expires_at IS NULL)),
519
- CHECK (presenter_id IS NULL OR status = 'presenting'),
520
516
  CHECK (consumed_at IS NULL OR status = 'settled')
521
517
  ) STRICT;
522
518
 
523
519
  CREATE INDEX interactive_requests_session_idx
524
520
  ON interactive_requests(target_session_id, status, created_at);
525
521
 
522
+ CREATE TABLE workflow_messages (
523
+ workflow_message_id TEXT PRIMARY KEY,
524
+ run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
525
+ target_session_id TEXT NOT NULL,
526
+ kind TEXT NOT NULL CHECK (kind IN ('step', 'decision', 'notification', 'terminal', 'followUp')),
527
+ source_id TEXT NOT NULL,
528
+ content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
529
+ order_number INTEGER NOT NULL CHECK (order_number > 0),
530
+ status TEXT NOT NULL CHECK (status IN ('pending', 'sent', 'cancelled')),
531
+ pi_session_entry_id TEXT,
532
+ created_at INTEGER NOT NULL,
533
+ updated_at INTEGER NOT NULL,
534
+ UNIQUE (target_session_id, order_number),
535
+ CHECK ((status = 'sent') = (pi_session_entry_id IS NOT NULL))
536
+ ) STRICT;
537
+
538
+ CREATE INDEX workflow_messages_session_idx
539
+ ON workflow_messages(target_session_id, status, order_number);
540
+ CREATE INDEX workflow_messages_run_idx ON workflow_messages(run_id, order_number);
541
+ CREATE INDEX workflow_messages_source_idx ON workflow_messages(kind, source_id, order_number);
542
+ CREATE UNIQUE INDEX workflow_messages_pending_step_source_idx
543
+ ON workflow_messages(source_id) WHERE kind = 'step' AND status = 'pending';
544
+
545
+ CREATE TABLE workflow_turns (
546
+ workflow_turn_id TEXT PRIMARY KEY,
547
+ workflow_message_id TEXT NOT NULL REFERENCES workflow_messages(workflow_message_id) ON DELETE CASCADE,
548
+ run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
549
+ target_session_id TEXT NOT NULL,
550
+ state TEXT NOT NULL CHECK (state IN ('started', 'ended')),
551
+ stop_reason TEXT CHECK (stop_reason IS NULL OR stop_reason IN ('completed', 'aborted', 'error', 'lost')),
552
+ response_session_entry_id TEXT,
553
+ started_at INTEGER NOT NULL,
554
+ ended_at INTEGER,
555
+ CHECK (
556
+ (state = 'started' AND stop_reason IS NULL AND ended_at IS NULL)
557
+ OR
558
+ (state = 'ended' AND stop_reason IS NOT NULL AND ended_at IS NOT NULL)
559
+ )
560
+ ) STRICT;
561
+
562
+ CREATE UNIQUE INDEX workflow_turns_open_message_idx
563
+ ON workflow_turns(workflow_message_id) WHERE state = 'started';
564
+ CREATE INDEX workflow_turns_session_idx ON workflow_turns(target_session_id, state, started_at);
565
+
566
+ CREATE TABLE session_terminal_views (
567
+ target_session_id TEXT PRIMARY KEY,
568
+ cleared_run_id TEXT REFERENCES runs(run_id) ON DELETE SET NULL,
569
+ cleared_at INTEGER NOT NULL
570
+ ) STRICT;
571
+
526
572
  CREATE TABLE interactive_submissions (
527
573
  submission_id TEXT PRIMARY KEY,
528
574
  request_id TEXT NOT NULL REFERENCES interactive_requests(request_id) ON DELETE CASCADE,
@@ -668,39 +714,6 @@ CREATE TABLE effect_attempts (
668
714
  PRIMARY KEY (effect_id, attempt_number)
669
715
  ) STRICT;
670
716
 
671
- CREATE TABLE notifications (
672
- notification_id TEXT PRIMARY KEY,
673
- effect_id TEXT NOT NULL UNIQUE REFERENCES effects(effect_id),
674
- run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
675
- attempt_id TEXT NOT NULL REFERENCES node_attempts(attempt_id),
676
- notification_index INTEGER NOT NULL CHECK (notification_index >= 0),
677
- target_session_id TEXT NOT NULL,
678
- notification_type TEXT NOT NULL CHECK (notification_type IN ('progress', 'final')),
679
- content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
680
- created_at INTEGER NOT NULL,
681
- UNIQUE (run_id, attempt_id, notification_index)
682
- ) STRICT;
683
-
684
- CREATE TABLE turn_intents (
685
- turn_intent_id TEXT PRIMARY KEY,
686
- resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id),
687
- effect_id TEXT NOT NULL UNIQUE REFERENCES effects(effect_id),
688
- source_event_id TEXT NOT NULL UNIQUE,
689
- run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
690
- workflow_ref TEXT NOT NULL,
691
- target_session_id TEXT NOT NULL,
692
- cause TEXT NOT NULL,
693
- node_id TEXT,
694
- attempt_id TEXT,
695
- resolution_type TEXT,
696
- resolution_message_id TEXT,
697
- facts_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
698
- requested_at INTEGER NOT NULL,
699
- eligible_at INTEGER,
700
- resolved_at INTEGER,
701
- created_at INTEGER NOT NULL
702
- ) STRICT;
703
-
704
717
  CREATE TABLE channels (
705
718
  channel_id TEXT PRIMARY KEY,
706
719
  resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id),
@@ -718,41 +731,18 @@ CREATE TABLE channel_cursors (
718
731
  PRIMARY KEY (channel_id, cursor_key)
719
732
  ) STRICT;
720
733
 
721
- CREATE TABLE channel_inbox (
722
- channel_id TEXT NOT NULL REFERENCES channels(channel_id) ON DELETE CASCADE,
723
- external_event_id TEXT NOT NULL,
724
- event_type TEXT NOT NULL CHECK (event_type IN ('callback', 'reply')),
725
- payload_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
726
- received_at INTEGER NOT NULL,
727
- processed_at INTEGER,
728
- result_hash BLOB REFERENCES blobs(blob_hash),
729
- PRIMARY KEY (channel_id, external_event_id)
730
- ) STRICT;
731
-
732
734
  CREATE TABLE channel_messages (
733
735
  message_id TEXT PRIMARY KEY,
734
736
  channel_id TEXT NOT NULL REFERENCES channels(channel_id) ON DELETE CASCADE,
735
737
  decision_id TEXT REFERENCES human_decisions(decision_id),
736
738
  purpose TEXT NOT NULL CHECK (purpose IN ('delivery', 'settlement')),
737
739
  content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
738
- external_conversation_ref TEXT,
739
- external_message_ref TEXT,
740
740
  status TEXT NOT NULL CHECK (status IN ('pending', 'confirmed', 'failed', 'ambiguous')),
741
741
  created_at INTEGER NOT NULL,
742
742
  updated_at INTEGER NOT NULL
743
743
  ) STRICT;
744
744
 
745
745
  CREATE INDEX channel_messages_decision_idx ON channel_messages(decision_id, purpose, created_at);
746
-
747
- CREATE TABLE channel_message_parts (
748
- message_id TEXT NOT NULL REFERENCES channel_messages(message_id) ON DELETE CASCADE,
749
- recipient_index INTEGER NOT NULL CHECK (recipient_index >= 0),
750
- part_index INTEGER NOT NULL CHECK (part_index >= 0),
751
- content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
752
- external_conversation_ref TEXT NOT NULL,
753
- external_message_ref TEXT NOT NULL,
754
- PRIMARY KEY (message_id, recipient_index, part_index)
755
- ) STRICT;
756
746
  `;
757
747
  export const STATE_SCHEMA_DIGEST = createHash("sha256").update(STATE_SCHEMA_SQL).digest();
758
748
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/state/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8uBzC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/state/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAouBzC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC"}
@@ -0,0 +1,96 @@
1
+ import type { StateDatabase } from "./database.js";
2
+ import { type JsonValue } from "./json.js";
3
+ export declare const WORKFLOW_MESSAGE_SCHEMA: "pi-workflows.workflow-message.v1";
4
+ export declare const WORKFLOW_MESSAGE_CONTENT_SCHEMA: "pi-workflows.workflow-message-content.v1";
5
+ export declare const WORKFLOW_TURN_SCHEMA: "pi-workflows.workflow-turn.v1";
6
+ export type WorkflowMessageKind = "step" | "decision" | "notification" | "terminal" | "followUp";
7
+ export type WorkflowMessageStatus = "pending" | "sent" | "cancelled";
8
+ export type WorkflowStepReason = "initial" | "reminder" | "resumed";
9
+ export type WorkflowTurnState = "started" | "ended";
10
+ export type WorkflowTurnStopReason = "completed" | "aborted" | "error" | "lost";
11
+ export type WorkflowMessageContent = {
12
+ schema: typeof WORKFLOW_MESSAGE_CONTENT_SCHEMA;
13
+ customType: string;
14
+ content: string;
15
+ display: boolean;
16
+ details: JsonValue;
17
+ triggerTurn: boolean;
18
+ };
19
+ export type WorkflowMessage = {
20
+ schema: typeof WORKFLOW_MESSAGE_SCHEMA;
21
+ workflowMessageId: string;
22
+ runId: string;
23
+ targetSessionId: string;
24
+ kind: WorkflowMessageKind;
25
+ sourceId: string;
26
+ contentDigest: string;
27
+ content: WorkflowMessageContent;
28
+ order: number;
29
+ status: WorkflowMessageStatus;
30
+ piSessionEntryId: string | null;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ };
34
+ export type WorkflowTurn = {
35
+ schema: typeof WORKFLOW_TURN_SCHEMA;
36
+ workflowTurnId: string;
37
+ workflowMessageId: string;
38
+ runId: string;
39
+ targetSessionId: string;
40
+ state: WorkflowTurnState;
41
+ stopReason: WorkflowTurnStopReason | null;
42
+ responseSessionEntryId: string | null;
43
+ startedAt: string;
44
+ endedAt: string | null;
45
+ };
46
+ export type WorkflowBranchEntry = {
47
+ workflowMessageId: string;
48
+ piSessionEntryId: string;
49
+ };
50
+ export type CreateWorkflowMessageOptions = {
51
+ workflowMessageId?: string;
52
+ runId: string;
53
+ targetSessionId: string;
54
+ kind: WorkflowMessageKind;
55
+ sourceId: string;
56
+ idempotencyKey: string;
57
+ content: WorkflowMessageContent;
58
+ now?: number;
59
+ };
60
+ /** Durable workflow content that the host requires Pi to add to one origin session. */
61
+ export declare class WorkflowMessageStore {
62
+ readonly state: StateDatabase;
63
+ constructor(state: StateDatabase);
64
+ create(options: CreateWorkflowMessageOptions): WorkflowMessage;
65
+ get(workflowMessageId: string): WorkflowMessage | undefined;
66
+ require(workflowMessageId: string): WorkflowMessage;
67
+ listSession(targetSessionId: string): WorkflowMessage[];
68
+ listRun(runId: string): WorkflowMessage[];
69
+ latestForSource(kind: WorkflowMessageKind, sourceId: string): WorkflowMessage | undefined;
70
+ cancelPendingForSource(sourceId: string, kind?: WorkflowMessageKind, now?: number): number;
71
+ adoptBranch(targetSessionId: string, entries: readonly WorkflowBranchEntry[], allowedMessageIds: ReadonlySet<string>, now?: number): WorkflowMessage[];
72
+ startTurn(options: {
73
+ workflowMessageId: string;
74
+ workflowTurnId?: string;
75
+ runId: string;
76
+ targetSessionId: string;
77
+ now?: number;
78
+ }): WorkflowTurn;
79
+ endTurn(options: {
80
+ workflowMessageId: string;
81
+ workflowTurnId: string;
82
+ runId: string;
83
+ targetSessionId: string;
84
+ stopReason: WorkflowTurnStopReason;
85
+ responseSessionEntryId?: string | null;
86
+ now?: number;
87
+ }): WorkflowTurn;
88
+ getTurn(workflowTurnId: string): WorkflowTurn | undefined;
89
+ requireTurn(workflowTurnId: string): WorkflowTurn;
90
+ openTurnForMessage(workflowMessageId: string): WorkflowTurn | undefined;
91
+ latestTurnForMessage(workflowMessageId: string): WorkflowTurn | undefined;
92
+ openTurnsForSession(targetSessionId: string): WorkflowTurn[];
93
+ private mapMessage;
94
+ }
95
+ export declare function workflowMessageIdFor(kind: WorkflowMessageKind, sourceId: string, idempotencyKey: string): string;
96
+ export declare function isWorkflowMessageContent(value: unknown): value is WorkflowMessageContent;