@warlock.js/ai 4.4.0 → 4.6.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 (648) hide show
  1. package/CHANGELOG.md +63 -52
  2. package/cjs/index.cjs +240 -14147
  3. package/cjs/src-Bmajk4Qg.cjs +30 -0
  4. package/cjs/src-OZyDYHxm.cjs +25089 -0
  5. package/cjs/src-OZyDYHxm.cjs.map +1 -0
  6. package/esm/agent/agent-config.type.d.mts +119 -1
  7. package/esm/agent/agent-config.type.d.mts.map +1 -1
  8. package/esm/agent/agent-input-builder.mjs +27 -6
  9. package/esm/agent/agent-input-builder.mjs.map +1 -1
  10. package/esm/agent/agent.d.mts +40 -1
  11. package/esm/agent/agent.d.mts.map +1 -1
  12. package/esm/agent/agent.mjs +328 -36
  13. package/esm/agent/agent.mjs.map +1 -1
  14. package/esm/agent/index.d.mts +2 -1
  15. package/esm/agent/index.mjs +1 -0
  16. package/esm/agent/judge-config.type.d.mts +33 -0
  17. package/esm/agent/judge-config.type.d.mts.map +1 -0
  18. package/esm/agent/judge-config.type.mjs +13 -0
  19. package/esm/agent/judge-config.type.mjs.map +1 -0
  20. package/esm/agent/signature.mjs +57 -0
  21. package/esm/agent/signature.mjs.map +1 -0
  22. package/esm/agent/snapshot.mjs +101 -0
  23. package/esm/agent/snapshot.mjs.map +1 -0
  24. package/esm/ai-openai/src/embedder.mjs +4 -0
  25. package/esm/ai-openai/src/image.mjs +5 -0
  26. package/esm/ai-openai/src/index.mjs +7 -0
  27. package/esm/ai-openai/src/model.mjs +5 -0
  28. package/esm/ai-openai/src/sdk.mjs +9 -0
  29. package/esm/ai-openai/src/speech.mjs +5 -0
  30. package/esm/ai-openai/src/transcription.mjs +6 -0
  31. package/esm/ai-openai/src/utils/index.mjs +5 -0
  32. package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
  33. package/esm/ai-openai/src/utils/to-openai-tools.mjs +3 -0
  34. package/esm/ai-openai/src/utils/wrap-openai-error.mjs +4 -0
  35. package/esm/ai.d.mts +164 -53
  36. package/esm/ai.d.mts.map +1 -1
  37. package/esm/ai.mjs +79 -8
  38. package/esm/ai.mjs.map +1 -1
  39. package/esm/batch/batch.d.mts.map +1 -1
  40. package/esm/batch/batch.mjs +21 -1
  41. package/esm/batch/batch.mjs.map +1 -1
  42. package/esm/batch/batch.type.d.mts +11 -4
  43. package/esm/batch/batch.type.d.mts.map +1 -1
  44. package/esm/config.d.mts +39 -3
  45. package/esm/config.d.mts.map +1 -1
  46. package/esm/config.mjs +26 -2
  47. package/esm/config.mjs.map +1 -1
  48. package/esm/contracts/agent/agent-options.type.d.mts +33 -5
  49. package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
  50. package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
  51. package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
  52. package/esm/contracts/agent/agent.contract.d.mts +29 -1
  53. package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
  54. package/esm/contracts/agent/eval.type.d.mts +43 -2
  55. package/esm/contracts/agent/eval.type.d.mts.map +1 -1
  56. package/esm/contracts/agent/index.d.mts +2 -1
  57. package/esm/contracts/attachment-policy.type.d.mts +51 -0
  58. package/esm/contracts/attachment-policy.type.d.mts.map +1 -0
  59. package/esm/contracts/attachment.type.d.mts +16 -7
  60. package/esm/contracts/attachment.type.d.mts.map +1 -1
  61. package/esm/contracts/content-part.type.d.mts +14 -5
  62. package/esm/contracts/content-part.type.d.mts.map +1 -1
  63. package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -1
  64. package/esm/contracts/image-model.contract.d.mts +156 -0
  65. package/esm/contracts/image-model.contract.d.mts.map +1 -0
  66. package/esm/contracts/index.d.mts +13 -6
  67. package/esm/contracts/model.contract.d.mts +11 -8
  68. package/esm/contracts/model.contract.d.mts.map +1 -1
  69. package/esm/contracts/orchestrator/index.d.mts +1 -0
  70. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +31 -2
  71. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
  72. package/esm/contracts/orchestrator/session-lock.contract.d.mts +47 -0
  73. package/esm/contracts/orchestrator/session-lock.contract.d.mts.map +1 -0
  74. package/esm/contracts/planner/index.d.mts +3 -2
  75. package/esm/contracts/planner/planner-config.type.d.mts +61 -0
  76. package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
  77. package/esm/contracts/planner/planner-execute-options.type.d.mts +60 -1
  78. package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
  79. package/esm/contracts/planner/planner-result.type.d.mts +8 -0
  80. package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
  81. package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
  82. package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
  83. package/esm/contracts/planner/planner.contract.d.mts +21 -1
  84. package/esm/contracts/planner/planner.contract.d.mts.map +1 -1
  85. package/esm/contracts/result/agent-result.type.d.mts +6 -4
  86. package/esm/contracts/result/agent-result.type.d.mts.map +1 -1
  87. package/esm/contracts/result/base-report.type.d.mts +21 -3
  88. package/esm/contracts/result/base-report.type.d.mts.map +1 -1
  89. package/esm/contracts/result/base-report.type.mjs.map +1 -1
  90. package/esm/contracts/result/execution-report.type.d.mts +53 -1
  91. package/esm/contracts/result/execution-report.type.d.mts.map +1 -1
  92. package/esm/contracts/result/supervisor-result.type.d.mts +14 -2
  93. package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
  94. package/esm/contracts/result/workflow-result.type.d.mts +2 -1
  95. package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
  96. package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
  97. package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
  98. package/esm/contracts/speech-model.contract.d.mts +97 -0
  99. package/esm/contracts/speech-model.contract.d.mts.map +1 -0
  100. package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
  101. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  102. package/esm/contracts/system-prompt.contract.d.mts +103 -1
  103. package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
  104. package/esm/contracts/team/index.d.mts +1 -0
  105. package/esm/contracts/team/team-config.type.d.mts +127 -0
  106. package/esm/contracts/team/team-config.type.d.mts.map +1 -0
  107. package/esm/contracts/tool.contract.d.mts +4 -2
  108. package/esm/contracts/tool.contract.d.mts.map +1 -1
  109. package/esm/contracts/transcription-model.contract.d.mts +101 -0
  110. package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
  111. package/esm/contracts/workflow/step.contract.d.mts +30 -5
  112. package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
  113. package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
  114. package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
  115. package/esm/errors/agent-drift-error.d.mts +32 -0
  116. package/esm/errors/agent-drift-error.d.mts.map +1 -0
  117. package/esm/errors/agent-drift-error.mjs +31 -0
  118. package/esm/errors/agent-drift-error.mjs.map +1 -0
  119. package/esm/errors/error-code.type.d.mts +1 -1
  120. package/esm/errors/index.d.mts +3 -0
  121. package/esm/errors/index.mjs +3 -0
  122. package/esm/errors/outbound-policy-error.d.mts +27 -0
  123. package/esm/errors/outbound-policy-error.d.mts.map +1 -0
  124. package/esm/errors/outbound-policy-error.mjs +32 -0
  125. package/esm/errors/outbound-policy-error.mjs.map +1 -0
  126. package/esm/errors/planner-drift-error.d.mts +34 -0
  127. package/esm/errors/planner-drift-error.d.mts.map +1 -0
  128. package/esm/errors/planner-drift-error.mjs +33 -0
  129. package/esm/errors/planner-drift-error.mjs.map +1 -0
  130. package/esm/eval/dataset.d.mts +28 -0
  131. package/esm/eval/dataset.d.mts.map +1 -0
  132. package/esm/eval/dataset.mjs +112 -0
  133. package/esm/eval/dataset.mjs.map +1 -0
  134. package/esm/eval/dataset.type.d.mts +53 -0
  135. package/esm/eval/dataset.type.d.mts.map +1 -0
  136. package/esm/eval/eval-runner.d.mts.map +1 -1
  137. package/esm/eval/eval-runner.mjs +16 -2
  138. package/esm/eval/eval-runner.mjs.map +1 -1
  139. package/esm/eval/index.d.mts +20 -1
  140. package/esm/eval/index.d.mts.map +1 -1
  141. package/esm/eval/index.mjs +20 -2
  142. package/esm/eval/index.mjs.map +1 -1
  143. package/esm/eval/regression.d.mts +30 -0
  144. package/esm/eval/regression.d.mts.map +1 -0
  145. package/esm/eval/regression.mjs +51 -0
  146. package/esm/eval/regression.mjs.map +1 -0
  147. package/esm/eval/report-json.d.mts +30 -0
  148. package/esm/eval/report-json.d.mts.map +1 -0
  149. package/esm/eval/report-json.mjs +33 -0
  150. package/esm/eval/report-json.mjs.map +1 -0
  151. package/esm/eval/report-junit.d.mts +22 -0
  152. package/esm/eval/report-junit.d.mts.map +1 -0
  153. package/esm/eval/report-junit.mjs +60 -0
  154. package/esm/eval/report-junit.mjs.map +1 -0
  155. package/esm/guard/contracts/guard-options.type.d.mts +165 -0
  156. package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
  157. package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
  158. package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
  159. package/esm/guard/contracts/index.d.mts +4 -0
  160. package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
  161. package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
  162. package/esm/guard/contracts/verdict.type.d.mts +76 -0
  163. package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
  164. package/esm/guard/detectors/index.d.mts +4 -0
  165. package/esm/guard/detectors/index.mjs +6 -0
  166. package/esm/guard/detectors/injection.d.mts +34 -0
  167. package/esm/guard/detectors/injection.d.mts.map +1 -0
  168. package/esm/guard/detectors/injection.mjs +254 -0
  169. package/esm/guard/detectors/injection.mjs.map +1 -0
  170. package/esm/guard/detectors/moderation.d.mts +32 -0
  171. package/esm/guard/detectors/moderation.d.mts.map +1 -0
  172. package/esm/guard/detectors/moderation.mjs +134 -0
  173. package/esm/guard/detectors/moderation.mjs.map +1 -0
  174. package/esm/guard/detectors/pii.d.mts +41 -0
  175. package/esm/guard/detectors/pii.d.mts.map +1 -0
  176. package/esm/guard/detectors/pii.mjs +199 -0
  177. package/esm/guard/detectors/pii.mjs.map +1 -0
  178. package/esm/guard/detectors/topic.d.mts +29 -0
  179. package/esm/guard/detectors/topic.d.mts.map +1 -0
  180. package/esm/guard/detectors/topic.mjs +99 -0
  181. package/esm/guard/detectors/topic.mjs.map +1 -0
  182. package/esm/guard/errors.d.mts +12 -0
  183. package/esm/guard/errors.d.mts.map +1 -0
  184. package/esm/guard/errors.mjs +18 -0
  185. package/esm/guard/errors.mjs.map +1 -0
  186. package/esm/guard/guard.d.mts +67 -0
  187. package/esm/guard/guard.d.mts.map +1 -0
  188. package/esm/guard/guard.mjs +209 -0
  189. package/esm/guard/guard.mjs.map +1 -0
  190. package/esm/guard/guardrail.d.mts +39 -0
  191. package/esm/guard/guardrail.d.mts.map +1 -0
  192. package/esm/guard/guardrail.mjs +22 -0
  193. package/esm/guard/guardrail.mjs.map +1 -0
  194. package/esm/human/contracts/approval.type.d.mts +154 -0
  195. package/esm/human/contracts/approval.type.d.mts.map +1 -0
  196. package/esm/human/contracts/human-approval.type.d.mts +38 -0
  197. package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
  198. package/esm/human/contracts/index.d.mts +4 -0
  199. package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
  200. package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
  201. package/esm/human/contracts/resume.type.d.mts +77 -0
  202. package/esm/human/contracts/resume.type.d.mts.map +1 -0
  203. package/esm/human/errors.d.mts +84 -0
  204. package/esm/human/errors.d.mts.map +1 -0
  205. package/esm/human/errors.mjs +60 -0
  206. package/esm/human/errors.mjs.map +1 -0
  207. package/esm/human/human-approval.d.mts +57 -0
  208. package/esm/human/human-approval.d.mts.map +1 -0
  209. package/esm/human/human-approval.mjs +170 -0
  210. package/esm/human/human-approval.mjs.map +1 -0
  211. package/esm/human/policy.d.mts +55 -0
  212. package/esm/human/policy.d.mts.map +1 -0
  213. package/esm/human/policy.mjs +67 -0
  214. package/esm/human/policy.mjs.map +1 -0
  215. package/esm/human/register.mjs +37 -0
  216. package/esm/human/register.mjs.map +1 -0
  217. package/esm/human/resume-seed.mjs +53 -0
  218. package/esm/human/resume-seed.mjs.map +1 -0
  219. package/esm/human/resume.d.mts +54 -0
  220. package/esm/human/resume.d.mts.map +1 -0
  221. package/esm/human/resume.mjs +121 -0
  222. package/esm/human/resume.mjs.map +1 -0
  223. package/esm/human/stores/index.mjs +5 -0
  224. package/esm/human/stores/memory.d.mts +30 -0
  225. package/esm/human/stores/memory.d.mts.map +1 -0
  226. package/esm/human/stores/memory.mjs +91 -0
  227. package/esm/human/stores/memory.mjs.map +1 -0
  228. package/esm/human/stores/pg.d.mts +59 -0
  229. package/esm/human/stores/pg.d.mts.map +1 -0
  230. package/esm/human/stores/pg.mjs +220 -0
  231. package/esm/human/stores/pg.mjs.map +1 -0
  232. package/esm/human/stores/redis.d.mts +56 -0
  233. package/esm/human/stores/redis.d.mts.map +1 -0
  234. package/esm/human/stores/redis.mjs +201 -0
  235. package/esm/human/stores/redis.mjs.map +1 -0
  236. package/esm/image/image-cost.d.mts +32 -0
  237. package/esm/image/image-cost.d.mts.map +1 -0
  238. package/esm/image/image-cost.mjs +55 -0
  239. package/esm/image/image-cost.mjs.map +1 -0
  240. package/esm/image/image.d.mts +92 -0
  241. package/esm/image/image.d.mts.map +1 -0
  242. package/esm/image/image.mjs +113 -0
  243. package/esm/image/image.mjs.map +1 -0
  244. package/esm/image/index.mjs +4 -0
  245. package/esm/index.d.mts +137 -24
  246. package/esm/index.mjs +101 -11
  247. package/esm/middleware/builtins/budget.mjs +6 -2
  248. package/esm/middleware/builtins/budget.mjs.map +1 -1
  249. package/esm/middleware/utils/extract-user-text.d.mts +8 -1
  250. package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
  251. package/esm/middleware/utils/extract-user-text.mjs +8 -1
  252. package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
  253. package/esm/mock/index.d.mts +3 -0
  254. package/esm/mock/index.mjs +3 -0
  255. package/esm/mock/mock-config.type.d.mts +22 -0
  256. package/esm/mock/mock-config.type.d.mts.map +1 -1
  257. package/esm/mock/mock-image-model.d.mts +41 -0
  258. package/esm/mock/mock-image-model.d.mts.map +1 -0
  259. package/esm/mock/mock-image-model.mjs +52 -0
  260. package/esm/mock/mock-image-model.mjs.map +1 -0
  261. package/esm/mock/mock-sdk.d.mts +7 -1
  262. package/esm/mock/mock-sdk.d.mts.map +1 -1
  263. package/esm/mock/mock-sdk.mjs +27 -0
  264. package/esm/mock/mock-sdk.mjs.map +1 -1
  265. package/esm/mock/mock-speech-model.d.mts +31 -0
  266. package/esm/mock/mock-speech-model.d.mts.map +1 -0
  267. package/esm/mock/mock-speech-model.mjs +39 -0
  268. package/esm/mock/mock-speech-model.mjs.map +1 -0
  269. package/esm/mock/mock-transcription-model.d.mts +32 -0
  270. package/esm/mock/mock-transcription-model.d.mts.map +1 -0
  271. package/esm/mock/mock-transcription-model.mjs +36 -0
  272. package/esm/mock/mock-transcription-model.mjs.map +1 -0
  273. package/esm/object-stream/index.d.mts +2 -0
  274. package/esm/object-stream/index.mjs +4 -0
  275. package/esm/object-stream/parse-partial-json.d.mts +22 -0
  276. package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
  277. package/esm/object-stream/parse-partial-json.mjs +78 -0
  278. package/esm/object-stream/parse-partial-json.mjs.map +1 -0
  279. package/esm/object-stream/stream-object.d.mts +68 -0
  280. package/esm/object-stream/stream-object.d.mts.map +1 -0
  281. package/esm/object-stream/stream-object.mjs +104 -0
  282. package/esm/object-stream/stream-object.mjs.map +1 -0
  283. package/esm/observe/index.mjs +4 -0
  284. package/esm/observe/observer-registry.d.mts +30 -0
  285. package/esm/observe/observer-registry.d.mts.map +1 -0
  286. package/esm/observe/observer-registry.mjs +51 -0
  287. package/esm/observe/observer-registry.mjs.map +1 -0
  288. package/esm/observe/observer.contract.d.mts +40 -0
  289. package/esm/observe/observer.contract.d.mts.map +1 -0
  290. package/esm/observe/resolve-observers.d.mts +40 -0
  291. package/esm/observe/resolve-observers.d.mts.map +1 -0
  292. package/esm/observe/resolve-observers.mjs +73 -0
  293. package/esm/observe/resolve-observers.mjs.map +1 -0
  294. package/esm/orchestrator/execution.d.mts.map +1 -1
  295. package/esm/orchestrator/execution.mjs +5 -2
  296. package/esm/orchestrator/execution.mjs.map +1 -1
  297. package/esm/orchestrator/index.d.mts +1 -0
  298. package/esm/orchestrator/index.mjs +1 -0
  299. package/esm/orchestrator/orchestrator.d.mts.map +1 -1
  300. package/esm/orchestrator/orchestrator.mjs +39 -6
  301. package/esm/orchestrator/orchestrator.mjs.map +1 -1
  302. package/esm/orchestrator/session-lock.d.mts +25 -0
  303. package/esm/orchestrator/session-lock.d.mts.map +1 -0
  304. package/esm/orchestrator/session-lock.mjs +83 -0
  305. package/esm/orchestrator/session-lock.mjs.map +1 -0
  306. package/esm/planner/dag-scheduler.mjs +97 -0
  307. package/esm/planner/dag-scheduler.mjs.map +1 -0
  308. package/esm/planner/plan-prompt.d.mts +1 -1
  309. package/esm/planner/plan-prompt.d.mts.map +1 -1
  310. package/esm/planner/plan-prompt.mjs +2 -1
  311. package/esm/planner/plan-prompt.mjs.map +1 -1
  312. package/esm/planner/planner-run.d.mts +8 -0
  313. package/esm/planner/planner-run.d.mts.map +1 -1
  314. package/esm/planner/planner-run.mjs +457 -31
  315. package/esm/planner/planner-run.mjs.map +1 -1
  316. package/esm/planner/planner.d.mts.map +1 -1
  317. package/esm/planner/planner.mjs +26 -2
  318. package/esm/planner/planner.mjs.map +1 -1
  319. package/esm/planner/snapshot.mjs +95 -0
  320. package/esm/planner/snapshot.mjs.map +1 -0
  321. package/esm/prompt/errors.d.mts +57 -0
  322. package/esm/prompt/errors.d.mts.map +1 -0
  323. package/esm/prompt/errors.mjs +73 -0
  324. package/esm/prompt/errors.mjs.map +1 -0
  325. package/esm/prompt/index.d.mts +3 -0
  326. package/esm/prompt/index.mjs +4 -0
  327. package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
  328. package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
  329. package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
  330. package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
  331. package/esm/prompt/prompt-validate.mjs +170 -0
  332. package/esm/prompt/prompt-validate.mjs.map +1 -0
  333. package/esm/prompt/prompt.d.mts +54 -0
  334. package/esm/prompt/prompt.d.mts.map +1 -0
  335. package/esm/prompt/prompt.mjs +218 -0
  336. package/esm/prompt/prompt.mjs.map +1 -0
  337. package/esm/prompt/prompt.type.d.mts +174 -0
  338. package/esm/prompt/prompt.type.d.mts.map +1 -0
  339. package/esm/prompts/index.d.mts +3 -0
  340. package/esm/prompts/index.mjs +3 -0
  341. package/esm/prompts/prompts-manager.contract.d.mts +154 -0
  342. package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
  343. package/esm/prompts/prompts-manager.d.mts +38 -0
  344. package/esm/prompts/prompts-manager.d.mts.map +1 -0
  345. package/esm/prompts/prompts-manager.mjs +410 -0
  346. package/esm/prompts/prompts-manager.mjs.map +1 -0
  347. package/esm/prompts/prompts-manager.type.d.mts +172 -0
  348. package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
  349. package/esm/prompts/prompts-validate.mjs +200 -0
  350. package/esm/prompts/prompts-validate.mjs.map +1 -0
  351. package/esm/rag/as-tool.mjs +48 -0
  352. package/esm/rag/as-tool.mjs.map +1 -0
  353. package/esm/rag/chunk/chunk.d.mts +24 -0
  354. package/esm/rag/chunk/chunk.d.mts.map +1 -0
  355. package/esm/rag/chunk/chunk.mjs +44 -0
  356. package/esm/rag/chunk/chunk.mjs.map +1 -0
  357. package/esm/rag/chunk/fixed.mjs +32 -0
  358. package/esm/rag/chunk/fixed.mjs.map +1 -0
  359. package/esm/rag/chunk/markdown.mjs +75 -0
  360. package/esm/rag/chunk/markdown.mjs.map +1 -0
  361. package/esm/rag/chunk/recursive.mjs +132 -0
  362. package/esm/rag/chunk/recursive.mjs.map +1 -0
  363. package/esm/rag/chunk/sentence.mjs +73 -0
  364. package/esm/rag/chunk/sentence.mjs.map +1 -0
  365. package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
  366. package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
  367. package/esm/rag/contracts/citation.type.d.mts +35 -0
  368. package/esm/rag/contracts/citation.type.d.mts.map +1 -0
  369. package/esm/rag/contracts/index.d.mts +4 -0
  370. package/esm/rag/contracts/rag-config.type.d.mts +68 -0
  371. package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
  372. package/esm/rag/contracts/rag-document.type.d.mts +21 -0
  373. package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
  374. package/esm/rag/hybrid/bm25.d.mts +23 -0
  375. package/esm/rag/hybrid/bm25.d.mts.map +1 -0
  376. package/esm/rag/hybrid/bm25.mjs +51 -0
  377. package/esm/rag/hybrid/bm25.mjs.map +1 -0
  378. package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
  379. package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
  380. package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
  381. package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
  382. package/esm/rag/hybrid/rrf.d.mts +25 -0
  383. package/esm/rag/hybrid/rrf.d.mts.map +1 -0
  384. package/esm/rag/hybrid/rrf.mjs +30 -0
  385. package/esm/rag/hybrid/rrf.mjs.map +1 -0
  386. package/esm/rag/index.d.mts +22 -0
  387. package/esm/rag/index.mjs +18 -0
  388. package/esm/rag/loaders/errors.d.mts +19 -0
  389. package/esm/rag/loaders/errors.d.mts.map +1 -0
  390. package/esm/rag/loaders/errors.mjs +25 -0
  391. package/esm/rag/loaders/errors.mjs.map +1 -0
  392. package/esm/rag/loaders/index.mjs +7 -0
  393. package/esm/rag/loaders/load-html.d.mts +26 -0
  394. package/esm/rag/loaders/load-html.d.mts.map +1 -0
  395. package/esm/rag/loaders/load-html.mjs +138 -0
  396. package/esm/rag/loaders/load-html.mjs.map +1 -0
  397. package/esm/rag/loaders/load-pdf.d.mts +38 -0
  398. package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
  399. package/esm/rag/loaders/load-pdf.mjs +150 -0
  400. package/esm/rag/loaders/load-pdf.mjs.map +1 -0
  401. package/esm/rag/loaders/load-text.d.mts +47 -0
  402. package/esm/rag/loaders/load-text.d.mts.map +1 -0
  403. package/esm/rag/loaders/load-text.mjs +60 -0
  404. package/esm/rag/loaders/load-text.mjs.map +1 -0
  405. package/esm/rag/loaders/load-web.d.mts +42 -0
  406. package/esm/rag/loaders/load-web.d.mts.map +1 -0
  407. package/esm/rag/loaders/load-web.mjs +89 -0
  408. package/esm/rag/loaders/load-web.mjs.map +1 -0
  409. package/esm/rag/loaders/loader.type.d.mts +89 -0
  410. package/esm/rag/loaders/loader.type.d.mts.map +1 -0
  411. package/esm/rag/rag.d.mts +38 -0
  412. package/esm/rag/rag.d.mts.map +1 -0
  413. package/esm/rag/rag.mjs +126 -0
  414. package/esm/rag/rag.mjs.map +1 -0
  415. package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
  416. package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
  417. package/esm/rag/rerank/keyword-reranker.mjs +58 -0
  418. package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
  419. package/esm/rag/rerank/llm-reranker.d.mts +36 -0
  420. package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
  421. package/esm/rag/rerank/llm-reranker.mjs +85 -0
  422. package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
  423. package/esm/rag/rerank/reranker.contract.d.mts +28 -0
  424. package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
  425. package/esm/rag/retrieve.mjs +68 -0
  426. package/esm/rag/retrieve.mjs.map +1 -0
  427. package/esm/rag/store/cache-vector-store.d.mts +27 -0
  428. package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
  429. package/esm/rag/store/cache-vector-store.mjs +48 -0
  430. package/esm/rag/store/cache-vector-store.mjs.map +1 -0
  431. package/esm/rag/store/pg-vector-store.d.mts +139 -0
  432. package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
  433. package/esm/rag/store/pg-vector-store.mjs +328 -0
  434. package/esm/rag/store/pg-vector-store.mjs.map +1 -0
  435. package/esm/rag/store/vector-store.contract.d.mts +38 -0
  436. package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
  437. package/esm/rag/transforms/multi-query.d.mts +27 -0
  438. package/esm/rag/transforms/multi-query.d.mts.map +1 -0
  439. package/esm/rag/transforms/multi-query.mjs +41 -0
  440. package/esm/rag/transforms/multi-query.mjs.map +1 -0
  441. package/esm/security/index.mjs +5 -0
  442. package/esm/security/outbound-policy.d.mts +46 -0
  443. package/esm/security/outbound-policy.d.mts.map +1 -0
  444. package/esm/security/outbound-policy.mjs +187 -0
  445. package/esm/security/outbound-policy.mjs.map +1 -0
  446. package/esm/security/outbound-policy.type.d.mts +74 -0
  447. package/esm/security/outbound-policy.type.d.mts.map +1 -0
  448. package/esm/security/private-ip.d.mts +15 -0
  449. package/esm/security/private-ip.d.mts.map +1 -0
  450. package/esm/security/private-ip.mjs +48 -0
  451. package/esm/security/private-ip.mjs.map +1 -0
  452. package/esm/security/redact.d.mts +59 -0
  453. package/esm/security/redact.d.mts.map +1 -0
  454. package/esm/security/redact.mjs +122 -0
  455. package/esm/security/redact.mjs.map +1 -0
  456. package/esm/serve/serve.d.mts +50 -0
  457. package/esm/serve/serve.d.mts.map +1 -0
  458. package/esm/serve/serve.mjs +90 -0
  459. package/esm/serve/serve.mjs.map +1 -0
  460. package/esm/serve/sse.d.mts +20 -0
  461. package/esm/serve/sse.d.mts.map +1 -0
  462. package/esm/serve/sse.mjs +25 -0
  463. package/esm/serve/sse.mjs.map +1 -0
  464. package/esm/serve/stream-to-sse.d.mts +29 -0
  465. package/esm/serve/stream-to-sse.d.mts.map +1 -0
  466. package/esm/serve/stream-to-sse.mjs +37 -0
  467. package/esm/serve/stream-to-sse.mjs.map +1 -0
  468. package/esm/skills/catalog.d.mts +49 -0
  469. package/esm/skills/catalog.d.mts.map +1 -0
  470. package/esm/skills/catalog.mjs +140 -0
  471. package/esm/skills/catalog.mjs.map +1 -0
  472. package/esm/skills/contracts/skill-record.type.d.mts +37 -0
  473. package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
  474. package/esm/skills/contracts/skills-config.type.d.mts +108 -0
  475. package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
  476. package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
  477. package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
  478. package/esm/skills/contracts/skills.contract.d.mts +43 -0
  479. package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
  480. package/esm/skills/index.d.mts +16 -0
  481. package/esm/skills/index.mjs +14 -0
  482. package/esm/skills/load-skill-tool.d.mts +38 -0
  483. package/esm/skills/load-skill-tool.d.mts.map +1 -0
  484. package/esm/skills/load-skill-tool.mjs +65 -0
  485. package/esm/skills/load-skill-tool.mjs.map +1 -0
  486. package/esm/skills/review-gate.d.mts +33 -0
  487. package/esm/skills/review-gate.d.mts.map +1 -0
  488. package/esm/skills/review-gate.mjs +60 -0
  489. package/esm/skills/review-gate.mjs.map +1 -0
  490. package/esm/skills/save-skill-tool.d.mts +39 -0
  491. package/esm/skills/save-skill-tool.d.mts.map +1 -0
  492. package/esm/skills/save-skill-tool.mjs +65 -0
  493. package/esm/skills/save-skill-tool.mjs.map +1 -0
  494. package/esm/skills/skills.d.mts +33 -0
  495. package/esm/skills/skills.d.mts.map +1 -0
  496. package/esm/skills/skills.mjs +109 -0
  497. package/esm/skills/skills.mjs.map +1 -0
  498. package/esm/skills/sources/directory-source.d.mts +19 -0
  499. package/esm/skills/sources/directory-source.d.mts.map +1 -0
  500. package/esm/skills/sources/directory-source.mjs +108 -0
  501. package/esm/skills/sources/directory-source.mjs.map +1 -0
  502. package/esm/skills/sources/index.d.mts +18 -0
  503. package/esm/skills/sources/index.d.mts.map +1 -0
  504. package/esm/skills/sources/index.mjs +27 -0
  505. package/esm/skills/sources/index.mjs.map +1 -0
  506. package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
  507. package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
  508. package/esm/skills/sources/parse-frontmatter.mjs +46 -0
  509. package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
  510. package/esm/skills/sources/store-source.d.mts +14 -0
  511. package/esm/skills/sources/store-source.d.mts.map +1 -0
  512. package/esm/skills/sources/store-source.mjs +15 -0
  513. package/esm/skills/sources/store-source.mjs.map +1 -0
  514. package/esm/skills/sources/url-source.d.mts +29 -0
  515. package/esm/skills/sources/url-source.d.mts.map +1 -0
  516. package/esm/skills/sources/url-source.mjs +117 -0
  517. package/esm/skills/sources/url-source.mjs.map +1 -0
  518. package/esm/skills/store/mock-skills-store.d.mts +57 -0
  519. package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
  520. package/esm/skills/store/mock-skills-store.mjs +100 -0
  521. package/esm/skills/store/mock-skills-store.mjs.map +1 -0
  522. package/esm/skills/store/procedural-skill-store.d.mts +30 -0
  523. package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
  524. package/esm/skills/store/procedural-skill-store.mjs +125 -0
  525. package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
  526. package/esm/speech/index.mjs +3 -0
  527. package/esm/speech/speech.d.mts +65 -0
  528. package/esm/speech/speech.d.mts.map +1 -0
  529. package/esm/speech/speech.mjs +123 -0
  530. package/esm/speech/speech.mjs.map +1 -0
  531. package/esm/supervisor/as-tool.mjs +2 -2
  532. package/esm/supervisor/as-tool.mjs.map +1 -1
  533. package/esm/supervisor/entries.mjs +2 -2
  534. package/esm/supervisor/entries.mjs.map +1 -1
  535. package/esm/supervisor/execution.d.mts.map +1 -1
  536. package/esm/supervisor/execution.mjs +31 -28
  537. package/esm/supervisor/execution.mjs.map +1 -1
  538. package/esm/supervisor/supervisor.d.mts.map +1 -1
  539. package/esm/supervisor/supervisor.mjs +8 -3
  540. package/esm/supervisor/supervisor.mjs.map +1 -1
  541. package/esm/system-prompt/index.d.mts +4 -0
  542. package/esm/system-prompt/system-prompt.d.mts +68 -4
  543. package/esm/system-prompt/system-prompt.d.mts.map +1 -1
  544. package/esm/system-prompt/system-prompt.mjs +89 -5
  545. package/esm/system-prompt/system-prompt.mjs.map +1 -1
  546. package/esm/team/gates.mjs +48 -0
  547. package/esm/team/gates.mjs.map +1 -0
  548. package/esm/team/index.d.mts +1 -0
  549. package/esm/team/index.mjs +3 -0
  550. package/esm/team/team.d.mts +42 -0
  551. package/esm/team/team.d.mts.map +1 -0
  552. package/esm/team/team.mjs +94 -0
  553. package/esm/team/team.mjs.map +1 -0
  554. package/esm/tool/executable-as-tool.d.mts.map +1 -1
  555. package/esm/tool/executable-as-tool.mjs +2 -2
  556. package/esm/tool/executable-as-tool.mjs.map +1 -1
  557. package/esm/tool/tool.d.mts.map +1 -1
  558. package/esm/tool/tool.mjs +2 -2
  559. package/esm/tool/tool.mjs.map +1 -1
  560. package/esm/transcribe/audio-input.d.mts +47 -0
  561. package/esm/transcribe/audio-input.d.mts.map +1 -0
  562. package/esm/transcribe/audio-input.mjs +84 -0
  563. package/esm/transcribe/audio-input.mjs.map +1 -0
  564. package/esm/transcribe/index.mjs +4 -0
  565. package/esm/transcribe/transcribe.d.mts +64 -0
  566. package/esm/transcribe/transcribe.d.mts.map +1 -0
  567. package/esm/transcribe/transcribe.mjs +128 -0
  568. package/esm/transcribe/transcribe.mjs.map +1 -0
  569. package/esm/utils/compute-cost.d.mts +17 -1
  570. package/esm/utils/compute-cost.d.mts.map +1 -1
  571. package/esm/utils/compute-cost.mjs +26 -1
  572. package/esm/utils/compute-cost.mjs.map +1 -1
  573. package/esm/utils/extract-json-lenient.d.mts +42 -0
  574. package/esm/utils/extract-json-lenient.d.mts.map +1 -0
  575. package/esm/utils/extract-json-lenient.mjs +97 -0
  576. package/esm/utils/extract-json-lenient.mjs.map +1 -0
  577. package/esm/utils/index.d.mts +4 -2
  578. package/esm/utils/index.mjs +3 -1
  579. package/esm/utils/json-schema.d.mts +1 -1
  580. package/esm/utils/prepare-attachment-part.d.mts +10 -1
  581. package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
  582. package/esm/utils/prepare-attachment-part.mjs +103 -11
  583. package/esm/utils/prepare-attachment-part.mjs.map +1 -1
  584. package/esm/utils/resolve-attachment.d.mts +4 -3
  585. package/esm/utils/resolve-attachment.d.mts.map +1 -1
  586. package/esm/utils/resolve-attachment.mjs +4 -3
  587. package/esm/utils/resolve-attachment.mjs.map +1 -1
  588. package/esm/utils/run-context.d.mts +94 -0
  589. package/esm/utils/run-context.d.mts.map +1 -0
  590. package/esm/utils/run-context.mjs +98 -0
  591. package/esm/utils/run-context.mjs.map +1 -0
  592. package/esm/vcr/cassette-io.mjs +57 -0
  593. package/esm/vcr/cassette-io.mjs.map +1 -0
  594. package/esm/vcr/errors.d.mts +42 -0
  595. package/esm/vcr/errors.d.mts.map +1 -0
  596. package/esm/vcr/errors.mjs +37 -0
  597. package/esm/vcr/errors.mjs.map +1 -0
  598. package/esm/vcr/hash-request.d.mts +28 -0
  599. package/esm/vcr/hash-request.d.mts.map +1 -0
  600. package/esm/vcr/hash-request.mjs +118 -0
  601. package/esm/vcr/hash-request.mjs.map +1 -0
  602. package/esm/vcr/index.d.mts +4 -0
  603. package/esm/vcr/index.mjs +5 -0
  604. package/esm/vcr/vcr.d.mts +32 -0
  605. package/esm/vcr/vcr.d.mts.map +1 -0
  606. package/esm/vcr/vcr.mjs +248 -0
  607. package/esm/vcr/vcr.mjs.map +1 -0
  608. package/esm/vcr/vcr.type.d.mts +118 -0
  609. package/esm/vcr/vcr.type.d.mts.map +1 -0
  610. package/esm/workflow/as-tool.mjs +2 -2
  611. package/esm/workflow/as-tool.mjs.map +1 -1
  612. package/esm/workflow/engine.mjs +1 -0
  613. package/esm/workflow/engine.mjs.map +1 -1
  614. package/esm/workflow/step-runner.mjs +19 -20
  615. package/esm/workflow/step-runner.mjs.map +1 -1
  616. package/esm/workflow/workflow.d.mts.map +1 -1
  617. package/esm/workflow/workflow.mjs +8 -3
  618. package/esm/workflow/workflow.mjs.map +1 -1
  619. package/llms-full.txt +2572 -204
  620. package/llms.txt +21 -4
  621. package/package.json +7 -3
  622. package/skills/README.md +44 -4
  623. package/skills/ai-dx-helpers/SKILL.md +2 -2
  624. package/skills/approve-tool-calls/SKILL.md +134 -0
  625. package/skills/attach-ai-middleware/SKILL.md +1 -1
  626. package/skills/detect-and-redact-pii/SKILL.md +104 -0
  627. package/skills/durable-agent-runs/SKILL.md +135 -0
  628. package/skills/durable-resume/SKILL.md +128 -0
  629. package/skills/escalate-block-to-human/SKILL.md +85 -0
  630. package/skills/eval-datasets-and-ci/SKILL.md +117 -0
  631. package/skills/generate-images/SKILL.md +138 -0
  632. package/skills/generate-speech/SKILL.md +139 -0
  633. package/skills/guard-input-output/SKILL.md +117 -0
  634. package/skills/manage-prompts/SKILL.md +186 -0
  635. package/skills/observe-ai-flows/SKILL.md +94 -0
  636. package/skills/rag-loaders-and-stores/SKILL.md +164 -0
  637. package/skills/record-replay-llm/SKILL.md +92 -0
  638. package/skills/run-ai-agent/SKILL.md +26 -1
  639. package/skills/run-ai-rag/SKILL.md +139 -0
  640. package/skills/run-ai-team/SKILL.md +107 -0
  641. package/skills/run-orchestrator/SKILL.md +2 -0
  642. package/skills/run-planner/SKILL.md +73 -8
  643. package/skills/run-supervisor/SKILL.md +20 -1
  644. package/skills/transcribe-audio/SKILL.md +157 -0
  645. package/skills/use-runtime-skills/SKILL.md +106 -0
  646. package/skills/write-system-prompt/SKILL.md +30 -1
  647. package/cjs/index.cjs.map +0 -1
  648. package/esm/contracts/result/index.d.mts +0 -15
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: run-planner
3
- description: 'Goal-driven planning with ai.planner({...}) — an LLM GENERATES an ordered execution plan over your registered capabilities (agents / workflows / supervisors / tools), then the planner EXECUTES that plan step-by-step, threading each step output into the next, and returns the unified {data, report, usage, error} envelope with report.type "planner". A plan step may delegate via ai.spawnSubAgent({...}) — a GENERAL one-shot-agent helper (a fresh agent + optional per-task budget), covered fully in `@warlock.js/ai/run-ai-agent/SKILL.md`; it is not planner-specific and the planner engine does not require it. Triggers: `ai.planner`, `planner.execute`, `spawnSubAgent`, `PlannerConfig`, `PlannerCapability`, `PlannerResult`, `PlannerReport`, `PlannerPlan`, `PlannerStep`, `maxSteps`, `report.plan`, `report.executedSteps`; ''let the model plan the steps'', ''dynamic plan from a goal'', ''decompose a goal into capability calls'', ''spawn a sub-agent for a subtask''; typical import `import { ai } from "@warlock.js/ai"`. Skip: a FIXED known pipeline — `@warlock.js/ai/run-ai-workflow/SKILL.md`; routing one input to a specialist each turn — `@warlock.js/ai/run-supervisor/SKILL.md`; a single model + tools call — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langgraph`, `crewai`.'
3
+ description: 'Goal-driven planning with ai.planner({...}) — an LLM GENERATES an ordered execution plan over your registered capabilities (agents / workflows / supervisors / tools), then the planner EXECUTES it, threading each step output into the next, and returns the unified {data, report, usage, error} envelope with report.type "planner". Supports DAG scheduling (dag:true + maxConcurrency off dependsOn), adaptive re-planning (replan:{maxReplans} + the onStep continue/abort/replan directive), and plan-only / approval (mode:"plan-only" → status "awaiting-approval" → approvedPlan). A plan step may delegate via ai.spawnSubAgent({...}) — a GENERAL one-shot-agent helper covered in `@warlock.js/ai/run-ai-agent/SKILL.md`; it is not planner-specific. Triggers: `ai.planner`, `planner.execute`, `spawnSubAgent`, `PlannerConfig`, `PlannerCapability`, `PlannerResult`, `PlannerReport`, `PlannerPlan`, `PlannerStep`, `PlannerStepDirective`, `PlannerPlanInvalidError`, `maxSteps`, `dag`, `maxConcurrency`, `dependsOn`, `replan`, `onStep`, `mode`, `approvedPlan`, `awaiting-approval`, `report.plan`, `report.executedSteps`; ''let the model plan the steps'', ''dynamic plan from a goal'', ''run independent steps in parallel'', ''re-plan when a step fails'', ''generate a plan for approval before running it''; typical import `import { ai } from "@warlock.js/ai"`. Skip: a FIXED known pipeline — `@warlock.js/ai/run-ai-workflow/SKILL.md`; routing one input to a specialist each turn — `@warlock.js/ai/run-supervisor/SKILL.md`; a single model + tools call — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langgraph`, `crewai`.'
4
4
  ---
5
5
 
6
6
  # `ai.planner()` — LLM-generated, then executed, plans
@@ -12,16 +12,19 @@ A planner turns a free-form **goal** into an ordered **plan** the LLM writes its
12
12
  - **`agent`** — one model + tools, single task. No multi-step decomposition.
13
13
  - **`workflow`** — a FIXED pipeline you author by hand (`steps: [...]`). The steps are known at design time.
14
14
  - **`supervisor`** — routes one input to the right specialist each turn; loops on a quality verdict.
15
- - **`planner`** — the steps are NOT known in advance. The LLM generates the ordered plan from the goal, then the planner executes it. Bounded v1: strictly sequential, no DAG scheduling, no mid-plan re-planning.
15
+ - **`planner`** — the steps are NOT known in advance. The LLM generates the ordered plan from the goal, then the planner executes it. Sequential by default; opt into **DAG** scheduling, **adaptive re-planning**, and **plan-only / approval** as needed (below).
16
16
 
17
17
  ## Shape
18
18
 
19
19
  ```ts
20
20
  import { ai } from "@warlock.js/ai";
21
+ import { OpenAISDK } from "@warlock.js/ai-openai";
22
+
23
+ const openai = new OpenAISDK({ apiKey: process.env.OPENAI_API_KEY! });
21
24
 
22
25
  const research = ai.planner({
23
26
  name: "research-assistant",
24
- model: ai.openai.model({ name: "gpt-4o" }), // the plan-GENERATION brain
27
+ model: openai.model({ name: "gpt-4o" }), // the plan-GENERATION brain
25
28
  capabilities: [
26
29
  { name: "search", description: "Search the web for sources", executable: searchAgent },
27
30
  { name: "summarize", description: "Summarize text into bullet points", executable: summarizer },
@@ -42,19 +45,81 @@ for (const step of report.executedSteps) { // forensic, in execution order
42
45
  - `planner` lets you bring your own fully-configured planning agent (custom prompt, middleware). The planner injects the plan schema as that agent's per-call `output`.
43
46
  - A `capability` is `{ name, description, executable }`. The `name` is what the LLM references per step; the `description` is what it reads to pick. `executable` is any `ExecutableContract` (agent / workflow / supervisor / tool).
44
47
 
45
- ## Execution model (bounded v1)
48
+ ## Execution model
46
49
 
47
- 1. **Generate** — the planning agent is asked for a `{ steps, summary? }` plan via a generated schema whose `capability` field is an `enum` of your capability names.
48
- 2. **Execute** — steps run **strictly in array order**. Each completed step's output is threaded into the next step's input as "Context from earlier steps". `dependsOn` on a step is advisory metadata only recorded, not scheduled on.
50
+ 1. **Generate** — the planning agent is asked for a `{ steps, summary? }` plan via a generated schema whose `capability` field is an `enum` of your capability names. Each `PlannerStep` is `{ capability, input, id?, reason?, dependsOn? }`.
51
+ 2. **Execute** — by default steps run **strictly in array order**; each completed step's output is threaded into the next step's input as "Context from earlier steps". (Set `dag: true` to schedule on `dependsOn` insteadbelow.)
49
52
  3. **Finalize** — when `output` is set (factory or per-call), the LAST completed step's structured output is validated into `result.data`. A capability that should feed typed output to the planner's `output` should declare its own `output` schema (the planner reads `data`, falling back to an agent's raw `text`).
50
53
 
51
- `report.type === "planner"`; `report.children[]` carries every dispatched capability report (plus the planning trip), with usage rolled up. Lazy capability loading is **deferred** — every capability is fully constructed up front.
54
+ `report.type === "planner"`; `report.children[]` carries every dispatched capability report (plus the planning trip), with usage rolled up. `report.executedSteps` is the authoritative per-step record (`PlannerStepSnapshot[]`). Lazy capability loading is **deferred** — every capability is fully constructed up front.
55
+
56
+ ## DAG scheduling — `dag: true` + `maxConcurrency`
57
+
58
+ Run independent steps in parallel instead of array-order:
59
+
60
+ ```ts
61
+ const research = ai.planner({
62
+ name: "research",
63
+ model,
64
+ capabilities,
65
+ dag: true, // build a DAG from each step's `id` / `dependsOn`
66
+ maxConcurrency: 4, // max steps in flight at once. default 4
67
+ });
68
+ ```
69
+
70
+ With `dag: true` the planner builds a DAG from step `id` / `dependsOn`, runs each **ready level concurrently** (up to `maxConcurrency`), and feeds each step **only its dependencies' outputs** (not the whole prior transcript). A **cycle** or a `dependsOn` naming an unknown step raises a typed `PlannerPlanInvalidError` **before any step runs**. Default `false` ⇒ the strict array-order loop, byte-for-byte unchanged (where `dependsOn` is advisory-only metadata).
71
+
72
+ ## Adaptive re-planning — `replan: { maxReplans }` + `onStep`
73
+
74
+ When set, a **failed step** (or a `replan` verdict from the `onStep` hook) **revises the REMAINING plan** instead of aborting — re-asking the planning agent for a fresh plan seeded with the executed-step digest plus the feedback. Bounded by `maxReplans`; on exhaustion the run ends with the last failure.
75
+
76
+ ```ts
77
+ const planner = ai.planner({
78
+ name: "adaptive",
79
+ model,
80
+ capabilities,
81
+ replan: { maxReplans: 2 },
82
+ });
83
+
84
+ await planner.execute(goal, {
85
+ onStep: (snapshot, plan) => {
86
+ // fired after EACH step settles (both the sequential and the DAG path)
87
+ if (snapshot.status === "completed" && looksWrong(snapshot.output)) {
88
+ return { type: "replan", feedback: "The summary missed the pricing section." };
89
+ }
90
+ // return nothing / { type: "continue" } to proceed; { type: "abort" } to stop
91
+ },
92
+ });
93
+ ```
94
+
95
+ The `onStep` directive (`PlannerStepDirective`):
96
+
97
+ - `{ type: "continue" }` (or returning nothing) — proceed.
98
+ - `{ type: "abort" }` — stop; remaining steps recorded `skipped` (exactly as a failure aborts).
99
+ - `{ type: "replan"; feedback }` — re-plan the remainder, seeded with the digest + `feedback`. **A `replan` directive with no `replan` config is treated as `continue`** (no-op). Default off ⇒ a failure aborts exactly as before.
100
+
101
+ ## Plan-only / approval — `mode: "plan-only"` + `approvedPlan`
102
+
103
+ Generate (and validate) a plan, return it for human sign-off, then execute the approved plan in a follow-up call:
104
+
105
+ ```ts
106
+ // 1. Generate WITHOUT executing.
107
+ const draft = await planner.execute(goal, { mode: "plan-only" });
108
+ // draft.report.status === "awaiting-approval"; draft.plan carries the generated PlannerPlan.
109
+
110
+ // 2. (human reviews draft.plan) ... then execute it verbatim.
111
+ const final = await planner.execute(goal, { approvedPlan: draft.plan! });
112
+ ```
113
+
114
+ - `mode: "plan-only"` generates + validates the plan and returns **without executing** — `report.status === "awaiting-approval"` (a planner-specific NON-terminal status) and `result.plan` carries the generated plan.
115
+ - `approvedPlan` executes that exact plan, **skipping plan generation entirely**. It is still validated against the **live** capabilities, so a stale plan naming a capability the planner no longer has surfaces a `PlannerPlanInvalidError`.
116
+ - `mode: "plan-only"` **with** `approvedPlan` is contradictory — `approvedPlan` wins (the plan executes).
52
117
 
53
118
  ## Failure + cancellation
54
119
 
55
120
  `execute()` never throws — failures surface on `result.error`:
56
121
 
57
- - **`PlannerPlanInvalidError`** (`PLANNER_PLAN_INVALID`, category `schema`) — empty plan or a step naming an unknown capability; also a final-output validation failure.
122
+ - **`PlannerPlanInvalidError`** (`PLANNER_PLAN_INVALID`, category `schema`) — empty plan, a step naming an unknown capability, a DAG cycle, a `dependsOn` naming an unknown step, a stale `approvedPlan`, or a final-output validation failure.
58
123
  - **`PlannerCancelledError`** (`PLANNER_CANCELLED`, category `cancelled`) — the `AbortSignal` fired. `report.status === "cancelled"`, `report.cancelledAt` set; remaining steps are `skipped`.
59
124
  - A child capability's own error (agent / tool / provider) flows through unchanged on the failing step's snapshot and as `result.error`. The planner stops at the first failed step and marks the rest `skipped`.
60
125
  - **`PlannerFailedError`** is the base for the `PLANNER_*` family.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: run-supervisor
3
- description: 'Multi-intent routing with ai.supervisor({...}) — classifier (iter-0 dispatch), router agent OR route callback, intents as agents / workflows / callbacks, fan-out, evaluate quality loop, ack receptionist, supervisor-level middleware. Triggers: `ai.supervisor`, `ai.router`, `ai.fanOut`, `supervisor.execute`, `supervisor.resume`, `intents`, `router`, `route`, `classifier`, `evaluate`, `ack`, `artifactsSchema`, `middleware`, `END`, `ctx.intents.X.execute`; ''route one input across specialists'', ''multi-intent dispatch'', ''fan-out then evaluate'', ''classifier then router'', ''supervisor middleware'', ''self-consistency / voting''; typical import `import { ai } from "@warlock.js/ai"`. Skip: durable multi-turn sessions — `@warlock.js/ai/run-orchestrator/SKILL.md`; fixed pipelines — `@warlock.js/ai/run-ai-workflow/SKILL.md`; single agent — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langgraph`, `crewai`.'
3
+ description: 'Multi-intent routing with ai.supervisor({...}) — classifier (iter-0 dispatch), router agent OR route callback, intents as agents / workflows / callbacks, fan-out, evaluate quality loop, ack receptionist, supervisor-level middleware. A callback that calls agent.execute() directly auto-nests agent → tool under the callback span (ambient RunFrame) with usage / cost rolled up — same for team members and orchestrator turns. Triggers: `ai.supervisor`, `ai.router`, `ai.fanOut`, `supervisor.execute`, `supervisor.resume`, `intents`, `router`, `route`, `classifier`, `evaluate`, `ack`, `artifactsSchema`, `middleware`, `END`, `ctx.intents.X.execute`, `ctx.run`, `RunFrame`, `callback span`, `children`, `parentRunId`, `rootRunId`, `trace nesting`, `sub-agent`; ''route one input across specialists'', ''multi-intent dispatch'', ''fan-out then evaluate'', ''classifier then router'', ''supervisor middleware'', ''self-consistency / voting'', ''why is my callback agent not nested / cost is $0'', ''nest a sub-agent under a callback''; typical import `import { ai } from "@warlock.js/ai"`. Skip: durable multi-turn sessions — `@warlock.js/ai/run-orchestrator/SKILL.md`; fixed pipelines — `@warlock.js/ai/run-ai-workflow/SKILL.md`; single agent — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langgraph`, `crewai`.'
4
4
  ---
5
5
 
6
6
  # `ai.supervisor()` — multi-intent routing
@@ -267,6 +267,25 @@ intents: {
267
267
 
268
268
  Cycle protection: per-branch call stack. Re-entry on same intent → `SUPERVISOR_DISPATCH_CYCLE`.
269
269
 
270
+ ### Sub-agent trace nesting — `agent.execute()` inside a callback auto-nests
271
+
272
+ A callback that calls `agent.execute()` (or `team` member / `orchestrator` turn callback) **directly** — not through `ctx.run(agent)` / `ctx.intents.X.execute()` — still nests under its enclosing span. An ambient async-local `RunFrame` lets the agent self-attach to the callback's `children[]`, so the report tree is `callback → agent → tool` with usage / cost **rolled up** (no `$0` lone callback span, no manual id threading):
273
+
274
+ ```ts
275
+ ai.supervisor({
276
+ intents: {
277
+ delegate: async (ctx) => {
278
+ const result = await worker.execute(String(ctx.input)); // direct call — still nested
279
+ return { reply: result.text };
280
+ },
281
+ },
282
+ route: (ctx) => (ctx.iteration === 0 ? "delegate" : END),
283
+ });
284
+ // report → callback("delegate") → agent("worker") → tool("echo"); usage flows up to the root.
285
+ ```
286
+
287
+ Same behavior across `ai.supervisor`, `ai.team` (member callbacks), and `ai.orchestrator` (turn callbacks) — and `sessionId` propagates onto the captured subtree. `ctx.run(agent)` is captured **exactly once** (the explicit path does not double-count via the ambient frame), and a standalone `agent.execute()` **outside** any callback keeps its own self-root (no frame leakage). This is what an `Observer` / panoptic sees — see [`@warlock.js/ai/observe-ai-flows/SKILL.md`](@warlock.js/ai/observe-ai-flows/SKILL.md).
288
+
270
289
  ## Per-call options
271
290
 
272
291
  ```ts
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: transcribe-audio
3
+ description: 'Speech-to-text via ai.transcribe({ model: sdk.transcribe({ name }), audio }) — the audio-INPUT verb (Theme I), returning the uniform never-throws { data, error, usage, report } envelope with cost-truth + panoptic observation. Feed it an AudioInput = { base64; mediaType; filename? } — build one with ai.audioFromFile(path) (reads disk, infers media type incl. WhatsApp .ogg/.opus) or ai.audioFromBuffer(bytes, mediaType). Models: OpenAI whisper-1 (verbose_json, per-minute, segments + durationSeconds) or gpt-4o-transcribe (json, per-token). Triggers: `ai.transcribe`, `ai.audioFromFile`, `ai.audioFromBuffer`, `sdk.transcribe`, `openai.transcribe`, `TranscriptionModelContract`, `AudioInput`, `TranscriptionSegment`, `MockTranscriptionModel`; ''speech to text'', ''transcribe audio'', ''voice note to text'', ''WhatsApp voice message'', ''whisper'', ''gpt-4o-transcribe'', ''subtitle segments'', ''audio input''; typical import `import { ai } from "@warlock.js/ai"` + `import { OpenAISDK } from "@warlock.js/ai-openai"`. Skip: text-to-speech / synthesizing a voice — [[generate-speech]]; competing libs raw `openai.audio.transcriptions.create`, `whisper.cpp`.'
4
+ ---
5
+
6
+ # Transcribe audio — the speech-to-text verb (`ai.transcribe`)
7
+
8
+ `ai.transcribe()` is the inverse of `ai.speech()` on the modality track (Theme I). Audio-in / text-out, wrapped in the same uniform result contract every executable returns — so transcribing a support voicemail slots into cost dashboards and panoptic traces exactly like an agent run.
9
+
10
+ **Extracting text from an audio file NEEDS AI** — that is the `ai.transcribe` step. The file handling (`ai.audioFromFile` / `ai.audioFromBuffer`) is pure, non-AI **utility** that just packages bytes into an `AudioInput`; it does no I/O to a provider on its own.
11
+
12
+ This is audio **input** (STT). For audio **output** (synthesizing a voice line), see [[generate-speech]].
13
+
14
+ ## Shape — WhatsApp voice note → text, end to end
15
+
16
+ ```ts
17
+ import { ai } from "@warlock.js/ai";
18
+ import { OpenAISDK } from "@warlock.js/ai-openai";
19
+
20
+ const openai = new OpenAISDK({ apiKey: process.env.OPENAI_API_KEY! });
21
+
22
+ // audioFromFile reads the file + infers the media type from the extension.
23
+ // .ogg / .opus (Android WhatsApp) and .m4a (iOS) are recognized out of the box.
24
+ const audio = await ai.audioFromFile("./voice-note.ogg");
25
+
26
+ const { data, error } = await ai.transcribe({
27
+ model: openai.transcribe({ name: "whisper-1" }),
28
+ audio,
29
+ language: "en", // BCP-47 hint — improves accuracy + latency
30
+ });
31
+
32
+ if (error) console.warn(error.code); // typed AIError
33
+ else console.log(data.text); // the transcript
34
+ ```
35
+
36
+ `TranscriptionModelContract` mirrors `SpeechModelContract` — a peer primitive produced by the adapter's optional `transcribe?()` factory. A non-STT model id (`openai.transcribe({ name: "gpt-4o" })`) throws `InvalidRequestError` **at construction** — fail fast, like the speech/embedder guards.
37
+
38
+ ## The `AudioInput` shape + the two builders
39
+
40
+ ```ts
41
+ type AudioInput = {
42
+ base64: string; // base64-encoded audio bytes
43
+ mediaType: string; // IANA type, e.g. "audio/ogg", "audio/mpeg"
44
+ filename?: string; // helps providers infer the codec from the extension
45
+ };
46
+
47
+ // From a file on disk — reads + infers media type (override for extensionless files).
48
+ const fromDisk = await ai.audioFromFile("./meeting.m4a");
49
+ const forced = await ai.audioFromFile("./blob", { mediaType: "audio/ogg" });
50
+
51
+ // From bytes you already hold (an upload buffer, a downloaded blob) — no I/O, no AI.
52
+ const fromBytes = ai.audioFromBuffer(uploadBuffer, "audio/ogg", "note.ogg");
53
+ ```
54
+
55
+ Keeping `AudioInput` as inlined base64 + explicit media type makes the verb provider-neutral and serializable — there is no `fs` coupling in core, so the same request can cross a queue or an RPC boundary.
56
+
57
+ ## The result envelope
58
+
59
+ ```ts
60
+ type TranscriptionResult = {
61
+ type: "transcription";
62
+ data?: {
63
+ text: string; // full transcript
64
+ segments?: TranscriptionSegment[]; // timestamped, in verbose mode
65
+ }; // undefined on failure
66
+ error?: AIError; // undefined on success — NEVER thrown
67
+ usage: Usage; // tokens (gpt-4o-transcribe) + cost when priced
68
+ report: TranscriptionReport; // type:"transcription", model, durationSeconds, lineage
69
+ };
70
+
71
+ type TranscriptionSegment = { text: string; start?: number; end?: number };
72
+ ```
73
+
74
+ `segments` and `report.durationSeconds` appear only when the provider returns them (whisper's `verbose_json` mode). Use segments to build subtitles or to jump-to-timestamp in a player.
75
+
76
+ ## Transcribe options (provider-neutral)
77
+
78
+ ```ts
79
+ await ai.transcribe({
80
+ model,
81
+ audio,
82
+ language: "en", // BCP-47 hint
83
+ prompt: "Names: Acme, Zoë", // priming — spelling / style hints
84
+ format: "verbose_json", // response-format override (segments + duration)
85
+ signal, // AbortSignal
86
+ observe: collector, // route the report to an Observer (panoptic)
87
+ sessionId: "ticket-88", // group into a session for flat cost/trace queries
88
+ options: { /* provider passthrough */ },
89
+ });
90
+ ```
91
+
92
+ ## OpenAI — whisper-1 (per-minute) + gpt-4o-transcribe (per-token)
93
+
94
+ ```ts
95
+ // whisper-1 — defaults to verbose_json → segments + duration; billed PER MINUTE.
96
+ const whisper = openai.transcribe({ name: "whisper-1", pricing: { perMinute: 0.006 } });
97
+
98
+ // gpt-4o-transcribe — defaults to json; billed PER TOKEN like a chat model.
99
+ const gpt = openai.transcribe({ name: "gpt-4o-transcribe", pricing: { input: 2.5, output: 10 } });
100
+
101
+ const { data, usage } = await ai.transcribe({ model: whisper, audio });
102
+ // data.segments → [{ text, start, end }, …]; usage.cost from report.durationSeconds
103
+ ```
104
+
105
+ The adapter wraps the base64 bytes in an uploadable via the SDK's `toFile`, using `audio.filename` (or `"audio"`) and `audio.mediaType` so the codec is declared correctly.
106
+
107
+ ## Cost-truth — one rollup, two metering models
108
+
109
+ `ai.transcribe` fills `usage.cost` so STT spend folds into the **same** `Usage.cost` rollup as text:
110
+
111
+ - **Per-minute** (`whisper-1`): `{ perMinute }` × `(durationSeconds / 60)` → `cost.input`. If the provider didn't report a duration, cost stays **`undefined`** (no guessing).
112
+ - **Token-metered** (`gpt-4o-transcribe`): `{ input, output }` USD-per-1M-tokens → standard `computeCost` against the returned token usage.
113
+
114
+ Per-minute wins when both are set; an unpriced model leaves `usage.cost` **`undefined`** (honest "cost unknown", never a false zero).
115
+
116
+ ## Pattern — inbound voice-message webhook
117
+
118
+ ```ts
119
+ const stt = openai.transcribe({ name: "whisper-1" });
120
+
121
+ async function onVoiceMessage(buffer: Buffer, mediaType: string) {
122
+ const audio = ai.audioFromBuffer(buffer, mediaType, "inbound.ogg");
123
+ const { data, error } = await ai.transcribe({ model: stt, audio, sessionId: "inbox" });
124
+
125
+ if (error) return replyWith("Sorry, I couldn't understand that audio.");
126
+ return routeToAgent(data.text); // hand the transcript to an ai.agent for a reply
127
+ }
128
+ ```
129
+
130
+ ## Observability
131
+
132
+ The completed `TranscriptionReport` (with `report.durationSeconds` and cost/latency attributed to `report.model`) routes to any registered `Observer` (panoptic, OTel, …) through the shared `observe` seam — `observe: true` (global), an `Observer` (flow-local), or observe-all. See [[observe-ai-flows]]. Provider faults surface as typed `AIError`s on `result.error`; see [[handle-ai-errors]].
133
+
134
+ ## Testing
135
+
136
+ `MockTranscriptionModel(name, responses, pricing?)` is a deterministic `TranscriptionModelContract` double — no HTTP. Script text/segments/duration/usage/errors and inspect `model.calls`. `MockSDK({ transcriptionResponses, transcriptionPricing }).transcribe({ name })` wires the same double behind a full adapter.
137
+
138
+ ```ts
139
+ import { MockTranscriptionModel, transcribe } from "@warlock.js/ai";
140
+
141
+ const AUDIO = { base64: "QUJD", mediaType: "audio/mpeg", filename: "clip.mp3" };
142
+
143
+ const model = new MockTranscriptionModel("whisper-1", [{ durationSeconds: 120 }], { perMinute: 0.006 });
144
+ const { data, usage, report } = await transcribe({ model, audio: AUDIO });
145
+ // data.text → "mock transcript"
146
+ // usage.cost.input → (120 / 60) * 0.006 report.durationSeconds → 120
147
+ // model.calls[0] records { audio, options } for assertions
148
+ ```
149
+
150
+ Scripting `[{ error: new ProviderRateLimitError("slow down") }]` drives the never-throws path — `result.error` is the typed error and `result.data` is `undefined`.
151
+
152
+ ## See also
153
+
154
+ - [[generate-speech]] — the inverse verb (`ai.speech`), text → audio
155
+ - [[generate-images]] — the sibling image-output verb (`ai.image`)
156
+ - [[observe-ai-flows]] — routing the `TranscriptionReport` to panoptic / OTel
157
+ - [[handle-ai-errors]] — the typed `AIError` taxonomy on `result.error`
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: use-runtime-skills
3
+ description: 'Progressive-disclosure agent skills with ai.skills({...}) and the first-class `skills` option on ai.agent — an always-injected cheap metadata catalog plus an on-demand loadSkill tool, backed by directory / url / store sources. Covers inject ("all" | {select:"semantic",topK,embedder}), maxLoadsPerRun, scope tags, the MockSkillsStore, semantic preload, and the inert-by-default Phase-2 self-authoring (saveSkill + default-DENY review gate → promote). Triggers: `ai.skills`, `SkillsConfig`, `SkillsContract`, `SkillSource`, `SkillInjectMode`, `SkillRecord`, `SkillCatalogEntry`, `loadSkill`, `loadSkillTool`, `saveSkill`, `saveSkillTool`, `SkillReviewGate`, `runReviewGate`, `MockSkillsStore`, `proceduralSkillStore`, `maxLoadsPerRun`, `inject`, `scope`, `review`, the agent `skills:` option; ''give an agent loadable skills'', ''progressive disclosure of instructions'', ''catalog of skills the model pulls on demand'', ''semantic preload of skill bodies'', ''let an agent author and review a skill''; typical import `import { ai } from "@warlock.js/ai"`. Skip: composing static system prompts — `@warlock.js/ai/write-system-prompt/SKILL.md`; durable agent memory tiers — `@warlock.js/ai/use-ai-memory/SKILL.md`; defining callable tools — `@warlock.js/ai/define-ai-tool/SKILL.md`.'
4
+ ---
5
+
6
+ # `ai.skills()` — runtime skills with progressive disclosure
7
+
8
+ A **skill is text injected into an agent's context — it never runs code.** `ai.skills(config)` builds a `SkillsContract`: the mechanism behind the first-class `skills` agent option. The agent always injects a cheap **metadata catalog** (one line per in-scope skill) and registers a `loadSkill` tool so the model pulls a skill's full **body** only when it needs it (progressive disclosure). Bodies are withheld until loaded — keeping context lean.
9
+
10
+ ## The first-class agent option (the supported way)
11
+
12
+ ```ts
13
+ import { ai } from "@warlock.js/ai";
14
+
15
+ const agent = ai.agent({
16
+ model: openai.model({ name: "gpt-4o" }),
17
+ systemPrompt: "You are a build assistant.",
18
+ skills: { // a SkillsConfig OR an ai.skills(...) instance
19
+ name: "build-skills",
20
+ sources: [{ type: "directory", path: "./agent-skills" }],
21
+ },
22
+ });
23
+ ```
24
+
25
+ When `skills` is set the agent owns the runtime flow at execute time: it **prepends the always-injected catalog** (and, under `inject`, the preloaded bodies) in front of your system prompt, auto-registers `loadSkill` (plus `saveSkill` only when a `review` gate is configured), and threads the run id so `maxLoadsPerRun` is enforced per execution. **Omitted ⇒ no skills behavior; the agent runs byte-for-byte as today.** The option accepts a raw `SkillsConfig` (the agent passes it to `skills()` for you) or a pre-built `SkillsContract`.
26
+
27
+ ## Factory config — `SkillsConfig`
28
+
29
+ ```ts
30
+ const lib = ai.skills({
31
+ name: "build-skills", // surfaced in analytics + the catalog block
32
+ sources: [{ type: "directory", path: "./agent-skills" }], // >= 1; later source wins on name clash
33
+ inject: { select: "semantic", topK: 2, embedder }, // body-injection policy (see below)
34
+ maxLoadsPerRun: 4, // cap on loadSkill calls per run. default 5
35
+ scope: { tags: ["frontend"] }, // only skills whose tags intersect are catalogued
36
+ review: { approve, store }, // Phase 2 — absent ⇒ saveSkill is NOT exposed
37
+ analytics: (event) => track(event), // optional efficacy sink (errors swallowed)
38
+ });
39
+ ```
40
+
41
+ ### Sources — `SkillSource` (discriminated by `type`, never `kind`)
42
+
43
+ - `{ type: "directory", path }` — reads `path/<folder>/SKILL.md` off disk (lazy `node:fs/promises`).
44
+ - `{ type: "url", url, headers? }` — `fetch()`es a JSON manifest of skills.
45
+ - `{ type: "store", store }` — any `SkillsStoreContract`, e.g. `MockSkillsStore`.
46
+
47
+ Sources merge in order; a later source wins on a name collision.
48
+
49
+ ### Injection — `inject` (`SkillInjectMode`)
50
+
51
+ The metadata catalog is **always** injected (it's cheap). `inject` controls whether any **bodies** are auto-injected up front:
52
+
53
+ - **omitted** (default) — inject NO bodies; the model pulls them via `loadSkill`. Pure progressive disclosure.
54
+ - `"all"` — inject every body up front (small libraries only).
55
+ - `{ select: "semantic", topK, embedder?, threshold? }` — embed the run input, rank the catalog by cosine similarity, inject the top-`topK` bodies. Needs an embedder (passed here, or lazily auto-resolved).
56
+
57
+ ## `SkillsContract` surface
58
+
59
+ ```ts
60
+ interface SkillsContract {
61
+ readonly name: string;
62
+ catalog(scopeInput?: string): Promise<SkillCatalogEntry[]>; // cheap metadata, body omitted
63
+ catalogPrompt(scopeInput?: string): Promise<string>; // catalog rendered as a system block
64
+ preload(input: string): Promise<SkillRecord[]>; // bodies per `inject`; [] when omitted
65
+ tools(runId?: string): AgentToolEntry<any, any>[]; // loadSkill always; saveSkill iff review
66
+ }
67
+ ```
68
+
69
+ A `SkillCatalogEntry` is `Pick<SkillRecord, "name"|"description"|"version"|"tags"|"type">` — the **structural omission of `body`** is the type-level guarantee the catalog never carries skill bodies. A `SkillRecord` adds the full `body` plus `type: "authored" | "promoted" | "candidate"`.
70
+
71
+ ## `maxLoadsPerRun` — a budget, not a throw
72
+
73
+ `loadSkill` calls are capped per run (default 5). Exhaustion is an **error RESULT the model self-corrects from**, never a throw — the tool returns `{ error }` and the loop continues. `runId` scopes both the budget and analytics correlation.
74
+
75
+ ## Stores
76
+
77
+ ```ts
78
+ import { ai, MockSkillsStore } from "@warlock.js/ai";
79
+
80
+ const store = new MockSkillsStore([
81
+ { name: "scaffold", description: "Scaffold a form", version: 1, body: "...", type: "authored" },
82
+ ]);
83
+ const lib = ai.skills({ name: "build", sources: [{ type: "store", store }] });
84
+ ```
85
+
86
+ `MockSkillsStore` is an in-memory `SkillsStoreContract` that ships with the package (construct via `new` — it is a concrete test/utility store, not a factory-fronted primitive). It holds the latest record per name, filters out `candidate`s from `list()` / `load()`, and exposes `saveCandidate` / `promote`. `proceduralSkillStore` is also exported (unifies proven procedural memories with named skills).
87
+
88
+ ## Phase 2 — self-authoring (inert by default)
89
+
90
+ Self-authoring is **gated and OFF unless a `review` gate is wired**:
91
+
92
+ - Without `review`, the `saveSkill` tool is **never registered** — a candidate can never be written, let alone injected.
93
+ - With `review: { approve, store }`, `saveSkill` writes an **INERT** `type: "candidate"` (`version: 0`), filtered out of every catalog/load until promoted.
94
+ - The `SkillReviewGate.approve(candidate)` is **default-DENY**: only `{ approve: true }` promotes the candidate to a new audited version (`promote` → `type: "promoted"`, `version + 1`). Anything else — `{ approve: false }`, a malformed result, or a **throw** (fail-closed) — keeps it inert. `runReviewGate(candidate, gate, emit?)` runs this and never throws (a throwing gate is a denial), emitting `promoted` / `denied` analytics events.
95
+
96
+ The three interchangeable approve shapes — a policy fn, a validator agent, a human callback — all reduce to one `Promise<{ approve: boolean; reason? }>`.
97
+
98
+ ## Analytics
99
+
100
+ The optional `analytics` sink fires `catalogued` / `loaded` / `used` / `saved` / `promoted` / `denied` events `{ type, skill, version, runId?, outcome? }`. Errors from the sink are swallowed (mirroring the agent's `onUsage` / `onComplete`), so analytics never crash a run.
101
+
102
+ ## See also
103
+
104
+ - [`@warlock.js/ai/write-system-prompt/SKILL.md`](@warlock.js/ai/write-system-prompt/SKILL.md) — static persona / instruction blocks (vs. dynamic loaded skills)
105
+ - [`@warlock.js/ai/use-ai-memory/SKILL.md`](@warlock.js/ai/use-ai-memory/SKILL.md) — the procedural memory tier `proceduralSkillStore` unifies with
106
+ - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — the agent the `skills` option attaches to
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write-system-prompt
3
- description: 'Compose system prompts via ai.systemPrompt() / ai.persona() / ai.instruction() — immutable builders with {{placeholder}} substitution, plus ai.systemPrompt.fromFile(path) to seed from a file read once at construction. Triggers: `ai.systemPrompt`, `ai.systemPrompt.fromFile`, `ai.persona`, `ai.instruction`, `SystemPromptBlockContract`, `PersonaContract`, `InstructionContract`, `placeholders`, `{{placeholder|default}}`, `InvalidRequestError`; ''write a system prompt'', ''compose persona + instructions'', ''prompt from a file'', ''per-call prompt override'', ''mustache placeholder''; typical import `import { ai } from "@warlock.js/ai"`. Skip: agent factory wiring — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langchain` `PromptTemplate`, raw f-strings.'
3
+ description: 'Compose system prompts via ai.systemPrompt() / ai.persona() / ai.instruction() — immutable builders with {{placeholder}} substitution, plus ai.systemPrompt.fromFile(path) to seed from a file read once at construction. Carry identity with .meta({ name, version, description, required }) (a name auto-registers in ai.prompts) and compose with merge(...blocks) / merge(contract) / merge(name, { fromVersion }) (provenance in meta.composedFrom). Triggers: `ai.systemPrompt`, `ai.systemPrompt.fromFile`, `ai.persona`, `ai.instruction`, `SystemPromptBlockContract`, `SystemPromptContract`, `SystemPromptMeta`, `SystemPromptMergeOptions`, `PersonaContract`, `InstructionContract`, `meta`, `merge`, `composedFrom`, `fromVersion`, `placeholders`, `{{placeholder|default}}`, `InvalidRequestError`; ''write a system prompt'', ''compose persona + instructions'', ''prompt from a file'', ''name and version a prompt'', ''merge prompts together'', ''per-call prompt override'', ''mustache placeholder''; typical import `import { ai } from "@warlock.js/ai"`. Skip: the named/versioned prompt registry (register / resolve / tag / diff / export / validate) — `@warlock.js/ai/manage-prompts/SKILL.md`; agent factory wiring — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs `langchain` `PromptTemplate`, raw f-strings.'
4
4
  ---
5
5
 
6
6
  # System prompts — immutable builders
@@ -107,6 +107,34 @@ ai.agent({ model, systemPrompt: prompt, placeholders: { language: "Arabic" } });
107
107
 
108
108
  Substitution works on the **rendered** concatenation of every block, so `{{key}}` inside a persona and inside an instruction both resolve against the same placeholder bag.
109
109
 
110
+ ## Identity + composition — `.meta()` and `merge()`
111
+
112
+ A prompt carries optional `SystemPromptMeta` — `{ name?, version?, description?, required?, composedFrom? }`. Read it with the no-argument accessor; update it immutably with the one-argument form. **Giving a prompt a `name` auto-registers it in the `ai.prompts` registry** (keyed by `name@version`):
113
+
114
+ ```ts
115
+ const base = ai.systemPrompt("You are support.", { name: "support", version: "1" });
116
+ base.meta(); // → { name: "support", version: "1" }
117
+ const v2 = base.meta({ version: "2" }); // new builder; original untouched; re-registers under support@2
118
+ ```
119
+
120
+ `merge(...)` folds blocks from another source into a **new** builder — a persona **replaces**, instructions **append**:
121
+
122
+ ```ts
123
+ // (a) N pre-built blocks in one call
124
+ const p = ai.systemPrompt().merge(ai.persona("You are Alex."), ai.instruction("Be concise."));
125
+
126
+ // (b) another prompt contract — its blocks fold in; meta.composedFrom records provenance
127
+ const merged = ai.systemPrompt("Be terse.").merge(otherPrompt);
128
+ merged.meta()?.composedFrom; // deterministic source labels, e.g. ["base@2"]
129
+
130
+ // (c) a registered prompt resolved from ai.prompts by name (latest, or a pinned fromVersion)
131
+ const composed = ai.systemPrompt("You are support.").merge("global", { fromVersion: "1" });
132
+ ```
133
+
134
+ The name / contract / registry-name forms are the registry's composition surface — full coverage (register / resolve / version / tag / diff / validate) in [`@warlock.js/ai/manage-prompts/SKILL.md`](@warlock.js/ai/manage-prompts/SKILL.md).
135
+
136
+ `.validate(options?)` is per-builder sugar over `ai.prompts.validate(this, options)` — the deterministic missing-placeholder check plus an optional Nova-safe LLM-judge.
137
+
110
138
  ## Per-call overrides
111
139
 
112
140
  Replace the agent's system prompt for a single run:
@@ -138,5 +166,6 @@ Three distinct prompts, one common foundation. Base is immutable — safe to sha
138
166
 
139
167
  ## See also
140
168
 
169
+ - [`@warlock.js/ai/manage-prompts/SKILL.md`](@warlock.js/ai/manage-prompts/SKILL.md) — the `ai.prompts` registry these named prompts auto-register into (resolve / version / tag / diff / export / validate)
141
170
  - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — `systemPrompt` on factory + per-call override
142
171
  - [`@warlock.js/ai/run-ai-workflow/SKILL.md`](@warlock.js/ai/run-ai-workflow/SKILL.md) — per-step agent references inherit their own system prompt