@swirls/looms 0.4.0 → 0.5.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 (241) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/actor/cell.d.ts +21 -2
  3. package/dist/actor/cell.js +15 -3
  4. package/dist/actor/host.d.ts +10 -2
  5. package/dist/actor/host.js +27 -4
  6. package/dist/actor/index.d.ts +2 -1
  7. package/dist/actor/index.js +1 -1
  8. package/dist/actor/routing.d.ts +3 -0
  9. package/dist/actor/routing.js +13 -2
  10. package/dist/agent/definitions-store.d.ts +1 -1
  11. package/dist/agent/definitions-store.js +1 -1
  12. package/dist/agent/definitions.d.ts +48 -0
  13. package/dist/agent/definitions.js +44 -0
  14. package/dist/agent/effects.d.ts +184 -0
  15. package/dist/agent/effects.js +172 -40
  16. package/dist/agent/events.d.ts +89 -0
  17. package/dist/agent/events.js +25 -0
  18. package/dist/agent/module.d.ts +412 -0
  19. package/dist/agent/module.js +5 -1
  20. package/dist/agent/scope.d.ts +88 -0
  21. package/dist/agent/threads.js +39 -3
  22. package/dist/agent/types.d.ts +4 -0
  23. package/dist/approval/effects.d.ts +40 -0
  24. package/dist/approval/module.d.ts +80 -0
  25. package/dist/client/client.d.ts +468 -119
  26. package/dist/client/client.js +214 -21
  27. package/dist/client/index.d.ts +1 -1
  28. package/dist/client/sse.d.ts +1 -1
  29. package/dist/client/sse.js +2 -2
  30. package/dist/cloudflare/durable-object.d.ts +66 -2
  31. package/dist/cloudflare/durable-object.js +96 -1
  32. package/dist/cloudflare/event-store.d.ts +7 -3
  33. package/dist/cloudflare/event-store.js +16 -3
  34. package/dist/cloudflare/index.d.ts +7 -1
  35. package/dist/cloudflare/index.js +7 -1
  36. package/dist/cloudflare/memory-queue.d.ts +18 -0
  37. package/dist/cloudflare/memory-queue.js +53 -0
  38. package/dist/cloudflare/queue-consumer.d.ts +52 -0
  39. package/dist/cloudflare/queue-consumer.js +102 -0
  40. package/dist/cloudflare/queue-message.d.ts +31 -0
  41. package/dist/cloudflare/queue-message.js +33 -0
  42. package/dist/cloudflare/queue-pull.d.ts +62 -0
  43. package/dist/cloudflare/queue-pull.js +130 -0
  44. package/dist/cloudflare/queue-worker.d.ts +39 -0
  45. package/dist/cloudflare/queue-worker.js +62 -0
  46. package/dist/cloudflare/r2-blob-store.d.ts +33 -0
  47. package/dist/cloudflare/r2-blob-store.js +60 -0
  48. package/dist/cloudflare/router.d.ts +4 -1
  49. package/dist/cloudflare/router.js +8 -3
  50. package/dist/cloudflare/websocket.d.ts +27 -0
  51. package/dist/cloudflare/websocket.js +215 -0
  52. package/dist/core/blob-offload.d.ts +21 -0
  53. package/dist/core/blob-offload.js +143 -0
  54. package/dist/core/blob-store.d.ts +45 -0
  55. package/dist/core/blob-store.js +164 -0
  56. package/dist/core/blobs.d.ts +37 -0
  57. package/dist/core/blobs.js +160 -0
  58. package/dist/core/definition-resolver.d.ts +40 -0
  59. package/dist/core/definition-resolver.js +129 -0
  60. package/dist/core/definition-store.d.ts +6 -0
  61. package/dist/core/definition-store.js +37 -1
  62. package/dist/core/effects.d.ts +86 -3
  63. package/dist/core/effects.js +99 -3
  64. package/dist/core/envelope.d.ts +9 -0
  65. package/dist/core/envelope.js +4 -0
  66. package/dist/core/event-codec.js +3 -0
  67. package/dist/core/fold.js +83 -1
  68. package/dist/core/ids.d.ts +2 -0
  69. package/dist/core/ids.js +4 -0
  70. package/dist/core/index.d.ts +8 -0
  71. package/dist/core/index.js +8 -0
  72. package/dist/core/launcher.d.ts +97 -0
  73. package/dist/core/launcher.js +67 -0
  74. package/dist/core/module-scope.d.ts +7 -3
  75. package/dist/core/module-scope.js +3 -0
  76. package/dist/core/module.d.ts +10 -0
  77. package/dist/core/projection.js +4 -0
  78. package/dist/core/protocol.d.ts +36 -1
  79. package/dist/core/protocol.js +35 -0
  80. package/dist/core/published.d.ts +2 -0
  81. package/dist/core/published.js +4 -1
  82. package/dist/core/replay.d.ts +96 -0
  83. package/dist/core/run-context.d.ts +33 -0
  84. package/dist/core/run-context.js +23 -0
  85. package/dist/core/sqlite-store.js +57 -5
  86. package/dist/core/state.d.ts +60 -0
  87. package/dist/core/state.js +19 -0
  88. package/dist/core/store.d.ts +6 -0
  89. package/dist/core/store.js +7 -0
  90. package/dist/core/subscription.d.ts +97 -0
  91. package/dist/core/subscription.js +224 -0
  92. package/dist/core/thread.d.ts +7 -0
  93. package/dist/core/thread.js +1 -0
  94. package/dist/core/trace.d.ts +21 -0
  95. package/dist/core/trace.js +45 -0
  96. package/dist/core/worker-callback.d.ts +25 -1
  97. package/dist/debugger/app/assets/{index-CgDzWJg7.css → index-B7GdT1UA.css} +1 -1
  98. package/dist/debugger/app/assets/index-C31SnCuN.js +22 -0
  99. package/dist/debugger/app/assets/routes-DPA3O5AF.js +47 -0
  100. package/dist/debugger/app/index.html +2 -2
  101. package/dist/debugger/components/event-inspector.d.ts +3 -1
  102. package/dist/debugger/components/event-inspector.js +25 -4
  103. package/dist/debugger/components/event-stream.d.ts +4 -1
  104. package/dist/debugger/components/event-stream.js +2 -2
  105. package/dist/debugger/components/run-tree.d.ts +5 -2
  106. package/dist/debugger/components/run-tree.js +10 -4
  107. package/dist/debugger/context.d.ts +8 -1
  108. package/dist/debugger/context.js +15 -3
  109. package/dist/debugger/events/protocol-summarize.js +18 -3
  110. package/dist/debugger/index.d.ts +1 -1
  111. package/dist/debugger/index.js +1 -1
  112. package/dist/debugger/shell/debugger-shell.js +1 -1
  113. package/dist/debugger/shell/events-pane.js +4 -3
  114. package/dist/debugger/styles.css +1 -0
  115. package/dist/evaluator/definitions-store.d.ts +3 -4
  116. package/dist/evaluator/definitions-store.js +3 -3
  117. package/dist/evaluator/definitions.d.ts +4 -1
  118. package/dist/evaluator/definitions.js +5 -2
  119. package/dist/evaluator/effects.d.ts +74 -33
  120. package/dist/evaluator/effects.js +6 -2
  121. package/dist/evaluator/module.d.ts +150 -66
  122. package/dist/evaluator/module.js +7 -3
  123. package/dist/evaluator/threads.d.ts +2 -0
  124. package/dist/evaluator/threads.js +4 -0
  125. package/dist/projectors/event-log.d.ts +87 -0
  126. package/dist/projectors/event-log.js +396 -0
  127. package/dist/projectors/index-model.d.ts +12 -0
  128. package/dist/projectors/index-model.js +12 -3
  129. package/dist/projectors/memory.js +7 -0
  130. package/dist/projectors/postgres.d.ts +1 -0
  131. package/dist/projectors/postgres.js +32 -15
  132. package/dist/projectors/schema.d.ts +5 -0
  133. package/dist/projectors/schema.js +26 -1
  134. package/dist/projectors/sqlite.js +47 -19
  135. package/dist/projectors/with-projectors.d.ts +7 -1
  136. package/dist/projectors/with-projectors.js +13 -3
  137. package/dist/react/materialize.js +5 -1
  138. package/dist/react/react.d.ts +10 -2
  139. package/dist/react/react.js +43 -19
  140. package/dist/react/store.d.ts +11 -2
  141. package/dist/react/store.js +104 -12
  142. package/dist/react/tables.d.ts +4 -1
  143. package/dist/runtime/cancellation.d.ts +2 -1
  144. package/dist/runtime/cancellation.js +35 -2
  145. package/dist/runtime/child-run.d.ts +10 -0
  146. package/dist/runtime/child-run.js +58 -0
  147. package/dist/runtime/deadline-transition-planner.js +11 -2
  148. package/dist/runtime/dispatch-effect.d.ts +2 -2
  149. package/dist/runtime/dispatch-effect.js +43 -19
  150. package/dist/runtime/errors.d.ts +14 -1
  151. package/dist/runtime/errors.js +10 -0
  152. package/dist/runtime/filesystem-blob-store.d.ts +6 -0
  153. package/dist/runtime/filesystem-blob-store.js +59 -0
  154. package/dist/runtime/helpers.d.ts +15 -6
  155. package/dist/runtime/helpers.js +46 -6
  156. package/dist/runtime/index.d.ts +4 -2
  157. package/dist/runtime/index.js +3 -1
  158. package/dist/runtime/local-effect-executor.d.ts +11 -2
  159. package/dist/runtime/local-effect-executor.js +80 -4
  160. package/dist/runtime/looms.d.ts +38 -4
  161. package/dist/runtime/looms.js +17 -3
  162. package/dist/runtime/repository.d.ts +5 -4
  163. package/dist/runtime/repository.js +5 -2
  164. package/dist/runtime/retry-policy.d.ts +5 -0
  165. package/dist/runtime/retry-policy.js +10 -2
  166. package/dist/runtime/run-start.d.ts +1 -1
  167. package/dist/runtime/run-start.js +10 -0
  168. package/dist/runtime/runtime.d.ts +2 -2
  169. package/dist/runtime/runtime.js +191 -68
  170. package/dist/runtime/server/auth.d.ts +3 -0
  171. package/dist/runtime/server/fetch-handler.d.ts +2 -2
  172. package/dist/runtime/server/fetch-handler.js +35 -4
  173. package/dist/runtime/server/grant.d.ts +49 -0
  174. package/dist/runtime/server/grant.js +177 -0
  175. package/dist/runtime/server/routes/effects.js +47 -5
  176. package/dist/runtime/server/routes/runs.js +6 -1
  177. package/dist/runtime/server/run-route.d.ts +18 -0
  178. package/dist/runtime/server/run-route.js +26 -0
  179. package/dist/runtime/server.d.ts +3 -1
  180. package/dist/runtime/server.js +3 -1
  181. package/dist/runtime/sse.js +26 -4
  182. package/dist/runtime/subscription.d.ts +8 -0
  183. package/dist/runtime/subscription.js +23 -0
  184. package/dist/runtime/types.d.ts +87 -8
  185. package/dist/runtime/wake-engine.d.ts +4 -2
  186. package/dist/runtime/wake-engine.js +57 -6
  187. package/dist/runtime/worker-callbacks.d.ts +12 -2
  188. package/dist/runtime/worker-callbacks.js +102 -72
  189. package/dist/runtime/worker-effect-dispatch.d.ts +14 -5
  190. package/dist/runtime/worker-effect-dispatch.js +84 -18
  191. package/dist/schedule/debugger/index.d.ts +4 -0
  192. package/dist/schedule/debugger/index.js +11 -0
  193. package/dist/schedule/debugger/schedule-view.d.ts +3 -0
  194. package/dist/schedule/debugger/schedule-view.js +68 -0
  195. package/dist/schedule/debugger/summarize.d.ts +2 -0
  196. package/dist/schedule/debugger/summarize.js +43 -0
  197. package/dist/schedule/definitions-store.d.ts +10 -0
  198. package/dist/schedule/definitions-store.js +8 -0
  199. package/dist/schedule/definitions.d.ts +57 -0
  200. package/dist/schedule/definitions.js +30 -0
  201. package/dist/schedule/effects.d.ts +756 -0
  202. package/dist/schedule/effects.js +244 -0
  203. package/dist/schedule/ensure.d.ts +55 -0
  204. package/dist/schedule/ensure.js +109 -0
  205. package/dist/schedule/events.d.ts +116 -0
  206. package/dist/schedule/events.js +49 -0
  207. package/dist/schedule/index.d.ts +11 -0
  208. package/dist/schedule/index.js +11 -0
  209. package/dist/schedule/module.d.ts +1474 -0
  210. package/dist/schedule/module.js +22 -0
  211. package/dist/schedule/projections.d.ts +55 -0
  212. package/dist/schedule/projections.js +88 -0
  213. package/dist/schedule/scope.d.ts +121 -0
  214. package/dist/schedule/scope.js +7 -0
  215. package/dist/schedule/signals.d.ts +25 -0
  216. package/dist/schedule/signals.js +33 -0
  217. package/dist/schedule/specs.d.ts +59 -0
  218. package/dist/schedule/specs.js +231 -0
  219. package/dist/schedule/threads.d.ts +25 -0
  220. package/dist/schedule/threads.js +259 -0
  221. package/dist/testing/corpus-module.d.ts +34 -0
  222. package/dist/testing/corpus-module.js +87 -0
  223. package/dist/testing/index.d.ts +2 -0
  224. package/dist/testing/index.js +5 -6
  225. package/dist/testing/replay-corpus.d.ts +22 -0
  226. package/dist/testing/replay-corpus.js +50 -0
  227. package/dist/workflow/definitions-store.d.ts +1 -1
  228. package/dist/workflow/definitions-store.js +1 -1
  229. package/dist/workflow/definitions.d.ts +14 -0
  230. package/dist/workflow/effects.d.ts +122 -0
  231. package/dist/workflow/effects.js +16 -6
  232. package/dist/workflow/events.d.ts +42 -0
  233. package/dist/workflow/events.js +4 -0
  234. package/dist/workflow/module.d.ts +345 -32
  235. package/dist/workflow/module.js +7 -3
  236. package/dist/workflow/scope.d.ts +42 -0
  237. package/dist/workflow/threads.d.ts +72 -0
  238. package/dist/workflow/threads.js +106 -38
  239. package/package.json +10 -1
  240. package/dist/debugger/app/assets/index-D--9esm9.js +0 -22
  241. package/dist/debugger/app/assets/routes-Dakrdusf.js +0 -47
@@ -19,8 +19,30 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
19
19
  }[] | undefined;
20
20
  }[] | undefined;
21
21
  readonly input?: Schema.Json | undefined;
22
+ readonly structuredOutput?: Schema.Json | undefined;
23
+ readonly alreadyCompacted?: boolean | undefined;
22
24
  readonly consumedSteerMessageIds?: readonly string[] | undefined;
23
25
  }, AgentDefinitionsTag | LlmTag, (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
26
+ readonly type: "agent.context.compacted";
27
+ readonly payload: {
28
+ readonly turn: number;
29
+ readonly originalCount: number;
30
+ readonly compactedCount: number;
31
+ readonly summary?: string | undefined;
32
+ readonly reason?: "manual" | "overflow" | "threshold" | undefined;
33
+ readonly messages?: readonly {
34
+ readonly role: "assistant" | "system" | "tool" | "user";
35
+ readonly content: string;
36
+ readonly toolCallId?: string | undefined;
37
+ readonly name?: string | undefined;
38
+ readonly toolCalls?: {
39
+ readonly id: string;
40
+ readonly name: string;
41
+ readonly arguments: Schema.Json;
42
+ }[] | undefined;
43
+ }[] | undefined;
44
+ };
45
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
24
46
  readonly type: "agent.effects.requested";
25
47
  readonly payload: {
26
48
  readonly toolCallId: string;
@@ -59,6 +81,9 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
59
81
  readonly actorId?: string | undefined;
60
82
  } | {
61
83
  readonly type: "system";
84
+ } | {
85
+ readonly type: "run";
86
+ readonly runId: string;
62
87
  } | undefined;
63
88
  readonly ephemeral?: boolean | undefined;
64
89
  readonly id?: string | undefined;
@@ -76,16 +101,35 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
76
101
  readonly type: "runtime.cancel";
77
102
  readonly threadId: string;
78
103
  readonly tag?: string | undefined;
104
+ } | {
105
+ readonly type: "runtime.launch";
106
+ readonly runId: string;
107
+ readonly kind: string;
108
+ readonly definitionName: string;
109
+ readonly definitionVersion: string;
110
+ readonly input: Schema.Json;
111
+ readonly close: "terminate" | "wait";
112
+ readonly tag?: string | undefined;
113
+ } | {
114
+ readonly type: "runtime.cancelRun";
115
+ readonly runId: string;
116
+ readonly tag?: string | undefined;
79
117
  } | {
80
118
  readonly type: string;
81
119
  readonly input: Schema.Json;
82
120
  readonly tag?: string | undefined;
121
+ readonly at?: number | undefined;
83
122
  })[];
84
123
  readonly waitOn?: {
85
124
  readonly type: string | readonly string[];
86
125
  readonly match?: Schema.Json | undefined;
87
126
  } | undefined;
88
127
  };
128
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
129
+ readonly type: "agent.lineage";
130
+ readonly payload: {
131
+ readonly depth: number;
132
+ };
89
133
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
90
134
  readonly type: "agent.message";
91
135
  readonly payload: {
@@ -160,6 +204,7 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
160
204
  readonly definitionVersion: string;
161
205
  readonly toolCallId: string;
162
206
  readonly input: Schema.Json;
207
+ readonly depth?: number | undefined;
163
208
  };
164
209
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
165
210
  readonly type: "agent.steered";
@@ -212,6 +257,26 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
212
257
  readonly turn: number;
213
258
  readonly delta: string;
214
259
  };
260
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
261
+ readonly type: "agent.turn.usage";
262
+ readonly payload: {
263
+ readonly turn: number;
264
+ readonly input: number;
265
+ readonly output: number;
266
+ };
267
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
268
+ readonly type: "runtime.child.close.requested";
269
+ readonly payload: {
270
+ readonly policy: "terminate" | "wait";
271
+ };
272
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
273
+ readonly type: "runtime.child.settled";
274
+ readonly payload: {
275
+ readonly runId: string;
276
+ readonly status: "cancelled" | "completed" | "failed";
277
+ readonly output: Schema.Json;
278
+ readonly error: string | null;
279
+ };
215
280
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
216
281
  readonly type: "runtime.effect.ambiguous";
217
282
  readonly payload: {
@@ -256,6 +321,8 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
256
321
  readonly payload: {
257
322
  readonly effectId: string;
258
323
  readonly error: string;
324
+ readonly nonRetryable?: boolean | undefined;
325
+ readonly retryAfterMs?: number | undefined;
259
326
  };
260
327
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
261
328
  readonly type: "runtime.effect.heartbeat";
@@ -264,6 +331,7 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
264
331
  readonly attempt: number;
265
332
  readonly heartbeatAt: number;
266
333
  readonly deadlineAt: number | null;
334
+ readonly details?: Schema.Json | undefined;
267
335
  };
268
336
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
269
337
  readonly type: "runtime.effect.queued";
@@ -316,6 +384,16 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
316
384
  readonly sourceRunId: string;
317
385
  readonly sourceSeq: number;
318
386
  };
387
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
388
+ readonly type: "runtime.run.launched";
389
+ readonly payload: {
390
+ readonly runId: string;
391
+ readonly kind: string;
392
+ readonly definitionName: string;
393
+ readonly definitionVersion: string;
394
+ readonly effectId: string;
395
+ readonly close: "terminate" | "wait";
396
+ };
319
397
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
320
398
  readonly type: "runtime.run.started";
321
399
  readonly payload: {
@@ -325,6 +403,20 @@ export declare const callLlmEffect: NoInfer<import("@swirls/looms/core").EffectD
325
403
  readonly definitionVersion: string;
326
404
  readonly input: Schema.Json;
327
405
  readonly requestedThreadId?: string | null | undefined;
406
+ readonly launchedBy?: {
407
+ readonly runId: string;
408
+ readonly threadId: string;
409
+ readonly effectId: string;
410
+ readonly causationId: string;
411
+ readonly causationSeq: number;
412
+ } | undefined;
413
+ readonly attributes?: {
414
+ readonly [x: string]: string;
415
+ } | undefined;
416
+ readonly trace?: {
417
+ readonly traceparent: string;
418
+ readonly tracestate?: string | undefined;
419
+ } | undefined;
328
420
  };
329
421
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
330
422
  readonly type: "runtime.signal.received";
@@ -419,7 +511,29 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
419
511
  readonly name: string;
420
512
  readonly arguments: Schema.Json;
421
513
  };
514
+ readonly input?: Schema.Json | undefined;
515
+ readonly depth?: number | undefined;
422
516
  }, AgentDefinitionsTag, (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
517
+ readonly type: "agent.context.compacted";
518
+ readonly payload: {
519
+ readonly turn: number;
520
+ readonly originalCount: number;
521
+ readonly compactedCount: number;
522
+ readonly summary?: string | undefined;
523
+ readonly reason?: "manual" | "overflow" | "threshold" | undefined;
524
+ readonly messages?: readonly {
525
+ readonly role: "assistant" | "system" | "tool" | "user";
526
+ readonly content: string;
527
+ readonly toolCallId?: string | undefined;
528
+ readonly name?: string | undefined;
529
+ readonly toolCalls?: {
530
+ readonly id: string;
531
+ readonly name: string;
532
+ readonly arguments: Schema.Json;
533
+ }[] | undefined;
534
+ }[] | undefined;
535
+ };
536
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
423
537
  readonly type: "agent.effects.requested";
424
538
  readonly payload: {
425
539
  readonly toolCallId: string;
@@ -458,6 +572,9 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
458
572
  readonly actorId?: string | undefined;
459
573
  } | {
460
574
  readonly type: "system";
575
+ } | {
576
+ readonly type: "run";
577
+ readonly runId: string;
461
578
  } | undefined;
462
579
  readonly ephemeral?: boolean | undefined;
463
580
  readonly id?: string | undefined;
@@ -475,16 +592,35 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
475
592
  readonly type: "runtime.cancel";
476
593
  readonly threadId: string;
477
594
  readonly tag?: string | undefined;
595
+ } | {
596
+ readonly type: "runtime.launch";
597
+ readonly runId: string;
598
+ readonly kind: string;
599
+ readonly definitionName: string;
600
+ readonly definitionVersion: string;
601
+ readonly input: Schema.Json;
602
+ readonly close: "terminate" | "wait";
603
+ readonly tag?: string | undefined;
604
+ } | {
605
+ readonly type: "runtime.cancelRun";
606
+ readonly runId: string;
607
+ readonly tag?: string | undefined;
478
608
  } | {
479
609
  readonly type: string;
480
610
  readonly input: Schema.Json;
481
611
  readonly tag?: string | undefined;
612
+ readonly at?: number | undefined;
482
613
  })[];
483
614
  readonly waitOn?: {
484
615
  readonly type: string | readonly string[];
485
616
  readonly match?: Schema.Json | undefined;
486
617
  } | undefined;
487
618
  };
619
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
620
+ readonly type: "agent.lineage";
621
+ readonly payload: {
622
+ readonly depth: number;
623
+ };
488
624
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
489
625
  readonly type: "agent.message";
490
626
  readonly payload: {
@@ -559,6 +695,7 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
559
695
  readonly definitionVersion: string;
560
696
  readonly toolCallId: string;
561
697
  readonly input: Schema.Json;
698
+ readonly depth?: number | undefined;
562
699
  };
563
700
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
564
701
  readonly type: "agent.steered";
@@ -611,6 +748,26 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
611
748
  readonly turn: number;
612
749
  readonly delta: string;
613
750
  };
751
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
752
+ readonly type: "agent.turn.usage";
753
+ readonly payload: {
754
+ readonly turn: number;
755
+ readonly input: number;
756
+ readonly output: number;
757
+ };
758
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
759
+ readonly type: "runtime.child.close.requested";
760
+ readonly payload: {
761
+ readonly policy: "terminate" | "wait";
762
+ };
763
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
764
+ readonly type: "runtime.child.settled";
765
+ readonly payload: {
766
+ readonly runId: string;
767
+ readonly status: "cancelled" | "completed" | "failed";
768
+ readonly output: Schema.Json;
769
+ readonly error: string | null;
770
+ };
614
771
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
615
772
  readonly type: "runtime.effect.ambiguous";
616
773
  readonly payload: {
@@ -655,6 +812,8 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
655
812
  readonly payload: {
656
813
  readonly effectId: string;
657
814
  readonly error: string;
815
+ readonly nonRetryable?: boolean | undefined;
816
+ readonly retryAfterMs?: number | undefined;
658
817
  };
659
818
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
660
819
  readonly type: "runtime.effect.heartbeat";
@@ -663,6 +822,7 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
663
822
  readonly attempt: number;
664
823
  readonly heartbeatAt: number;
665
824
  readonly deadlineAt: number | null;
825
+ readonly details?: Schema.Json | undefined;
666
826
  };
667
827
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
668
828
  readonly type: "runtime.effect.queued";
@@ -715,6 +875,16 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
715
875
  readonly sourceRunId: string;
716
876
  readonly sourceSeq: number;
717
877
  };
878
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
879
+ readonly type: "runtime.run.launched";
880
+ readonly payload: {
881
+ readonly runId: string;
882
+ readonly kind: string;
883
+ readonly definitionName: string;
884
+ readonly definitionVersion: string;
885
+ readonly effectId: string;
886
+ readonly close: "terminate" | "wait";
887
+ };
718
888
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
719
889
  readonly type: "runtime.run.started";
720
890
  readonly payload: {
@@ -724,6 +894,20 @@ export declare const executeToolEffect: NoInfer<import("@swirls/looms/core").Eff
724
894
  readonly definitionVersion: string;
725
895
  readonly input: Schema.Json;
726
896
  readonly requestedThreadId?: string | null | undefined;
897
+ readonly launchedBy?: {
898
+ readonly runId: string;
899
+ readonly threadId: string;
900
+ readonly effectId: string;
901
+ readonly causationId: string;
902
+ readonly causationSeq: number;
903
+ } | undefined;
904
+ readonly attributes?: {
905
+ readonly [x: string]: string;
906
+ } | undefined;
907
+ readonly trace?: {
908
+ readonly traceparent: string;
909
+ readonly tracestate?: string | undefined;
910
+ } | undefined;
727
911
  };
728
912
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
729
913
  readonly type: "runtime.signal.received";
@@ -1,6 +1,6 @@
1
1
  import { Data, Effect, Predicate, Schema } from 'effect';
2
2
  import { createThreadId, DEFAULT_DEFINITION_VERSION, validateInputEffect, } from '@swirls/looms/core';
3
- import { normalizeTools } from './definitions.js';
3
+ import { buildStructuredOutputInstructions, defaultAgentCompactor, defineTool, isContextOverflowError, normalizeTools, STRUCTURED_OUTPUT_TOOL_NAME, TEAM_MEMBER_MAX_DEPTH, } from './definitions.js';
4
4
  import { AgentDefinitionsTag } from './definitions-store.js';
5
5
  import { LlmTag } from './llm.js';
6
6
  import { agentModule } from './scope.js';
@@ -12,6 +12,8 @@ const CallLlmInput = Schema.Struct({
12
12
  definitionVersion: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_DEFINITION_VERSION))),
13
13
  messages: Schema.optional(Schema.Array(MessageSchema)),
14
14
  input: Schema.optional(Schema.Json),
15
+ structuredOutput: Schema.optional(Schema.NullOr(Schema.Json)),
16
+ alreadyCompacted: Schema.optional(Schema.Boolean),
15
17
  consumedSteerMessageIds: Schema.optional(Schema.Array(Schema.String)),
16
18
  });
17
19
  const ExecuteToolInput = Schema.Struct({
@@ -19,6 +21,8 @@ const ExecuteToolInput = Schema.Struct({
19
21
  definitionName: Schema.optional(Schema.String),
20
22
  definitionVersion: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_DEFINITION_VERSION))),
21
23
  toolCall: ToolCallSchema,
24
+ input: Schema.optional(Schema.Json),
25
+ depth: Schema.optional(Schema.Finite),
22
26
  });
23
27
  class AgentExecutionError extends Data.TaggedError('AgentExecutionError') {
24
28
  constructor(operation, cause) {
@@ -33,6 +37,41 @@ class AgentExecutionError extends Data.TaggedError('AgentExecutionError') {
33
37
  function findTool(tools, name) {
34
38
  return tools.find((tool) => tool.name === name);
35
39
  }
40
+ /** Static tools, then `resolveTools`, then `submit_output` when the agent declares an output. */
41
+ function agentTools(definition, ctx) {
42
+ return Effect.gen(function* () {
43
+ const tools = normalizeTools(definition.tools);
44
+ if (definition.resolveTools) {
45
+ const resolved = yield* Effect.tryPromise({
46
+ try: () => Promise.resolve(definition.resolveTools(ctx)),
47
+ catch: (cause) => new AgentExecutionError('resolve tools', cause),
48
+ });
49
+ tools.push(...normalizeTools(resolved));
50
+ }
51
+ if (definition.output) {
52
+ tools.push(defineTool({
53
+ name: STRUCTURED_OUTPUT_TOOL_NAME,
54
+ description: 'Submit the final structured output for this task. Call it once all work is done, with values that match the output schema.',
55
+ input: definition.output,
56
+ handler: (output) => ({ accepted: true, output }),
57
+ }));
58
+ }
59
+ return tools;
60
+ });
61
+ }
62
+ function toolError(input, threadId, error) {
63
+ return {
64
+ type: 'agent.tool.result',
65
+ payload: {
66
+ turn: input.turn,
67
+ toolCallId: input.toolCall.id,
68
+ name: input.toolCall.name,
69
+ result: null,
70
+ error,
71
+ },
72
+ threadId,
73
+ };
74
+ }
36
75
  export const callLlmEffect = agentModule.effect({
37
76
  type: 'agent.callLLM',
38
77
  input: CallLlmInput,
@@ -42,6 +81,8 @@ export const callLlmEffect = agentModule.effect({
42
81
  definitionVersion: input.definitionVersion,
43
82
  messages: [...(input.messages ?? [])],
44
83
  input: input.input ?? null,
84
+ structuredOutput: input.structuredOutput ?? null,
85
+ alreadyCompacted: input.alreadyCompacted ?? false,
45
86
  consumedSteerMessageIds: [...(input.consumedSteerMessageIds ?? [])],
46
87
  runId: ctx.runId,
47
88
  threadId: ctx.threadId,
@@ -51,10 +92,12 @@ export const callLlmEffect = agentModule.effect({
51
92
  });
52
93
  function runCallLlm(args) {
53
94
  return Effect.gen(function* () {
54
- const { turn, threadId, emit, definitionName, definitionVersion, messages, input, consumedSteerMessageIds, signal, } = args;
95
+ const { turn, threadId, emit, definitionName, definitionVersion, messages, input, structuredOutput, consumedSteerMessageIds, signal, } = args;
55
96
  const agents = yield* AgentDefinitionsTag;
56
97
  const llm = yield* LlmTag;
57
- const definition = definitionName ? agents.get(definitionName, definitionVersion) : undefined;
98
+ const definition = definitionName
99
+ ? yield* agents.resolve(definitionName, definitionVersion)
100
+ : undefined;
58
101
  if (!definition) {
59
102
  return [
60
103
  {
@@ -73,32 +116,59 @@ function runCallLlm(args) {
73
116
  },
74
117
  ];
75
118
  }
76
- const tools = normalizeTools(definition.tools);
77
- const events = [
78
- {
79
- type: 'agent.turn.started',
80
- payload: { turn },
81
- threadId,
82
- },
83
- ];
119
+ const tools = yield* agentTools(definition, { threadId, turn, input });
120
+ const instructions = definition.output
121
+ ? `${definition.instructions}\n\n${buildStructuredOutputInstructions(STRUCTURED_OUTPUT_TOOL_NAME)}`
122
+ : definition.instructions;
84
123
  const turnCtx = {
85
124
  threadId,
86
125
  turn,
87
126
  messages,
88
127
  input,
89
128
  tools,
90
- instructions: definition.instructions,
129
+ instructions,
91
130
  signal,
92
131
  };
93
- const result = definition.runTurn
94
- ? yield* Effect.tryPromise({
95
- try: () => Promise.resolve(definition.runTurn(turnCtx)),
96
- catch: (cause) => new AgentExecutionError('run agent turn', cause),
97
- })
98
- : yield* llm.complete({
132
+ if (definition.assertCredits) {
133
+ const creditCheck = yield* Effect.tryPromise({
134
+ try: () => Promise.resolve(definition.assertCredits(turnCtx)),
135
+ catch: (cause) => new AgentExecutionError('credit gate check', cause),
136
+ }).pipe(Effect.match({
137
+ onFailure: (error) => ({ ok: false, error: error.message }),
138
+ onSuccess: () => ({ ok: true }),
139
+ }));
140
+ if (!creditCheck.ok) {
141
+ return [
142
+ {
143
+ type: 'runtime.thread.failed',
144
+ payload: { threadId, error: creditCheck.error },
145
+ threadId,
146
+ },
147
+ ];
148
+ }
149
+ }
150
+ const events = [
151
+ {
152
+ type: 'agent.turn.started',
153
+ payload: { turn },
154
+ threadId,
155
+ },
156
+ ];
157
+ const executeTurn = (turnMessages) => {
158
+ if (definition.runTurn) {
159
+ return Effect.tryPromise({
160
+ try: () => Promise.resolve(definition.runTurn({
161
+ ...turnCtx,
162
+ messages: [...turnMessages],
163
+ instructions,
164
+ })),
165
+ catch: (cause) => new AgentExecutionError('run agent turn', cause),
166
+ });
167
+ }
168
+ return llm.complete({
99
169
  model: definition.model,
100
- instructions: definition.instructions,
101
- messages: [{ role: 'system', content: definition.instructions }, ...turnCtx.messages],
170
+ instructions,
171
+ messages: [{ role: 'system', content: instructions }, ...turnMessages],
102
172
  tools,
103
173
  toolSpecs: toolSpecs(tools),
104
174
  signal,
@@ -109,11 +179,48 @@ function runCallLlm(args) {
109
179
  ephemeral: true,
110
180
  }),
111
181
  });
182
+ };
183
+ let currentMessages = turnCtx.messages;
184
+ const result = yield* executeTurn(currentMessages).pipe(Effect.matchEffect({
185
+ onFailure: (err) => {
186
+ if (isContextOverflowError(err) && !args.alreadyCompacted) {
187
+ return Effect.gen(function* () {
188
+ const compactor = definition.compact ?? defaultAgentCompactor;
189
+ const originalCount = currentMessages.length;
190
+ const compacted = yield* Effect.tryPromise({
191
+ try: () => Promise.resolve(compactor({
192
+ threadId,
193
+ turn,
194
+ messages: currentMessages,
195
+ reason: 'overflow',
196
+ })),
197
+ catch: (cause) => new AgentExecutionError('context compaction', cause),
198
+ });
199
+ events.push({
200
+ type: 'agent.context.compacted',
201
+ payload: {
202
+ turn,
203
+ originalCount,
204
+ compactedCount: compacted.messages.length,
205
+ summary: compacted.summary,
206
+ reason: 'overflow',
207
+ messages: [...compacted.messages],
208
+ },
209
+ threadId,
210
+ });
211
+ currentMessages = [...compacted.messages];
212
+ return yield* executeTurn(currentMessages);
213
+ });
214
+ }
215
+ return Effect.fail(err);
216
+ },
217
+ onSuccess: (res) => Effect.succeed(res),
218
+ }));
112
219
  const toolCalls = result.toolCalls ?? result.message.toolCalls ?? [];
113
220
  const shouldStop = definition.stopWhen?.({
114
221
  turn,
115
222
  maxTurns: definition.maxTurns ?? 20,
116
- messages: turnCtx.messages,
223
+ messages: currentMessages,
117
224
  toolCalls,
118
225
  result,
119
226
  });
@@ -126,9 +233,26 @@ function runCallLlm(args) {
126
233
  },
127
234
  threadId,
128
235
  });
236
+ if (result.usage) {
237
+ events.push({
238
+ type: 'agent.turn.usage',
239
+ payload: {
240
+ turn,
241
+ input: result.usage.input,
242
+ output: result.usage.output,
243
+ },
244
+ threadId,
245
+ });
246
+ if (definition.trackUsage) {
247
+ yield* Effect.tryPromise({
248
+ try: () => Promise.resolve(definition.trackUsage({ input: result.usage.input, output: result.usage.output, turn }, turnCtx)),
249
+ catch: (cause) => new AgentExecutionError('track usage', cause),
250
+ }).pipe(Effect.catch((error) => Effect.logWarning('[@swirls/looms/agent] trackUsage failed', error)));
251
+ }
252
+ }
129
253
  if (shouldStop) {
130
254
  if (!definition.conversational) {
131
- const output = result.output ?? { text: result.message.content };
255
+ const output = structuredOutput ?? result.output ?? { text: result.message.content };
132
256
  events.push({
133
257
  type: 'runtime.thread.completed',
134
258
  payload: {
@@ -148,7 +272,7 @@ function runCallLlm(args) {
148
272
  });
149
273
  }
150
274
  if (toolCalls.length === 0 && !definition.conversational) {
151
- const output = result.output ?? { text: result.message.content };
275
+ const output = structuredOutput ?? result.output ?? { text: result.message.content };
152
276
  events.push({
153
277
  type: 'runtime.thread.completed',
154
278
  payload: {
@@ -168,7 +292,7 @@ export const executeToolEffect = agentModule.effect({
168
292
  const threadId = ctx.threadId;
169
293
  const agents = yield* AgentDefinitionsTag;
170
294
  const definition = input.definitionName
171
- ? agents.get(input.definitionName, input.definitionVersion)
295
+ ? yield* agents.resolve(input.definitionName, input.definitionVersion)
172
296
  : undefined;
173
297
  if (!definition) {
174
298
  return [
@@ -185,22 +309,20 @@ export const executeToolEffect = agentModule.effect({
185
309
  },
186
310
  ];
187
311
  }
188
- const tools = normalizeTools(definition.tools);
189
- const tool = findTool(tools, input.toolCall.name);
312
+ const resolved = yield* agentTools(definition, {
313
+ threadId,
314
+ turn: input.turn,
315
+ input: input.input ?? null,
316
+ }).pipe(Effect.match({
317
+ onFailure: (error) => ({ ok: false, error: error.message }),
318
+ onSuccess: (tools) => ({ ok: true, tools }),
319
+ }));
320
+ if (!resolved.ok) {
321
+ return [toolError(input, threadId, `Could not resolve tools: ${resolved.error}`)];
322
+ }
323
+ const tool = findTool(resolved.tools, input.toolCall.name);
190
324
  if (!tool) {
191
- return [
192
- {
193
- type: 'agent.tool.result',
194
- payload: {
195
- turn: input.turn,
196
- toolCallId: input.toolCall.id,
197
- name: input.toolCall.name,
198
- result: null,
199
- error: `Unknown tool: ${input.toolCall.name}`,
200
- },
201
- threadId,
202
- },
203
- ];
325
+ return [toolError(input, threadId, `Unknown tool: ${input.toolCall.name}`)];
204
326
  }
205
327
  switch (tool.kind) {
206
328
  case 'function': {
@@ -209,6 +331,7 @@ export const executeToolEffect = agentModule.effect({
209
331
  onSuccess: (value) => ({ ok: true, value }),
210
332
  }));
211
333
  if (!validated.ok) {
334
+ const isSubmit = tool.name === STRUCTURED_OUTPUT_TOOL_NAME;
212
335
  return [
213
336
  {
214
337
  type: 'agent.tool.result',
@@ -217,7 +340,9 @@ export const executeToolEffect = agentModule.effect({
217
340
  toolCallId: input.toolCall.id,
218
341
  name: input.toolCall.name,
219
342
  result: null,
220
- error: validated.error,
343
+ error: isSubmit
344
+ ? `Output validation failed: ${validated.error}. Fix the fields and call ${STRUCTURED_OUTPUT_TOOL_NAME} again.`
345
+ : validated.error,
221
346
  },
222
347
  threadId,
223
348
  },
@@ -248,6 +373,12 @@ export const executeToolEffect = agentModule.effect({
248
373
  ];
249
374
  }
250
375
  case 'thread': {
376
+ const depth = input.depth ?? 0;
377
+ if (depth >= TEAM_MEMBER_MAX_DEPTH) {
378
+ return [
379
+ toolError(input, threadId, `Subagent depth limit reached (max depth: ${TEAM_MEMBER_MAX_DEPTH})`),
380
+ ];
381
+ }
251
382
  const validated = tool.input
252
383
  ? yield* validateInputEffect(tool.input, input.toolCall.arguments).pipe(Effect.match({
253
384
  onFailure: (error) => ({ ok: false, error: error.message }),
@@ -281,6 +412,7 @@ export const executeToolEffect = agentModule.effect({
281
412
  definitionVersion: tool.childVersion,
282
413
  input: childInput,
283
414
  toolCallId: input.toolCall.id,
415
+ depth: depth + 1,
284
416
  },
285
417
  threadId,
286
418
  },