@warlock.js/ai 4.2.11 → 4.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 (427) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/cjs/index.cjs +10151 -4625
  3. package/cjs/index.cjs.map +1 -1
  4. package/cjs/magic-string.es-BtxW4VqG.cjs +1015 -0
  5. package/cjs/magic-string.es-BtxW4VqG.cjs.map +1 -0
  6. package/cjs/matcher-logic-SBnzYohQ.cjs +217 -0
  7. package/cjs/matcher-logic-SBnzYohQ.cjs.map +1 -0
  8. package/cjs/matchers-BBh3gyB-.cjs +13739 -0
  9. package/cjs/matchers-BBh3gyB-.cjs.map +1 -0
  10. package/esm/agent/agent-config.type.d.mts +19 -6
  11. package/esm/agent/agent-config.type.d.mts.map +1 -1
  12. package/esm/agent/agent.d.mts.map +1 -1
  13. package/esm/agent/agent.mjs +17 -6
  14. package/esm/agent/agent.mjs.map +1 -1
  15. package/esm/agent/index.d.mts +2 -1
  16. package/esm/agent/index.mjs +1 -0
  17. package/esm/agent/spawn-sub-agent.d.mts +87 -0
  18. package/esm/agent/spawn-sub-agent.d.mts.map +1 -0
  19. package/esm/agent/spawn-sub-agent.mjs +68 -0
  20. package/esm/agent/spawn-sub-agent.mjs.map +1 -0
  21. package/esm/ai.d.mts +58 -3
  22. package/esm/ai.d.mts.map +1 -1
  23. package/esm/ai.mjs +58 -3
  24. package/esm/ai.mjs.map +1 -1
  25. package/esm/batch/batch.d.mts +43 -0
  26. package/esm/batch/batch.d.mts.map +1 -0
  27. package/esm/batch/batch.mjs +179 -0
  28. package/esm/batch/batch.mjs.map +1 -0
  29. package/esm/batch/batch.type.d.mts +144 -0
  30. package/esm/batch/batch.type.d.mts.map +1 -0
  31. package/esm/batch/index.mjs +3 -0
  32. package/esm/batch/run-batch-item.mjs +100 -0
  33. package/esm/batch/run-batch-item.mjs.map +1 -0
  34. package/esm/batch/run-with-concurrency.mjs +39 -0
  35. package/esm/batch/run-with-concurrency.mjs.map +1 -0
  36. package/esm/checkpoint/index.d.mts +3 -0
  37. package/esm/checkpoint/memory.d.mts +21 -0
  38. package/esm/checkpoint/memory.d.mts.map +1 -0
  39. package/esm/checkpoint/memory.mjs +0 -0
  40. package/esm/checkpoint/memory.mjs.map +1 -0
  41. package/esm/checkpoint/pg.d.mts +37 -0
  42. package/esm/checkpoint/pg.d.mts.map +1 -0
  43. package/esm/checkpoint/pg.mjs +265 -0
  44. package/esm/checkpoint/pg.mjs.map +1 -0
  45. package/esm/checkpoint/redis.d.mts +39 -0
  46. package/esm/checkpoint/redis.d.mts.map +1 -0
  47. package/esm/checkpoint/redis.mjs +200 -0
  48. package/esm/checkpoint/redis.mjs.map +1 -0
  49. package/esm/config.d.mts +61 -14
  50. package/esm/config.d.mts.map +1 -1
  51. package/esm/config.mjs +25 -6
  52. package/esm/config.mjs.map +1 -1
  53. package/esm/contracts/agent/agent.contract.d.mts +43 -0
  54. package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
  55. package/esm/contracts/agent/eval.type.d.mts +143 -0
  56. package/esm/contracts/agent/eval.type.d.mts.map +1 -0
  57. package/esm/contracts/agent/index.d.mts +1 -0
  58. package/esm/contracts/events/supervisor-events.type.d.mts +3 -3
  59. package/esm/contracts/fallback-model.contract.d.mts +65 -0
  60. package/esm/contracts/fallback-model.contract.d.mts.map +1 -0
  61. package/esm/contracts/index.d.mts +32 -12
  62. package/esm/contracts/memory/index.d.mts +4 -0
  63. package/esm/contracts/memory/memory-config.type.d.mts +150 -0
  64. package/esm/contracts/memory/memory-config.type.d.mts.map +1 -0
  65. package/esm/contracts/memory/memory-item.type.d.mts +64 -0
  66. package/esm/contracts/memory/memory-item.type.d.mts.map +1 -0
  67. package/esm/contracts/memory/memory.contract.d.mts +87 -0
  68. package/esm/contracts/memory/memory.contract.d.mts.map +1 -0
  69. package/esm/contracts/memory/recall-options.type.d.mts +33 -0
  70. package/esm/contracts/memory/recall-options.type.d.mts.map +1 -0
  71. package/esm/contracts/middleware/index.d.mts +2 -2
  72. package/esm/contracts/middleware/middleware-context.type.d.mts +42 -2
  73. package/esm/contracts/middleware/middleware-context.type.d.mts.map +1 -1
  74. package/esm/contracts/middleware/middleware.contract.d.mts +46 -2
  75. package/esm/contracts/middleware/middleware.contract.d.mts.map +1 -1
  76. package/esm/contracts/model.contract.d.mts +63 -2
  77. package/esm/contracts/model.contract.d.mts.map +1 -1
  78. package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts +91 -0
  79. package/esm/contracts/orchestrator/checkpoint-store.contract.d.mts.map +1 -0
  80. package/esm/contracts/orchestrator/index.d.mts +8 -0
  81. package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts +43 -0
  82. package/esm/contracts/orchestrator/orchestrator-commands.type.d.mts.map +1 -0
  83. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +170 -0
  84. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -0
  85. package/esm/contracts/orchestrator/orchestrator-event.type.d.mts +118 -0
  86. package/esm/contracts/orchestrator/orchestrator-event.type.d.mts.map +1 -0
  87. package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts +44 -0
  88. package/esm/contracts/orchestrator/orchestrator-execute-options.type.d.mts.map +1 -0
  89. package/esm/contracts/orchestrator/orchestrator.contract.d.mts +129 -0
  90. package/esm/contracts/orchestrator/orchestrator.contract.d.mts.map +1 -0
  91. package/esm/contracts/orchestrator/session.contract.d.mts +26 -0
  92. package/esm/contracts/orchestrator/session.contract.d.mts.map +1 -0
  93. package/esm/contracts/orchestrator/snapshot-store.contract.d.mts +89 -0
  94. package/esm/contracts/orchestrator/snapshot-store.contract.d.mts.map +1 -0
  95. package/esm/contracts/planner/index.d.mts +6 -0
  96. package/esm/contracts/planner/planner-capability.type.d.mts +39 -0
  97. package/esm/contracts/planner/planner-capability.type.d.mts.map +1 -0
  98. package/esm/contracts/planner/planner-config.type.d.mts +78 -0
  99. package/esm/contracts/planner/planner-config.type.d.mts.map +1 -0
  100. package/esm/contracts/planner/planner-execute-options.type.d.mts +43 -0
  101. package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -0
  102. package/esm/contracts/planner/planner-plan.type.d.mts +48 -0
  103. package/esm/contracts/planner/planner-plan.type.d.mts.map +1 -0
  104. package/esm/contracts/planner/planner-result.type.d.mts +82 -0
  105. package/esm/contracts/planner/planner-result.type.d.mts.map +1 -0
  106. package/esm/contracts/planner/planner.contract.d.mts +60 -0
  107. package/esm/contracts/planner/planner.contract.d.mts.map +1 -0
  108. package/esm/contracts/result/base-report.type.d.mts +7 -2
  109. package/esm/contracts/result/base-report.type.d.mts.map +1 -1
  110. package/esm/contracts/result/base-report.type.mjs.map +1 -1
  111. package/esm/contracts/result/index.d.mts +2 -1
  112. package/esm/contracts/result/model-pricing.type.d.mts +10 -0
  113. package/esm/contracts/result/model-pricing.type.d.mts.map +1 -1
  114. package/esm/contracts/result/orchestrator-result.type.d.mts +139 -0
  115. package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -0
  116. package/esm/contracts/result/session-send-result.type.d.mts +12 -3
  117. package/esm/contracts/result/session-send-result.type.d.mts.map +1 -1
  118. package/esm/contracts/result/supervisor-result.type.d.mts +1 -1
  119. package/esm/contracts/result/usage.type.d.mts +24 -0
  120. package/esm/contracts/result/usage.type.d.mts.map +1 -1
  121. package/esm/contracts/sdk-adapter.contract.d.mts +1 -1
  122. package/esm/contracts/supervisor/dispatch-context.type.d.mts +3 -3
  123. package/esm/contracts/supervisor/evaluate-context.type.d.mts +1 -1
  124. package/esm/contracts/supervisor/index.d.mts +5 -5
  125. package/esm/contracts/supervisor/route-context.type.d.mts +2 -2
  126. package/esm/contracts/supervisor/supervisor-config.type.d.mts +55 -13
  127. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  128. package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts +1 -1
  129. package/esm/contracts/supervisor/supervisor.contract.d.mts +9 -2
  130. package/esm/contracts/supervisor/supervisor.contract.d.mts.map +1 -1
  131. package/esm/contracts/workflow/index.d.mts +2 -2
  132. package/esm/contracts/workflow/workflow.contract.d.mts +28 -7
  133. package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
  134. package/esm/errors/error-code.type.d.mts +1 -1
  135. package/esm/errors/index.d.mts +7 -0
  136. package/esm/errors/index.mjs +7 -0
  137. package/esm/errors/orchestrator-cancelled-error.d.mts +32 -0
  138. package/esm/errors/orchestrator-cancelled-error.d.mts.map +1 -0
  139. package/esm/errors/orchestrator-cancelled-error.mjs +31 -0
  140. package/esm/errors/orchestrator-cancelled-error.mjs.map +1 -0
  141. package/esm/errors/orchestrator-config-error.d.mts +26 -0
  142. package/esm/errors/orchestrator-config-error.d.mts.map +1 -0
  143. package/esm/errors/orchestrator-config-error.mjs +30 -0
  144. package/esm/errors/orchestrator-config-error.mjs.map +1 -0
  145. package/esm/errors/orchestrator-drift-error.d.mts +38 -0
  146. package/esm/errors/orchestrator-drift-error.d.mts.map +1 -0
  147. package/esm/errors/orchestrator-drift-error.mjs +37 -0
  148. package/esm/errors/orchestrator-drift-error.mjs.map +1 -0
  149. package/esm/errors/orchestrator-failed-error.d.mts +33 -0
  150. package/esm/errors/orchestrator-failed-error.d.mts.map +1 -0
  151. package/esm/errors/orchestrator-failed-error.mjs +36 -0
  152. package/esm/errors/orchestrator-failed-error.mjs.map +1 -0
  153. package/esm/errors/planner-cancelled-error.d.mts +33 -0
  154. package/esm/errors/planner-cancelled-error.d.mts.map +1 -0
  155. package/esm/errors/planner-cancelled-error.mjs +29 -0
  156. package/esm/errors/planner-cancelled-error.mjs.map +1 -0
  157. package/esm/errors/planner-failed-error.d.mts +40 -0
  158. package/esm/errors/planner-failed-error.d.mts.map +1 -0
  159. package/esm/errors/planner-failed-error.mjs +37 -0
  160. package/esm/errors/planner-failed-error.mjs.map +1 -0
  161. package/esm/errors/planner-plan-invalid-error.d.mts +21 -0
  162. package/esm/errors/planner-plan-invalid-error.d.mts.map +1 -0
  163. package/esm/errors/planner-plan-invalid-error.mjs +25 -0
  164. package/esm/errors/planner-plan-invalid-error.mjs.map +1 -0
  165. package/esm/eval/eval-runner.d.mts +17 -0
  166. package/esm/eval/eval-runner.d.mts.map +1 -0
  167. package/esm/eval/eval-runner.mjs +121 -0
  168. package/esm/eval/eval-runner.mjs.map +1 -0
  169. package/esm/eval/index.d.mts +29 -0
  170. package/esm/eval/index.d.mts.map +1 -0
  171. package/esm/eval/index.mjs +30 -0
  172. package/esm/eval/index.mjs.map +1 -0
  173. package/esm/eval/judge-scorer.d.mts +21 -0
  174. package/esm/eval/judge-scorer.d.mts.map +1 -0
  175. package/esm/eval/judge-scorer.mjs +87 -0
  176. package/esm/eval/judge-scorer.mjs.map +1 -0
  177. package/esm/eval/scorers.d.mts +50 -0
  178. package/esm/eval/scorers.d.mts.map +1 -0
  179. package/esm/eval/scorers.mjs +101 -0
  180. package/esm/eval/scorers.mjs.map +1 -0
  181. package/esm/index.d.mts +95 -30
  182. package/esm/index.mjs +66 -22
  183. package/esm/memory/derive-id.mjs +24 -0
  184. package/esm/memory/derive-id.mjs.map +1 -0
  185. package/esm/memory/episodic-memory.mjs +106 -0
  186. package/esm/memory/episodic-memory.mjs.map +1 -0
  187. package/esm/memory/index.d.mts +5 -0
  188. package/esm/memory/memory.d.mts +42 -0
  189. package/esm/memory/memory.d.mts.map +1 -0
  190. package/esm/memory/memory.mjs +166 -0
  191. package/esm/memory/memory.mjs.map +1 -0
  192. package/esm/memory/procedural-memory.mjs +103 -0
  193. package/esm/memory/procedural-memory.mjs.map +1 -0
  194. package/esm/memory/semantic-memory.mjs +80 -0
  195. package/esm/memory/semantic-memory.mjs.map +1 -0
  196. package/esm/memory/working-memory.mjs +62 -0
  197. package/esm/memory/working-memory.mjs.map +1 -0
  198. package/esm/middleware/builtins/budget-contract.type.d.mts +126 -0
  199. package/esm/middleware/builtins/budget-contract.type.d.mts.map +1 -0
  200. package/esm/middleware/builtins/budget.d.mts +71 -1
  201. package/esm/middleware/builtins/budget.d.mts.map +1 -1
  202. package/esm/middleware/builtins/budget.mjs +119 -4
  203. package/esm/middleware/builtins/budget.mjs.map +1 -1
  204. package/esm/middleware/builtins/semantic-cache.d.mts +1 -1
  205. package/esm/middleware/index.d.mts +2 -1
  206. package/esm/middleware/index.mjs +1 -1
  207. package/esm/middleware/pipeline.d.mts +9 -6
  208. package/esm/middleware/pipeline.d.mts.map +1 -1
  209. package/esm/middleware/pipeline.mjs.map +1 -1
  210. package/esm/mock/index.d.mts +1 -0
  211. package/esm/mock/index.mjs +1 -0
  212. package/esm/mock/mock-router.d.mts +63 -0
  213. package/esm/mock/mock-router.d.mts.map +1 -0
  214. package/esm/mock/mock-router.mjs +58 -0
  215. package/esm/mock/mock-router.mjs.map +1 -0
  216. package/esm/model/fallback-model.d.mts +45 -0
  217. package/esm/model/fallback-model.d.mts.map +1 -0
  218. package/esm/model/fallback-model.mjs +218 -0
  219. package/esm/model/fallback-model.mjs.map +1 -0
  220. package/esm/model/index.d.mts +2 -0
  221. package/esm/model/index.mjs +3 -0
  222. package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +78 -0
  223. package/esm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
  224. package/esm/node_modules/@vitest/expect/dist/index.mjs +1473 -0
  225. package/esm/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
  226. package/esm/node_modules/@vitest/pretty-format/dist/index.mjs +888 -0
  227. package/esm/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
  228. package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs +1533 -0
  229. package/esm/node_modules/@vitest/runner/dist/chunk-artifact.mjs.map +1 -0
  230. package/esm/node_modules/@vitest/runner/dist/index.mjs +3 -0
  231. package/esm/node_modules/@vitest/runner/dist/utils.mjs +3 -0
  232. package/esm/node_modules/@vitest/snapshot/dist/index.mjs +922 -0
  233. package/esm/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
  234. package/esm/node_modules/@vitest/spy/dist/index.mjs +386 -0
  235. package/esm/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
  236. package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs +82 -0
  237. package/esm/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs.map +1 -0
  238. package/esm/node_modules/@vitest/utils/dist/diff.mjs +1357 -0
  239. package/esm/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
  240. package/esm/node_modules/@vitest/utils/dist/display.mjs +559 -0
  241. package/esm/node_modules/@vitest/utils/dist/display.mjs.map +1 -0
  242. package/esm/node_modules/@vitest/utils/dist/error.mjs +38 -0
  243. package/esm/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
  244. package/esm/node_modules/@vitest/utils/dist/helpers.mjs +181 -0
  245. package/esm/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
  246. package/esm/node_modules/@vitest/utils/dist/offset.mjs +27 -0
  247. package/esm/node_modules/@vitest/utils/dist/offset.mjs.map +1 -0
  248. package/esm/node_modules/@vitest/utils/dist/serialize.mjs +77 -0
  249. package/esm/node_modules/@vitest/utils/dist/serialize.mjs.map +1 -0
  250. package/esm/node_modules/@vitest/utils/dist/source-map.mjs +374 -0
  251. package/esm/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
  252. package/esm/node_modules/@vitest/utils/dist/timers.mjs +37 -0
  253. package/esm/node_modules/@vitest/utils/dist/timers.mjs.map +1 -0
  254. package/esm/node_modules/chai/index.mjs +2973 -0
  255. package/esm/node_modules/chai/index.mjs.map +1 -0
  256. package/esm/node_modules/magic-string/dist/magic-string.es.mjs +940 -0
  257. package/esm/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
  258. package/esm/node_modules/tinyrainbow/dist/index.mjs +87 -0
  259. package/esm/node_modules/tinyrainbow/dist/index.mjs.map +1 -0
  260. package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs +6 -0
  261. package/esm/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs.map +1 -0
  262. package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs +52 -0
  263. package/esm/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs.map +1 -0
  264. package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs +2697 -0
  265. package/esm/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs.map +1 -0
  266. package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs +45 -0
  267. package/esm/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs.map +1 -0
  268. package/esm/orchestrator/as-tool.d.mts +42 -0
  269. package/esm/orchestrator/as-tool.d.mts.map +1 -0
  270. package/esm/orchestrator/as-tool.mjs +98 -0
  271. package/esm/orchestrator/as-tool.mjs.map +1 -0
  272. package/esm/orchestrator/checkpoint.mjs +75 -0
  273. package/esm/orchestrator/checkpoint.mjs.map +1 -0
  274. package/esm/orchestrator/commands.d.mts +38 -0
  275. package/esm/orchestrator/commands.d.mts.map +1 -0
  276. package/esm/orchestrator/commands.mjs +34 -0
  277. package/esm/orchestrator/commands.mjs.map +1 -0
  278. package/esm/orchestrator/compaction.mjs +206 -0
  279. package/esm/orchestrator/compaction.mjs.map +1 -0
  280. package/esm/orchestrator/dispatch.mjs +171 -0
  281. package/esm/orchestrator/dispatch.mjs.map +1 -0
  282. package/esm/orchestrator/emitter-port.type.d.mts +31 -0
  283. package/esm/orchestrator/emitter-port.type.d.mts.map +1 -0
  284. package/esm/orchestrator/emitter.d.mts +56 -0
  285. package/esm/orchestrator/emitter.d.mts.map +1 -0
  286. package/esm/orchestrator/emitter.mjs +85 -0
  287. package/esm/orchestrator/emitter.mjs.map +1 -0
  288. package/esm/orchestrator/engine-context.type.d.mts +56 -0
  289. package/esm/orchestrator/engine-context.type.d.mts.map +1 -0
  290. package/esm/orchestrator/execution.d.mts +116 -0
  291. package/esm/orchestrator/execution.d.mts.map +1 -0
  292. package/esm/orchestrator/execution.mjs +406 -0
  293. package/esm/orchestrator/execution.mjs.map +1 -0
  294. package/esm/orchestrator/index.d.mts +8 -0
  295. package/esm/orchestrator/index.mjs +10 -0
  296. package/esm/orchestrator/load.mjs +49 -0
  297. package/esm/orchestrator/load.mjs.map +1 -0
  298. package/esm/orchestrator/lock.mjs +75 -0
  299. package/esm/orchestrator/lock.mjs.map +1 -0
  300. package/esm/orchestrator/memory.d.mts +84 -0
  301. package/esm/orchestrator/memory.d.mts.map +1 -0
  302. package/esm/orchestrator/memory.mjs +141 -0
  303. package/esm/orchestrator/memory.mjs.map +1 -0
  304. package/esm/orchestrator/orchestrator-stream.d.mts +42 -0
  305. package/esm/orchestrator/orchestrator-stream.d.mts.map +1 -0
  306. package/esm/orchestrator/orchestrator-stream.mjs +98 -0
  307. package/esm/orchestrator/orchestrator-stream.mjs.map +1 -0
  308. package/esm/orchestrator/orchestrator.d.mts +38 -0
  309. package/esm/orchestrator/orchestrator.d.mts.map +1 -0
  310. package/esm/orchestrator/orchestrator.mjs +173 -0
  311. package/esm/orchestrator/orchestrator.mjs.map +1 -0
  312. package/esm/orchestrator/resume.mjs +74 -0
  313. package/esm/orchestrator/resume.mjs.map +1 -0
  314. package/esm/orchestrator/signature.d.mts +40 -0
  315. package/esm/orchestrator/signature.d.mts.map +1 -0
  316. package/esm/orchestrator/signature.mjs +120 -0
  317. package/esm/orchestrator/signature.mjs.map +1 -0
  318. package/esm/orchestrator/window.mjs +56 -0
  319. package/esm/orchestrator/window.mjs.map +1 -0
  320. package/esm/planner/index.d.mts +5 -0
  321. package/esm/planner/index.mjs +6 -0
  322. package/esm/planner/plan-prompt.d.mts +17 -0
  323. package/esm/planner/plan-prompt.d.mts.map +1 -0
  324. package/esm/planner/plan-prompt.mjs +30 -0
  325. package/esm/planner/plan-prompt.mjs.map +1 -0
  326. package/esm/planner/plan-schema.d.mts +27 -0
  327. package/esm/planner/plan-schema.d.mts.map +1 -0
  328. package/esm/planner/plan-schema.mjs +117 -0
  329. package/esm/planner/plan-schema.mjs.map +1 -0
  330. package/esm/planner/planner-run.d.mts +23 -0
  331. package/esm/planner/planner-run.d.mts.map +1 -0
  332. package/esm/planner/planner-run.mjs +344 -0
  333. package/esm/planner/planner-run.mjs.map +1 -0
  334. package/esm/planner/planner.d.mts +37 -0
  335. package/esm/planner/planner.d.mts.map +1 -0
  336. package/esm/planner/planner.mjs +120 -0
  337. package/esm/planner/planner.mjs.map +1 -0
  338. package/esm/planner/signature.d.mts +18 -0
  339. package/esm/planner/signature.d.mts.map +1 -0
  340. package/esm/planner/signature.mjs +27 -0
  341. package/esm/planner/signature.mjs.map +1 -0
  342. package/esm/snapshot/index.d.mts +3 -0
  343. package/esm/snapshot/memory.d.mts +26 -0
  344. package/esm/snapshot/memory.d.mts.map +1 -0
  345. package/esm/snapshot/memory.mjs +81 -0
  346. package/esm/snapshot/memory.mjs.map +1 -0
  347. package/esm/snapshot/pg.d.mts +41 -0
  348. package/esm/snapshot/pg.d.mts.map +1 -0
  349. package/esm/snapshot/pg.mjs +146 -0
  350. package/esm/snapshot/pg.mjs.map +1 -0
  351. package/esm/snapshot/redis.d.mts +42 -0
  352. package/esm/snapshot/redis.d.mts.map +1 -0
  353. package/esm/snapshot/redis.mjs +101 -0
  354. package/esm/snapshot/redis.mjs.map +1 -0
  355. package/esm/supervisor/as-tool.d.mts +0 -6
  356. package/esm/supervisor/as-tool.d.mts.map +1 -1
  357. package/esm/supervisor/as-tool.mjs +0 -6
  358. package/esm/supervisor/as-tool.mjs.map +1 -1
  359. package/esm/supervisor/execution.d.mts +43 -8
  360. package/esm/supervisor/execution.d.mts.map +1 -1
  361. package/esm/supervisor/execution.mjs +66 -16
  362. package/esm/supervisor/execution.mjs.map +1 -1
  363. package/esm/supervisor/fan-out.d.mts +65 -0
  364. package/esm/supervisor/fan-out.d.mts.map +1 -0
  365. package/esm/supervisor/fan-out.mjs +65 -0
  366. package/esm/supervisor/fan-out.mjs.map +1 -0
  367. package/esm/supervisor/index.d.mts +5 -3
  368. package/esm/supervisor/index.mjs +3 -1
  369. package/esm/supervisor/router-factory.d.mts +110 -0
  370. package/esm/supervisor/router-factory.d.mts.map +1 -0
  371. package/esm/supervisor/router-factory.mjs +141 -0
  372. package/esm/supervisor/router-factory.mjs.map +1 -0
  373. package/esm/supervisor/router-prompt.d.mts +1 -1
  374. package/esm/supervisor/snapshot.d.mts +4 -10
  375. package/esm/supervisor/snapshot.d.mts.map +1 -1
  376. package/esm/supervisor/snapshot.mjs +8 -16
  377. package/esm/supervisor/snapshot.mjs.map +1 -1
  378. package/esm/supervisor/supervisor.mjs +1 -0
  379. package/esm/supervisor/supervisor.mjs.map +1 -1
  380. package/esm/system-prompt/index.mjs +6 -0
  381. package/esm/system-prompt/system-prompt.d.mts +51 -3
  382. package/esm/system-prompt/system-prompt.d.mts.map +1 -1
  383. package/esm/system-prompt/system-prompt.mjs +52 -6
  384. package/esm/system-prompt/system-prompt.mjs.map +1 -1
  385. package/esm/testing/matcher-logic.d.mts +76 -0
  386. package/esm/testing/matcher-logic.d.mts.map +1 -0
  387. package/esm/testing/matcher-logic.mjs +144 -0
  388. package/esm/testing/matcher-logic.mjs.map +1 -0
  389. package/esm/testing/matchers.d.mts +48 -0
  390. package/esm/testing/matchers.d.mts.map +1 -0
  391. package/esm/testing/matchers.mjs +37 -0
  392. package/esm/testing/matchers.mjs.map +1 -0
  393. package/esm/testing/register-lazy.d.mts +20 -0
  394. package/esm/testing/register-lazy.d.mts.map +1 -0
  395. package/esm/testing/register-lazy.mjs +24 -0
  396. package/esm/testing/register-lazy.mjs.map +1 -0
  397. package/esm/tool/executable-as-tool.d.mts +87 -0
  398. package/esm/tool/executable-as-tool.d.mts.map +1 -0
  399. package/esm/tool/executable-as-tool.mjs +81 -0
  400. package/esm/tool/executable-as-tool.mjs.map +1 -0
  401. package/esm/tool/index.d.mts +2 -1
  402. package/esm/tool/index.mjs +1 -0
  403. package/esm/workflow/as-tool.mjs +0 -6
  404. package/esm/workflow/as-tool.mjs.map +1 -1
  405. package/esm/workflow/engine.mjs +2 -2
  406. package/esm/workflow/snapshot.mjs +13 -7
  407. package/esm/workflow/snapshot.mjs.map +1 -1
  408. package/esm/workflow/step-runner.mjs +1 -1
  409. package/esm/workflow/workflow.mjs +1 -0
  410. package/esm/workflow/workflow.mjs.map +1 -1
  411. package/llms-full.txt +947 -42
  412. package/llms.txt +13 -8
  413. package/package.json +3 -3
  414. package/skills/README.md +25 -5
  415. package/skills/ai-basics/SKILL.md +18 -7
  416. package/skills/ai-dx-helpers/SKILL.md +180 -0
  417. package/skills/attach-ai-middleware/SKILL.md +32 -3
  418. package/skills/handle-ai-errors/SKILL.md +20 -6
  419. package/skills/manage-ai-stores/SKILL.md +127 -0
  420. package/skills/persist-ai-data/SKILL.md +21 -10
  421. package/skills/pick-ai-provider/SKILL.md +46 -12
  422. package/skills/run-ai-agent/SKILL.md +51 -2
  423. package/skills/run-orchestrator/SKILL.md +198 -0
  424. package/skills/run-planner/SKILL.md +68 -0
  425. package/skills/run-supervisor/SKILL.md +47 -2
  426. package/skills/use-ai-memory/SKILL.md +124 -0
  427. package/skills/write-system-prompt/SKILL.md +14 -1
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/supervisor/supervisor.ts"],"sourcesContent":["import type { SupervisorEventMap } from \"../contracts/events/event-map.type\";\nimport type { SupervisorResult } from \"../contracts/result/supervisor-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type {\n SupervisorConfig,\n SupervisorEventHandler,\n} from \"../contracts/supervisor/supervisor-config.type\";\nimport type {\n SupervisorExecuteOptions,\n SupervisorResumeOptions,\n} from \"../contracts/supervisor/supervisor-execute-options.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { SupervisorStreamEvent } from \"../contracts/supervisor/supervisor-stream-event.type\";\nimport type {\n SupervisorAsToolOptions,\n SupervisorContract,\n} from \"../contracts/supervisor/supervisor.contract\";\nimport { SupervisorFailedError } from \"../errors\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool } from \"./as-tool\";\nimport { SupervisorEmitter } from \"./emitter\";\nimport { assertRouterDescriptions, resolveIntentEntries } from \"./entries\";\nimport { SupervisorExecution } from \"./execution\";\nimport { computeSignature } from \"./signature\";\nimport { loadSnapshotForResume } from \"./snapshot\";\nimport { createSupervisorStream } from \"./supervisor-stream\";\n\n/**\n * `ai.supervisor(config)` — construct a `SupervisorContract`. Validates\n * the config at author time (throws `SupervisorFailedError` on bad\n * shape), resolves agent entries, computes a stable structural\n * signature, wires the three-tier event emitter, and returns an\n * instance that satisfies `ExecutableContract` so it can compose into\n * tools, outer agents, and (future) orchestrators uniformly.\n *\n * @example\n * const support = ai.supervisor({\n * name: \"customer-support\",\n * router: routerAgent,\n * intents: { triage, orderLookup, billingLookup, resolver },\n * evaluate: (ctx) => ctx.result.resolver?.output ? { satisfied: true } : undefined,\n * output: z.object({ response: z.string(), refund: z.boolean() }),\n * maxIterations: 6,\n * });\n */\nexport function supervisor<\n TOutput = unknown,\n TState = TOutput,\n TIntents extends Record<string, SupervisorIntentValue> = Record<string, SupervisorIntentValue>,\n TArtifacts = Record<string, unknown>,\n>(config: SupervisorConfig<TOutput, TState, TIntents, TArtifacts>): SupervisorContract<TOutput> {\n validateFactoryConfig(config as unknown as SupervisorConfig<TOutput>);\n\n const entries = resolveIntentEntries(config.intents, config.name);\n\n assertRouterDescriptions(config as SupervisorConfig<unknown>, entries);\n\n if (config.initialAgent && !entries.has(config.initialAgent)) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n { context: { authoring: true } },\n );\n }\n\n const signature = computeSignature(config as SupervisorConfig<unknown>, entries);\n const emitter = new SupervisorEmitter(config.on);\n\n async function execute(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const runId = options?.runId ?? generateRunId();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n });\n\n return execution.run();\n }\n\n function stream(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): StreamContract<SupervisorResult<TOutput>, SupervisorStreamEvent> {\n const runId = options?.runId ?? generateRunId();\n const { controller, stream: contract } = createSupervisorStream<SupervisorResult<TOutput>>();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n streamController: controller,\n });\n\n void execution.run();\n\n return contract;\n }\n\n async function resume(\n runId: string,\n options?: SupervisorResumeOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const snapshot = await loadSnapshotForResume({\n config: config as SupervisorConfig<unknown>,\n signature,\n runId,\n options,\n });\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input: snapshot.input,\n runId,\n options,\n resumeFrom: snapshot,\n });\n\n return execution.run();\n }\n\n const instance: SupervisorContract<TOutput> = {\n name: config.name,\n signature,\n execute,\n stream,\n resume,\n on<K extends keyof SupervisorEventMap>(\n event: K,\n handler: SupervisorEventHandler<K>,\n ): () => void {\n return emitter.on(event, handler);\n },\n off<K extends keyof SupervisorEventMap>(event: K, handler: SupervisorEventHandler<K>): void {\n emitter.off(event, handler);\n },\n asTool<TToolInput = string>(\n options: SupervisorAsToolOptions<TToolInput>,\n ): ToolContract<TToolInput, TOutput> {\n return asTool<TOutput, TToolInput>(instance, options);\n },\n };\n\n return instance;\n}\n\n/**\n * Factory-time validation. Enforces the XOR + pairing rules the design\n * locked in §2 and surfaces any violation as a typed\n * `SupervisorFailedError` tagged `authoring: true`.\n */\nfunction validateFactoryConfig<T>(config: SupervisorConfig<T>): void {\n if (!config.name || typeof config.name !== \"string\") {\n throw new SupervisorFailedError(\"ai.supervisor: `name` is required and must be a string\", {\n context: { authoring: true },\n });\n }\n\n if (!config.intents || typeof config.intents !== \"object\") {\n throw new SupervisorFailedError(`ai.supervisor(\"${config.name}\"): \\`intents\\` is required`, {\n context: { authoring: true },\n });\n }\n\n const hasRoute = typeof config.route === \"function\";\n const hasRouter = !!config.router;\n\n if (hasRouter) {\n const router = config.router as { execute?: unknown } | { agent?: { execute?: unknown } };\n const isBareAgent = typeof (router as { execute?: unknown }).execute === \"function\";\n const isEntryForm =\n !isBareAgent &&\n typeof (router as { agent?: { execute?: unknown } }).agent === \"object\" &&\n typeof (router as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n\n if (!isBareAgent && !isEntryForm) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`router\\` must be an agent contract or a \\`{ agent, placeholders?, input? }\\` entry`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (hasRoute && hasRouter) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 / decisions §37 — `classifier` is the iter-0 prelude;\n // satisfies the \"must have a dispatch source\" rule on its own.\n // Composes with router/route (classifier drives iter 0; router/route\n // takes iter 1+). When configured alone, supervisor terminates after\n // iter 0's branch settles.\n const hasClassifier = config.classifier !== undefined;\n\n if (!hasRoute && !hasRouter && !hasClassifier) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): one of \\`route\\`, \\`router\\`, or \\`classifier\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 — classifier and initialAgent both decide what runs first.\n // Coexistence is meaningless; throw loudly.\n if (hasClassifier && config.initialAgent) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`classifier\\` and \\`initialAgent\\` are mutually exclusive — both decide which intent runs first. Pick one.`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 3.4 (Q9) — evaluate now pairs with both `route` and\n // `router`. State-driven termination is useful in either dispatch\n // mode; the historical router-only restriction was incidental,\n // not principled.\n\n if (config.ack !== undefined) {\n const ack = config.ack;\n const isCallback = typeof ack === \"function\";\n const isAgentEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n const isRunEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { run?: unknown }).run === \"function\";\n\n if (!isCallback && !isAgentEntry && !isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` must be an \\`{ agent, ... }\\` entry, an \\`{ run, ... }\\` entry, or a bare callback function`,\n { context: { authoring: true } },\n );\n }\n\n if (isAgentEntry && isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` cannot declare both \\`agent\\` and \\`run\\` — pick one`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (config.maxIterations !== undefined && config.maxIterations < 1) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n { context: { authoring: true, maxIterations: config.maxIterations } },\n );\n }\n}\n\nfunction generateRunId(): string {\n return `sup_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"supervisor.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/supervisor/supervisor.ts"],"sourcesContent":["import type { SupervisorEventMap } from \"../contracts/events/event-map.type\";\nimport type { SupervisorResult } from \"../contracts/result/supervisor-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type {\n SupervisorConfig,\n SupervisorEventHandler,\n} from \"../contracts/supervisor/supervisor-config.type\";\nimport type {\n SupervisorExecuteOptions,\n SupervisorResumeOptions,\n} from \"../contracts/supervisor/supervisor-execute-options.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { SupervisorStreamEvent } from \"../contracts/supervisor/supervisor-stream-event.type\";\nimport type {\n SupervisorAsToolOptions,\n SupervisorContract,\n} from \"../contracts/supervisor/supervisor.contract\";\nimport { SupervisorFailedError } from \"../errors\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool } from \"./as-tool\";\nimport { SupervisorEmitter } from \"./emitter\";\nimport { assertRouterDescriptions, resolveIntentEntries } from \"./entries\";\nimport { SupervisorExecution } from \"./execution\";\nimport { computeSignature } from \"./signature\";\nimport { loadSnapshotForResume } from \"./snapshot\";\nimport { createSupervisorStream } from \"./supervisor-stream\";\n\n/**\n * `ai.supervisor(config)` — construct a `SupervisorContract`. Validates\n * the config at author time (throws `SupervisorFailedError` on bad\n * shape), resolves agent entries, computes a stable structural\n * signature, wires the three-tier event emitter, and returns an\n * instance that satisfies `ExecutableContract` so it can compose into\n * tools, outer agents, and (future) orchestrators uniformly.\n *\n * @example\n * const support = ai.supervisor({\n * name: \"customer-support\",\n * router: routerAgent,\n * intents: { triage, orderLookup, billingLookup, resolver },\n * evaluate: (ctx) => ctx.result.resolver?.output ? { satisfied: true } : undefined,\n * output: z.object({ response: z.string(), refund: z.boolean() }),\n * maxIterations: 6,\n * });\n */\nexport function supervisor<\n TOutput = unknown,\n TState = TOutput,\n TIntents extends Record<string, SupervisorIntentValue> = Record<string, SupervisorIntentValue>,\n TArtifacts = Record<string, unknown>,\n>(config: SupervisorConfig<TOutput, TState, TIntents, TArtifacts>): SupervisorContract<TOutput> {\n validateFactoryConfig(config as unknown as SupervisorConfig<TOutput>);\n\n const entries = resolveIntentEntries(config.intents, config.name);\n\n assertRouterDescriptions(config as SupervisorConfig<unknown>, entries);\n\n if (config.initialAgent && !entries.has(config.initialAgent)) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n { context: { authoring: true } },\n );\n }\n\n const signature = computeSignature(config as SupervisorConfig<unknown>, entries);\n const emitter = new SupervisorEmitter(config.on);\n\n async function execute(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const runId = options?.runId ?? generateRunId();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n });\n\n return execution.run();\n }\n\n function stream(\n input: SupervisorInput,\n options?: SupervisorExecuteOptions,\n ): StreamContract<SupervisorResult<TOutput>, SupervisorStreamEvent> {\n const runId = options?.runId ?? generateRunId();\n const { controller, stream: contract } = createSupervisorStream<SupervisorResult<TOutput>>();\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input,\n runId,\n options,\n streamController: controller,\n });\n\n void execution.run();\n\n return contract;\n }\n\n async function resume(\n runId: string,\n options?: SupervisorResumeOptions,\n ): Promise<SupervisorResult<TOutput>> {\n const snapshot = await loadSnapshotForResume({\n config: config as SupervisorConfig<unknown>,\n signature,\n runId,\n options,\n });\n\n const execution = new SupervisorExecution<TOutput>({\n config: config as unknown as SupervisorConfig<TOutput>,\n entries,\n signature,\n emitter,\n input: snapshot.input,\n runId,\n options,\n resumeFrom: snapshot,\n });\n\n return execution.run();\n }\n\n const instance: SupervisorContract<TOutput> = {\n name: config.name,\n inputSchema: config.inputSchema,\n signature,\n execute,\n stream,\n resume,\n on<K extends keyof SupervisorEventMap>(\n event: K,\n handler: SupervisorEventHandler<K>,\n ): () => void {\n return emitter.on(event, handler);\n },\n off<K extends keyof SupervisorEventMap>(event: K, handler: SupervisorEventHandler<K>): void {\n emitter.off(event, handler);\n },\n asTool<TToolInput = string>(\n options: SupervisorAsToolOptions<TToolInput>,\n ): ToolContract<TToolInput, TOutput> {\n return asTool<TOutput, TToolInput>(instance, options);\n },\n };\n\n return instance;\n}\n\n/**\n * Factory-time validation. Enforces the XOR + pairing rules the design\n * locked in §2 and surfaces any violation as a typed\n * `SupervisorFailedError` tagged `authoring: true`.\n */\nfunction validateFactoryConfig<T>(config: SupervisorConfig<T>): void {\n if (!config.name || typeof config.name !== \"string\") {\n throw new SupervisorFailedError(\"ai.supervisor: `name` is required and must be a string\", {\n context: { authoring: true },\n });\n }\n\n if (!config.intents || typeof config.intents !== \"object\") {\n throw new SupervisorFailedError(`ai.supervisor(\"${config.name}\"): \\`intents\\` is required`, {\n context: { authoring: true },\n });\n }\n\n const hasRoute = typeof config.route === \"function\";\n const hasRouter = !!config.router;\n\n if (hasRouter) {\n const router = config.router as { execute?: unknown } | { agent?: { execute?: unknown } };\n const isBareAgent = typeof (router as { execute?: unknown }).execute === \"function\";\n const isEntryForm =\n !isBareAgent &&\n typeof (router as { agent?: { execute?: unknown } }).agent === \"object\" &&\n typeof (router as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n\n if (!isBareAgent && !isEntryForm) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`router\\` must be an agent contract or a \\`{ agent, placeholders?, input? }\\` entry`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (hasRoute && hasRouter) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 / decisions §37 — `classifier` is the iter-0 prelude;\n // satisfies the \"must have a dispatch source\" rule on its own.\n // Composes with router/route (classifier drives iter 0; router/route\n // takes iter 1+). When configured alone, supervisor terminates after\n // iter 0's branch settles.\n const hasClassifier = config.classifier !== undefined;\n\n if (!hasRoute && !hasRouter && !hasClassifier) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): one of \\`route\\`, \\`router\\`, or \\`classifier\\` is required`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 7 — classifier and initialAgent both decide what runs first.\n // Coexistence is meaningless; throw loudly.\n if (hasClassifier && config.initialAgent) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`classifier\\` and \\`initialAgent\\` are mutually exclusive — both decide which intent runs first. Pick one.`,\n { context: { authoring: true } },\n );\n }\n\n // Phase 3.4 (Q9) — evaluate now pairs with both `route` and\n // `router`. State-driven termination is useful in either dispatch\n // mode; the historical router-only restriction was incidental,\n // not principled.\n\n if (config.ack !== undefined) {\n const ack = config.ack;\n const isCallback = typeof ack === \"function\";\n const isAgentEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n const isRunEntry =\n typeof ack === \"object\" &&\n ack !== null &&\n typeof (ack as { run?: unknown }).run === \"function\";\n\n if (!isCallback && !isAgentEntry && !isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` must be an \\`{ agent, ... }\\` entry, an \\`{ run, ... }\\` entry, or a bare callback function`,\n { context: { authoring: true } },\n );\n }\n\n if (isAgentEntry && isRunEntry) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`ack\\` cannot declare both \\`agent\\` and \\`run\\` — pick one`,\n { context: { authoring: true } },\n );\n }\n }\n\n if (config.maxIterations !== undefined && config.maxIterations < 1) {\n throw new SupervisorFailedError(\n `ai.supervisor(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n { context: { authoring: true, maxIterations: config.maxIterations } },\n );\n }\n}\n\nfunction generateRunId(): string {\n return `sup_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { renderPlaceholders } from "./render-placeholders.mjs";
2
+ import { Instruction, instruction } from "./instruction.mjs";
3
+ import { Persona, persona } from "./persona.mjs";
4
+ import { SystemPrompt, systemPrompt } from "./system-prompt.mjs";
5
+
6
+ export { };
@@ -54,6 +54,32 @@ import { InstructionContract, PersonaContract, SystemPromptBlockContract, System
54
54
  declare class SystemPrompt implements SystemPromptContract {
55
55
  readonly blocks: readonly SystemPromptBlockContract[];
56
56
  constructor(blocks?: readonly SystemPromptBlockContract[]);
57
+ /**
58
+ * Build a system prompt by reading the file at `path` once, synchronously,
59
+ * at construction time. The file's UTF-8 contents seed a single instruction
60
+ * block — the same semantics as the string-seed form of `systemPrompt()` —
61
+ * so placeholders inside the file (`{{language|English}}`) resolve at
62
+ * `resolve()` time and the result can be forked with further
63
+ * `.persona()` / `.instruction()` calls.
64
+ *
65
+ * One-shot by design: the file is read exactly once here, never re-read on
66
+ * `resolve()`. Reads are synchronous so the call stays a drop-in for the
67
+ * synchronous `systemPrompt()` factory and the synchronous `resolve()` API.
68
+ *
69
+ * Throws `InvalidRequestError` when the file cannot be read (missing path,
70
+ * permission denied) — surfacing the underlying cause so a typo in the
71
+ * prompt path fails loudly at construction instead of silently producing an
72
+ * empty prompt.
73
+ *
74
+ * @param path - Filesystem path to the prompt template file.
75
+ *
76
+ * @example
77
+ * const prompt = SystemPrompt.fromFile("./prompts/support-agent.md");
78
+ *
79
+ * const localized = prompt.instruction("Respond in {{language|English}}.");
80
+ * localized.resolve({ language: "Arabic" });
81
+ */
82
+ static fromFile(path: string): SystemPrompt;
57
83
  /**
58
84
  * Return a new builder with the persona block set. If a persona already
59
85
  * exists it's replaced in place (preserving its position in `blocks`);
@@ -78,6 +104,23 @@ declare class SystemPrompt implements SystemPromptContract {
78
104
  */
79
105
  resolve(placeholders?: Placeholders): string;
80
106
  }
107
+ /**
108
+ * Public factory for `SystemPrompt`, callable directly or via its
109
+ * `fromFile` static. Exists as a named interface so the callable signature
110
+ * and the `fromFile` attachment travel together as one public type.
111
+ */
112
+ interface SystemPromptFactory {
113
+ (input?: string | ReadonlyArray<SystemPromptBlockContract>): SystemPrompt;
114
+ /**
115
+ * Build a system prompt from a file read once at construction. Delegates
116
+ * to {@link SystemPrompt.fromFile}, so `ai.systemPrompt.fromFile(path)` and
117
+ * `SystemPrompt.fromFile(path)` behave identically.
118
+ *
119
+ * @example
120
+ * const prompt = ai.systemPrompt.fromFile("./prompts/support-agent.md");
121
+ */
122
+ fromFile(path: string): SystemPrompt;
123
+ }
81
124
  /**
82
125
  * Create a new immutable system-prompt builder.
83
126
  *
@@ -85,10 +128,11 @@ declare class SystemPrompt implements SystemPromptContract {
85
128
  * free of `new` and consistent with `ai.tool()`, `ai.agent()`,
86
129
  * `ai.persona()`, `ai.instruction()`.
87
130
  *
88
- * Three input forms:
131
+ * Input forms:
89
132
  * - No argument → empty builder, chain `.persona()` / `.instruction()`
90
133
  * - Single string → seeded with one instruction for quick one-shot prompts
91
134
  * - Array of blocks → used verbatim, preserving insertion order
135
+ * - `.fromFile(path)` → seeded from a file read once at construction
92
136
  *
93
137
  * @example
94
138
  * // Composed builder
@@ -104,6 +148,10 @@ declare class SystemPrompt implements SystemPromptContract {
104
148
  * const prompt = systemPrompt("Answer only with JSON matching the schema.");
105
149
  *
106
150
  * @example
151
+ * // From a file, read once at construction
152
+ * const prompt = systemPrompt.fromFile("./prompts/support-agent.md");
153
+ *
154
+ * @example
107
155
  * // Array form — fully declarative
108
156
  * const prompt = systemPrompt([
109
157
  * ai.persona("You are Alex."),
@@ -111,7 +159,7 @@ declare class SystemPrompt implements SystemPromptContract {
111
159
  * ai.instruction("Respond in {{language|English}}."),
112
160
  * ]);
113
161
  */
114
- declare function systemPrompt(input?: string | ReadonlyArray<SystemPromptBlockContract>): SystemPrompt;
162
+ declare const systemPrompt: SystemPromptFactory;
115
163
  //#endregion
116
- export { SystemPrompt, systemPrompt };
164
+ export { SystemPrompt, SystemPromptFactory, systemPrompt };
117
165
  //# sourceMappingURL=system-prompt.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"mappings":";;;;;;AA2DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiD4C;AAyC5C;;;;;;;;;;;;;AAEe;;cA5FF,YAAA,YAAwB,oBAAA;EAAA,SAEjB,MAAA,WAAiB,yBAAA;cAAjB,MAAA,YAAiB,yBAAA;;;;;;;;;EAW5B,OAAA,CAAQ,KAAA,EAAO,eAAA,YAA2B,oBAAA;;;;;;;EAsB1C,WAAA,CACL,KAAA,EAAO,mBAAA,YACN,oBAAA;;;;;;;EAYI,OAAA,CAAQ,YAAA,GAAe,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyChB,YAAA,CACd,KAAA,YAAiB,aAAA,CAAc,yBAAA,IAC9B,YAAA"}
1
+ {"version":3,"file":"system-prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"mappings":";;;;;;AA6DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2F4C;AAa5C;;;;;;;;;;;cAxGa,YAAA,YAAwB,oBAAA;EAAA,SAEjB,MAAA,WAAiB,yBAAA;cAAjB,MAAA,YAAiB,yBAAA;EAiH1B;;;AAA2B;AAuDtC;;;;AAGC;;;;;;;;;;;;;;;;;EA1DU,OArFK,QAAA,CAAS,IAAA,WAAe,YAAA;;;;;;;;;EAyB/B,OAAA,CAAQ,KAAA,EAAO,eAAA,YAA2B,oBAAA;;;;;;;EAsB1C,WAAA,CACL,KAAA,EAAO,mBAAA,YACN,oBAAA;;;;;;;EAYI,OAAA,CAAQ,YAAA,GAAe,YAAA;AAAA;;;;;;UAaf,mBAAA;EAAA,CACd,KAAA,YAAiB,aAAA,CAAc,yBAAA,IAA6B,YAAA;;;;;;;;;EAU7D,QAAA,CAAS,IAAA,WAAe,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuDb,YAAA,EAAc,mBAG1B"}
@@ -1,5 +1,8 @@
1
+ import { InvalidRequestError } from "../errors/invalid-request-error.mjs";
2
+ import "../errors/index.mjs";
1
3
  import { Instruction } from "./instruction.mjs";
2
4
  import { Persona } from "./persona.mjs";
5
+ import { readFileSync } from "node:fs";
3
6
 
4
7
  //#region ../@warlock.js/ai/src/system-prompt/system-prompt.ts
5
8
  /**
@@ -56,6 +59,43 @@ var SystemPrompt = class SystemPrompt {
56
59
  this.blocks = blocks;
57
60
  }
58
61
  /**
62
+ * Build a system prompt by reading the file at `path` once, synchronously,
63
+ * at construction time. The file's UTF-8 contents seed a single instruction
64
+ * block — the same semantics as the string-seed form of `systemPrompt()` —
65
+ * so placeholders inside the file (`{{language|English}}`) resolve at
66
+ * `resolve()` time and the result can be forked with further
67
+ * `.persona()` / `.instruction()` calls.
68
+ *
69
+ * One-shot by design: the file is read exactly once here, never re-read on
70
+ * `resolve()`. Reads are synchronous so the call stays a drop-in for the
71
+ * synchronous `systemPrompt()` factory and the synchronous `resolve()` API.
72
+ *
73
+ * Throws `InvalidRequestError` when the file cannot be read (missing path,
74
+ * permission denied) — surfacing the underlying cause so a typo in the
75
+ * prompt path fails loudly at construction instead of silently producing an
76
+ * empty prompt.
77
+ *
78
+ * @param path - Filesystem path to the prompt template file.
79
+ *
80
+ * @example
81
+ * const prompt = SystemPrompt.fromFile("./prompts/support-agent.md");
82
+ *
83
+ * const localized = prompt.instruction("Respond in {{language|English}}.");
84
+ * localized.resolve({ language: "Arabic" });
85
+ */
86
+ static fromFile(path) {
87
+ let contents;
88
+ try {
89
+ contents = readFileSync(path, "utf8");
90
+ } catch (error) {
91
+ throw new InvalidRequestError(`Failed to read system prompt file "${path}" — ${error instanceof Error ? error.message : String(error)}`, {
92
+ context: { path },
93
+ cause: error
94
+ });
95
+ }
96
+ return new SystemPrompt([new Instruction(contents)]);
97
+ }
98
+ /**
59
99
  * Return a new builder with the persona block set. If a persona already
60
100
  * exists it's replaced in place (preserving its position in `blocks`);
61
101
  * otherwise the new persona is prepended so persona-first remains the
@@ -93,6 +133,11 @@ var SystemPrompt = class SystemPrompt {
93
133
  return this.blocks.map((block) => block.resolve(placeholders)).join("\n\n").trim();
94
134
  }
95
135
  };
136
+ function systemPromptFactory(input) {
137
+ if (input === void 0) return new SystemPrompt();
138
+ if (typeof input === "string") return new SystemPrompt([new Instruction(input)]);
139
+ return new SystemPrompt([...input]);
140
+ }
96
141
  /**
97
142
  * Create a new immutable system-prompt builder.
98
143
  *
@@ -100,10 +145,11 @@ var SystemPrompt = class SystemPrompt {
100
145
  * free of `new` and consistent with `ai.tool()`, `ai.agent()`,
101
146
  * `ai.persona()`, `ai.instruction()`.
102
147
  *
103
- * Three input forms:
148
+ * Input forms:
104
149
  * - No argument → empty builder, chain `.persona()` / `.instruction()`
105
150
  * - Single string → seeded with one instruction for quick one-shot prompts
106
151
  * - Array of blocks → used verbatim, preserving insertion order
152
+ * - `.fromFile(path)` → seeded from a file read once at construction
107
153
  *
108
154
  * @example
109
155
  * // Composed builder
@@ -119,6 +165,10 @@ var SystemPrompt = class SystemPrompt {
119
165
  * const prompt = systemPrompt("Answer only with JSON matching the schema.");
120
166
  *
121
167
  * @example
168
+ * // From a file, read once at construction
169
+ * const prompt = systemPrompt.fromFile("./prompts/support-agent.md");
170
+ *
171
+ * @example
122
172
  * // Array form — fully declarative
123
173
  * const prompt = systemPrompt([
124
174
  * ai.persona("You are Alex."),
@@ -126,11 +176,7 @@ var SystemPrompt = class SystemPrompt {
126
176
  * ai.instruction("Respond in {{language|English}}."),
127
177
  * ]);
128
178
  */
129
- function systemPrompt(input) {
130
- if (input === void 0) return new SystemPrompt();
131
- if (typeof input === "string") return new SystemPrompt([new Instruction(input)]);
132
- return new SystemPrompt([...input]);
133
- }
179
+ const systemPrompt = Object.assign(systemPromptFactory, { fromFile: SystemPrompt.fromFile });
134
180
 
135
181
  //#endregion
136
182
  export { SystemPrompt, systemPrompt };
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"sourcesContent":["import type { Placeholders } from \"../contracts/placeholders.type\";\nimport type {\n InstructionContract,\n PersonaContract,\n SystemPromptBlockContract,\n SystemPromptContract,\n} from \"../contracts/system-prompt.contract\";\nimport { Instruction } from \"./instruction\";\nimport { Persona } from \"./persona\";\n\n/**\n * Concrete `SystemPromptContract` — an immutable layered prompt builder.\n *\n * **Role.** The top-level composer for a system prompt: it holds an ordered\n * list of typed blocks (persona + instructions) and resolves the whole\n * stack into one final string when the agent is about to call the model.\n *\n * **Responsibility.**\n * - Owns: the ordered `blocks` list and the block-join rules (insertion\n * order, blank-line separator, trim).\n * - Does NOT own: how any individual block is rendered (delegated to each\n * block's `resolve()`), the placeholder syntax (delegated to\n * `renderPlaceholders`), or any knowledge of the agent, model, or\n * session consuming the resolved text.\n *\n * Blocks are discriminated by a string `type` tag (`\"persona\"` /\n * `\"instruction\"`) rather than `instanceof`, so user-supplied blocks that\n * implement `SystemPromptBlockContract` interoperate seamlessly with blocks\n * built via `ai.persona()` / `ai.instruction()` — even across duplicate\n * package copies or bundler scope boundaries.\n *\n * The builder is **immutable** — every `.persona()` / `.instruction()`\n * call returns a fresh `SystemPrompt` instance sharing nothing mutable\n * with its parent. This makes forking a base prompt into specialized\n * variants a safe, side-effect-free operation.\n *\n * Users construct via the `ai.systemPrompt()` factory — `new SystemPrompt()`\n * is not the public API (see §4.2 of code-style.md). Modeled as a class so\n * that methods live on the prototype (one copy shared across every forked\n * instance) and downstream code can branch via `instanceof SystemPrompt`.\n *\n * @example\n * // Chainable form\n * const alex = ai.persona(\"You are Alex, a TypeScript expert.\");\n * const replyIn = ai.instruction(\"Respond in {{language|English}}.\");\n *\n * const base = ai.systemPrompt().persona(alex).instruction(replyIn);\n * const arabicVariant = base.instruction(\"Prefer Arabic comments.\");\n *\n * base.resolve({ language: \"English\" });\n * arabicVariant.resolve({ language: \"Arabic\" });\n *\n * @example\n * // Array form — insertion order is preserved exactly\n * const prompt = ai.systemPrompt([\n * ai.persona(\"You are Alex, a TypeScript expert.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport class SystemPrompt implements SystemPromptContract {\n public constructor(\n public readonly blocks: readonly SystemPromptBlockContract[] = [],\n ) {}\n\n /**\n * Return a new builder with the persona block set. If a persona already\n * exists it's replaced in place (preserving its position in `blocks`);\n * otherwise the new persona is prepended so persona-first remains the\n * default for chain-built prompts. Accepts either raw text (auto-wrapped\n * via `new Persona`) or an existing `PersonaContract` instance for reuse\n * across prompts.\n */\n public persona(value: PersonaContract | string): SystemPromptContract {\n const block = typeof value === \"string\" ? new Persona(value) : value;\n const existingIndex = this.blocks.findIndex(\n candidate => candidate.type === \"persona\",\n );\n\n if (existingIndex >= 0) {\n const next = [...this.blocks];\n next[existingIndex] = block;\n\n return new SystemPrompt(next) as this;\n }\n\n return new SystemPrompt([block, ...this.blocks]);\n }\n\n /**\n * Return a new builder with the given instruction appended. Instructions\n * render in insertion order. Accepts either raw text (auto-wrapped via\n * `new Instruction`) or an existing `InstructionContract` instance for\n * cross-prompt reuse.\n */\n public instruction(\n value: InstructionContract | string,\n ): SystemPromptContract {\n const block = typeof value === \"string\" ? new Instruction(value) : value;\n\n return new SystemPrompt([...this.blocks, block]);\n }\n\n /**\n * Resolve every block against the placeholder map, join the results with\n * blank-line separators (in insertion order), and trim. Returns an empty\n * string when no blocks are present — callers treat that as \"no system\n * message\".\n */\n public resolve(placeholders?: Placeholders): string {\n return this.blocks\n .map(block => block.resolve(placeholders))\n .join(\"\\n\\n\")\n .trim();\n }\n}\n\n/**\n * Create a new immutable system-prompt builder.\n *\n * **Role.** Public factory for `SystemPrompt` — keeps user-facing code\n * free of `new` and consistent with `ai.tool()`, `ai.agent()`,\n * `ai.persona()`, `ai.instruction()`.\n *\n * Three input forms:\n * - No argument → empty builder, chain `.persona()` / `.instruction()`\n * - Single string → seeded with one instruction for quick one-shot prompts\n * - Array of blocks → used verbatim, preserving insertion order\n *\n * @example\n * // Composed builder\n * const prompt = systemPrompt()\n * .persona(\"You are Alex, a senior TypeScript engineer.\")\n * .instruction(\"Always include working code examples.\")\n * .instruction(\"Respond in {{language|English}}.\");\n *\n * prompt.resolve({ language: \"Arabic\" });\n *\n * @example\n * // One-shot seed\n * const prompt = systemPrompt(\"Answer only with JSON matching the schema.\");\n *\n * @example\n * // Array form — fully declarative\n * const prompt = systemPrompt([\n * ai.persona(\"You are Alex.\"),\n * ai.instruction(\"Always cite sources.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport function systemPrompt(\n input?: string | ReadonlyArray<SystemPromptBlockContract>,\n): SystemPrompt {\n if (input === undefined) {\n return new SystemPrompt();\n }\n\n if (typeof input === \"string\") {\n return new SystemPrompt([new Instruction(input)]);\n }\n\n return new SystemPrompt([...input]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,eAAb,MAAa,aAA6C;CACxD,AAAO,YACL,AAAgB,SAA+C,CAAC,GAChE;EADgB;CACf;;;;;;;;;CAUH,AAAO,QAAQ,OAAuD;EACpE,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,QAAQ,KAAK,IAAI;EAC/D,MAAM,gBAAgB,KAAK,OAAO,WAChC,cAAa,UAAU,SAAS,SAClC;EAEA,IAAI,iBAAiB,GAAG;GACtB,MAAM,OAAO,CAAC,GAAG,KAAK,MAAM;GAC5B,KAAK,iBAAiB;GAEtB,OAAO,IAAI,aAAa,IAAI;EAC9B;EAEA,OAAO,IAAI,aAAa,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;CACjD;;;;;;;CAQA,AAAO,YACL,OACsB;EACtB,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,YAAY,KAAK,IAAI;EAEnE,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,QAAQ,KAAK,CAAC;CACjD;;;;;;;CAQA,AAAO,QAAQ,cAAqC;EAClD,OAAO,KAAK,OACT,KAAI,UAAS,MAAM,QAAQ,YAAY,CAAC,CAAC,CACzC,KAAK,MAAM,CAAC,CACZ,KAAK;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,aACd,OACc;CACd,IAAI,UAAU,QACZ,OAAO,IAAI,aAAa;CAG1B,IAAI,OAAO,UAAU,UACnB,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC;CAGlD,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,CAAC;AACpC"}
1
+ {"version":3,"file":"system-prompt.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/system-prompt/system-prompt.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { Placeholders } from \"../contracts/placeholders.type\";\nimport type {\n InstructionContract,\n PersonaContract,\n SystemPromptBlockContract,\n SystemPromptContract,\n} from \"../contracts/system-prompt.contract\";\nimport { InvalidRequestError } from \"../errors\";\nimport { Instruction } from \"./instruction\";\nimport { Persona } from \"./persona\";\n\n/**\n * Concrete `SystemPromptContract` — an immutable layered prompt builder.\n *\n * **Role.** The top-level composer for a system prompt: it holds an ordered\n * list of typed blocks (persona + instructions) and resolves the whole\n * stack into one final string when the agent is about to call the model.\n *\n * **Responsibility.**\n * - Owns: the ordered `blocks` list and the block-join rules (insertion\n * order, blank-line separator, trim).\n * - Does NOT own: how any individual block is rendered (delegated to each\n * block's `resolve()`), the placeholder syntax (delegated to\n * `renderPlaceholders`), or any knowledge of the agent, model, or\n * session consuming the resolved text.\n *\n * Blocks are discriminated by a string `type` tag (`\"persona\"` /\n * `\"instruction\"`) rather than `instanceof`, so user-supplied blocks that\n * implement `SystemPromptBlockContract` interoperate seamlessly with blocks\n * built via `ai.persona()` / `ai.instruction()` — even across duplicate\n * package copies or bundler scope boundaries.\n *\n * The builder is **immutable** — every `.persona()` / `.instruction()`\n * call returns a fresh `SystemPrompt` instance sharing nothing mutable\n * with its parent. This makes forking a base prompt into specialized\n * variants a safe, side-effect-free operation.\n *\n * Users construct via the `ai.systemPrompt()` factory — `new SystemPrompt()`\n * is not the public API (see §4.2 of code-style.md). Modeled as a class so\n * that methods live on the prototype (one copy shared across every forked\n * instance) and downstream code can branch via `instanceof SystemPrompt`.\n *\n * @example\n * // Chainable form\n * const alex = ai.persona(\"You are Alex, a TypeScript expert.\");\n * const replyIn = ai.instruction(\"Respond in {{language|English}}.\");\n *\n * const base = ai.systemPrompt().persona(alex).instruction(replyIn);\n * const arabicVariant = base.instruction(\"Prefer Arabic comments.\");\n *\n * base.resolve({ language: \"English\" });\n * arabicVariant.resolve({ language: \"Arabic\" });\n *\n * @example\n * // Array form — insertion order is preserved exactly\n * const prompt = ai.systemPrompt([\n * ai.persona(\"You are Alex, a TypeScript expert.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport class SystemPrompt implements SystemPromptContract {\n public constructor(\n public readonly blocks: readonly SystemPromptBlockContract[] = [],\n ) {}\n\n /**\n * Build a system prompt by reading the file at `path` once, synchronously,\n * at construction time. The file's UTF-8 contents seed a single instruction\n * block — the same semantics as the string-seed form of `systemPrompt()` —\n * so placeholders inside the file (`{{language|English}}`) resolve at\n * `resolve()` time and the result can be forked with further\n * `.persona()` / `.instruction()` calls.\n *\n * One-shot by design: the file is read exactly once here, never re-read on\n * `resolve()`. Reads are synchronous so the call stays a drop-in for the\n * synchronous `systemPrompt()` factory and the synchronous `resolve()` API.\n *\n * Throws `InvalidRequestError` when the file cannot be read (missing path,\n * permission denied) — surfacing the underlying cause so a typo in the\n * prompt path fails loudly at construction instead of silently producing an\n * empty prompt.\n *\n * @param path - Filesystem path to the prompt template file.\n *\n * @example\n * const prompt = SystemPrompt.fromFile(\"./prompts/support-agent.md\");\n *\n * const localized = prompt.instruction(\"Respond in {{language|English}}.\");\n * localized.resolve({ language: \"Arabic\" });\n */\n public static fromFile(path: string): SystemPrompt {\n let contents: string;\n\n try {\n contents = readFileSync(path, \"utf8\");\n } catch (error) {\n throw new InvalidRequestError(\n `Failed to read system prompt file \"${path}\" — ${\n error instanceof Error ? error.message : String(error)\n }`,\n { context: { path }, cause: error },\n );\n }\n\n return new SystemPrompt([new Instruction(contents)]);\n }\n\n /**\n * Return a new builder with the persona block set. If a persona already\n * exists it's replaced in place (preserving its position in `blocks`);\n * otherwise the new persona is prepended so persona-first remains the\n * default for chain-built prompts. Accepts either raw text (auto-wrapped\n * via `new Persona`) or an existing `PersonaContract` instance for reuse\n * across prompts.\n */\n public persona(value: PersonaContract | string): SystemPromptContract {\n const block = typeof value === \"string\" ? new Persona(value) : value;\n const existingIndex = this.blocks.findIndex(\n candidate => candidate.type === \"persona\",\n );\n\n if (existingIndex >= 0) {\n const next = [...this.blocks];\n next[existingIndex] = block;\n\n return new SystemPrompt(next) as this;\n }\n\n return new SystemPrompt([block, ...this.blocks]);\n }\n\n /**\n * Return a new builder with the given instruction appended. Instructions\n * render in insertion order. Accepts either raw text (auto-wrapped via\n * `new Instruction`) or an existing `InstructionContract` instance for\n * cross-prompt reuse.\n */\n public instruction(\n value: InstructionContract | string,\n ): SystemPromptContract {\n const block = typeof value === \"string\" ? new Instruction(value) : value;\n\n return new SystemPrompt([...this.blocks, block]);\n }\n\n /**\n * Resolve every block against the placeholder map, join the results with\n * blank-line separators (in insertion order), and trim. Returns an empty\n * string when no blocks are present — callers treat that as \"no system\n * message\".\n */\n public resolve(placeholders?: Placeholders): string {\n return this.blocks\n .map(block => block.resolve(placeholders))\n .join(\"\\n\\n\")\n .trim();\n }\n}\n\n/**\n * Public factory for `SystemPrompt`, callable directly or via its\n * `fromFile` static. Exists as a named interface so the callable signature\n * and the `fromFile` attachment travel together as one public type.\n */\nexport interface SystemPromptFactory {\n (input?: string | ReadonlyArray<SystemPromptBlockContract>): SystemPrompt;\n\n /**\n * Build a system prompt from a file read once at construction. Delegates\n * to {@link SystemPrompt.fromFile}, so `ai.systemPrompt.fromFile(path)` and\n * `SystemPrompt.fromFile(path)` behave identically.\n *\n * @example\n * const prompt = ai.systemPrompt.fromFile(\"./prompts/support-agent.md\");\n */\n fromFile(path: string): SystemPrompt;\n}\n\nfunction systemPromptFactory(\n input?: string | ReadonlyArray<SystemPromptBlockContract>,\n): SystemPrompt {\n if (input === undefined) {\n return new SystemPrompt();\n }\n\n if (typeof input === \"string\") {\n return new SystemPrompt([new Instruction(input)]);\n }\n\n return new SystemPrompt([...input]);\n}\n\n/**\n * Create a new immutable system-prompt builder.\n *\n * **Role.** Public factory for `SystemPrompt` — keeps user-facing code\n * free of `new` and consistent with `ai.tool()`, `ai.agent()`,\n * `ai.persona()`, `ai.instruction()`.\n *\n * Input forms:\n * - No argument → empty builder, chain `.persona()` / `.instruction()`\n * - Single string → seeded with one instruction for quick one-shot prompts\n * - Array of blocks → used verbatim, preserving insertion order\n * - `.fromFile(path)` → seeded from a file read once at construction\n *\n * @example\n * // Composed builder\n * const prompt = systemPrompt()\n * .persona(\"You are Alex, a senior TypeScript engineer.\")\n * .instruction(\"Always include working code examples.\")\n * .instruction(\"Respond in {{language|English}}.\");\n *\n * prompt.resolve({ language: \"Arabic\" });\n *\n * @example\n * // One-shot seed\n * const prompt = systemPrompt(\"Answer only with JSON matching the schema.\");\n *\n * @example\n * // From a file, read once at construction\n * const prompt = systemPrompt.fromFile(\"./prompts/support-agent.md\");\n *\n * @example\n * // Array form — fully declarative\n * const prompt = systemPrompt([\n * ai.persona(\"You are Alex.\"),\n * ai.instruction(\"Always cite sources.\"),\n * ai.instruction(\"Respond in {{language|English}}.\"),\n * ]);\n */\nexport const systemPrompt: SystemPromptFactory = Object.assign(\n systemPromptFactory,\n { fromFile: SystemPrompt.fromFile },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAa,eAAb,MAAa,aAA6C;CACxD,AAAO,YACL,AAAgB,SAA+C,CAAC,GAChE;EADgB;CACf;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BH,OAAc,SAAS,MAA4B;EACjD,IAAI;EAEJ,IAAI;GACF,WAAW,aAAa,MAAM,MAAM;EACtC,SAAS,OAAO;GACd,MAAM,IAAI,oBACR,sCAAsC,KAAK,MACzC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAEvD;IAAE,SAAS,EAAE,KAAK;IAAG,OAAO;GAAM,CACpC;EACF;EAEA,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,QAAQ,CAAC,CAAC;CACrD;;;;;;;;;CAUA,AAAO,QAAQ,OAAuD;EACpE,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,QAAQ,KAAK,IAAI;EAC/D,MAAM,gBAAgB,KAAK,OAAO,WAChC,cAAa,UAAU,SAAS,SAClC;EAEA,IAAI,iBAAiB,GAAG;GACtB,MAAM,OAAO,CAAC,GAAG,KAAK,MAAM;GAC5B,KAAK,iBAAiB;GAEtB,OAAO,IAAI,aAAa,IAAI;EAC9B;EAEA,OAAO,IAAI,aAAa,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;CACjD;;;;;;;CAQA,AAAO,YACL,OACsB;EACtB,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,YAAY,KAAK,IAAI;EAEnE,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,QAAQ,KAAK,CAAC;CACjD;;;;;;;CAQA,AAAO,QAAQ,cAAqC;EAClD,OAAO,KAAK,OACT,KAAI,UAAS,MAAM,QAAQ,YAAY,CAAC,CAAC,CACzC,KAAK,MAAM,CAAC,CACZ,KAAK;CACV;AACF;AAqBA,SAAS,oBACP,OACc;CACd,IAAI,UAAU,QACZ,OAAO,IAAI,aAAa;CAG1B,IAAI,OAAO,UAAU,UACnB,OAAO,IAAI,aAAa,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC;CAGlD,OAAO,IAAI,aAAa,CAAC,GAAG,KAAK,CAAC;AACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,eAAoC,OAAO,OACtD,qBACA,EAAE,UAAU,aAAa,SAAS,CACpC"}
@@ -0,0 +1,76 @@
1
+ import { BaseReport } from "../contracts/result/base-report.type.mjs";
2
+ import { END } from "../contracts/end.type.mjs";
3
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
+
5
+ //#region ../@warlock.js/ai/src/testing/matcher-logic.d.ts
6
+ /**
7
+ * Normalized matcher verdict — the library-agnostic shape every
8
+ * matcher in this module returns. Vitest's `expect.extend` consumes
9
+ * the same `{ pass, message }` contract, so the registration layer
10
+ * forwards these verbatim.
11
+ */
12
+ type MatcherVerdict = {
13
+ /** Whether the assertion passed. */pass: boolean; /** Lazy message factory — Vitest calls it only when reporting. */
14
+ message: () => string;
15
+ };
16
+ /**
17
+ * Any unified result envelope a matcher can be handed. Accepts the
18
+ * full `{ report, ... }` result or a bare `BaseReport` so callers can
19
+ * assert against either `await x.execute()` or `result.report`.
20
+ */
21
+ type ReportLike = BaseReport | {
22
+ report: BaseReport;
23
+ };
24
+ /**
25
+ * Assert that a supervisor routed to (dispatched) the named intent at
26
+ * least once across its iterations. Targets a `SupervisorResult` or a
27
+ * `SupervisorReport`.
28
+ *
29
+ * @example
30
+ * expect(await supervisor.execute(input)).toRouteTo("critic");
31
+ */
32
+ declare function matchRouteTo(received: ReportLike, intent: string): MatcherVerdict;
33
+ /**
34
+ * Assert that a supervisor converged — terminated on its own decision
35
+ * (`router` / `route` / `evaluate` / `classifier`) with a
36
+ * `"completed"` status, rather than hitting the iteration cap, being
37
+ * cancelled, or erroring. Targets a `SupervisorResult` or
38
+ * `SupervisorReport`.
39
+ *
40
+ * @example
41
+ * expect(await supervisor.execute(input)).toConverge();
42
+ */
43
+ declare function matchConverge(received: ReportLike): MatcherVerdict;
44
+ /**
45
+ * Assert that a workflow step completed successfully. Targets a
46
+ * `WorkflowResult` or `WorkflowReport`; looks the step up by name in
47
+ * `report.steps` and checks its status is `"completed"`.
48
+ *
49
+ * @example
50
+ * expect(await workflow.execute(input)).toPassStep("draft");
51
+ */
52
+ declare function matchPassStep(received: ReportLike, stepName: string): MatcherVerdict;
53
+ /**
54
+ * Result envelope carrying a typed `data` payload — what
55
+ * `matchOutputShape` validates against a schema.
56
+ */
57
+ type DataResult = {
58
+ data?: unknown;
59
+ };
60
+ /**
61
+ * Assert that a result's `data` validates against a Standard Schema.
62
+ * Targets any result envelope with a `data` field (agent / workflow /
63
+ * supervisor). Runs the schema's `~standard.validate` and passes only
64
+ * when it reports no issues.
65
+ *
66
+ * Synchronous-only: a schema whose `validate` returns a Promise is
67
+ * rejected with a clear message rather than silently passing — the
68
+ * async variant belongs on a dedicated async matcher if needed.
69
+ *
70
+ * @example
71
+ * expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
72
+ */
73
+ declare function matchOutputShape(received: DataResult, schema: StandardSchemaV1): MatcherVerdict;
74
+ //#endregion
75
+ export { MatcherVerdict, matchConverge, matchOutputShape, matchPassStep, matchRouteTo };
76
+ //# sourceMappingURL=matcher-logic.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher-logic.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matcher-logic.ts"],"mappings":";;;;;;;AAYA;;;;KAAY,cAAA;EAYP,oCAVH,IAAA;EAEA,OAAO;AAAA;;;;AAQ0C;AAgDnD;KAhDK,UAAA,GAAa,UAAA;EAAe,MAAA,EAAQ,UAAU;AAAA;;;;;;AAgD+B;AAkClF;;iBAlCgB,YAAA,CAAa,QAAA,EAAU,UAAA,EAAY,MAAA,WAAiB,cAAc;;;;;;AAkCf;AAkCnE;;;;iBAlCgB,aAAA,CAAc,QAAA,EAAU,UAAA,GAAa,cAAc;;;;;AAkCkB;AAgCpF;;;iBAhCe,aAAA,CAAc,QAAA,EAAU,UAAA,EAAY,QAAA,WAAmB,cAAc;AAsC7D;AAexB;;;AAfwB,KAAnB,UAAA;EAAe,IAAI;AAAA;;;;;;;;;AAkBP;;;;;iBAHD,gBAAA,CACd,QAAA,EAAU,UAAA,EACV,MAAA,EAAQ,gBAAA,GACP,cAAA"}
@@ -0,0 +1,144 @@
1
+ import { END } from "../contracts/end.type.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/testing/matcher-logic.ts
4
+ /**
5
+ * Coerce a matcher target into its `BaseReport`. Accepts the result
6
+ * envelope (`{ report }`) or a report directly.
7
+ */
8
+ function toReport(received) {
9
+ if ("report" in received && received.report) return received.report;
10
+ return received;
11
+ }
12
+ /** Narrow a `BaseReport` to a `SupervisorReport` by its discriminator. */
13
+ function asSupervisorReport(report) {
14
+ return report.type === "supervisor" ? report : void 0;
15
+ }
16
+ /** Narrow a `BaseReport` to a `WorkflowReport` by its discriminator. */
17
+ function asWorkflowReport(report) {
18
+ return report.type === "workflow" ? report : void 0;
19
+ }
20
+ /**
21
+ * Collect every intent name dispatched by a supervisor across all
22
+ * iterations — the keys of each iteration snapshot's `result` record.
23
+ */
24
+ function dispatchedIntents(report) {
25
+ const intents = /* @__PURE__ */ new Set();
26
+ for (const snapshot of report.snapshots) for (const intent of Object.keys(snapshot.result)) intents.add(intent);
27
+ return [...intents];
28
+ }
29
+ /**
30
+ * Assert that a supervisor routed to (dispatched) the named intent at
31
+ * least once across its iterations. Targets a `SupervisorResult` or a
32
+ * `SupervisorReport`.
33
+ *
34
+ * @example
35
+ * expect(await supervisor.execute(input)).toRouteTo("critic");
36
+ */
37
+ function matchRouteTo(received, intent) {
38
+ const report = toReport(received);
39
+ const supervisorReport = asSupervisorReport(report);
40
+ if (!supervisorReport) return {
41
+ pass: false,
42
+ message: () => `toRouteTo expects a supervisor result, but received a "${report.type}" report`
43
+ };
44
+ const intents = dispatchedIntents(supervisorReport);
45
+ const pass = intents.includes(intent);
46
+ return {
47
+ pass,
48
+ message: () => pass ? `expected supervisor not to route to "${intent}", but it did` : `expected supervisor to route to "${intent}", but it routed to [${intents.join(", ")}]`
49
+ };
50
+ }
51
+ /**
52
+ * Assert that a supervisor converged — terminated on its own decision
53
+ * (`router` / `route` / `evaluate` / `classifier`) with a
54
+ * `"completed"` status, rather than hitting the iteration cap, being
55
+ * cancelled, or erroring. Targets a `SupervisorResult` or
56
+ * `SupervisorReport`.
57
+ *
58
+ * @example
59
+ * expect(await supervisor.execute(input)).toConverge();
60
+ */
61
+ function matchConverge(received) {
62
+ const report = toReport(received);
63
+ const supervisorReport = asSupervisorReport(report);
64
+ if (!supervisorReport) return {
65
+ pass: false,
66
+ message: () => `toConverge expects a supervisor result, but received a "${report.type}" report`
67
+ };
68
+ const nonConvergent = new Set([
69
+ "max-iterations",
70
+ "cancelled",
71
+ "error"
72
+ ]);
73
+ const pass = supervisorReport.status === "completed" && !nonConvergent.has(supervisorReport.terminatedBy);
74
+ return {
75
+ pass,
76
+ message: () => pass ? `expected supervisor not to converge, but it terminated via "${supervisorReport.terminatedBy}"` : `expected supervisor to converge, but status="${supervisorReport.status}" terminatedBy="${supervisorReport.terminatedBy}" after ${supervisorReport.iterations} iteration(s)`
77
+ };
78
+ }
79
+ /**
80
+ * Assert that a workflow step completed successfully. Targets a
81
+ * `WorkflowResult` or `WorkflowReport`; looks the step up by name in
82
+ * `report.steps` and checks its status is `"completed"`.
83
+ *
84
+ * @example
85
+ * expect(await workflow.execute(input)).toPassStep("draft");
86
+ */
87
+ function matchPassStep(received, stepName) {
88
+ const report = toReport(received);
89
+ const workflowReport = asWorkflowReport(report);
90
+ if (!workflowReport) return {
91
+ pass: false,
92
+ message: () => `toPassStep expects a workflow result, but received a "${report.type}" report`
93
+ };
94
+ const step = workflowReport.steps[stepName];
95
+ if (!step) {
96
+ const known = Object.keys(workflowReport.steps).join(", ");
97
+ return {
98
+ pass: false,
99
+ message: () => `expected workflow to have a step "${stepName}", but steps are [${known}]`
100
+ };
101
+ }
102
+ const pass = step.status === "completed";
103
+ return {
104
+ pass,
105
+ message: () => pass ? `expected step "${stepName}" not to pass, but it completed` : `expected step "${stepName}" to pass, but its status was "${step.status}"`
106
+ };
107
+ }
108
+ /**
109
+ * Assert that a result's `data` validates against a Standard Schema.
110
+ * Targets any result envelope with a `data` field (agent / workflow /
111
+ * supervisor). Runs the schema's `~standard.validate` and passes only
112
+ * when it reports no issues.
113
+ *
114
+ * Synchronous-only: a schema whose `validate` returns a Promise is
115
+ * rejected with a clear message rather than silently passing — the
116
+ * async variant belongs on a dedicated async matcher if needed.
117
+ *
118
+ * @example
119
+ * expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
120
+ */
121
+ function matchOutputShape(received, schema) {
122
+ const data = received.data;
123
+ if (data === void 0) return {
124
+ pass: false,
125
+ message: () => "toOutputShape expected result.data to be defined, but it was undefined"
126
+ };
127
+ const validation = schema["~standard"].validate(data);
128
+ if (validation instanceof Promise) return {
129
+ pass: false,
130
+ message: () => "toOutputShape received an async schema; use a synchronous Standard Schema for this matcher"
131
+ };
132
+ const pass = validation.issues === void 0;
133
+ return {
134
+ pass,
135
+ message: () => {
136
+ if (pass) return "expected result.data not to match the schema, but it did";
137
+ return `expected result.data to match the schema, but validation failed: ${(validation.issues ?? []).map((issue) => issue.message).join("; ")}`;
138
+ }
139
+ };
140
+ }
141
+
142
+ //#endregion
143
+ export { matchConverge, matchOutputShape, matchPassStep, matchRouteTo };
144
+ //# sourceMappingURL=matcher-logic.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher-logic.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matcher-logic.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { END } from \"../contracts/end.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport type { SupervisorReport } from \"../contracts/result/supervisor-result.type\";\nimport type { WorkflowReport } from \"../contracts/result/workflow-result.type\";\n\n/**\n * Normalized matcher verdict — the library-agnostic shape every\n * matcher in this module returns. Vitest's `expect.extend` consumes\n * the same `{ pass, message }` contract, so the registration layer\n * forwards these verbatim.\n */\nexport type MatcherVerdict = {\n /** Whether the assertion passed. */\n pass: boolean;\n /** Lazy message factory — Vitest calls it only when reporting. */\n message: () => string;\n};\n\n/**\n * Any unified result envelope a matcher can be handed. Accepts the\n * full `{ report, ... }` result or a bare `BaseReport` so callers can\n * assert against either `await x.execute()` or `result.report`.\n */\ntype ReportLike = BaseReport | { report: BaseReport };\n\n/**\n * Coerce a matcher target into its `BaseReport`. Accepts the result\n * envelope (`{ report }`) or a report directly.\n */\nfunction toReport(received: ReportLike): BaseReport {\n if (\"report\" in received && received.report) {\n return received.report;\n }\n\n return received as BaseReport;\n}\n\n/** Narrow a `BaseReport` to a `SupervisorReport` by its discriminator. */\nfunction asSupervisorReport(report: BaseReport): SupervisorReport | undefined {\n return report.type === \"supervisor\" ? (report as SupervisorReport) : undefined;\n}\n\n/** Narrow a `BaseReport` to a `WorkflowReport` by its discriminator. */\nfunction asWorkflowReport(report: BaseReport): WorkflowReport | undefined {\n return report.type === \"workflow\" ? (report as WorkflowReport) : undefined;\n}\n\n/**\n * Collect every intent name dispatched by a supervisor across all\n * iterations — the keys of each iteration snapshot's `result` record.\n */\nfunction dispatchedIntents(report: SupervisorReport): string[] {\n const intents = new Set<string>();\n\n for (const snapshot of report.snapshots) {\n for (const intent of Object.keys(snapshot.result)) {\n intents.add(intent);\n }\n }\n\n return [...intents];\n}\n\n/**\n * Assert that a supervisor routed to (dispatched) the named intent at\n * least once across its iterations. Targets a `SupervisorResult` or a\n * `SupervisorReport`.\n *\n * @example\n * expect(await supervisor.execute(input)).toRouteTo(\"critic\");\n */\nexport function matchRouteTo(received: ReportLike, intent: string): MatcherVerdict {\n const report = toReport(received);\n const supervisorReport = asSupervisorReport(report);\n\n if (!supervisorReport) {\n return {\n pass: false,\n message: () =>\n `toRouteTo expects a supervisor result, but received a \"${report.type}\" report`,\n };\n }\n\n const intents = dispatchedIntents(supervisorReport);\n const pass = intents.includes(intent);\n\n return {\n pass,\n message: () =>\n pass\n ? `expected supervisor not to route to \"${intent}\", but it did`\n : `expected supervisor to route to \"${intent}\", but it routed to [${intents.join(\", \")}]`,\n };\n}\n\n/**\n * Assert that a supervisor converged — terminated on its own decision\n * (`router` / `route` / `evaluate` / `classifier`) with a\n * `\"completed\"` status, rather than hitting the iteration cap, being\n * cancelled, or erroring. Targets a `SupervisorResult` or\n * `SupervisorReport`.\n *\n * @example\n * expect(await supervisor.execute(input)).toConverge();\n */\nexport function matchConverge(received: ReportLike): MatcherVerdict {\n const report = toReport(received);\n const supervisorReport = asSupervisorReport(report);\n\n if (!supervisorReport) {\n return {\n pass: false,\n message: () =>\n `toConverge expects a supervisor result, but received a \"${report.type}\" report`,\n };\n }\n\n const nonConvergent = new Set([\"max-iterations\", \"cancelled\", \"error\"]);\n const pass =\n supervisorReport.status === \"completed\" &&\n !nonConvergent.has(supervisorReport.terminatedBy);\n\n return {\n pass,\n message: () =>\n pass\n ? `expected supervisor not to converge, but it terminated via \"${supervisorReport.terminatedBy}\"`\n : `expected supervisor to converge, but status=\"${supervisorReport.status}\" terminatedBy=\"${supervisorReport.terminatedBy}\" after ${supervisorReport.iterations} iteration(s)`,\n };\n}\n\n/**\n * Assert that a workflow step completed successfully. Targets a\n * `WorkflowResult` or `WorkflowReport`; looks the step up by name in\n * `report.steps` and checks its status is `\"completed\"`.\n *\n * @example\n * expect(await workflow.execute(input)).toPassStep(\"draft\");\n */\nexport function matchPassStep(received: ReportLike, stepName: string): MatcherVerdict {\n const report = toReport(received);\n const workflowReport = asWorkflowReport(report);\n\n if (!workflowReport) {\n return {\n pass: false,\n message: () =>\n `toPassStep expects a workflow result, but received a \"${report.type}\" report`,\n };\n }\n\n const step = workflowReport.steps[stepName];\n\n if (!step) {\n const known = Object.keys(workflowReport.steps).join(\", \");\n return {\n pass: false,\n message: () =>\n `expected workflow to have a step \"${stepName}\", but steps are [${known}]`,\n };\n }\n\n const pass = step.status === \"completed\";\n\n return {\n pass,\n message: () =>\n pass\n ? `expected step \"${stepName}\" not to pass, but it completed`\n : `expected step \"${stepName}\" to pass, but its status was \"${step.status}\"`,\n };\n}\n\n/**\n * Result envelope carrying a typed `data` payload — what\n * `matchOutputShape` validates against a schema.\n */\ntype DataResult = { data?: unknown };\n\n/**\n * Assert that a result's `data` validates against a Standard Schema.\n * Targets any result envelope with a `data` field (agent / workflow /\n * supervisor). Runs the schema's `~standard.validate` and passes only\n * when it reports no issues.\n *\n * Synchronous-only: a schema whose `validate` returns a Promise is\n * rejected with a clear message rather than silently passing — the\n * async variant belongs on a dedicated async matcher if needed.\n *\n * @example\n * expect(await agent.execute(input, { output: schema })).toOutputShape(schema);\n */\nexport function matchOutputShape(\n received: DataResult,\n schema: StandardSchemaV1,\n): MatcherVerdict {\n const data = received.data;\n\n if (data === undefined) {\n return {\n pass: false,\n message: () => \"toOutputShape expected result.data to be defined, but it was undefined\",\n };\n }\n\n const validation = schema[\"~standard\"].validate(data);\n\n if (validation instanceof Promise) {\n return {\n pass: false,\n message: () =>\n \"toOutputShape received an async schema; use a synchronous Standard Schema for this matcher\",\n };\n }\n\n const pass = validation.issues === undefined;\n\n return {\n pass,\n message: () => {\n if (pass) {\n return \"expected result.data not to match the schema, but it did\";\n }\n\n const summary = (validation.issues ?? []).map((issue) => issue.message).join(\"; \");\n return `expected result.data to match the schema, but validation failed: ${summary}`;\n },\n };\n}\n\n// Re-exported so matcher consumers and tests can reference the\n// termination sentinel without reaching into contracts.\nexport { END };\n"],"mappings":";;;;;;;AA8BA,SAAS,SAAS,UAAkC;CAClD,IAAI,YAAY,YAAY,SAAS,QACnC,OAAO,SAAS;CAGlB,OAAO;AACT;;AAGA,SAAS,mBAAmB,QAAkD;CAC5E,OAAO,OAAO,SAAS,eAAgB,SAA8B;AACvE;;AAGA,SAAS,iBAAiB,QAAgD;CACxE,OAAO,OAAO,SAAS,aAAc,SAA4B;AACnE;;;;;AAMA,SAAS,kBAAkB,QAAoC;CAC7D,MAAM,0BAAU,IAAI,IAAY;CAEhC,KAAK,MAAM,YAAY,OAAO,WAC5B,KAAK,MAAM,UAAU,OAAO,KAAK,SAAS,MAAM,GAC9C,QAAQ,IAAI,MAAM;CAItB,OAAO,CAAC,GAAG,OAAO;AACpB;;;;;;;;;AAUA,SAAgB,aAAa,UAAsB,QAAgC;CACjF,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,mBAAmB,mBAAmB,MAAM;CAElD,IAAI,CAAC,kBACH,OAAO;EACL,MAAM;EACN,eACE,0DAA0D,OAAO,KAAK;CAC1E;CAGF,MAAM,UAAU,kBAAkB,gBAAgB;CAClD,MAAM,OAAO,QAAQ,SAAS,MAAM;CAEpC,OAAO;EACL;EACA,eACE,OACI,wCAAwC,OAAO,iBAC/C,oCAAoC,OAAO,uBAAuB,QAAQ,KAAK,IAAI,EAAE;CAC7F;AACF;;;;;;;;;;;AAYA,SAAgB,cAAc,UAAsC;CAClE,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,mBAAmB,mBAAmB,MAAM;CAElD,IAAI,CAAC,kBACH,OAAO;EACL,MAAM;EACN,eACE,2DAA2D,OAAO,KAAK;CAC3E;CAGF,MAAM,gBAAgB,IAAI,IAAI;EAAC;EAAkB;EAAa;CAAO,CAAC;CACtE,MAAM,OACJ,iBAAiB,WAAW,eAC5B,CAAC,cAAc,IAAI,iBAAiB,YAAY;CAElD,OAAO;EACL;EACA,eACE,OACI,+DAA+D,iBAAiB,aAAa,KAC7F,gDAAgD,iBAAiB,OAAO,kBAAkB,iBAAiB,aAAa,UAAU,iBAAiB,WAAW;CACtK;AACF;;;;;;;;;AAUA,SAAgB,cAAc,UAAsB,UAAkC;CACpF,MAAM,SAAS,SAAS,QAAQ;CAChC,MAAM,iBAAiB,iBAAiB,MAAM;CAE9C,IAAI,CAAC,gBACH,OAAO;EACL,MAAM;EACN,eACE,yDAAyD,OAAO,KAAK;CACzE;CAGF,MAAM,OAAO,eAAe,MAAM;CAElC,IAAI,CAAC,MAAM;EACT,MAAM,QAAQ,OAAO,KAAK,eAAe,KAAK,CAAC,CAAC,KAAK,IAAI;EACzD,OAAO;GACL,MAAM;GACN,eACE,qCAAqC,SAAS,oBAAoB,MAAM;EAC5E;CACF;CAEA,MAAM,OAAO,KAAK,WAAW;CAE7B,OAAO;EACL;EACA,eACE,OACI,kBAAkB,SAAS,mCAC3B,kBAAkB,SAAS,iCAAiC,KAAK,OAAO;CAChF;AACF;;;;;;;;;;;;;;AAqBA,SAAgB,iBACd,UACA,QACgB;CAChB,MAAM,OAAO,SAAS;CAEtB,IAAI,SAAS,QACX,OAAO;EACL,MAAM;EACN,eAAe;CACjB;CAGF,MAAM,aAAa,OAAO,YAAY,CAAC,SAAS,IAAI;CAEpD,IAAI,sBAAsB,SACxB,OAAO;EACL,MAAM;EACN,eACE;CACJ;CAGF,MAAM,OAAO,WAAW,WAAW;CAEnC,OAAO;EACL;EACA,eAAe;GACb,IAAI,MACF,OAAO;GAIT,OAAO,qEADU,WAAW,UAAU,CAAC,EAAC,CAAE,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,IACI;EACnF;CACF;AACF"}
@@ -0,0 +1,48 @@
1
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
+
3
+ //#region ../@warlock.js/ai/src/testing/matchers.d.ts
4
+ /**
5
+ * Custom Vitest matchers over the unified `@warlock.js/ai` report tree.
6
+ *
7
+ * - `toRouteTo(intent)` — a supervisor dispatched the named intent.
8
+ * - `toConverge()` — a supervisor terminated cleanly on its own
9
+ * decision (not max-iterations / cancelled / error).
10
+ * - `toPassStep(name)` — a workflow step completed successfully.
11
+ * - `toOutputShape(schema)` — a result's `data` validates against a
12
+ * Standard Schema.
13
+ *
14
+ * @example
15
+ * import { registerAiMatchers } from "@warlock.js/ai";
16
+ * registerAiMatchers();
17
+ *
18
+ * expect(await supervisor.execute(input)).toRouteTo("critic");
19
+ * expect(await supervisor.execute(input)).toConverge();
20
+ * expect(await workflow.execute(input)).toPassStep("draft");
21
+ * expect(await agent.execute(input, { output: schema })).toOutputShape(schema);
22
+ */
23
+ interface AiMatchers<R = unknown> {
24
+ /** Assert a supervisor dispatched the named intent across its run. */
25
+ toRouteTo(intent: string): R;
26
+ /** Assert a supervisor terminated cleanly on its own decision. */
27
+ toConverge(): R;
28
+ /** Assert a named workflow step completed successfully. */
29
+ toPassStep(stepName: string): R;
30
+ /** Assert a result's `data` validates against a Standard Schema. */
31
+ toOutputShape(schema: StandardSchemaV1): R;
32
+ }
33
+ declare module "vitest" {
34
+ interface Matchers<T = any> extends AiMatchers<T> {}
35
+ }
36
+ /**
37
+ * Register the `@warlock.js/ai` custom matchers on Vitest's global
38
+ * `expect`. Call once per test file (or in a shared import) before
39
+ * using `toRouteTo` / `toConverge` / `toPassStep` / `toOutputShape`.
40
+ * Idempotent — repeated calls are a no-op.
41
+ *
42
+ * @example
43
+ * import { registerAiMatchers } from "@warlock.js/ai";
44
+ * registerAiMatchers();
45
+ */
46
+ //#endregion
47
+ export { AiMatchers };
48
+ //# sourceMappingURL=matchers.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchers.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/testing/matchers.ts"],"mappings":";;;;;AA4BA;;;;;;;;;;;;;;;;;UAAiB,UAAA;EAMe;EAJ9B,SAAA,CAAU,MAAA,WAAiB,CAAA;EAML;EAJtB,UAAA,IAAc,CAAA;EAI2B;EAFzC,UAAA,CAAW,QAAA,WAAmB,CAAA;EAEY;EAA1C,aAAA,CAAc,MAAA,EAAQ,gBAAA,GAAmB,CAAA;AAAA;AAAA;EAAA,UAQ/B,QAAA,kBAA0B,UAAU,CAAC,CAAA;AAAA;;;;;AAAC"}