@swirls/looms 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/actor/host.js +4 -5
  3. package/dist/actor/index.d.ts +1 -1
  4. package/dist/actor/index.js +1 -1
  5. package/dist/actor/routing.d.ts +5 -0
  6. package/dist/actor/routing.js +14 -0
  7. package/dist/agent/agent-session.js +1 -0
  8. package/dist/agent/debugger/agent-chat.d.ts +2 -0
  9. package/dist/agent/debugger/agent-chat.js +210 -0
  10. package/dist/agent/debugger/index.d.ts +5 -0
  11. package/dist/agent/debugger/index.js +19 -0
  12. package/dist/agent/debugger/summarize.d.ts +2 -0
  13. package/dist/agent/debugger/summarize.js +53 -0
  14. package/dist/agent/debugger/token-usage.d.ts +3 -0
  15. package/dist/agent/debugger/token-usage.js +11 -0
  16. package/dist/agent/definitions.d.ts +3 -11
  17. package/dist/agent/definitions.js +5 -6
  18. package/dist/agent/effects.d.ts +30 -0
  19. package/dist/agent/events.d.ts +2 -0
  20. package/dist/agent/events.js +2 -0
  21. package/dist/agent/llm.js +1 -8
  22. package/dist/agent/module.d.ts +604 -534
  23. package/dist/agent/module.js +11 -7
  24. package/dist/agent/projections.d.ts +5 -0
  25. package/dist/agent/projections.js +43 -2
  26. package/dist/agent/scope.d.ts +2 -0
  27. package/dist/agent/signals.d.ts +7 -0
  28. package/dist/agent/signals.js +25 -16
  29. package/dist/agent/threads.js +35 -21
  30. package/dist/agent/tool-schema.d.ts +1 -17
  31. package/dist/agent/tool-schema.js +3 -42
  32. package/dist/agent/transcript.d.ts +7 -0
  33. package/dist/agent/transcript.js +19 -0
  34. package/dist/agent/types.d.ts +10 -0
  35. package/dist/agent/types.js +4 -0
  36. package/dist/ai-vercel/index.d.ts +1 -1
  37. package/dist/ai-vercel/vercel-evaluator.d.ts +21 -8
  38. package/dist/ai-vercel/vercel-evaluator.js +7 -2
  39. package/dist/approval/debugger/approvals-view.d.ts +3 -0
  40. package/dist/approval/debugger/approvals-view.js +18 -0
  41. package/dist/approval/debugger/index.d.ts +4 -0
  42. package/dist/approval/debugger/index.js +11 -0
  43. package/dist/approval/debugger/summarize.d.ts +2 -0
  44. package/dist/approval/debugger/summarize.js +17 -0
  45. package/dist/approval/effects.d.ts +12 -0
  46. package/dist/approval/module.d.ts +24 -0
  47. package/dist/client/client.d.ts +310 -0
  48. package/dist/client/client.js +20 -2
  49. package/dist/cloudflare/router.d.ts +1 -1
  50. package/dist/cloudflare/router.js +6 -8
  51. package/dist/core/compose.js +1 -0
  52. package/dist/core/debugger-host.d.ts +16 -0
  53. package/dist/core/debugger-host.js +1 -0
  54. package/dist/core/effects.d.ts +7 -0
  55. package/dist/core/effects.js +1 -0
  56. package/dist/core/fold.js +12 -6
  57. package/dist/core/fork.d.ts +35 -0
  58. package/dist/core/fork.js +129 -0
  59. package/dist/core/index.d.ts +3 -0
  60. package/dist/core/index.js +2 -0
  61. package/dist/core/module-scope.d.ts +1 -0
  62. package/dist/core/module.d.ts +4 -2
  63. package/dist/core/projection.js +1 -0
  64. package/dist/core/protocol.d.ts +10 -1
  65. package/dist/core/protocol.js +11 -0
  66. package/dist/core/published.d.ts +43 -0
  67. package/dist/core/published.js +44 -0
  68. package/dist/core/replay.d.ts +8 -0
  69. package/dist/core/schema.d.ts +3 -1
  70. package/dist/core/schema.js +38 -0
  71. package/dist/core/snapshot-store.d.ts +4 -0
  72. package/dist/core/snapshot-store.js +7 -0
  73. package/dist/core/snapshots.js +3 -17
  74. package/dist/core/sqlite-store.js +39 -0
  75. package/dist/core/state.d.ts +14 -0
  76. package/dist/core/state.js +25 -2
  77. package/dist/core/store.d.ts +1 -0
  78. package/dist/debugger/app/assets/index-BevQYa-U.js +22 -0
  79. package/dist/debugger/app/assets/index-CgDzWJg7.css +2 -0
  80. package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  81. package/dist/debugger/app/assets/routes-B17Om93i.js +47 -0
  82. package/dist/debugger/app/index.html +14 -0
  83. package/dist/debugger/components/composer.d.ts +20 -0
  84. package/dist/debugger/components/composer.js +26 -0
  85. package/dist/debugger/components/debugger-split.d.ts +2 -1
  86. package/dist/debugger/components/debugger-split.js +2 -2
  87. package/dist/debugger/components/event-inspector.d.ts +2 -1
  88. package/dist/debugger/components/event-inspector.js +25 -16
  89. package/dist/debugger/components/event-stream.d.ts +2 -1
  90. package/dist/debugger/components/event-stream.js +12 -71
  91. package/dist/debugger/components/follow-list.d.ts +19 -0
  92. package/dist/debugger/components/follow-list.js +96 -0
  93. package/dist/debugger/components/json-tree.d.ts +11 -0
  94. package/dist/debugger/components/json-tree.js +120 -0
  95. package/dist/debugger/components/json-view.js +2 -2
  96. package/dist/debugger/components/run-tree.js +50 -20
  97. package/dist/debugger/components/status-dot.d.ts +4 -0
  98. package/dist/debugger/components/status-dot.js +6 -2
  99. package/dist/debugger/context.d.ts +14 -0
  100. package/dist/debugger/context.js +17 -0
  101. package/dist/debugger/contracts.d.ts +7 -4
  102. package/dist/debugger/events/builtin-families.d.ts +3 -0
  103. package/dist/debugger/events/builtin-families.js +9 -0
  104. package/dist/debugger/events/catalog.d.ts +3 -4
  105. package/dist/debugger/events/catalog.js +25 -17
  106. package/dist/debugger/events/protocol-summarize.d.ts +1 -2
  107. package/dist/debugger/events/protocol-summarize.js +36 -37
  108. package/dist/debugger/index.d.ts +20 -6
  109. package/dist/debugger/index.js +19 -5
  110. package/dist/debugger/lib/cn.d.ts +1 -0
  111. package/dist/debugger/lib/cn.js +3 -0
  112. package/dist/debugger/lib/event-counts.d.ts +2 -2
  113. package/dist/debugger/lib/event-counts.js +5 -9
  114. package/dist/debugger/lib/event-meta.d.ts +2 -3
  115. package/dist/debugger/lib/event-meta.js +6 -11
  116. package/dist/debugger/lib/json.d.ts +25 -0
  117. package/dist/debugger/lib/json.js +87 -0
  118. package/dist/debugger/lib/payload.d.ts +7 -0
  119. package/dist/debugger/lib/payload.js +11 -0
  120. package/dist/debugger/lib/time.d.ts +3 -0
  121. package/dist/debugger/lib/time.js +24 -0
  122. package/dist/debugger/plugin.d.ts +36 -0
  123. package/dist/debugger/plugin.js +14 -0
  124. package/dist/debugger/server/index.d.ts +14 -0
  125. package/dist/debugger/server/index.js +114 -0
  126. package/dist/debugger/shell/debugger-shell.d.ts +15 -0
  127. package/dist/debugger/shell/debugger-shell.js +43 -0
  128. package/dist/debugger/shell/definition-key.d.ts +3 -0
  129. package/dist/debugger/shell/definition-key.js +4 -0
  130. package/dist/debugger/shell/events-pane.d.ts +12 -0
  131. package/dist/debugger/shell/events-pane.js +25 -0
  132. package/dist/debugger/shell/projections-panel.d.ts +4 -0
  133. package/dist/debugger/shell/projections-panel.js +59 -0
  134. package/dist/debugger/shell/run-controls.d.ts +5 -0
  135. package/dist/debugger/shell/run-controls.js +99 -0
  136. package/dist/debugger/shell/run-search.d.ts +6 -0
  137. package/dist/debugger/shell/run-search.js +100 -0
  138. package/dist/debugger/shell/run-type-menu.d.ts +6 -0
  139. package/dist/debugger/shell/run-type-menu.js +11 -0
  140. package/dist/debugger/shell/schema-form.d.ts +31 -0
  141. package/dist/debugger/shell/schema-form.js +117 -0
  142. package/dist/debugger/shell/start-form.d.ts +3 -0
  143. package/dist/debugger/shell/start-form.js +75 -0
  144. package/dist/debugger/shell/use-start-run.d.ts +14 -0
  145. package/dist/debugger/shell/use-start-run.js +32 -0
  146. package/dist/debugger/shell/workspace.d.ts +6 -0
  147. package/dist/debugger/shell/workspace.js +15 -0
  148. package/dist/debugger/styles.css +111 -27
  149. package/dist/debugger/ui/button.d.ts +24 -0
  150. package/dist/debugger/ui/button.js +24 -0
  151. package/dist/debugger/ui/command.d.ts +9 -0
  152. package/dist/debugger/ui/command.js +24 -0
  153. package/dist/debugger/ui/dropdown-menu.d.ts +13 -0
  154. package/dist/debugger/ui/dropdown-menu.js +37 -0
  155. package/dist/debugger/ui/panel.d.ts +14 -0
  156. package/dist/debugger/ui/panel.js +16 -0
  157. package/dist/debugger/ui/popover.d.ts +7 -0
  158. package/dist/debugger/ui/popover.js +17 -0
  159. package/dist/debugger/ui/resizable.d.ts +7 -0
  160. package/dist/debugger/ui/resizable.js +14 -0
  161. package/dist/debugger/ui/scroll-area.d.ts +2 -1
  162. package/dist/debugger/ui/scroll-area.js +5 -3
  163. package/dist/debugger/ui/select.d.ts +10 -0
  164. package/dist/debugger/ui/select.js +21 -0
  165. package/dist/debugger/ui/tabs.js +2 -2
  166. package/dist/debugger/ui/textarea.d.ts +3 -0
  167. package/dist/debugger/ui/textarea.js +7 -0
  168. package/dist/evaluator/effects.d.ts +12 -0
  169. package/dist/evaluator/module.d.ts +24 -0
  170. package/dist/projectors/index-model.d.ts +13 -7
  171. package/dist/projectors/index-model.js +21 -26
  172. package/dist/projectors/memory.js +19 -11
  173. package/dist/projectors/postgres.js +20 -19
  174. package/dist/projectors/schema.js +20 -18
  175. package/dist/projectors/sqlite.js +32 -27
  176. package/dist/react/materialize.js +16 -11
  177. package/dist/react/react.d.ts +6 -2
  178. package/dist/react/react.js +5 -2
  179. package/dist/react/store.d.ts +1 -1
  180. package/dist/react/store.js +1 -1
  181. package/dist/react/tables.d.ts +3 -2
  182. package/dist/runtime/cancellation.js +14 -27
  183. package/dist/runtime/errors.d.ts +39 -0
  184. package/dist/runtime/errors.js +32 -0
  185. package/dist/runtime/helpers.d.ts +2 -0
  186. package/dist/runtime/helpers.js +23 -1
  187. package/dist/runtime/index.d.ts +1 -1
  188. package/dist/runtime/index.js +1 -1
  189. package/dist/runtime/looms.d.ts +13 -1
  190. package/dist/runtime/looms.js +5 -2
  191. package/dist/runtime/repository.js +16 -1
  192. package/dist/runtime/run-start.js +1 -3
  193. package/dist/runtime/runtime.d.ts +1 -1
  194. package/dist/runtime/runtime.js +60 -18
  195. package/dist/runtime/server/auth.d.ts +1 -0
  196. package/dist/runtime/server/auth.js +5 -0
  197. package/dist/runtime/server/debugger-host.d.ts +11 -0
  198. package/dist/runtime/server/debugger-host.js +32 -0
  199. package/dist/runtime/server/fetch-handler.d.ts +5 -1
  200. package/dist/runtime/server/fetch-handler.js +24 -13
  201. package/dist/runtime/server/http.d.ts +3 -0
  202. package/dist/runtime/server/http.js +21 -2
  203. package/dist/runtime/server/routes/definitions.d.ts +3 -0
  204. package/dist/runtime/server/routes/definitions.js +20 -0
  205. package/dist/runtime/server/routes/runs.js +43 -3
  206. package/dist/runtime/server.d.ts +3 -1
  207. package/dist/runtime/server.js +3 -1
  208. package/dist/runtime/types.d.ts +11 -1
  209. package/dist/runtime/wake-engine.js +5 -2
  210. package/dist/s2/snapshot-store.js +45 -7
  211. package/dist/workflow/debugger/index.d.ts +4 -0
  212. package/dist/workflow/debugger/index.js +11 -0
  213. package/dist/workflow/debugger/nodes-view.d.ts +3 -0
  214. package/dist/workflow/debugger/nodes-view.js +13 -0
  215. package/dist/workflow/debugger/summarize.d.ts +2 -0
  216. package/dist/workflow/debugger/summarize.js +30 -0
  217. package/dist/workflow/effects.d.ts +24 -0
  218. package/dist/workflow/effects.js +1 -0
  219. package/dist/workflow/module.d.ts +48 -0
  220. package/package.json +20 -1
  221. package/dist/debugger/events/domain-summarize.d.ts +0 -3
  222. package/dist/debugger/events/domain-summarize.js +0 -107
  223. package/dist/debugger/events/family.d.ts +0 -8
  224. package/dist/debugger/events/family.js +0 -44
@@ -138,6 +138,11 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
138
138
  readonly attempt: number;
139
139
  readonly deadlineAt: number | null;
140
140
  };
141
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
142
+ readonly type: "runtime.fork.elided";
143
+ readonly payload: {
144
+ readonly type: string;
145
+ };
141
146
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
142
147
  readonly type: "runtime.run.cancelled";
143
148
  readonly payload: {
@@ -149,6 +154,12 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
149
154
  readonly output: import("effect/Schema").Json;
150
155
  readonly error: string | null;
151
156
  };
157
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
158
+ readonly type: "runtime.run.forked";
159
+ readonly payload: {
160
+ readonly sourceRunId: string;
161
+ readonly sourceSeq: number;
162
+ };
152
163
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
153
164
  readonly type: "runtime.run.started";
154
165
  readonly payload: {
@@ -181,6 +192,7 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
181
192
  readonly payload: {
182
193
  readonly threadId: string;
183
194
  readonly reason?: string | undefined;
195
+ readonly resumeSeq?: number | undefined;
184
196
  };
185
197
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
186
198
  readonly type: "runtime.thread.completed";
@@ -372,6 +384,11 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
372
384
  readonly attempt: number;
373
385
  readonly deadlineAt: number | null;
374
386
  };
387
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
388
+ readonly type: "runtime.fork.elided";
389
+ readonly payload: {
390
+ readonly type: string;
391
+ };
375
392
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
376
393
  readonly type: "runtime.run.cancelled";
377
394
  readonly payload: {
@@ -383,6 +400,12 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
383
400
  readonly output: import("effect/Schema").Json;
384
401
  readonly error: string | null;
385
402
  };
403
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
404
+ readonly type: "runtime.run.forked";
405
+ readonly payload: {
406
+ readonly sourceRunId: string;
407
+ readonly sourceSeq: number;
408
+ };
386
409
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
387
410
  readonly type: "runtime.run.started";
388
411
  readonly payload: {
@@ -415,6 +438,7 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
415
438
  readonly payload: {
416
439
  readonly threadId: string;
417
440
  readonly reason?: string | undefined;
441
+ readonly resumeSeq?: number | undefined;
418
442
  };
419
443
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
420
444
  readonly type: "runtime.thread.completed";
@@ -37,6 +37,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
37
37
  readonly idempotencyKey: string | null;
38
38
  readonly rootThreadId: string;
39
39
  } | null;
40
+ readonly forkedFrom: {
41
+ readonly runId: string;
42
+ readonly seq: number;
43
+ } | null;
40
44
  readonly threads: {
41
45
  readonly [x: string]: {
42
46
  readonly threadId: string;
@@ -160,6 +164,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
160
164
  readonly idempotencyKey: string | null;
161
165
  readonly rootThreadId: string;
162
166
  } | null;
167
+ readonly forkedFrom: {
168
+ readonly runId: string;
169
+ readonly seq: number;
170
+ } | null;
163
171
  readonly threads: {
164
172
  readonly [x: string]: {
165
173
  readonly threadId: string;
@@ -281,6 +289,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
281
289
  readonly idempotencyKey: string | null;
282
290
  readonly rootThreadId: string;
283
291
  } | null;
292
+ readonly forkedFrom: {
293
+ readonly runId: string;
294
+ readonly seq: number;
295
+ } | null;
284
296
  readonly threads: {
285
297
  readonly [x: string]: {
286
298
  readonly threadId: string;
@@ -402,6 +414,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
402
414
  readonly idempotencyKey: string | null;
403
415
  readonly rootThreadId: string;
404
416
  } | null;
417
+ readonly forkedFrom: {
418
+ readonly runId: string;
419
+ readonly seq: number;
420
+ } | null;
405
421
  readonly threads: {
406
422
  readonly [x: string]: {
407
423
  readonly threadId: string;
@@ -553,6 +569,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
553
569
  readonly idempotencyKey: string | null;
554
570
  readonly rootThreadId: string;
555
571
  } | null;
572
+ readonly forkedFrom: {
573
+ readonly runId: string;
574
+ readonly seq: number;
575
+ } | null;
556
576
  readonly threads: {
557
577
  readonly [x: string]: {
558
578
  readonly threadId: string;
@@ -674,6 +694,266 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
674
694
  readonly idempotencyKey: string | null;
675
695
  readonly rootThreadId: string;
676
696
  } | null;
697
+ readonly forkedFrom: {
698
+ readonly runId: string;
699
+ readonly seq: number;
700
+ } | null;
701
+ readonly threads: {
702
+ readonly [x: string]: {
703
+ readonly threadId: string;
704
+ readonly kind: string;
705
+ readonly definitionName: string;
706
+ readonly definitionVersion: string;
707
+ readonly parentThreadId: string | null;
708
+ readonly status: "cancelled" | "completed" | "failed" | "running" | "waiting";
709
+ readonly input: Schema.Json;
710
+ readonly output: Schema.Json;
711
+ readonly error: string | null;
712
+ readonly state: Schema.Json;
713
+ };
714
+ };
715
+ readonly waits: {
716
+ readonly [x: string]: {
717
+ readonly waitId: string;
718
+ readonly threadId: string;
719
+ readonly on: {
720
+ readonly type: string | readonly string[];
721
+ readonly match?: Schema.Json | undefined;
722
+ } | {
723
+ readonly timerAt: number;
724
+ };
725
+ readonly tag?: Schema.Json | undefined;
726
+ };
727
+ };
728
+ readonly outstandingEffects: readonly {
729
+ readonly effectId: string;
730
+ readonly threadId: string;
731
+ readonly causingSeq: number;
732
+ readonly causingEventId: string;
733
+ readonly effect: {
734
+ readonly type: "runtime.spawn";
735
+ readonly childThreadId: string;
736
+ readonly kind: string;
737
+ readonly definitionName: string;
738
+ readonly definitionVersion: string;
739
+ readonly input: Schema.Json;
740
+ } | {
741
+ readonly type: "runtime.wait";
742
+ readonly waitId: string;
743
+ readonly on: {
744
+ readonly type: string | readonly string[];
745
+ readonly match?: Schema.Json | undefined;
746
+ } | {
747
+ readonly timerAt: number;
748
+ };
749
+ readonly tag?: Schema.Json | undefined;
750
+ } | {
751
+ readonly type: "runtime.emit";
752
+ readonly event: {
753
+ readonly type: string;
754
+ readonly payload: Schema.Json;
755
+ readonly threadId?: string | null | undefined;
756
+ readonly parentThreadId?: string | null | undefined;
757
+ readonly causationId?: string | null | undefined;
758
+ readonly correlationId?: string | null | undefined;
759
+ readonly effectId?: string | null | undefined;
760
+ readonly origin?: {
761
+ readonly type: "thread";
762
+ readonly threadId: string;
763
+ } | {
764
+ readonly type: "external";
765
+ readonly actorId?: string | undefined;
766
+ } | {
767
+ readonly type: "system";
768
+ } | undefined;
769
+ readonly ephemeral?: boolean | undefined;
770
+ readonly id?: string | undefined;
771
+ readonly ts?: number | undefined;
772
+ readonly idempotencyKey?: string | null | undefined;
773
+ };
774
+ readonly tag?: string | undefined;
775
+ } | {
776
+ readonly type: "runtime.complete";
777
+ readonly output: Schema.Json;
778
+ } | {
779
+ readonly type: "runtime.fail";
780
+ readonly error: string;
781
+ } | {
782
+ readonly type: "runtime.cancel";
783
+ readonly threadId: string;
784
+ readonly tag?: string | undefined;
785
+ } | {
786
+ readonly type: string;
787
+ readonly input: Schema.Json;
788
+ readonly tag?: string | undefined;
789
+ };
790
+ }[];
791
+ readonly effectExecutions: {
792
+ readonly [x: string]: {
793
+ readonly effectId: string;
794
+ readonly attempt: number;
795
+ readonly status: "ambiguous" | "cancel_requested" | "dispatched" | "heartbeat" | "queued" | "retry_wait" | "running" | "started" | "timed_out";
796
+ readonly nextAttemptAt: number | null;
797
+ readonly deadlineAt: number | null;
798
+ readonly startedAt: number | null;
799
+ readonly lastHeartbeatAt: number | null;
800
+ readonly lastError: string | null;
801
+ };
802
+ };
803
+ readonly completedEffectIds: readonly string[];
804
+ readonly processedIdempotencyKeys: readonly string[];
805
+ };
806
+ readonly appended: number;
807
+ }>;
808
+ /** Cancel a thread and its descendants; omit `threadId` to cancel the whole run. */
809
+ cancel: (runId: string, threadId?: string) => Promise<{
810
+ readonly runId: string;
811
+ readonly state: {
812
+ readonly runId: string;
813
+ readonly status: "cancelled" | "completed" | "failed" | "running";
814
+ readonly rootThreadId: string | null;
815
+ readonly startIdentity: {
816
+ readonly kind: string;
817
+ readonly definitionName: string;
818
+ readonly definitionVersion: string;
819
+ readonly input: Schema.Json;
820
+ readonly requestedThreadId: string | null;
821
+ readonly idempotencyKey: string | null;
822
+ readonly rootThreadId: string;
823
+ } | null;
824
+ readonly forkedFrom: {
825
+ readonly runId: string;
826
+ readonly seq: number;
827
+ } | null;
828
+ readonly threads: {
829
+ readonly [x: string]: {
830
+ readonly threadId: string;
831
+ readonly kind: string;
832
+ readonly definitionName: string;
833
+ readonly definitionVersion: string;
834
+ readonly parentThreadId: string | null;
835
+ readonly status: "cancelled" | "completed" | "failed" | "running" | "waiting";
836
+ readonly input: Schema.Json;
837
+ readonly output: Schema.Json;
838
+ readonly error: string | null;
839
+ readonly state: Schema.Json;
840
+ };
841
+ };
842
+ readonly waits: {
843
+ readonly [x: string]: {
844
+ readonly waitId: string;
845
+ readonly threadId: string;
846
+ readonly on: {
847
+ readonly type: string | readonly string[];
848
+ readonly match?: Schema.Json | undefined;
849
+ } | {
850
+ readonly timerAt: number;
851
+ };
852
+ readonly tag?: Schema.Json | undefined;
853
+ };
854
+ };
855
+ readonly outstandingEffects: readonly {
856
+ readonly effectId: string;
857
+ readonly threadId: string;
858
+ readonly causingSeq: number;
859
+ readonly causingEventId: string;
860
+ readonly effect: {
861
+ readonly type: "runtime.spawn";
862
+ readonly childThreadId: string;
863
+ readonly kind: string;
864
+ readonly definitionName: string;
865
+ readonly definitionVersion: string;
866
+ readonly input: Schema.Json;
867
+ } | {
868
+ readonly type: "runtime.wait";
869
+ readonly waitId: string;
870
+ readonly on: {
871
+ readonly type: string | readonly string[];
872
+ readonly match?: Schema.Json | undefined;
873
+ } | {
874
+ readonly timerAt: number;
875
+ };
876
+ readonly tag?: Schema.Json | undefined;
877
+ } | {
878
+ readonly type: "runtime.emit";
879
+ readonly event: {
880
+ readonly type: string;
881
+ readonly payload: Schema.Json;
882
+ readonly threadId?: string | null | undefined;
883
+ readonly parentThreadId?: string | null | undefined;
884
+ readonly causationId?: string | null | undefined;
885
+ readonly correlationId?: string | null | undefined;
886
+ readonly effectId?: string | null | undefined;
887
+ readonly origin?: {
888
+ readonly type: "thread";
889
+ readonly threadId: string;
890
+ } | {
891
+ readonly type: "external";
892
+ readonly actorId?: string | undefined;
893
+ } | {
894
+ readonly type: "system";
895
+ } | undefined;
896
+ readonly ephemeral?: boolean | undefined;
897
+ readonly id?: string | undefined;
898
+ readonly ts?: number | undefined;
899
+ readonly idempotencyKey?: string | null | undefined;
900
+ };
901
+ readonly tag?: string | undefined;
902
+ } | {
903
+ readonly type: "runtime.complete";
904
+ readonly output: Schema.Json;
905
+ } | {
906
+ readonly type: "runtime.fail";
907
+ readonly error: string;
908
+ } | {
909
+ readonly type: "runtime.cancel";
910
+ readonly threadId: string;
911
+ readonly tag?: string | undefined;
912
+ } | {
913
+ readonly type: string;
914
+ readonly input: Schema.Json;
915
+ readonly tag?: string | undefined;
916
+ };
917
+ }[];
918
+ readonly effectExecutions: {
919
+ readonly [x: string]: {
920
+ readonly effectId: string;
921
+ readonly attempt: number;
922
+ readonly status: "ambiguous" | "cancel_requested" | "dispatched" | "heartbeat" | "queued" | "retry_wait" | "running" | "started" | "timed_out";
923
+ readonly nextAttemptAt: number | null;
924
+ readonly deadlineAt: number | null;
925
+ readonly startedAt: number | null;
926
+ readonly lastHeartbeatAt: number | null;
927
+ readonly lastError: string | null;
928
+ };
929
+ };
930
+ readonly completedEffectIds: readonly string[];
931
+ readonly processedIdempotencyKeys: readonly string[];
932
+ };
933
+ }>;
934
+ /** Start a new run that continues where a finished run ended. */
935
+ fork: (sourceRunId: string, forkOptions?: {
936
+ runId?: string;
937
+ }) => Promise<{
938
+ readonly runId: string;
939
+ readonly threadId: string;
940
+ readonly state: {
941
+ readonly runId: string;
942
+ readonly status: "cancelled" | "completed" | "failed" | "running";
943
+ readonly rootThreadId: string | null;
944
+ readonly startIdentity: {
945
+ readonly kind: string;
946
+ readonly definitionName: string;
947
+ readonly definitionVersion: string;
948
+ readonly input: Schema.Json;
949
+ readonly requestedThreadId: string | null;
950
+ readonly idempotencyKey: string | null;
951
+ readonly rootThreadId: string;
952
+ } | null;
953
+ readonly forkedFrom: {
954
+ readonly runId: string;
955
+ readonly seq: number;
956
+ } | null;
677
957
  readonly threads: {
678
958
  readonly [x: string]: {
679
959
  readonly threadId: string;
@@ -795,6 +1075,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
795
1075
  readonly idempotencyKey: string | null;
796
1076
  readonly rootThreadId: string;
797
1077
  } | null;
1078
+ readonly forkedFrom: {
1079
+ readonly runId: string;
1080
+ readonly seq: number;
1081
+ } | null;
798
1082
  readonly threads: {
799
1083
  readonly [x: string]: {
800
1084
  readonly threadId: string;
@@ -901,6 +1185,24 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
901
1185
  readonly processedIdempotencyKeys: readonly string[];
902
1186
  };
903
1187
  }>;
1188
+ listRunSummaries: () => Promise<{
1189
+ readonly runs: readonly {
1190
+ readonly runId: string;
1191
+ readonly status: "cancelled" | "completed" | "failed" | "running";
1192
+ readonly kind: string | null;
1193
+ readonly definitionName: string | null;
1194
+ }[];
1195
+ }>;
1196
+ listDefinitions: () => Promise<{
1197
+ readonly definitions: readonly {
1198
+ readonly kind: string;
1199
+ readonly name: string;
1200
+ readonly version: string;
1201
+ readonly description?: string | undefined;
1202
+ readonly inputSchema?: Schema.Json | undefined;
1203
+ }[];
1204
+ readonly projections: readonly string[];
1205
+ }>;
904
1206
  replayTo: (runId: string, seq: number) => Promise<{
905
1207
  readonly runId: string;
906
1208
  readonly step: {
@@ -942,6 +1244,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
942
1244
  readonly idempotencyKey: string | null;
943
1245
  readonly rootThreadId: string;
944
1246
  } | null;
1247
+ readonly forkedFrom: {
1248
+ readonly runId: string;
1249
+ readonly seq: number;
1250
+ } | null;
945
1251
  readonly threads: {
946
1252
  readonly [x: string]: {
947
1253
  readonly threadId: string;
@@ -1060,6 +1366,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
1060
1366
  readonly idempotencyKey: string | null;
1061
1367
  readonly rootThreadId: string;
1062
1368
  } | null;
1369
+ readonly forkedFrom: {
1370
+ readonly runId: string;
1371
+ readonly seq: number;
1372
+ } | null;
1063
1373
  readonly threads: {
1064
1374
  readonly [x: string]: {
1065
1375
  readonly threadId: string;
@@ -1,5 +1,5 @@
1
1
  import { Data, Effect, Option, Schema, Stream } from 'effect';
2
- import { createRunId, EventEnvelopeSchema, ReplayStepSchema, RunStateSchema, stringifyJson, } from '@swirls/looms/core';
2
+ import { createRunId, DefinitionCatalogSchema, EventEnvelopeSchema, ReplayStepSchema, RunStateSchema, RunSummariesSchema, stringifyJson, } from '@swirls/looms/core';
3
3
  import { consumeSseStreamEffect, eventsFromSseData, sseFrames } from './sse.js';
4
4
  class LoomsClientError extends Data.TaggedError('LoomsClientError') {
5
5
  constructor(message, cause) {
@@ -14,6 +14,12 @@ const StartResultSchema = Schema.Struct({
14
14
  state: RunStateSchema,
15
15
  });
16
16
  const RunResultSchema = Schema.Struct({ runId: Schema.String, state: RunStateSchema });
17
+ /** `appended` counts the events the run gained while the wake ran. */
18
+ const WakeResultSchema = Schema.Struct({
19
+ runId: Schema.String,
20
+ state: RunStateSchema,
21
+ appended: Schema.Finite,
22
+ });
17
23
  const EventsResultSchema = Schema.Struct({
18
24
  runId: Schema.String,
19
25
  events: Schema.Array(EventEnvelopeSchema),
@@ -157,8 +163,20 @@ export function createLoomsClient(options = {}) {
157
163
  method: 'POST',
158
164
  body: stringifyJson({ events }),
159
165
  }),
160
- wake: (runId) => request(`/runs/${encodeURIComponent(runId)}/wake`, RunResultSchema, { method: 'POST' }),
166
+ wake: (runId) => request(`/runs/${encodeURIComponent(runId)}/wake`, WakeResultSchema, { method: 'POST' }),
167
+ /** Cancel a thread and its descendants; omit `threadId` to cancel the whole run. */
168
+ cancel: (runId, threadId) => request(`/runs/${encodeURIComponent(runId)}/cancel`, RunResultSchema, {
169
+ method: 'POST',
170
+ body: stringifyJson(threadId === undefined ? {} : { threadId }),
171
+ }),
172
+ /** Start a new run that continues where a finished run ended. */
173
+ fork: (sourceRunId, forkOptions) => request(`/runs/${encodeURIComponent(sourceRunId)}/fork`, StartResultSchema, {
174
+ method: 'POST',
175
+ body: stringifyJson(forkOptions?.runId === undefined ? {} : { runId: forkOptions.runId }),
176
+ }),
161
177
  workerCallback,
178
+ listRunSummaries: () => request('/runs/summaries', RunSummariesSchema),
179
+ listDefinitions: () => request('/definitions', DefinitionCatalogSchema),
162
180
  replayTo: (runId, seq) => request(`/runs/${encodeURIComponent(runId)}/replay?seq=${seq}`, ReplayResultSchema),
163
181
  project: (runId, name) => request(`/runs/${encodeURIComponent(runId)}/projections/${encodeURIComponent(name)}`, ProjectionResultSchema),
164
182
  subscribeEvents,
@@ -6,7 +6,7 @@ export interface DurableObjectNamespaceLike<T extends DurableObjectStubLike = Du
6
6
  }
7
7
  /**
8
8
  * Routes incoming HTTP requests to the appropriate Durable Object actor cell.
9
- * Handles `/health` locally, returns 501 for global `GET /runs`, and forwards
9
+ * Handles `/health` locally, returns 501 for global run lists and forks, and forwards
10
10
  * all other run and event-stream requests to `namespace.getByName(runId)`.
11
11
  */
12
12
  export declare function routeToDurableObject(namespace: DurableObjectNamespaceLike, req: Request): Promise<Response | null>;
@@ -1,18 +1,16 @@
1
- import { resolveRunTarget, RunTargetError } from '@swirls/looms/actor';
1
+ import { crossRunResponse, resolveRunTarget, RunTargetError } from '@swirls/looms/actor';
2
2
  /**
3
3
  * Routes incoming HTTP requests to the appropriate Durable Object actor cell.
4
- * Handles `/health` locally, returns 501 for global `GET /runs`, and forwards
4
+ * Handles `/health` locally, returns 501 for global run lists and forks, and forwards
5
5
  * all other run and event-stream requests to `namespace.getByName(runId)`.
6
6
  */
7
7
  export function routeToDurableObject(namespace, req) {
8
- const url = new URL(req.url);
9
- if (url.pathname === '/health') {
8
+ if (new URL(req.url).pathname === '/health') {
10
9
  return Promise.resolve(Response.json({ ok: true }));
11
10
  }
12
- if (req.method === 'GET' && url.pathname === '/runs') {
13
- return Promise.resolve(Response.json({
14
- error: 'Global run listing is not supported in the Durable Object backend without a global index',
15
- }, { status: 501 }));
11
+ const unsupported = crossRunResponse(req, 'the Durable Object backend');
12
+ if (unsupported) {
13
+ return Promise.resolve(unsupported);
16
14
  }
17
15
  return resolveRunTarget(req)
18
16
  .then(({ runId, request }) => namespace.getByName(runId).fetch(request))
@@ -57,6 +57,7 @@ export function composeModules(modules) {
57
57
  name: definition.name,
58
58
  version,
59
59
  input: definition.input,
60
+ description: definition.description,
60
61
  value: definition,
61
62
  });
62
63
  }
@@ -0,0 +1,16 @@
1
+ /** A request the runtime has matched and authorized under the debugger mount. */
2
+ export interface DebuggerRequest {
3
+ /** Mount path without a trailing slash, such as `/debugger`. */
4
+ readonly basePath: string;
5
+ /** Path below the mount: empty for the mount itself, otherwise it starts with `/`. */
6
+ readonly path: string;
7
+ }
8
+ /**
9
+ * Serves a debugger UI under `basePath`. The runtime matches, authorizes, and strips the mount
10
+ * path; the host only serves files.
11
+ */
12
+ export interface DebuggerHost {
13
+ /** Absolute mount path, such as `/debugger`. Must not overlap the HTTP API. */
14
+ readonly basePath: string;
15
+ fetch(req: Request, mount: DebuggerRequest): Promise<Response | null>;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -166,6 +166,11 @@ export interface EffectDefinition<TInput = JsonValue, R = Context.Service.Any, E
166
166
  readonly execution?: EffectExecution;
167
167
  /** Whether `execute` runs a user handler. Without one, the effect can only complete through a worker. */
168
168
  readonly hasHandler: boolean;
169
+ /**
170
+ * The outcome follows from the input alone, like scheduling from state already folded. Forking
171
+ * a failed run retries the effect that produced the failure, not a deterministic one passing it on.
172
+ */
173
+ readonly deterministic?: boolean;
169
174
  readonly [effectInputType]?: (input: TInput) => TInput;
170
175
  execute(input: JsonValue, ctx: EffectContext): Effect.Effect<ReadonlyArray<E>, InvalidInputError | EffectHandlerError, R>;
171
176
  }
@@ -182,6 +187,7 @@ export declare function defineEffect<TSchema extends SchemaInput, R = never, E e
182
187
  input: TSchema;
183
188
  retry?: RetryPolicy;
184
189
  execution?: EffectExecution;
190
+ deterministic?: boolean;
185
191
  execute?: (input: InferDefinedSchema<TSchema>, ctx: EffectContext) => EffectHandlerResult<R, E, HandlerError>;
186
192
  }): EffectDefinition<InferDefinedSchema<TSchema>, R, E>;
187
193
  export declare function defineEffect<R = never, E extends EventInput = EventInput, HandlerError = never>(def: {
@@ -189,6 +195,7 @@ export declare function defineEffect<R = never, E extends EventInput = EventInpu
189
195
  input?: undefined;
190
196
  retry?: RetryPolicy;
191
197
  execution?: EffectExecution;
198
+ deterministic?: boolean;
192
199
  execute?: (input: JsonValue, ctx: EffectContext) => EffectHandlerResult<R, E, HandlerError>;
193
200
  }): EffectDefinition<JsonValue, R, E>;
194
201
  export declare function spawn(args: {
@@ -106,6 +106,7 @@ export function defineEffect(def) {
106
106
  retry: def.retry,
107
107
  execution: def.execution,
108
108
  hasHandler: handler !== undefined,
109
+ deterministic: def.deterministic,
109
110
  execute: (raw, ctx) => Effect.gen(function* () {
110
111
  const input = schema ? yield* validateInputEffect(schema, raw) : raw;
111
112
  return handler ? yield* liftHandlerResult(handler(input, ctx)) : noOutput;
package/dist/core/fold.js CHANGED
@@ -2,7 +2,7 @@ import { Option, Predicate, Schema, Stream } from 'effect';
2
2
  import { isWithdrawnError, WaitConditionSchema } from './effects.js';
3
3
  import { createEffectId } from './ids.js';
4
4
  import { DEFAULT_DEFINITION_VERSION } from './module.js';
5
- import { emptyRunState } from './state.js';
5
+ import { completedRunStatus, emptyRunState } from './state.js';
6
6
  import { isTerminalStatus } from './thread.js';
7
7
  const decodeWaitCondition = Schema.decodeUnknownOption(WaitConditionSchema);
8
8
  function payloadObject(event) {
@@ -25,6 +25,7 @@ function cloneState(state) {
25
25
  status: state.status,
26
26
  rootThreadId: state.rootThreadId,
27
27
  startIdentity: state.startIdentity,
28
+ forkedFrom: state.forkedFrom,
28
29
  threads: { ...state.threads },
29
30
  waits: { ...state.waits },
30
31
  outstandingEffects: [...state.outstandingEffects],
@@ -104,13 +105,18 @@ function applyProtocol(state, event, registry) {
104
105
  status: 'running',
105
106
  };
106
107
  }
107
- case 'runtime.run.completed': {
108
- const error = payload.error;
109
- const status = Predicate.isString(error) && error.length > 0 ? 'failed' : 'completed';
110
- return { ...state, status };
111
- }
108
+ case 'runtime.run.completed':
109
+ return { ...state, status: completedRunStatus(payload) };
112
110
  case 'runtime.run.cancelled':
113
111
  return { ...state, status: 'cancelled' };
112
+ case 'runtime.run.forked': {
113
+ const sourceRunId = readString(payload, 'sourceRunId');
114
+ const sourceSeq = payload.sourceSeq;
115
+ // Attempts recorded in the copied history belong to the source run's processes.
116
+ return sourceRunId && Predicate.isNumber(sourceSeq)
117
+ ? { ...state, forkedFrom: { runId: sourceRunId, seq: sourceSeq }, effectExecutions: {} }
118
+ : state;
119
+ }
114
120
  case 'runtime.thread.started': {
115
121
  const threadId = readString(payload, 'threadId') ?? event.threadId;
116
122
  const kind = readString(payload, 'kind');
@@ -0,0 +1,35 @@
1
+ import { Effect } from 'effect';
2
+ import { type EffectDefinition } from './effects';
3
+ import { type EventEnvelope } from './envelope';
4
+ import { type FoldRegistry } from './fold';
5
+ declare const ForkSourceError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
6
+ readonly _tag: "ForkSourceError";
7
+ } & Readonly<A>;
8
+ export declare class ForkSourceError extends ForkSourceError_base<{
9
+ readonly runId: string;
10
+ readonly message: string;
11
+ }> {
12
+ constructor(runId: string, message: string);
13
+ }
14
+ export interface ForkRegistry extends FoldRegistry {
15
+ readonly effects: ReadonlyMap<string, Pick<EffectDefinition, 'deterministic'>>;
16
+ }
17
+ export interface ForkPlan {
18
+ /** The fork's history: the copied prefix, keeping source seqs, then the `runtime.run.forked` marker. */
19
+ readonly events: readonly EventEnvelope[];
20
+ /** Last source seq the fork copied. */
21
+ readonly sourceSeq: number;
22
+ readonly rootThreadId: string;
23
+ }
24
+ /**
25
+ * Plan a new run that continues where the source run ended. The fork copies the source's
26
+ * history up to the point the run finished, keeping sequence numbers so effect ids still
27
+ * line up, and its next wake re-issues whatever effects were outstanding there.
28
+ */
29
+ export declare function planFork(input: {
30
+ readonly sourceRunId: string;
31
+ readonly runId: string;
32
+ readonly events: readonly EventEnvelope[];
33
+ readonly registry: ForkRegistry;
34
+ }): Effect.Effect<ForkPlan, ForkSourceError>;
35
+ export {};