@osolmaz/pi-workflows 0.16.0 → 0.16.2

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 (175) hide show
  1. package/README.md +18 -2
  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/client.d.ts +1 -0
  15. package/dist/client/client.js +5 -1
  16. package/dist/client/client.js.map +1 -1
  17. package/dist/client/index.d.ts +1 -1
  18. package/dist/client/protocol.d.ts +1 -1
  19. package/dist/client/protocol.js +11 -5
  20. package/dist/client/protocol.js.map +1 -1
  21. package/dist/client/view.d.ts +48 -16
  22. package/dist/client/view.js +1 -0
  23. package/dist/client/view.js.map +1 -1
  24. package/dist/controllers/index.d.ts +1 -1
  25. package/dist/controllers/index.js.map +1 -1
  26. package/dist/controllers/sqlite.d.ts +20 -165
  27. package/dist/controllers/sqlite.js +178 -436
  28. package/dist/controllers/sqlite.js.map +1 -1
  29. package/dist/extension/index.d.ts +23 -2
  30. package/dist/extension/index.js +637 -534
  31. package/dist/extension/index.js.map +1 -1
  32. package/dist/extension/recorder.d.ts +95 -0
  33. package/dist/extension/recorder.js +530 -0
  34. package/dist/extension/recorder.js.map +1 -0
  35. package/dist/extension/remote-recorder-store.d.ts +25 -0
  36. package/dist/extension/remote-recorder-store.js +81 -0
  37. package/dist/extension/remote-recorder-store.js.map +1 -0
  38. package/dist/extension/session-events.d.ts +134 -0
  39. package/dist/extension/session-events.js +60 -0
  40. package/dist/extension/session-events.js.map +1 -0
  41. package/dist/extension/session-view.d.ts +2 -0
  42. package/dist/extension/session-view.js +60 -2
  43. package/dist/extension/session-view.js.map +1 -1
  44. package/dist/extension/step-message.d.ts +6 -4
  45. package/dist/extension/step-message.js +12 -6
  46. package/dist/extension/step-message.js.map +1 -1
  47. package/dist/extension/widget.d.ts +2 -2
  48. package/dist/extension/widget.js +28 -18
  49. package/dist/extension/widget.js.map +1 -1
  50. package/dist/extension/workflow-message-coordinator.d.ts +28 -0
  51. package/dist/extension/workflow-message-coordinator.js +346 -0
  52. package/dist/extension/workflow-message-coordinator.js.map +1 -0
  53. package/dist/host/channel-effects.d.ts +72 -0
  54. package/dist/host/channel-effects.js +271 -0
  55. package/dist/host/channel-effects.js.map +1 -0
  56. package/dist/host/channel-supervisor.d.ts +21 -0
  57. package/dist/host/channel-supervisor.js +54 -0
  58. package/dist/host/channel-supervisor.js.map +1 -0
  59. package/dist/host/runner.d.ts +50 -8
  60. package/dist/host/runner.js +1632 -341
  61. package/dist/host/runner.js.map +1 -1
  62. package/dist/host/state.d.ts +19 -16
  63. package/dist/host/state.js +251 -63
  64. package/dist/host/state.js.map +1 -1
  65. package/dist/host/view.d.ts +19 -9
  66. package/dist/host/view.js +227 -119
  67. package/dist/host/view.js.map +1 -1
  68. package/dist/host/worker-entry.d.ts +4 -1
  69. package/dist/host/worker-entry.js +23 -24
  70. package/dist/host/worker-entry.js.map +1 -1
  71. package/dist/host/worker-protocol.d.ts +15 -0
  72. package/dist/host/worker-protocol.js.map +1 -1
  73. package/dist/state/prune.js +3 -25
  74. package/dist/state/prune.js.map +1 -1
  75. package/dist/state/schema.js +76 -97
  76. package/dist/state/schema.js.map +1 -1
  77. package/dist/state/workflow-messages.d.ts +98 -0
  78. package/dist/state/workflow-messages.js +366 -0
  79. package/dist/state/workflow-messages.js.map +1 -0
  80. package/dist/viewer/render.js +1 -1
  81. package/dist/viewer/render.js.map +1 -1
  82. package/dist/viewer/tui.d.ts +1 -1
  83. package/dist/viewer/tui.js +65 -8
  84. package/dist/viewer/tui.js.map +1 -1
  85. package/dist/workflows/composition.js +0 -4
  86. package/dist/workflows/composition.js.map +1 -1
  87. package/dist/workflows/definition.js +0 -8
  88. package/dist/workflows/definition.js.map +1 -1
  89. package/dist/workflows/engine.js +4 -5
  90. package/dist/workflows/engine.js.map +1 -1
  91. package/dist/workflows/human-decision.d.ts +2 -0
  92. package/dist/workflows/human-decision.js +8 -2
  93. package/dist/workflows/human-decision.js.map +1 -1
  94. package/dist/workflows/index.d.ts +1 -1
  95. package/dist/workflows/index.js.map +1 -1
  96. package/dist/workflows/schema.js +0 -4
  97. package/dist/workflows/schema.js.map +1 -1
  98. package/dist/workflows/settings.d.ts +1 -8
  99. package/dist/workflows/settings.js.map +1 -1
  100. package/dist/workflows/store.d.ts +20 -19
  101. package/dist/workflows/store.js +163 -354
  102. package/dist/workflows/store.js.map +1 -1
  103. package/dist/workflows/tool-input.d.ts +21 -0
  104. package/dist/workflows/tool-input.js +23 -1
  105. package/dist/workflows/tool-input.js.map +1 -1
  106. package/dist/workflows/types.d.ts +6 -8
  107. package/dist/workflows/workflow-message-content.d.ts +38 -0
  108. package/dist/workflows/workflow-message-content.js +157 -0
  109. package/dist/workflows/workflow-message-content.js.map +1 -0
  110. package/docs/2026-08-18-herdr-piw-plan.md +2 -1
  111. package/docs/2026-08-20-durable-workflow-launch-plan.md +1 -1
  112. package/docs/2026-08-25-workflow-follow-ups.md +26 -50
  113. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
  114. package/docs/2026-09-01-restore-session-delivery-controls-plan.md +4 -0
  115. package/docs/2026-09-01-unified-workflow-client-plan.md +5 -1
  116. package/docs/2026-09-02-installed-live-e2e-plan.md +15 -1
  117. package/docs/2026-09-02-unify-workflow-messages-plan.md +562 -0
  118. package/docs/2026-09-04-workflow-run-state-plan.md +363 -0
  119. package/docs/DEFERRED_TURNS.md +66 -294
  120. package/docs/HUMAN_DECISIONS.md +29 -30
  121. package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -11
  122. package/docs/SQLITE_STATE.md +25 -17
  123. package/docs/WORKFLOW_HOST.md +105 -31
  124. package/docs/WORKFLOW_STEP_MESSAGES.md +166 -75
  125. package/docs/live-replay-protocol.md +8 -4
  126. package/docs/tui-viewer.md +3 -1
  127. package/docs/workflows.md +44 -28
  128. package/herdr-plugin.toml +1 -1
  129. package/package.json +1 -1
  130. package/plugins/herdr/viewer.mjs +14 -5
  131. package/src/channels/adapter-entry.ts +220 -0
  132. package/src/channels/config.ts +296 -0
  133. package/src/channels/protocol.ts +333 -0
  134. package/src/channels/telegram.ts +335 -0
  135. package/src/client/client.ts +6 -2
  136. package/src/client/index.ts +2 -1
  137. package/src/client/protocol.ts +11 -5
  138. package/src/client/view.ts +51 -18
  139. package/src/controllers/index.ts +0 -1
  140. package/src/controllers/sqlite.ts +247 -845
  141. package/src/extension/index.ts +712 -647
  142. package/src/extension/recorder.ts +687 -0
  143. package/src/extension/remote-recorder-store.ts +126 -0
  144. package/src/extension/session-events.ts +119 -0
  145. package/src/extension/session-view.ts +86 -3
  146. package/src/extension/step-message.ts +19 -9
  147. package/src/extension/widget.ts +37 -17
  148. package/src/extension/workflow-message-coordinator.ts +398 -0
  149. package/src/host/channel-effects.ts +465 -0
  150. package/src/host/channel-supervisor.ts +73 -0
  151. package/src/host/runner.ts +2163 -525
  152. package/src/host/state.ts +333 -94
  153. package/src/host/view.ts +254 -122
  154. package/src/host/worker-entry.ts +38 -30
  155. package/src/host/worker-protocol.ts +11 -0
  156. package/src/state/prune.ts +3 -31
  157. package/src/state/schema.ts +76 -97
  158. package/src/state/workflow-messages.ts +599 -0
  159. package/src/viewer/render.ts +1 -5
  160. package/src/viewer/tui.ts +71 -6
  161. package/src/workflows/composition.ts +0 -5
  162. package/src/workflows/definition.ts +0 -8
  163. package/src/workflows/engine.ts +4 -6
  164. package/src/workflows/human-decision.ts +18 -2
  165. package/src/workflows/index.ts +0 -1
  166. package/src/workflows/schema.ts +0 -6
  167. package/src/workflows/settings.ts +1 -20
  168. package/src/workflows/store.ts +237 -489
  169. package/src/workflows/tool-input.ts +36 -1
  170. package/src/workflows/types.ts +6 -8
  171. package/src/workflows/workflow-message-content.ts +197 -0
  172. package/dist/extension/decision-channels.d.ts +0 -134
  173. package/dist/extension/decision-channels.js +0 -1307
  174. package/dist/extension/decision-channels.js.map +0 -1
  175. package/src/extension/decision-channels.ts +0 -1826
@@ -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,24 @@ 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';
137
151
 
138
152
  CREATE TABLE run_view_content (
139
153
  run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
@@ -231,33 +245,10 @@ CREATE TABLE workflow_setting_changes (
231
245
  UNIQUE (scope_id, change_number)
232
246
  ) STRICT;
233
247
 
234
- CREATE TABLE workflow_follow_up_queues (
235
- run_id TEXT PRIMARY KEY REFERENCES runs(run_id) ON DELETE CASCADE,
236
- resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id) ON DELETE CASCADE,
237
- origin_session_id TEXT,
238
- presentation_state TEXT NOT NULL DEFAULT 'none' CHECK (presentation_state IN (
239
- 'none', 'not-needed', 'pending', 'settled', 'unavailable'
240
- )),
241
- presentation_entry_id TEXT,
242
- presentation_assistant_entry_id TEXT,
243
- presentation_reason_hash BLOB REFERENCES blobs(blob_hash),
244
- presentation_updated_at INTEGER,
245
- created_at INTEGER NOT NULL,
246
- updated_at INTEGER NOT NULL,
247
- CHECK (
248
- (presentation_state IN ('none', 'not-needed', 'pending') AND presentation_assistant_entry_id IS NULL AND presentation_reason_hash IS NULL)
249
- OR
250
- (presentation_state = 'unavailable' AND presentation_assistant_entry_id IS NULL AND presentation_reason_hash IS NOT NULL)
251
- OR
252
- (presentation_state = 'settled' AND presentation_entry_id IS NOT NULL AND presentation_assistant_entry_id IS NOT NULL AND presentation_reason_hash IS NULL)
253
- )
254
- ) STRICT;
255
-
256
248
  CREATE TABLE workflow_follow_ups (
257
249
  follow_up_id TEXT PRIMARY KEY,
258
250
  resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id) ON DELETE CASCADE,
259
- queue_resource_id TEXT NOT NULL REFERENCES resources(resource_id),
260
- 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,
261
252
  request_id TEXT NOT NULL,
262
253
  order_number INTEGER NOT NULL CHECK (order_number > 0),
263
254
  target_session_id TEXT NOT NULL,
@@ -267,21 +258,17 @@ CREATE TABLE workflow_follow_ups (
267
258
  actor_id TEXT,
268
259
  source_type TEXT NOT NULL,
269
260
  prompt_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
270
- status TEXT NOT NULL CHECK (status IN (
271
- 'queued', 'pending_presentation', 'ready', 'sent', 'removed', 'cancelled'
272
- )),
273
- session_entry_id TEXT,
261
+ status TEXT NOT NULL CHECK (status IN ('queued', 'removed', 'cancelled')),
274
262
  reason_hash BLOB REFERENCES blobs(blob_hash),
275
263
  created_at INTEGER NOT NULL,
276
264
  updated_at INTEGER NOT NULL,
277
- sent_at INTEGER,
278
265
  UNIQUE (run_id, request_id),
279
266
  UNIQUE (run_id, order_number),
280
- CHECK ((status = 'sent') = (session_entry_id IS NOT NULL AND sent_at IS NOT NULL)),
281
267
  CHECK ((status IN ('removed', 'cancelled')) = (reason_hash IS NOT NULL))
282
268
  ) STRICT;
283
269
 
284
- 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);
285
272
 
286
273
  CREATE TABLE run_queue (
287
274
  run_id TEXT PRIMARY KEY REFERENCES runs(run_id) ON DELETE CASCADE,
@@ -310,7 +297,9 @@ CREATE TABLE host_commands (
310
297
  operation TEXT NOT NULL CHECK (operation IN (
311
298
  'run.start', 'run.pause', 'run.resume', 'run.cancel', 'run.status', 'run.list',
312
299
  'checkpoint.answer', 'decision.answer', 'interaction.submit', 'interaction.update',
313
- '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',
314
303
  'controller.list', 'controller.get', 'controller.apply', 'controller.reconcile', 'controller.delete',
315
304
  'host.status', 'host.stop', 'state.backup', 'state.prune'
316
305
  )),
@@ -516,24 +505,70 @@ CREATE TABLE interactive_requests (
516
505
  kind TEXT NOT NULL CHECK (kind IN ('agent', 'assistant', 'decision')),
517
506
  contract_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
518
507
  revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),
519
- status TEXT NOT NULL CHECK (status IN ('pending', 'presenting', 'settled', 'cancelled')),
520
- presenter_id TEXT,
521
- presentation_claim_expires_at INTEGER,
522
- 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),
523
510
  accepted_submission_id TEXT,
524
511
  created_at INTEGER NOT NULL,
525
512
  updated_at INTEGER NOT NULL,
526
513
  settled_at INTEGER,
527
514
  consumed_at INTEGER,
528
515
  CHECK ((status = 'settled') = (accepted_submission_id IS NOT NULL AND settled_at IS NOT NULL)),
529
- CHECK ((presenter_id IS NULL) = (presentation_claim_expires_at IS NULL)),
530
- CHECK (presenter_id IS NULL OR status = 'presenting'),
531
516
  CHECK (consumed_at IS NULL OR status = 'settled')
532
517
  ) STRICT;
533
518
 
534
519
  CREATE INDEX interactive_requests_session_idx
535
520
  ON interactive_requests(target_session_id, status, created_at);
536
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
+
537
572
  CREATE TABLE interactive_submissions (
538
573
  submission_id TEXT PRIMARY KEY,
539
574
  request_id TEXT NOT NULL REFERENCES interactive_requests(request_id) ON DELETE CASCADE,
@@ -679,39 +714,6 @@ CREATE TABLE effect_attempts (
679
714
  PRIMARY KEY (effect_id, attempt_number)
680
715
  ) STRICT;
681
716
 
682
- CREATE TABLE notifications (
683
- notification_id TEXT PRIMARY KEY,
684
- effect_id TEXT NOT NULL UNIQUE REFERENCES effects(effect_id),
685
- run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
686
- attempt_id TEXT NOT NULL REFERENCES node_attempts(attempt_id),
687
- notification_index INTEGER NOT NULL CHECK (notification_index >= 0),
688
- target_session_id TEXT NOT NULL,
689
- notification_type TEXT NOT NULL CHECK (notification_type IN ('progress', 'final')),
690
- content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
691
- created_at INTEGER NOT NULL,
692
- UNIQUE (run_id, attempt_id, notification_index)
693
- ) STRICT;
694
-
695
- CREATE TABLE turn_intents (
696
- turn_intent_id TEXT PRIMARY KEY,
697
- resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id),
698
- effect_id TEXT NOT NULL UNIQUE REFERENCES effects(effect_id),
699
- source_event_id TEXT NOT NULL UNIQUE,
700
- run_id TEXT NOT NULL REFERENCES runs(run_id) ON DELETE CASCADE,
701
- workflow_ref TEXT NOT NULL,
702
- target_session_id TEXT NOT NULL,
703
- cause TEXT NOT NULL,
704
- node_id TEXT,
705
- attempt_id TEXT,
706
- resolution_type TEXT,
707
- resolution_message_id TEXT,
708
- facts_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
709
- requested_at INTEGER NOT NULL,
710
- eligible_at INTEGER,
711
- resolved_at INTEGER,
712
- created_at INTEGER NOT NULL
713
- ) STRICT;
714
-
715
717
  CREATE TABLE channels (
716
718
  channel_id TEXT PRIMARY KEY,
717
719
  resource_id TEXT NOT NULL UNIQUE REFERENCES resources(resource_id),
@@ -729,41 +731,18 @@ CREATE TABLE channel_cursors (
729
731
  PRIMARY KEY (channel_id, cursor_key)
730
732
  ) STRICT;
731
733
 
732
- CREATE TABLE channel_inbox (
733
- channel_id TEXT NOT NULL REFERENCES channels(channel_id) ON DELETE CASCADE,
734
- external_event_id TEXT NOT NULL,
735
- event_type TEXT NOT NULL CHECK (event_type IN ('callback', 'reply')),
736
- payload_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
737
- received_at INTEGER NOT NULL,
738
- processed_at INTEGER,
739
- result_hash BLOB REFERENCES blobs(blob_hash),
740
- PRIMARY KEY (channel_id, external_event_id)
741
- ) STRICT;
742
-
743
734
  CREATE TABLE channel_messages (
744
735
  message_id TEXT PRIMARY KEY,
745
736
  channel_id TEXT NOT NULL REFERENCES channels(channel_id) ON DELETE CASCADE,
746
737
  decision_id TEXT REFERENCES human_decisions(decision_id),
747
738
  purpose TEXT NOT NULL CHECK (purpose IN ('delivery', 'settlement')),
748
739
  content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
749
- external_conversation_ref TEXT,
750
- external_message_ref TEXT,
751
740
  status TEXT NOT NULL CHECK (status IN ('pending', 'confirmed', 'failed', 'ambiguous')),
752
741
  created_at INTEGER NOT NULL,
753
742
  updated_at INTEGER NOT NULL
754
743
  ) STRICT;
755
744
 
756
745
  CREATE INDEX channel_messages_decision_idx ON channel_messages(decision_id, purpose, created_at);
757
-
758
- CREATE TABLE channel_message_parts (
759
- message_id TEXT NOT NULL REFERENCES channel_messages(message_id) ON DELETE CASCADE,
760
- recipient_index INTEGER NOT NULL CHECK (recipient_index >= 0),
761
- part_index INTEGER NOT NULL CHECK (part_index >= 0),
762
- content_hash BLOB NOT NULL REFERENCES blobs(blob_hash),
763
- external_conversation_ref TEXT NOT NULL,
764
- external_message_ref TEXT NOT NULL,
765
- PRIMARY KEY (message_id, recipient_index, part_index)
766
- ) STRICT;
767
746
  `;
768
747
  export const STATE_SCHEMA_DIGEST = createHash("sha256").update(STATE_SCHEMA_SQL).digest();
769
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyvBzC,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,98 @@
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
+ settleOpenTurnsForRun(runId: string, stopReason?: WorkflowTurnStopReason, now?: number): WorkflowTurn[];
89
+ cancelPendingForRun(runId: string, now?: number, kinds?: readonly WorkflowMessageKind[]): number;
90
+ getTurn(workflowTurnId: string): WorkflowTurn | undefined;
91
+ requireTurn(workflowTurnId: string): WorkflowTurn;
92
+ openTurnForMessage(workflowMessageId: string): WorkflowTurn | undefined;
93
+ latestTurnForMessage(workflowMessageId: string): WorkflowTurn | undefined;
94
+ openTurnsForSession(targetSessionId: string): WorkflowTurn[];
95
+ private mapMessage;
96
+ }
97
+ export declare function workflowMessageIdFor(kind: WorkflowMessageKind, sourceId: string, idempotencyKey: string): string;
98
+ export declare function isWorkflowMessageContent(value: unknown): value is WorkflowMessageContent;