@autonome-research/thread-phase 3.0.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 (263) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/agent/index.d.ts +28 -0
  4. package/dist/agent/index.d.ts.map +1 -0
  5. package/dist/agent/index.js +28 -0
  6. package/dist/agent/index.js.map +1 -0
  7. package/dist/agent/openai-adapter.d.ts +15 -0
  8. package/dist/agent/openai-adapter.d.ts.map +1 -0
  9. package/dist/agent/openai-adapter.js +57 -0
  10. package/dist/agent/openai-adapter.js.map +1 -0
  11. package/dist/agent/parse-json.d.ts +12 -0
  12. package/dist/agent/parse-json.d.ts.map +1 -0
  13. package/dist/agent/parse-json.js +31 -0
  14. package/dist/agent/parse-json.js.map +1 -0
  15. package/dist/agent/retry.d.ts +15 -0
  16. package/dist/agent/retry.d.ts.map +1 -0
  17. package/dist/agent/retry.js +35 -0
  18. package/dist/agent/retry.js.map +1 -0
  19. package/dist/agent/runner.d.ts +25 -0
  20. package/dist/agent/runner.d.ts.map +1 -0
  21. package/dist/agent/runner.js +270 -0
  22. package/dist/agent/runner.js.map +1 -0
  23. package/dist/agent/stream-consumer.d.ts +57 -0
  24. package/dist/agent/stream-consumer.d.ts.map +1 -0
  25. package/dist/agent/stream-consumer.js +126 -0
  26. package/dist/agent/stream-consumer.js.map +1 -0
  27. package/dist/agent/types.d.ts +135 -0
  28. package/dist/agent/types.d.ts.map +1 -0
  29. package/dist/agent/types.js +9 -0
  30. package/dist/agent/types.js.map +1 -0
  31. package/dist/agent-runner.d.ts +10 -0
  32. package/dist/agent-runner.d.ts.map +1 -0
  33. package/dist/agent-runner.js +10 -0
  34. package/dist/agent-runner.js.map +1 -0
  35. package/dist/agents/capability.d.ts +36 -0
  36. package/dist/agents/capability.d.ts.map +1 -0
  37. package/dist/agents/capability.js +51 -0
  38. package/dist/agents/capability.js.map +1 -0
  39. package/dist/agents/event-bus.d.ts +20 -0
  40. package/dist/agents/event-bus.d.ts.map +1 -0
  41. package/dist/agents/event-bus.js +40 -0
  42. package/dist/agents/event-bus.js.map +1 -0
  43. package/dist/agents/index.d.ts +23 -0
  44. package/dist/agents/index.d.ts.map +1 -0
  45. package/dist/agents/index.js +33 -0
  46. package/dist/agents/index.js.map +1 -0
  47. package/dist/agents/inference-adapter.d.ts +52 -0
  48. package/dist/agents/inference-adapter.d.ts.map +1 -0
  49. package/dist/agents/inference-adapter.js +209 -0
  50. package/dist/agents/inference-adapter.js.map +1 -0
  51. package/dist/agents/job-store-bridge.d.ts +44 -0
  52. package/dist/agents/job-store-bridge.d.ts.map +1 -0
  53. package/dist/agents/job-store-bridge.js +58 -0
  54. package/dist/agents/job-store-bridge.js.map +1 -0
  55. package/dist/agents/memory.d.ts +40 -0
  56. package/dist/agents/memory.d.ts.map +1 -0
  57. package/dist/agents/memory.js +14 -0
  58. package/dist/agents/memory.js.map +1 -0
  59. package/dist/agents/protocol.d.ts +302 -0
  60. package/dist/agents/protocol.d.ts.map +1 -0
  61. package/dist/agents/protocol.js +36 -0
  62. package/dist/agents/protocol.js.map +1 -0
  63. package/dist/agents/run-helpers.d.ts +70 -0
  64. package/dist/agents/run-helpers.d.ts.map +1 -0
  65. package/dist/agents/run-helpers.js +131 -0
  66. package/dist/agents/run-helpers.js.map +1 -0
  67. package/dist/agents/serialize-error.d.ts +18 -0
  68. package/dist/agents/serialize-error.d.ts.map +1 -0
  69. package/dist/agents/serialize-error.js +27 -0
  70. package/dist/agents/serialize-error.js.map +1 -0
  71. package/dist/agents/structured-output.d.ts +90 -0
  72. package/dist/agents/structured-output.d.ts.map +1 -0
  73. package/dist/agents/structured-output.js +101 -0
  74. package/dist/agents/structured-output.js.map +1 -0
  75. package/dist/agents/test-utils/conformance.d.ts +59 -0
  76. package/dist/agents/test-utils/conformance.d.ts.map +1 -0
  77. package/dist/agents/test-utils/conformance.js +207 -0
  78. package/dist/agents/test-utils/conformance.js.map +1 -0
  79. package/dist/agents/test-utils/index.d.ts +12 -0
  80. package/dist/agents/test-utils/index.d.ts.map +1 -0
  81. package/dist/agents/test-utils/index.js +12 -0
  82. package/dist/agents/test-utils/index.js.map +1 -0
  83. package/dist/agents/test-utils/mock-agent.d.ts +66 -0
  84. package/dist/agents/test-utils/mock-agent.d.ts.map +1 -0
  85. package/dist/agents/test-utils/mock-agent.js +244 -0
  86. package/dist/agents/test-utils/mock-agent.js.map +1 -0
  87. package/dist/agents/thread.d.ts +57 -0
  88. package/dist/agents/thread.d.ts.map +1 -0
  89. package/dist/agents/thread.js +128 -0
  90. package/dist/agents/thread.js.map +1 -0
  91. package/dist/agents/turn-accumulator.d.ts +94 -0
  92. package/dist/agents/turn-accumulator.d.ts.map +1 -0
  93. package/dist/agents/turn-accumulator.js +150 -0
  94. package/dist/agents/turn-accumulator.js.map +1 -0
  95. package/dist/agents/with-memory.d.ts +55 -0
  96. package/dist/agents/with-memory.d.ts.map +1 -0
  97. package/dist/agents/with-memory.js +155 -0
  98. package/dist/agents/with-memory.js.map +1 -0
  99. package/dist/agents/with-thread.d.ts +45 -0
  100. package/dist/agents/with-thread.d.ts.map +1 -0
  101. package/dist/agents/with-thread.js +70 -0
  102. package/dist/agents/with-thread.js.map +1 -0
  103. package/dist/cache.d.ts +47 -0
  104. package/dist/cache.d.ts.map +1 -0
  105. package/dist/cache.js +81 -0
  106. package/dist/cache.js.map +1 -0
  107. package/dist/context/compressor.d.ts +36 -0
  108. package/dist/context/compressor.d.ts.map +1 -0
  109. package/dist/context/compressor.js +158 -0
  110. package/dist/context/compressor.js.map +1 -0
  111. package/dist/context/index.d.ts +4 -0
  112. package/dist/context/index.d.ts.map +1 -0
  113. package/dist/context/index.js +4 -0
  114. package/dist/context/index.js.map +1 -0
  115. package/dist/context/result-capper.d.ts +32 -0
  116. package/dist/context/result-capper.d.ts.map +1 -0
  117. package/dist/context/result-capper.js +50 -0
  118. package/dist/context/result-capper.js.map +1 -0
  119. package/dist/context/token-budget.d.ts +81 -0
  120. package/dist/context/token-budget.d.ts.map +1 -0
  121. package/dist/context/token-budget.js +99 -0
  122. package/dist/context/token-budget.js.map +1 -0
  123. package/dist/helpers/caller.d.ts +18 -0
  124. package/dist/helpers/caller.d.ts.map +1 -0
  125. package/dist/helpers/caller.js +40 -0
  126. package/dist/helpers/caller.js.map +1 -0
  127. package/dist/helpers/hook.d.ts +73 -0
  128. package/dist/helpers/hook.d.ts.map +1 -0
  129. package/dist/helpers/hook.js +244 -0
  130. package/dist/helpers/hook.js.map +1 -0
  131. package/dist/helpers/index.d.ts +12 -0
  132. package/dist/helpers/index.d.ts.map +1 -0
  133. package/dist/helpers/index.js +11 -0
  134. package/dist/helpers/index.js.map +1 -0
  135. package/dist/helpers/one-shot.d.ts +27 -0
  136. package/dist/helpers/one-shot.d.ts.map +1 -0
  137. package/dist/helpers/one-shot.js +43 -0
  138. package/dist/helpers/one-shot.js.map +1 -0
  139. package/dist/helpers/schedule.d.ts +59 -0
  140. package/dist/helpers/schedule.d.ts.map +1 -0
  141. package/dist/helpers/schedule.js +118 -0
  142. package/dist/helpers/schedule.js.map +1 -0
  143. package/dist/helpers/types.d.ts +34 -0
  144. package/dist/helpers/types.d.ts.map +1 -0
  145. package/dist/helpers/types.js +11 -0
  146. package/dist/helpers/types.js.map +1 -0
  147. package/dist/index.d.ts +26 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +37 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/inference.d.ts +27 -0
  152. package/dist/inference.d.ts.map +1 -0
  153. package/dist/inference.js +34 -0
  154. package/dist/inference.js.map +1 -0
  155. package/dist/messages.d.ts +64 -0
  156. package/dist/messages.d.ts.map +1 -0
  157. package/dist/messages.js +17 -0
  158. package/dist/messages.js.map +1 -0
  159. package/dist/orchestrator.d.ts +56 -0
  160. package/dist/orchestrator.d.ts.map +1 -0
  161. package/dist/orchestrator.js +62 -0
  162. package/dist/orchestrator.js.map +1 -0
  163. package/dist/patterns/bounded-fanout-of.d.ts +61 -0
  164. package/dist/patterns/bounded-fanout-of.d.ts.map +1 -0
  165. package/dist/patterns/bounded-fanout-of.js +142 -0
  166. package/dist/patterns/bounded-fanout-of.js.map +1 -0
  167. package/dist/patterns/bounded-fanout.d.ts +111 -0
  168. package/dist/patterns/bounded-fanout.d.ts.map +1 -0
  169. package/dist/patterns/bounded-fanout.js +151 -0
  170. package/dist/patterns/bounded-fanout.js.map +1 -0
  171. package/dist/patterns/index.d.ts +14 -0
  172. package/dist/patterns/index.d.ts.map +1 -0
  173. package/dist/patterns/index.js +13 -0
  174. package/dist/patterns/index.js.map +1 -0
  175. package/dist/patterns/intent-gate.d.ts +27 -0
  176. package/dist/patterns/intent-gate.d.ts.map +1 -0
  177. package/dist/patterns/intent-gate.js +32 -0
  178. package/dist/patterns/intent-gate.js.map +1 -0
  179. package/dist/patterns/match.d.ts +30 -0
  180. package/dist/patterns/match.d.ts.map +1 -0
  181. package/dist/patterns/match.js +58 -0
  182. package/dist/patterns/match.js.map +1 -0
  183. package/dist/patterns/parallel-fanout.d.ts +28 -0
  184. package/dist/patterns/parallel-fanout.d.ts.map +1 -0
  185. package/dist/patterns/parallel-fanout.js +24 -0
  186. package/dist/patterns/parallel-fanout.js.map +1 -0
  187. package/dist/patterns/parallel-phases.d.ts +27 -0
  188. package/dist/patterns/parallel-phases.d.ts.map +1 -0
  189. package/dist/patterns/parallel-phases.js +77 -0
  190. package/dist/patterns/parallel-phases.js.map +1 -0
  191. package/dist/patterns/preflight-confidence.d.ts +20 -0
  192. package/dist/patterns/preflight-confidence.d.ts.map +1 -0
  193. package/dist/patterns/preflight-confidence.js +38 -0
  194. package/dist/patterns/preflight-confidence.js.map +1 -0
  195. package/dist/patterns/spot-check.d.ts +19 -0
  196. package/dist/patterns/spot-check.d.ts.map +1 -0
  197. package/dist/patterns/spot-check.js +33 -0
  198. package/dist/patterns/spot-check.js.map +1 -0
  199. package/dist/patterns/sub-pipeline.d.ts +84 -0
  200. package/dist/patterns/sub-pipeline.d.ts.map +1 -0
  201. package/dist/patterns/sub-pipeline.js +90 -0
  202. package/dist/patterns/sub-pipeline.js.map +1 -0
  203. package/dist/patterns/synthesize-with-followup.d.ts +35 -0
  204. package/dist/patterns/synthesize-with-followup.d.ts.map +1 -0
  205. package/dist/patterns/synthesize-with-followup.js +45 -0
  206. package/dist/patterns/synthesize-with-followup.js.map +1 -0
  207. package/dist/patterns/while-condition.d.ts +31 -0
  208. package/dist/patterns/while-condition.d.ts.map +1 -0
  209. package/dist/patterns/while-condition.js +59 -0
  210. package/dist/patterns/while-condition.js.map +1 -0
  211. package/dist/patterns/with-retry.d.ts +37 -0
  212. package/dist/patterns/with-retry.d.ts.map +1 -0
  213. package/dist/patterns/with-retry.js +73 -0
  214. package/dist/patterns/with-retry.js.map +1 -0
  215. package/dist/phase.d.ts +78 -0
  216. package/dist/phase.d.ts.map +1 -0
  217. package/dist/phase.js +36 -0
  218. package/dist/phase.js.map +1 -0
  219. package/dist/session/index.d.ts +5 -0
  220. package/dist/session/index.d.ts.map +1 -0
  221. package/dist/session/index.js +4 -0
  222. package/dist/session/index.js.map +1 -0
  223. package/dist/session/job-runner.d.ts +67 -0
  224. package/dist/session/job-runner.d.ts.map +1 -0
  225. package/dist/session/job-runner.js +131 -0
  226. package/dist/session/job-runner.js.map +1 -0
  227. package/dist/session/job-store.d.ts +98 -0
  228. package/dist/session/job-store.d.ts.map +1 -0
  229. package/dist/session/job-store.js +37 -0
  230. package/dist/session/job-store.js.map +1 -0
  231. package/dist/session/sqlite-job-store.d.ts +40 -0
  232. package/dist/session/sqlite-job-store.d.ts.map +1 -0
  233. package/dist/session/sqlite-job-store.js +200 -0
  234. package/dist/session/sqlite-job-store.js.map +1 -0
  235. package/dist/session/sse.d.ts +60 -0
  236. package/dist/session/sse.d.ts.map +1 -0
  237. package/dist/session/sse.js +97 -0
  238. package/dist/session/sse.js.map +1 -0
  239. package/dist/tools/index.d.ts +2 -0
  240. package/dist/tools/index.d.ts.map +1 -0
  241. package/dist/tools/index.js +2 -0
  242. package/dist/tools/index.js.map +1 -0
  243. package/dist/tools/registry.d.ts +44 -0
  244. package/dist/tools/registry.d.ts.map +1 -0
  245. package/dist/tools/registry.js +74 -0
  246. package/dist/tools/registry.js.map +1 -0
  247. package/dist/triggers/index.d.ts +15 -0
  248. package/dist/triggers/index.d.ts.map +1 -0
  249. package/dist/triggers/index.js +14 -0
  250. package/dist/triggers/index.js.map +1 -0
  251. package/dist/triggers/run-trigger.d.ts +86 -0
  252. package/dist/triggers/run-trigger.d.ts.map +1 -0
  253. package/dist/triggers/run-trigger.js +146 -0
  254. package/dist/triggers/run-trigger.js.map +1 -0
  255. package/dist/triggers/timer-trigger.d.ts +46 -0
  256. package/dist/triggers/timer-trigger.d.ts.map +1 -0
  257. package/dist/triggers/timer-trigger.js +74 -0
  258. package/dist/triggers/timer-trigger.js.map +1 -0
  259. package/dist/triggers/types.d.ts +61 -0
  260. package/dist/triggers/types.d.ts.map +1 -0
  261. package/dist/triggers/types.js +23 -0
  262. package/dist/triggers/types.js.map +1 -0
  263. package/package.json +64 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * parallel-phases — run several phases concurrently as one composite phase.
3
+ *
4
+ * The framework treats pipelines as an ordered array, which covers linear
5
+ * flow, conditional skip (`intentGate`), and self-iteration
6
+ * (`whileCondition`). The one DAG shape it doesn't natively express is
7
+ * "run two independent branches at the same time, then continue when
8
+ * both finish." That's what this pattern is for.
9
+ *
10
+ * Semantics:
11
+ * - Sub-phases share the parent `ctx`. If two branches both write to the
12
+ * same field, last-write-wins. Keep branches' ctx writes disjoint.
13
+ * - Events from all branches interleave into the composite phase's
14
+ * output stream in arrival order.
15
+ * - If a sub-phase throws, the composite re-throws (after letting other
16
+ * branches finish what they're doing — no in-flight cancellation).
17
+ * - If a sub-phase sets `ctx.stop`, sibling branches still run to
18
+ * completion. The orchestrator's stop check fires AFTER the composite
19
+ * phase returns, halting subsequent top-level phases.
20
+ *
21
+ * For data-dependent fan-in, write each branch's output to a distinct ctx
22
+ * field; a downstream phase reads them all via `requireCtx`. That's a
23
+ * complete DAG-edge expression without a graph framework.
24
+ */
25
+ export function parallelPhases(phaseName, phases) {
26
+ return {
27
+ name: phaseName,
28
+ async *run(ctx) {
29
+ if (phases.length === 0)
30
+ return;
31
+ // Producer/consumer: each sub-phase pushes events into a shared queue;
32
+ // the composite generator drains the queue and yields downstream.
33
+ const queue = [];
34
+ let resolveWaiter = null;
35
+ const wake = () => {
36
+ const fn = resolveWaiter;
37
+ resolveWaiter = null;
38
+ fn?.();
39
+ };
40
+ const wait = () => new Promise((r) => (resolveWaiter = r));
41
+ let errored = null;
42
+ let running = phases.length;
43
+ const drain = async (phase) => {
44
+ try {
45
+ for await (const ev of phase.run(ctx)) {
46
+ queue.push(ev);
47
+ wake();
48
+ if (errored)
49
+ return;
50
+ }
51
+ }
52
+ catch (err) {
53
+ if (!errored)
54
+ errored = err;
55
+ }
56
+ finally {
57
+ running--;
58
+ wake();
59
+ }
60
+ };
61
+ const allDone = Promise.all(phases.map(drain));
62
+ while (running > 0 || queue.length > 0) {
63
+ if (errored && queue.length === 0)
64
+ break;
65
+ if (queue.length === 0) {
66
+ await Promise.race([wait(), allDone]);
67
+ continue;
68
+ }
69
+ yield queue.shift();
70
+ }
71
+ await allDone;
72
+ if (errored)
73
+ throw errored;
74
+ },
75
+ };
76
+ }
77
+ //# sourceMappingURL=parallel-phases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-phases.js","sourceRoot":"","sources":["../../src/patterns/parallel-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,MAAM,UAAU,cAAc,CAI5B,SAAiB,EACjB,MAA0C;IAE1C,OAAO;QACL,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;YACZ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAEhC,uEAAuE;YACvE,kEAAkE;YAClE,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,aAAa,GAAwB,IAAI,CAAC;YAC9C,MAAM,IAAI,GAAG,GAAG,EAAE;gBAChB,MAAM,EAAE,GAAG,aAAa,CAAC;gBACzB,aAAa,GAAG,IAAI,CAAC;gBACrB,EAAE,EAAE,EAAE,CAAC;YACT,CAAC,CAAC;YACF,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC;YAEjE,IAAI,OAAO,GAAY,IAAI,CAAC;YAC5B,IAAI,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;YAE5B,MAAM,KAAK,GAAG,KAAK,EAAE,KAA0B,EAAiB,EAAE;gBAChE,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBACf,IAAI,EAAE,CAAC;wBACP,IAAI,OAAO;4BAAE,OAAO;oBACtB,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,OAAO;wBAAE,OAAO,GAAG,GAAG,CAAC;gBAC9B,CAAC;wBAAS,CAAC;oBACT,OAAO,EAAE,CAAC;oBACV,IAAI,EAAE,CAAC;gBACT,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAE/C,OAAO,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAM;gBACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;oBACtC,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC,KAAK,EAAG,CAAC;YACvB,CAAC;YAED,MAAM,OAAO,CAAC;YACd,IAAI,OAAO;gBAAE,MAAM,OAAO,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * preflight-confidence — assess feasibility before spending big-model tokens.
3
+ *
4
+ * Run a fast, cheap check (often a metadata read or small LLM call) that
5
+ * returns a typed score. The pipeline can either surface the score and
6
+ * continue, or stop on insufficient signal.
7
+ */
8
+ import type { BasePipelineContext, Phase } from '../phase.js';
9
+ export interface PreflightOptions<TCtx extends BasePipelineContext, TScore> {
10
+ /** Compute the score. May be an LLM call, metadata read, or pure logic. */
11
+ assess: (ctx: TCtx) => Promise<TScore>;
12
+ /** Stash the score on ctx (typed by the caller's context type). */
13
+ writeTo: (ctx: TCtx, score: TScore) => void;
14
+ /** Optional: human-readable description appended as a `content` event. */
15
+ describe?: (score: TScore) => string;
16
+ /** Optional: return a non-null reason to halt the pipeline. */
17
+ stopIf?: (score: TScore) => string | null;
18
+ }
19
+ export declare function preflightConfidence<TCtx extends BasePipelineContext, TScore>(phaseName: string, options: PreflightOptions<TCtx, TScore>): Phase<TCtx>;
20
+ //# sourceMappingURL=preflight-confidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-confidence.d.ts","sourceRoot":"","sources":["../../src/patterns/preflight-confidence.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM;IACxE,2EAA2E;IAC3E,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,mEAAmE;IACnE,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM,EAC1E,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,GACtC,KAAK,CAAC,IAAI,CAAC,CAgCb"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * preflight-confidence — assess feasibility before spending big-model tokens.
3
+ *
4
+ * Run a fast, cheap check (often a metadata read or small LLM call) that
5
+ * returns a typed score. The pipeline can either surface the score and
6
+ * continue, or stop on insufficient signal.
7
+ */
8
+ export function preflightConfidence(phaseName, options) {
9
+ return {
10
+ name: phaseName,
11
+ async *run(ctx) {
12
+ let score;
13
+ try {
14
+ score = await options.assess(ctx);
15
+ }
16
+ catch (err) {
17
+ const e = err;
18
+ yield {
19
+ type: 'agent_activity',
20
+ agent: phaseName,
21
+ action: 'error',
22
+ detail: e.message?.slice(0, 120),
23
+ };
24
+ return;
25
+ }
26
+ options.writeTo(ctx, score);
27
+ yield { type: 'data', key: phaseName, value: score };
28
+ if (options.describe) {
29
+ yield { type: 'content', content: `${options.describe(score)}\n` };
30
+ }
31
+ const stopReason = options.stopIf?.(score);
32
+ if (stopReason !== null && stopReason !== undefined) {
33
+ ctx.stop = { reason: stopReason };
34
+ }
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=preflight-confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-confidence.js","sourceRoot":"","sources":["../../src/patterns/preflight-confidence.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,OAAuC;IAEvC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;YACZ,IAAI,KAAa,CAAC;YAClB,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,GAA2B,CAAC;gBACtC,MAAM;oBACJ,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,OAAO;oBACf,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;iBACjC,CAAC;gBACF,OAAO;YACT,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAE5B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAErD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACrE,CAAC;YAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBACpD,GAAG,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YACpC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * spot-check — verify a sample of typed claims from a prior phase.
3
+ *
4
+ * Pattern: extract a list of claims from an upstream artifact (synthesis,
5
+ * report, draft), verify a capped subset in parallel, stash the results.
6
+ */
7
+ import type { BasePipelineContext, Phase } from '../phase.js';
8
+ export interface SpotCheckOptions<TCtx extends BasePipelineContext, TClaim, TResult> {
9
+ /** Pull the candidate claims from ctx (typically off a prior phase's output). */
10
+ extractClaims: (ctx: TCtx) => TClaim[];
11
+ /** Verify a single claim. Often runs an agent with read-only tools. */
12
+ verify: (claim: TClaim, ctx: TCtx) => Promise<TResult>;
13
+ /** Stash results on ctx. */
14
+ writeTo: (ctx: TCtx, results: TResult[]) => void;
15
+ /** Cap concurrent verifications. Default 5. */
16
+ maxClaims?: number;
17
+ }
18
+ export declare function spotCheck<TCtx extends BasePipelineContext, TClaim, TResult>(phaseName: string, options: SpotCheckOptions<TCtx, TClaim, TResult>): Phase<TCtx>;
19
+ //# sourceMappingURL=spot-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spot-check.d.ts","sourceRoot":"","sources":["../../src/patterns/spot-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAG9D,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM,EAAE,OAAO;IACjF,iFAAiF;IACjF,aAAa,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;IACvC,uEAAuE;IACvE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,4BAA4B;IAC5B,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACjD,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM,EAAE,OAAO,EACzE,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,GAC/C,KAAK,CAAC,IAAI,CAAC,CA4Bb"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * spot-check — verify a sample of typed claims from a prior phase.
3
+ *
4
+ * Pattern: extract a list of claims from an upstream artifact (synthesis,
5
+ * report, draft), verify a capped subset in parallel, stash the results.
6
+ */
7
+ import { parallelFanout } from './parallel-fanout.js';
8
+ export function spotCheck(phaseName, options) {
9
+ return {
10
+ name: phaseName,
11
+ async *run(ctx) {
12
+ const allClaims = options.extractClaims(ctx);
13
+ const max = options.maxClaims ?? 5;
14
+ const claims = allClaims.slice(0, max);
15
+ yield {
16
+ type: 'phase',
17
+ phase: phaseName,
18
+ detail: `Verifying ${claims.length}/${allClaims.length} claim(s)`,
19
+ counts: { claims: claims.length, total: allClaims.length },
20
+ };
21
+ if (claims.length === 0) {
22
+ options.writeTo(ctx, []);
23
+ return;
24
+ }
25
+ const results = await parallelFanout({
26
+ items: claims,
27
+ runner: (claim) => options.verify(claim, ctx),
28
+ });
29
+ options.writeTo(ctx, results);
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=spot-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spot-check.js","sourceRoot":"","sources":["../../src/patterns/spot-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAatD,MAAM,UAAU,SAAS,CACvB,SAAiB,EACjB,OAAgD;IAEhD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;YACZ,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAEvC,MAAM;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,aAAa,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,WAAW;gBACjE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE;aAC3D,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC;gBACnC,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;aAC9C,CAAC,CAAC;YAEH,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * subPipeline — compose a registered (or inline) pipeline as a phase
3
+ * inside another pipeline.
4
+ *
5
+ * Two surface forms:
6
+ *
7
+ * - **`subPipeline(name, options)`** — higher-order pattern returning a
8
+ * `Phase<TOuterCtx>`. Compose like any other phase.
9
+ * - **`runSubPipeline(spec, options)`** — free function for imperative
10
+ * use inside phase bodies. Returns `{ ctx, summary }`.
11
+ *
12
+ * The inner pipeline gets:
13
+ * - a fresh `PipelineCache` (cache scopes are isolated)
14
+ * - the outer ctx's `signal` (cancellation propagates down)
15
+ *
16
+ * Events from the inner pipeline flatten into the outer event stream
17
+ * via `yield*` — JobStore consumers, SSE listeners, and the orchestrator
18
+ * see one continuous stream.
19
+ */
20
+ import type { BasePipelineContext, Phase } from '../phase.js';
21
+ /**
22
+ * The inner pipeline spec. Either a direct `{ phases, ctx }` object, or a
23
+ * lazy resolver returning one (or `undefined` if not found). The CLI uses
24
+ * the resolver form to look up registered pipelines by name without making
25
+ * the core depend on the Registry.
26
+ */
27
+ export type SubPipelineSource<TInnerCtx extends BasePipelineContext> = {
28
+ phases: ReadonlyArray<Phase<TInnerCtx>>;
29
+ ctx: TInnerCtx;
30
+ } | (() => {
31
+ phases: ReadonlyArray<Phase<TInnerCtx>>;
32
+ ctx: TInnerCtx;
33
+ } | undefined);
34
+ export interface SubPipelineOptions<TOuterCtx extends BasePipelineContext, TInnerCtx extends BasePipelineContext> {
35
+ /** Inner pipeline source: direct object or lazy resolver. */
36
+ pipeline: SubPipelineSource<TInnerCtx>;
37
+ /**
38
+ * Map outer ctx to the inner pipeline's starting ctx. Optional — if
39
+ * omitted, the inner pipeline starts with its own ctx as supplied by the
40
+ * source (the outer's `signal` is still wired in either way).
41
+ */
42
+ mapInput?: (outer: TOuterCtx) => TInnerCtx;
43
+ /**
44
+ * Merge the inner pipeline's terminal state back into outer ctx. Optional
45
+ * — if omitted, the inner's outputs are discarded.
46
+ */
47
+ mapOutput?: (outer: TOuterCtx, inner: TInnerCtx) => void;
48
+ }
49
+ /** A higher-order pattern returning a `Phase<TOuterCtx>`. */
50
+ export declare function subPipeline<TOuterCtx extends BasePipelineContext, TInnerCtx extends BasePipelineContext>(name: string, options: SubPipelineOptions<TOuterCtx, TInnerCtx>): Phase<TOuterCtx>;
51
+ /**
52
+ * Type-inferred convenience over `subPipeline` for the direct-object case.
53
+ * `TInnerCtx` is inferred from `source.ctx`, so callers only spell the outer
54
+ * ctx generic (and often not even that):
55
+ *
56
+ * subPipelineOf('inner', innerSpec, { mapOutput: ... })
57
+ *
58
+ * vs. the more verbose `subPipeline<MyOuter, MyInner>(...)`. For the lazy
59
+ * registry-lookup case, use `subPipeline` directly — the resolver form needs
60
+ * explicit generics anyway.
61
+ */
62
+ export declare function subPipelineOf<TInnerCtx extends BasePipelineContext, TOuterCtx extends BasePipelineContext = BasePipelineContext>(name: string, source: {
63
+ phases: ReadonlyArray<Phase<TInnerCtx>>;
64
+ ctx: TInnerCtx;
65
+ }, mapping?: Omit<SubPipelineOptions<TOuterCtx, TInnerCtx>, 'pipeline'>): Phase<TOuterCtx>;
66
+ /**
67
+ * Imperative form: invoke an inner pipeline from inside a phase body.
68
+ * Returns the inner ctx (post-run) and the pipeline summary. Phase
69
+ * exceptions in the inner pipeline propagate as rejections.
70
+ */
71
+ export declare function runSubPipeline<TInnerCtx extends BasePipelineContext>(source: SubPipelineSource<TInnerCtx>, options?: {
72
+ /** Optional outer signal to propagate into the inner pipeline's ctx. */
73
+ signal?: AbortSignal;
74
+ /** Optional override of the inner ctx (otherwise source's ctx is used). */
75
+ ctx?: TInnerCtx;
76
+ }): Promise<{
77
+ ctx: TInnerCtx;
78
+ summary: {
79
+ status: 'completed' | 'stopped';
80
+ reason?: string;
81
+ eventCount: number;
82
+ };
83
+ }>;
84
+ //# sourceMappingURL=sub-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-pipeline.d.ts","sourceRoot":"","sources":["../../src/patterns/sub-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EACV,mBAAmB,EACnB,KAAK,EAEN,MAAM,aAAa,CAAC;AAGrB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,CAAC,SAAS,SAAS,mBAAmB,IAC/D;IAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GAC3D,CAAC,MAAM;IAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAAC,CAAC;AAEpF,MAAM,WAAW,kBAAkB,CACjC,SAAS,SAAS,mBAAmB,EACrC,SAAS,SAAS,mBAAmB;IAErC,6DAA6D;IAC7D,QAAQ,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,CAAC;IAC3C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CAC1D;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CACzB,SAAS,SAAS,mBAAmB,EACrC,SAAS,SAAS,mBAAmB,EAErC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,GAChD,KAAK,CAAC,SAAS,CAAC,CA8BlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,SAAS,SAAS,mBAAmB,EACrC,SAAS,SAAS,mBAAmB,GAAG,mBAAmB,EAE3D,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,EACnE,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,GACnE,KAAK,CAAC,SAAS,CAAC,CAKlB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,SAAS,mBAAmB,EAErC,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,EACpC,OAAO,GAAE;IACP,wEAAwE;IACxE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,SAAS,CAAC;CACZ,GACL,OAAO,CAAC;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE;QAAE,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CA4BhH"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * subPipeline — compose a registered (or inline) pipeline as a phase
3
+ * inside another pipeline.
4
+ *
5
+ * Two surface forms:
6
+ *
7
+ * - **`subPipeline(name, options)`** — higher-order pattern returning a
8
+ * `Phase<TOuterCtx>`. Compose like any other phase.
9
+ * - **`runSubPipeline(spec, options)`** — free function for imperative
10
+ * use inside phase bodies. Returns `{ ctx, summary }`.
11
+ *
12
+ * The inner pipeline gets:
13
+ * - a fresh `PipelineCache` (cache scopes are isolated)
14
+ * - the outer ctx's `signal` (cancellation propagates down)
15
+ *
16
+ * Events from the inner pipeline flatten into the outer event stream
17
+ * via `yield*` — JobStore consumers, SSE listeners, and the orchestrator
18
+ * see one continuous stream.
19
+ */
20
+ import { runPipeline } from '../orchestrator.js';
21
+ import { PipelineCache } from '../cache.js';
22
+ /** A higher-order pattern returning a `Phase<TOuterCtx>`. */
23
+ export function subPipeline(name, options) {
24
+ return {
25
+ name,
26
+ async *run(outer) {
27
+ const source = typeof options.pipeline === 'function'
28
+ ? options.pipeline()
29
+ : options.pipeline;
30
+ if (!source) {
31
+ throw new Error(`subPipeline "${name}": pipeline resolver returned undefined`);
32
+ }
33
+ const inner = options.mapInput
34
+ ? options.mapInput(outer)
35
+ : source.ctx;
36
+ // Isolate the inner pipeline's cache; propagate the outer's signal.
37
+ inner.cache = new PipelineCache();
38
+ inner.signal = outer.signal;
39
+ yield* runPipeline(source.phases, inner);
40
+ options.mapOutput?.(outer, inner);
41
+ },
42
+ };
43
+ }
44
+ /**
45
+ * Type-inferred convenience over `subPipeline` for the direct-object case.
46
+ * `TInnerCtx` is inferred from `source.ctx`, so callers only spell the outer
47
+ * ctx generic (and often not even that):
48
+ *
49
+ * subPipelineOf('inner', innerSpec, { mapOutput: ... })
50
+ *
51
+ * vs. the more verbose `subPipeline<MyOuter, MyInner>(...)`. For the lazy
52
+ * registry-lookup case, use `subPipeline` directly — the resolver form needs
53
+ * explicit generics anyway.
54
+ */
55
+ export function subPipelineOf(name, source, mapping) {
56
+ return subPipeline(name, {
57
+ pipeline: source,
58
+ ...mapping,
59
+ });
60
+ }
61
+ /**
62
+ * Imperative form: invoke an inner pipeline from inside a phase body.
63
+ * Returns the inner ctx (post-run) and the pipeline summary. Phase
64
+ * exceptions in the inner pipeline propagate as rejections.
65
+ */
66
+ export async function runSubPipeline(source, options = {}) {
67
+ const resolved = typeof source === 'function' ? source() : source;
68
+ if (!resolved) {
69
+ throw new Error('runSubPipeline: pipeline resolver returned undefined');
70
+ }
71
+ const inner = options.ctx ?? resolved.ctx;
72
+ inner.cache = new PipelineCache();
73
+ if (options.signal)
74
+ inner.signal = options.signal;
75
+ let eventCount = 0;
76
+ let stopReason;
77
+ for await (const event of runPipeline(resolved.phases, inner)) {
78
+ eventCount++;
79
+ if (event.type === 'done') {
80
+ stopReason = event.reason;
81
+ }
82
+ }
83
+ return {
84
+ ctx: inner,
85
+ summary: stopReason !== undefined
86
+ ? { status: 'stopped', reason: stopReason, eventCount }
87
+ : { status: 'completed', eventCount },
88
+ };
89
+ }
90
+ //# sourceMappingURL=sub-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-pipeline.js","sourceRoot":"","sources":["../../src/patterns/sub-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+B5C,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CAIzB,IAAY,EACZ,OAAiD;IAEjD,OAAO;QACL,IAAI;QACJ,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK;YACd,MAAM,MAAM,GACV,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU;gBACpC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACpB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;YACvB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,yCAAyC,CAC9D,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ;gBAC5B,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YAEf,oEAAoE;YACnE,KAAkC,CAAC,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;YAChE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAE5B,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAGtC,CAAC;YAEF,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAI3B,IAAY,EACZ,MAAmE,EACnE,OAAoE;IAEpE,OAAO,WAAW,CAAuB,IAAI,EAAE;QAC7C,QAAQ,EAAE,MAAM;QAChB,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAGlC,MAAoC,EACpC,UAKI,EAAE;IAEN,MAAM,QAAQ,GACZ,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC;IACzC,KAAkC,CAAC,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAElD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAA8B,CAAC;IAEnC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QAC9D,UAAU,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,UAAU,GAAI,KAA6B,CAAC,MAAM,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,EAAE,KAAK;QACV,OAAO,EACL,UAAU,KAAK,SAAS;YACtB,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE;YACvD,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE;KAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * synthesize-with-followup — synthesizer reviews its own output and may
3
+ * request another round of upstream work.
4
+ *
5
+ * Loop:
6
+ * 1. Synthesizer produces draft text (typically streaming).
7
+ * 2. extractFollowUp inspects the draft for explicit "I need more on X".
8
+ * 3. If present and budget allows, doFollowUp runs whatever upstream phases
9
+ * need to re-run, then we loop.
10
+ * 4. Otherwise the loop exits and the final text is written to ctx.
11
+ */
12
+ import type { BasePipelineContext, Phase, PipelineEvent } from '../phase.js';
13
+ export interface SynthesizeWithFollowupOptions<TCtx extends BasePipelineContext, TFollowUp> {
14
+ /**
15
+ * Run the synthesizer. May yield events (typically streamed `content`).
16
+ * Returns the final text via the generator's return value.
17
+ */
18
+ synthesize: (ctx: TCtx, iteration: number) => AsyncGenerator<PipelineEvent, string, void>;
19
+ /**
20
+ * Inspect the synthesizer output. Return null if synthesis is complete,
21
+ * or a typed follow-up directive if more work is needed.
22
+ */
23
+ extractFollowUp: (output: string) => TFollowUp | null;
24
+ /**
25
+ * Run whatever extra work the follow-up requested (often re-runs of
26
+ * upstream phases). May yield events.
27
+ */
28
+ doFollowUp: (ctx: TCtx, followUp: TFollowUp, iteration: number) => AsyncGenerator<PipelineEvent, void, void>;
29
+ /** Stash the final synthesized text on ctx. */
30
+ writeTo: (ctx: TCtx, text: string) => void;
31
+ /** Cap iterations. Default 2 (one synthesis + one follow-up). */
32
+ maxIterations?: number;
33
+ }
34
+ export declare function synthesizeWithFollowup<TCtx extends BasePipelineContext, TFollowUp>(phaseName: string, options: SynthesizeWithFollowupOptions<TCtx, TFollowUp>): Phase<TCtx>;
35
+ //# sourceMappingURL=synthesize-with-followup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesize-with-followup.d.ts","sourceRoot":"","sources":["../../src/patterns/synthesize-with-followup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,6BAA6B,CAAC,IAAI,SAAS,mBAAmB,EAAE,SAAS;IACxF;;;OAGG;IACH,UAAU,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1F;;;OAGG;IACH,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,GAAG,IAAI,CAAC;IACtD;;;OAGG;IACH,UAAU,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,KAAK,cAAc,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7G,+CAA+C;IAC/C,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,SAAS,mBAAmB,EAAE,SAAS,EAChF,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,6BAA6B,CAAC,IAAI,EAAE,SAAS,CAAC,GACtD,KAAK,CAAC,IAAI,CAAC,CAmCb"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * synthesize-with-followup — synthesizer reviews its own output and may
3
+ * request another round of upstream work.
4
+ *
5
+ * Loop:
6
+ * 1. Synthesizer produces draft text (typically streaming).
7
+ * 2. extractFollowUp inspects the draft for explicit "I need more on X".
8
+ * 3. If present and budget allows, doFollowUp runs whatever upstream phases
9
+ * need to re-run, then we loop.
10
+ * 4. Otherwise the loop exits and the final text is written to ctx.
11
+ */
12
+ export function synthesizeWithFollowup(phaseName, options) {
13
+ return {
14
+ name: phaseName,
15
+ async *run(ctx) {
16
+ const max = options.maxIterations ?? 2;
17
+ let finalText = '';
18
+ for (let iter = 0; iter < max; iter++) {
19
+ const synthGen = options.synthesize(ctx, iter);
20
+ let stepText = '';
21
+ while (true) {
22
+ const next = await synthGen.next();
23
+ if (next.done) {
24
+ stepText = next.value;
25
+ break;
26
+ }
27
+ yield next.value;
28
+ }
29
+ finalText = stepText;
30
+ const followUp = options.extractFollowUp(stepText);
31
+ if (!followUp || iter === max - 1)
32
+ break;
33
+ yield {
34
+ type: 'agent_activity',
35
+ agent: phaseName,
36
+ action: 'follow_up',
37
+ detail: `iteration ${iter + 1} requested more work`,
38
+ };
39
+ yield* options.doFollowUp(ctx, followUp, iter);
40
+ }
41
+ options.writeTo(ctx, finalText);
42
+ },
43
+ };
44
+ }
45
+ //# sourceMappingURL=synthesize-with-followup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesize-with-followup.js","sourceRoot":"","sources":["../../src/patterns/synthesize-with-followup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA0BH,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,OAAuD;IAEvD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;YACZ,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;YACvC,IAAI,SAAS,GAAG,EAAE,CAAC;YAEnB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBAC/C,IAAI,QAAQ,GAAG,EAAE,CAAC;gBAClB,OAAO,IAAI,EAAE,CAAC;oBACZ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACnC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;wBACd,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;wBACtB,MAAM;oBACR,CAAC;oBACD,MAAM,IAAI,CAAC,KAAK,CAAC;gBACnB,CAAC;gBACD,SAAS,GAAG,QAAQ,CAAC;gBAErB,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;gBACnD,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,GAAG,GAAG,CAAC;oBAAE,MAAM;gBAEzC,MAAM;oBACJ,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,WAAW;oBACnB,MAAM,EAAE,aAAa,IAAI,GAAG,CAAC,sBAAsB;iBACpD,CAAC;gBACF,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * while-condition — a general convergence loop.
3
+ *
4
+ * Runs `body` repeatedly while `predicate(ctx)` is true, capped at
5
+ * `maxIterations`. Predicate is async and runs *before* each iteration —
6
+ * an immediately-false predicate produces zero body executions, like a
7
+ * standard `while` loop.
8
+ *
9
+ * Exits via one of:
10
+ * - predicate returns false → emits a `data` event with key
11
+ * `${name}.converged` and value
12
+ * `{ iterations }`.
13
+ * - maxIterations reached → sets ctx.stop with a reason naming
14
+ * the pattern; emits `data` event
15
+ * `${name}.max-iterations`.
16
+ * - body sets ctx.stop → propagates immediately.
17
+ *
18
+ * Body composition: pass a list of phases — they run in order each
19
+ * iteration, sharing ctx. Use `parallelPhases` if you want them concurrent.
20
+ */
21
+ import type { BasePipelineContext, Phase } from '../phase.js';
22
+ export interface WhileConditionOptions<TCtx extends BasePipelineContext> {
23
+ /** Predicate evaluated before each iteration. Loop continues while true. */
24
+ predicate: (ctx: TCtx) => boolean | Promise<boolean>;
25
+ /** Phases to run each iteration. */
26
+ body: Phase<TCtx>[];
27
+ /** Hard cap on iterations to prevent runaway loops. Default: 10. */
28
+ maxIterations?: number;
29
+ }
30
+ export declare function whileCondition<TCtx extends BasePipelineContext>(phaseName: string, options: WhileConditionOptions<TCtx>): Phase<TCtx>;
31
+ //# sourceMappingURL=while-condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"while-condition.d.ts","sourceRoot":"","sources":["../../src/patterns/while-condition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAiB,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,qBAAqB,CAAC,IAAI,SAAS,mBAAmB;IACrE,4EAA4E;IAC5E,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,oCAAoC;IACpC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,IAAI,SAAS,mBAAmB,EAC7D,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,CAAC,IAAI,CAAC,GACnC,KAAK,CAAC,IAAI,CAAC,CA0Cb"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * while-condition — a general convergence loop.
3
+ *
4
+ * Runs `body` repeatedly while `predicate(ctx)` is true, capped at
5
+ * `maxIterations`. Predicate is async and runs *before* each iteration —
6
+ * an immediately-false predicate produces zero body executions, like a
7
+ * standard `while` loop.
8
+ *
9
+ * Exits via one of:
10
+ * - predicate returns false → emits a `data` event with key
11
+ * `${name}.converged` and value
12
+ * `{ iterations }`.
13
+ * - maxIterations reached → sets ctx.stop with a reason naming
14
+ * the pattern; emits `data` event
15
+ * `${name}.max-iterations`.
16
+ * - body sets ctx.stop → propagates immediately.
17
+ *
18
+ * Body composition: pass a list of phases — they run in order each
19
+ * iteration, sharing ctx. Use `parallelPhases` if you want them concurrent.
20
+ */
21
+ export function whileCondition(phaseName, options) {
22
+ const max = options.maxIterations ?? 10;
23
+ return {
24
+ name: phaseName,
25
+ async *run(ctx) {
26
+ let iterations = 0;
27
+ while (iterations < max) {
28
+ const shouldContinue = await options.predicate(ctx);
29
+ if (!shouldContinue) {
30
+ yield {
31
+ type: 'data',
32
+ key: `${phaseName}.converged`,
33
+ value: { iterations },
34
+ };
35
+ return;
36
+ }
37
+ yield {
38
+ type: 'agent_activity',
39
+ agent: phaseName,
40
+ action: 'iteration',
41
+ detail: `${iterations + 1}/${max}`,
42
+ };
43
+ for (const phase of options.body) {
44
+ yield* phase.run(ctx);
45
+ if (ctx.stop)
46
+ return;
47
+ }
48
+ iterations++;
49
+ }
50
+ yield {
51
+ type: 'data',
52
+ key: `${phaseName}.max-iterations`,
53
+ value: { iterations },
54
+ };
55
+ ctx.stop = { reason: `${phaseName}: max iterations (${max}) reached` };
56
+ },
57
+ };
58
+ }
59
+ //# sourceMappingURL=while-condition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"while-condition.js","sourceRoot":"","sources":["../../src/patterns/while-condition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAaH,MAAM,UAAU,cAAc,CAC5B,SAAiB,EACjB,OAAoC;IAEpC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAExC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;YACZ,IAAI,UAAU,GAAG,CAAC,CAAC;YAEnB,OAAO,UAAU,GAAG,GAAG,EAAE,CAAC;gBACxB,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACpD,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,MAAM;wBACJ,IAAI,EAAE,MAAM;wBACZ,GAAG,EAAE,GAAG,SAAS,YAAY;wBAC7B,KAAK,EAAE,EAAE,UAAU,EAAE;qBACtB,CAAC;oBACF,OAAO;gBACT,CAAC;gBAED,MAAM;oBACJ,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,WAAW;oBACnB,MAAM,EAAE,GAAG,UAAU,GAAG,CAAC,IAAI,GAAG,EAAE;iBACnC,CAAC;gBAEF,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACtB,IAAI,GAAG,CAAC,IAAI;wBAAE,OAAO;gBACvB,CAAC;gBAED,UAAU,EAAE,CAAC;YACf,CAAC;YAED,MAAM;gBACJ,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,GAAG,SAAS,iBAAiB;gBAClC,KAAK,EAAE,EAAE,UAAU,EAAE;aACtB,CAAC;YACF,GAAG,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,GAAG,SAAS,qBAAqB,GAAG,WAAW,EAAE,CAAC;QACzE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * with-retry — higher-order phase wrapper for retrying flaky work.
3
+ *
4
+ * Wraps any `Phase` and retries it on failure. Failure means either:
5
+ * - the inner phase throws an exception, OR
6
+ * - the inner phase yields then sets `ctx.stop` (a clean failure signal)
7
+ *
8
+ * Both default to retryable. Override with `isFailure(ctx, error?)` if a
9
+ * specific `ctx.stop.reason` should *not* trigger a retry (e.g. user
10
+ * cancellation, terminal validation error).
11
+ *
12
+ * Retries are bounded by `maxAttempts` (default 3) and spaced with
13
+ * exponential backoff starting at `baseDelayMs` (default 1000).
14
+ *
15
+ * Idempotence is the caller's responsibility. The wrapper does NOT
16
+ * snapshot/restore ctx between attempts — a partially-applied mutation
17
+ * from a failed attempt is visible to the retry. Pass `resetState` if
18
+ * you need to undo partial work before each retry.
19
+ *
20
+ * Events emitted by the inner phase pass through unmodified. The wrapper
21
+ * additionally emits `data` events with key `${phase.name}.attempt`.
22
+ */
23
+ import type { BasePipelineContext, Phase } from '../phase.js';
24
+ export interface WithRetryOptions<TCtx extends BasePipelineContext> {
25
+ /** Maximum total attempts including the first. Default: 3. */
26
+ maxAttempts?: number;
27
+ /** Base delay for exponential backoff, in milliseconds. Default: 1000. */
28
+ baseDelayMs?: number;
29
+ /** Decide whether the most recent attempt counts as a failure. Default: ctx.stop is set OR an error was thrown. */
30
+ isFailure?: (ctx: TCtx, error?: unknown) => boolean;
31
+ /** Called before each retry (not before the first attempt). */
32
+ onRetry?: (ctx: TCtx, attempt: number, error?: unknown) => void;
33
+ /** Called between attempts. Use to undo partial mutations from the failed attempt. */
34
+ resetState?: (ctx: TCtx) => void;
35
+ }
36
+ export declare function withRetry<TCtx extends BasePipelineContext>(phase: Phase<TCtx>, options?: WithRetryOptions<TCtx>): Phase<TCtx>;
37
+ //# sourceMappingURL=with-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-retry.d.ts","sourceRoot":"","sources":["../../src/patterns/with-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAiB,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,mBAAmB;IAChE,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mHAAmH;IACnH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IACpD,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAChE,sFAAsF;IACtF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC;CAClC;AAID,wBAAgB,SAAS,CAAC,IAAI,SAAS,mBAAmB,EACxD,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAClB,OAAO,GAAE,gBAAgB,CAAC,IAAI,CAAM,GACnC,KAAK,CAAC,IAAI,CAAC,CAwDb"}