@warlock.js/ai 4.3.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/CHANGELOG.md +52 -48
  2. package/cjs/index.cjs +221 -14144
  3. package/cjs/src-C02yzsLs.cjs +22991 -0
  4. package/cjs/src-C02yzsLs.cjs.map +1 -0
  5. package/cjs/src-DFibP2FQ.cjs +30 -0
  6. package/esm/agent/agent-config.type.d.mts +90 -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 +203 -30
  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/ai-openai/src/embedder.mjs +4 -0
  21. package/esm/ai-openai/src/index.mjs +4 -0
  22. package/esm/ai-openai/src/model.mjs +5 -0
  23. package/esm/ai-openai/src/sdk.mjs +6 -0
  24. package/esm/ai-openai/src/utils/index.mjs +4 -0
  25. package/esm/ai-openai/src/utils/to-openai-tools.mjs +3 -0
  26. package/esm/ai-openai/src/utils/wrap-openai-error.mjs +4 -0
  27. package/esm/ai.d.mts +119 -53
  28. package/esm/ai.d.mts.map +1 -1
  29. package/esm/ai.mjs +43 -8
  30. package/esm/ai.mjs.map +1 -1
  31. package/esm/batch/batch.d.mts.map +1 -1
  32. package/esm/batch/batch.mjs +21 -1
  33. package/esm/batch/batch.mjs.map +1 -1
  34. package/esm/batch/batch.type.d.mts +11 -4
  35. package/esm/batch/batch.type.d.mts.map +1 -1
  36. package/esm/config.d.mts +39 -3
  37. package/esm/config.d.mts.map +1 -1
  38. package/esm/config.mjs +26 -2
  39. package/esm/config.mjs.map +1 -1
  40. package/esm/contracts/agent/agent-options.type.d.mts +11 -3
  41. package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
  42. package/esm/contracts/agent/eval.type.d.mts +43 -2
  43. package/esm/contracts/agent/eval.type.d.mts.map +1 -1
  44. package/esm/contracts/attachment-policy.type.d.mts +51 -0
  45. package/esm/contracts/attachment-policy.type.d.mts.map +1 -0
  46. package/esm/contracts/attachment.type.d.mts +16 -7
  47. package/esm/contracts/attachment.type.d.mts.map +1 -1
  48. package/esm/contracts/content-part.type.d.mts +14 -5
  49. package/esm/contracts/content-part.type.d.mts.map +1 -1
  50. package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -1
  51. package/esm/contracts/index.d.mts +6 -4
  52. package/esm/contracts/model.contract.d.mts +11 -8
  53. package/esm/contracts/model.contract.d.mts.map +1 -1
  54. package/esm/contracts/orchestrator/index.d.mts +1 -0
  55. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +31 -2
  56. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
  57. package/esm/contracts/orchestrator/session-lock.contract.d.mts +47 -0
  58. package/esm/contracts/orchestrator/session-lock.contract.d.mts.map +1 -0
  59. package/esm/contracts/planner/index.d.mts +1 -1
  60. package/esm/contracts/planner/planner-config.type.d.mts +31 -0
  61. package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
  62. package/esm/contracts/planner/planner-execute-options.type.d.mts +48 -1
  63. package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
  64. package/esm/contracts/planner/planner-result.type.d.mts +19 -5
  65. package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
  66. package/esm/contracts/planner/planner.contract.d.mts +1 -1
  67. package/esm/contracts/result/agent-result.type.d.mts +6 -4
  68. package/esm/contracts/result/agent-result.type.d.mts.map +1 -1
  69. package/esm/contracts/result/base-report.type.d.mts +21 -3
  70. package/esm/contracts/result/base-report.type.d.mts.map +1 -1
  71. package/esm/contracts/result/base-report.type.mjs.map +1 -1
  72. package/esm/contracts/result/execution-report.type.d.mts +53 -1
  73. package/esm/contracts/result/execution-report.type.d.mts.map +1 -1
  74. package/esm/contracts/result/orchestrator-result.type.d.mts +15 -11
  75. package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -1
  76. package/esm/contracts/result/supervisor-result.type.d.mts +13 -1
  77. package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
  78. package/esm/contracts/result/tool-call.type.d.mts +2 -2
  79. package/esm/contracts/result/tool-call.type.d.mts.map +1 -1
  80. package/esm/contracts/result/workflow-result.type.d.mts +1 -0
  81. package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
  82. package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
  83. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  84. package/esm/contracts/system-prompt.contract.d.mts +103 -1
  85. package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
  86. package/esm/contracts/team/index.d.mts +1 -0
  87. package/esm/contracts/team/team-config.type.d.mts +127 -0
  88. package/esm/contracts/team/team-config.type.d.mts.map +1 -0
  89. package/esm/contracts/tool.contract.d.mts +4 -2
  90. package/esm/contracts/tool.contract.d.mts.map +1 -1
  91. package/esm/contracts/workflow/step.contract.d.mts +30 -5
  92. package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
  93. package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
  94. package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
  95. package/esm/errors/error-code.type.d.mts +1 -1
  96. package/esm/errors/index.d.mts +1 -0
  97. package/esm/errors/index.mjs +1 -0
  98. package/esm/errors/outbound-policy-error.d.mts +27 -0
  99. package/esm/errors/outbound-policy-error.d.mts.map +1 -0
  100. package/esm/errors/outbound-policy-error.mjs +32 -0
  101. package/esm/errors/outbound-policy-error.mjs.map +1 -0
  102. package/esm/eval/dataset.d.mts +28 -0
  103. package/esm/eval/dataset.d.mts.map +1 -0
  104. package/esm/eval/dataset.mjs +112 -0
  105. package/esm/eval/dataset.mjs.map +1 -0
  106. package/esm/eval/dataset.type.d.mts +53 -0
  107. package/esm/eval/dataset.type.d.mts.map +1 -0
  108. package/esm/eval/eval-runner.d.mts.map +1 -1
  109. package/esm/eval/eval-runner.mjs +16 -2
  110. package/esm/eval/eval-runner.mjs.map +1 -1
  111. package/esm/eval/index.d.mts +20 -1
  112. package/esm/eval/index.d.mts.map +1 -1
  113. package/esm/eval/index.mjs +20 -2
  114. package/esm/eval/index.mjs.map +1 -1
  115. package/esm/eval/regression.d.mts +30 -0
  116. package/esm/eval/regression.d.mts.map +1 -0
  117. package/esm/eval/regression.mjs +51 -0
  118. package/esm/eval/regression.mjs.map +1 -0
  119. package/esm/eval/report-json.d.mts +30 -0
  120. package/esm/eval/report-json.d.mts.map +1 -0
  121. package/esm/eval/report-json.mjs +33 -0
  122. package/esm/eval/report-json.mjs.map +1 -0
  123. package/esm/eval/report-junit.d.mts +22 -0
  124. package/esm/eval/report-junit.d.mts.map +1 -0
  125. package/esm/eval/report-junit.mjs +60 -0
  126. package/esm/eval/report-junit.mjs.map +1 -0
  127. package/esm/guard/contracts/guard-options.type.d.mts +165 -0
  128. package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
  129. package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
  130. package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
  131. package/esm/guard/contracts/index.d.mts +4 -0
  132. package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
  133. package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
  134. package/esm/guard/contracts/verdict.type.d.mts +76 -0
  135. package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
  136. package/esm/guard/detectors/index.d.mts +4 -0
  137. package/esm/guard/detectors/index.mjs +6 -0
  138. package/esm/guard/detectors/injection.d.mts +34 -0
  139. package/esm/guard/detectors/injection.d.mts.map +1 -0
  140. package/esm/guard/detectors/injection.mjs +254 -0
  141. package/esm/guard/detectors/injection.mjs.map +1 -0
  142. package/esm/guard/detectors/moderation.d.mts +32 -0
  143. package/esm/guard/detectors/moderation.d.mts.map +1 -0
  144. package/esm/guard/detectors/moderation.mjs +134 -0
  145. package/esm/guard/detectors/moderation.mjs.map +1 -0
  146. package/esm/guard/detectors/pii.d.mts +41 -0
  147. package/esm/guard/detectors/pii.d.mts.map +1 -0
  148. package/esm/guard/detectors/pii.mjs +199 -0
  149. package/esm/guard/detectors/pii.mjs.map +1 -0
  150. package/esm/guard/detectors/topic.d.mts +29 -0
  151. package/esm/guard/detectors/topic.d.mts.map +1 -0
  152. package/esm/guard/detectors/topic.mjs +99 -0
  153. package/esm/guard/detectors/topic.mjs.map +1 -0
  154. package/esm/guard/errors.d.mts +12 -0
  155. package/esm/guard/errors.d.mts.map +1 -0
  156. package/esm/guard/errors.mjs +18 -0
  157. package/esm/guard/errors.mjs.map +1 -0
  158. package/esm/guard/guard.d.mts +67 -0
  159. package/esm/guard/guard.d.mts.map +1 -0
  160. package/esm/guard/guard.mjs +209 -0
  161. package/esm/guard/guard.mjs.map +1 -0
  162. package/esm/guard/guardrail.d.mts +39 -0
  163. package/esm/guard/guardrail.d.mts.map +1 -0
  164. package/esm/guard/guardrail.mjs +22 -0
  165. package/esm/guard/guardrail.mjs.map +1 -0
  166. package/esm/human/contracts/approval.type.d.mts +154 -0
  167. package/esm/human/contracts/approval.type.d.mts.map +1 -0
  168. package/esm/human/contracts/human-approval.type.d.mts +38 -0
  169. package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
  170. package/esm/human/contracts/index.d.mts +4 -0
  171. package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
  172. package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
  173. package/esm/human/contracts/resume.type.d.mts +77 -0
  174. package/esm/human/contracts/resume.type.d.mts.map +1 -0
  175. package/esm/human/errors.d.mts +84 -0
  176. package/esm/human/errors.d.mts.map +1 -0
  177. package/esm/human/errors.mjs +60 -0
  178. package/esm/human/errors.mjs.map +1 -0
  179. package/esm/human/human-approval.d.mts +57 -0
  180. package/esm/human/human-approval.d.mts.map +1 -0
  181. package/esm/human/human-approval.mjs +170 -0
  182. package/esm/human/human-approval.mjs.map +1 -0
  183. package/esm/human/policy.d.mts +55 -0
  184. package/esm/human/policy.d.mts.map +1 -0
  185. package/esm/human/policy.mjs +67 -0
  186. package/esm/human/policy.mjs.map +1 -0
  187. package/esm/human/register.mjs +37 -0
  188. package/esm/human/register.mjs.map +1 -0
  189. package/esm/human/resume-seed.mjs +53 -0
  190. package/esm/human/resume-seed.mjs.map +1 -0
  191. package/esm/human/resume.d.mts +54 -0
  192. package/esm/human/resume.d.mts.map +1 -0
  193. package/esm/human/resume.mjs +121 -0
  194. package/esm/human/resume.mjs.map +1 -0
  195. package/esm/human/stores/index.mjs +5 -0
  196. package/esm/human/stores/memory.d.mts +30 -0
  197. package/esm/human/stores/memory.d.mts.map +1 -0
  198. package/esm/human/stores/memory.mjs +91 -0
  199. package/esm/human/stores/memory.mjs.map +1 -0
  200. package/esm/human/stores/pg.d.mts +59 -0
  201. package/esm/human/stores/pg.d.mts.map +1 -0
  202. package/esm/human/stores/pg.mjs +220 -0
  203. package/esm/human/stores/pg.mjs.map +1 -0
  204. package/esm/human/stores/redis.d.mts +56 -0
  205. package/esm/human/stores/redis.d.mts.map +1 -0
  206. package/esm/human/stores/redis.mjs +201 -0
  207. package/esm/human/stores/redis.mjs.map +1 -0
  208. package/esm/index.d.mts +113 -22
  209. package/esm/index.mjs +82 -11
  210. package/esm/middleware/builtins/budget.mjs +6 -2
  211. package/esm/middleware/builtins/budget.mjs.map +1 -1
  212. package/esm/middleware/utils/extract-user-text.d.mts +8 -1
  213. package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
  214. package/esm/middleware/utils/extract-user-text.mjs +8 -1
  215. package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
  216. package/esm/object-stream/index.d.mts +2 -0
  217. package/esm/object-stream/index.mjs +4 -0
  218. package/esm/object-stream/parse-partial-json.d.mts +22 -0
  219. package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
  220. package/esm/object-stream/parse-partial-json.mjs +78 -0
  221. package/esm/object-stream/parse-partial-json.mjs.map +1 -0
  222. package/esm/object-stream/stream-object.d.mts +68 -0
  223. package/esm/object-stream/stream-object.d.mts.map +1 -0
  224. package/esm/object-stream/stream-object.mjs +104 -0
  225. package/esm/object-stream/stream-object.mjs.map +1 -0
  226. package/esm/observe/index.mjs +4 -0
  227. package/esm/observe/observer-registry.d.mts +30 -0
  228. package/esm/observe/observer-registry.d.mts.map +1 -0
  229. package/esm/observe/observer-registry.mjs +51 -0
  230. package/esm/observe/observer-registry.mjs.map +1 -0
  231. package/esm/observe/observer.contract.d.mts +40 -0
  232. package/esm/observe/observer.contract.d.mts.map +1 -0
  233. package/esm/observe/resolve-observers.d.mts +40 -0
  234. package/esm/observe/resolve-observers.d.mts.map +1 -0
  235. package/esm/observe/resolve-observers.mjs +73 -0
  236. package/esm/observe/resolve-observers.mjs.map +1 -0
  237. package/esm/orchestrator/execution.d.mts.map +1 -1
  238. package/esm/orchestrator/execution.mjs +5 -2
  239. package/esm/orchestrator/execution.mjs.map +1 -1
  240. package/esm/orchestrator/index.d.mts +1 -0
  241. package/esm/orchestrator/index.mjs +1 -0
  242. package/esm/orchestrator/orchestrator.d.mts.map +1 -1
  243. package/esm/orchestrator/orchestrator.mjs +39 -6
  244. package/esm/orchestrator/orchestrator.mjs.map +1 -1
  245. package/esm/orchestrator/session-lock.d.mts +25 -0
  246. package/esm/orchestrator/session-lock.d.mts.map +1 -0
  247. package/esm/orchestrator/session-lock.mjs +83 -0
  248. package/esm/orchestrator/session-lock.mjs.map +1 -0
  249. package/esm/planner/dag-scheduler.mjs +97 -0
  250. package/esm/planner/dag-scheduler.mjs.map +1 -0
  251. package/esm/planner/plan-prompt.d.mts +1 -1
  252. package/esm/planner/plan-prompt.d.mts.map +1 -1
  253. package/esm/planner/plan-prompt.mjs +2 -1
  254. package/esm/planner/plan-prompt.mjs.map +1 -1
  255. package/esm/planner/plan-schema.mjs +17 -14
  256. package/esm/planner/plan-schema.mjs.map +1 -1
  257. package/esm/planner/planner-run.d.mts.map +1 -1
  258. package/esm/planner/planner-run.mjs +300 -29
  259. package/esm/planner/planner-run.mjs.map +1 -1
  260. package/esm/planner/planner.mjs +1 -1
  261. package/esm/planner/planner.mjs.map +1 -1
  262. package/esm/prompt/errors.d.mts +57 -0
  263. package/esm/prompt/errors.d.mts.map +1 -0
  264. package/esm/prompt/errors.mjs +73 -0
  265. package/esm/prompt/errors.mjs.map +1 -0
  266. package/esm/prompt/index.d.mts +3 -0
  267. package/esm/prompt/index.mjs +4 -0
  268. package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
  269. package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
  270. package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
  271. package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
  272. package/esm/prompt/prompt-validate.mjs +170 -0
  273. package/esm/prompt/prompt-validate.mjs.map +1 -0
  274. package/esm/prompt/prompt.d.mts +54 -0
  275. package/esm/prompt/prompt.d.mts.map +1 -0
  276. package/esm/prompt/prompt.mjs +218 -0
  277. package/esm/prompt/prompt.mjs.map +1 -0
  278. package/esm/prompt/prompt.type.d.mts +174 -0
  279. package/esm/prompt/prompt.type.d.mts.map +1 -0
  280. package/esm/prompts/index.d.mts +3 -0
  281. package/esm/prompts/index.mjs +3 -0
  282. package/esm/prompts/prompts-manager.contract.d.mts +154 -0
  283. package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
  284. package/esm/prompts/prompts-manager.d.mts +38 -0
  285. package/esm/prompts/prompts-manager.d.mts.map +1 -0
  286. package/esm/prompts/prompts-manager.mjs +410 -0
  287. package/esm/prompts/prompts-manager.mjs.map +1 -0
  288. package/esm/prompts/prompts-manager.type.d.mts +172 -0
  289. package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
  290. package/esm/prompts/prompts-validate.mjs +200 -0
  291. package/esm/prompts/prompts-validate.mjs.map +1 -0
  292. package/esm/rag/as-tool.mjs +48 -0
  293. package/esm/rag/as-tool.mjs.map +1 -0
  294. package/esm/rag/chunk/chunk.d.mts +24 -0
  295. package/esm/rag/chunk/chunk.d.mts.map +1 -0
  296. package/esm/rag/chunk/chunk.mjs +44 -0
  297. package/esm/rag/chunk/chunk.mjs.map +1 -0
  298. package/esm/rag/chunk/fixed.mjs +32 -0
  299. package/esm/rag/chunk/fixed.mjs.map +1 -0
  300. package/esm/rag/chunk/markdown.mjs +75 -0
  301. package/esm/rag/chunk/markdown.mjs.map +1 -0
  302. package/esm/rag/chunk/recursive.mjs +132 -0
  303. package/esm/rag/chunk/recursive.mjs.map +1 -0
  304. package/esm/rag/chunk/sentence.mjs +73 -0
  305. package/esm/rag/chunk/sentence.mjs.map +1 -0
  306. package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
  307. package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
  308. package/esm/rag/contracts/citation.type.d.mts +35 -0
  309. package/esm/rag/contracts/citation.type.d.mts.map +1 -0
  310. package/esm/rag/contracts/index.d.mts +4 -0
  311. package/esm/rag/contracts/rag-config.type.d.mts +68 -0
  312. package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
  313. package/esm/rag/contracts/rag-document.type.d.mts +21 -0
  314. package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
  315. package/esm/rag/hybrid/bm25.d.mts +23 -0
  316. package/esm/rag/hybrid/bm25.d.mts.map +1 -0
  317. package/esm/rag/hybrid/bm25.mjs +51 -0
  318. package/esm/rag/hybrid/bm25.mjs.map +1 -0
  319. package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
  320. package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
  321. package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
  322. package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
  323. package/esm/rag/hybrid/rrf.d.mts +25 -0
  324. package/esm/rag/hybrid/rrf.d.mts.map +1 -0
  325. package/esm/rag/hybrid/rrf.mjs +30 -0
  326. package/esm/rag/hybrid/rrf.mjs.map +1 -0
  327. package/esm/rag/index.d.mts +15 -0
  328. package/esm/rag/index.mjs +11 -0
  329. package/esm/rag/rag.d.mts +38 -0
  330. package/esm/rag/rag.d.mts.map +1 -0
  331. package/esm/rag/rag.mjs +126 -0
  332. package/esm/rag/rag.mjs.map +1 -0
  333. package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
  334. package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
  335. package/esm/rag/rerank/keyword-reranker.mjs +58 -0
  336. package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
  337. package/esm/rag/rerank/llm-reranker.d.mts +36 -0
  338. package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
  339. package/esm/rag/rerank/llm-reranker.mjs +85 -0
  340. package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
  341. package/esm/rag/rerank/reranker.contract.d.mts +28 -0
  342. package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
  343. package/esm/rag/retrieve.mjs +68 -0
  344. package/esm/rag/retrieve.mjs.map +1 -0
  345. package/esm/rag/store/cache-vector-store.d.mts +27 -0
  346. package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
  347. package/esm/rag/store/cache-vector-store.mjs +48 -0
  348. package/esm/rag/store/cache-vector-store.mjs.map +1 -0
  349. package/esm/rag/store/vector-store.contract.d.mts +38 -0
  350. package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
  351. package/esm/rag/transforms/multi-query.d.mts +27 -0
  352. package/esm/rag/transforms/multi-query.d.mts.map +1 -0
  353. package/esm/rag/transforms/multi-query.mjs +41 -0
  354. package/esm/rag/transforms/multi-query.mjs.map +1 -0
  355. package/esm/security/index.mjs +5 -0
  356. package/esm/security/outbound-policy.d.mts +46 -0
  357. package/esm/security/outbound-policy.d.mts.map +1 -0
  358. package/esm/security/outbound-policy.mjs +187 -0
  359. package/esm/security/outbound-policy.mjs.map +1 -0
  360. package/esm/security/outbound-policy.type.d.mts +74 -0
  361. package/esm/security/outbound-policy.type.d.mts.map +1 -0
  362. package/esm/security/private-ip.d.mts +15 -0
  363. package/esm/security/private-ip.d.mts.map +1 -0
  364. package/esm/security/private-ip.mjs +48 -0
  365. package/esm/security/private-ip.mjs.map +1 -0
  366. package/esm/security/redact.d.mts +59 -0
  367. package/esm/security/redact.d.mts.map +1 -0
  368. package/esm/security/redact.mjs +122 -0
  369. package/esm/security/redact.mjs.map +1 -0
  370. package/esm/serve/serve.d.mts +50 -0
  371. package/esm/serve/serve.d.mts.map +1 -0
  372. package/esm/serve/serve.mjs +90 -0
  373. package/esm/serve/serve.mjs.map +1 -0
  374. package/esm/serve/sse.d.mts +20 -0
  375. package/esm/serve/sse.d.mts.map +1 -0
  376. package/esm/serve/sse.mjs +25 -0
  377. package/esm/serve/sse.mjs.map +1 -0
  378. package/esm/serve/stream-to-sse.d.mts +29 -0
  379. package/esm/serve/stream-to-sse.d.mts.map +1 -0
  380. package/esm/serve/stream-to-sse.mjs +37 -0
  381. package/esm/serve/stream-to-sse.mjs.map +1 -0
  382. package/esm/skills/catalog.d.mts +49 -0
  383. package/esm/skills/catalog.d.mts.map +1 -0
  384. package/esm/skills/catalog.mjs +140 -0
  385. package/esm/skills/catalog.mjs.map +1 -0
  386. package/esm/skills/contracts/skill-record.type.d.mts +37 -0
  387. package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
  388. package/esm/skills/contracts/skills-config.type.d.mts +108 -0
  389. package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
  390. package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
  391. package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
  392. package/esm/skills/contracts/skills.contract.d.mts +43 -0
  393. package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
  394. package/esm/skills/index.d.mts +16 -0
  395. package/esm/skills/index.mjs +14 -0
  396. package/esm/skills/load-skill-tool.d.mts +38 -0
  397. package/esm/skills/load-skill-tool.d.mts.map +1 -0
  398. package/esm/skills/load-skill-tool.mjs +65 -0
  399. package/esm/skills/load-skill-tool.mjs.map +1 -0
  400. package/esm/skills/review-gate.d.mts +33 -0
  401. package/esm/skills/review-gate.d.mts.map +1 -0
  402. package/esm/skills/review-gate.mjs +60 -0
  403. package/esm/skills/review-gate.mjs.map +1 -0
  404. package/esm/skills/save-skill-tool.d.mts +39 -0
  405. package/esm/skills/save-skill-tool.d.mts.map +1 -0
  406. package/esm/skills/save-skill-tool.mjs +65 -0
  407. package/esm/skills/save-skill-tool.mjs.map +1 -0
  408. package/esm/skills/skills.d.mts +33 -0
  409. package/esm/skills/skills.d.mts.map +1 -0
  410. package/esm/skills/skills.mjs +109 -0
  411. package/esm/skills/skills.mjs.map +1 -0
  412. package/esm/skills/sources/directory-source.d.mts +19 -0
  413. package/esm/skills/sources/directory-source.d.mts.map +1 -0
  414. package/esm/skills/sources/directory-source.mjs +108 -0
  415. package/esm/skills/sources/directory-source.mjs.map +1 -0
  416. package/esm/skills/sources/index.d.mts +18 -0
  417. package/esm/skills/sources/index.d.mts.map +1 -0
  418. package/esm/skills/sources/index.mjs +27 -0
  419. package/esm/skills/sources/index.mjs.map +1 -0
  420. package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
  421. package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
  422. package/esm/skills/sources/parse-frontmatter.mjs +46 -0
  423. package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
  424. package/esm/skills/sources/store-source.d.mts +14 -0
  425. package/esm/skills/sources/store-source.d.mts.map +1 -0
  426. package/esm/skills/sources/store-source.mjs +15 -0
  427. package/esm/skills/sources/store-source.mjs.map +1 -0
  428. package/esm/skills/sources/url-source.d.mts +29 -0
  429. package/esm/skills/sources/url-source.d.mts.map +1 -0
  430. package/esm/skills/sources/url-source.mjs +117 -0
  431. package/esm/skills/sources/url-source.mjs.map +1 -0
  432. package/esm/skills/store/mock-skills-store.d.mts +57 -0
  433. package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
  434. package/esm/skills/store/mock-skills-store.mjs +100 -0
  435. package/esm/skills/store/mock-skills-store.mjs.map +1 -0
  436. package/esm/skills/store/procedural-skill-store.d.mts +30 -0
  437. package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
  438. package/esm/skills/store/procedural-skill-store.mjs +125 -0
  439. package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
  440. package/esm/supervisor/as-tool.mjs +2 -2
  441. package/esm/supervisor/as-tool.mjs.map +1 -1
  442. package/esm/supervisor/execution.d.mts.map +1 -1
  443. package/esm/supervisor/execution.mjs +31 -28
  444. package/esm/supervisor/execution.mjs.map +1 -1
  445. package/esm/supervisor/supervisor.d.mts.map +1 -1
  446. package/esm/supervisor/supervisor.mjs +8 -3
  447. package/esm/supervisor/supervisor.mjs.map +1 -1
  448. package/esm/system-prompt/index.d.mts +4 -0
  449. package/esm/system-prompt/system-prompt.d.mts +68 -4
  450. package/esm/system-prompt/system-prompt.d.mts.map +1 -1
  451. package/esm/system-prompt/system-prompt.mjs +89 -5
  452. package/esm/system-prompt/system-prompt.mjs.map +1 -1
  453. package/esm/team/gates.mjs +48 -0
  454. package/esm/team/gates.mjs.map +1 -0
  455. package/esm/team/index.d.mts +1 -0
  456. package/esm/team/index.mjs +3 -0
  457. package/esm/team/team.d.mts +42 -0
  458. package/esm/team/team.d.mts.map +1 -0
  459. package/esm/team/team.mjs +94 -0
  460. package/esm/team/team.mjs.map +1 -0
  461. package/esm/tool/executable-as-tool.d.mts.map +1 -1
  462. package/esm/tool/executable-as-tool.mjs +2 -2
  463. package/esm/tool/executable-as-tool.mjs.map +1 -1
  464. package/esm/tool/tool.d.mts.map +1 -1
  465. package/esm/tool/tool.mjs +2 -2
  466. package/esm/tool/tool.mjs.map +1 -1
  467. package/esm/utils/compute-cost.d.mts +17 -1
  468. package/esm/utils/compute-cost.d.mts.map +1 -1
  469. package/esm/utils/compute-cost.mjs +26 -1
  470. package/esm/utils/compute-cost.mjs.map +1 -1
  471. package/esm/utils/extract-json-lenient.d.mts +42 -0
  472. package/esm/utils/extract-json-lenient.d.mts.map +1 -0
  473. package/esm/utils/extract-json-lenient.mjs +97 -0
  474. package/esm/utils/extract-json-lenient.mjs.map +1 -0
  475. package/esm/utils/index.d.mts +4 -2
  476. package/esm/utils/index.mjs +3 -1
  477. package/esm/utils/json-schema.d.mts +1 -1
  478. package/esm/utils/prepare-attachment-part.d.mts +10 -1
  479. package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
  480. package/esm/utils/prepare-attachment-part.mjs +103 -11
  481. package/esm/utils/prepare-attachment-part.mjs.map +1 -1
  482. package/esm/utils/resolve-attachment.d.mts +4 -3
  483. package/esm/utils/resolve-attachment.d.mts.map +1 -1
  484. package/esm/utils/resolve-attachment.mjs +4 -3
  485. package/esm/utils/resolve-attachment.mjs.map +1 -1
  486. package/esm/utils/run-context.d.mts +94 -0
  487. package/esm/utils/run-context.d.mts.map +1 -0
  488. package/esm/utils/run-context.mjs +98 -0
  489. package/esm/utils/run-context.mjs.map +1 -0
  490. package/esm/vcr/cassette-io.mjs +57 -0
  491. package/esm/vcr/cassette-io.mjs.map +1 -0
  492. package/esm/vcr/errors.d.mts +42 -0
  493. package/esm/vcr/errors.d.mts.map +1 -0
  494. package/esm/vcr/errors.mjs +37 -0
  495. package/esm/vcr/errors.mjs.map +1 -0
  496. package/esm/vcr/hash-request.d.mts +28 -0
  497. package/esm/vcr/hash-request.d.mts.map +1 -0
  498. package/esm/vcr/hash-request.mjs +118 -0
  499. package/esm/vcr/hash-request.mjs.map +1 -0
  500. package/esm/vcr/index.d.mts +4 -0
  501. package/esm/vcr/index.mjs +5 -0
  502. package/esm/vcr/vcr.d.mts +32 -0
  503. package/esm/vcr/vcr.d.mts.map +1 -0
  504. package/esm/vcr/vcr.mjs +248 -0
  505. package/esm/vcr/vcr.mjs.map +1 -0
  506. package/esm/vcr/vcr.type.d.mts +118 -0
  507. package/esm/vcr/vcr.type.d.mts.map +1 -0
  508. package/esm/workflow/as-tool.mjs +2 -2
  509. package/esm/workflow/as-tool.mjs.map +1 -1
  510. package/esm/workflow/engine.mjs +1 -0
  511. package/esm/workflow/engine.mjs.map +1 -1
  512. package/esm/workflow/step-runner.mjs +19 -20
  513. package/esm/workflow/step-runner.mjs.map +1 -1
  514. package/esm/workflow/workflow.d.mts.map +1 -1
  515. package/esm/workflow/workflow.mjs +8 -3
  516. package/esm/workflow/workflow.mjs.map +1 -1
  517. package/llms-full.txt +1683 -68
  518. package/llms.txt +16 -4
  519. package/package.json +7 -3
  520. package/skills/README.md +40 -4
  521. package/skills/ai-dx-helpers/SKILL.md +2 -2
  522. package/skills/approve-tool-calls/SKILL.md +134 -0
  523. package/skills/attach-ai-middleware/SKILL.md +1 -1
  524. package/skills/detect-and-redact-pii/SKILL.md +104 -0
  525. package/skills/durable-resume/SKILL.md +128 -0
  526. package/skills/escalate-block-to-human/SKILL.md +85 -0
  527. package/skills/eval-datasets-and-ci/SKILL.md +117 -0
  528. package/skills/guard-input-output/SKILL.md +117 -0
  529. package/skills/manage-prompts/SKILL.md +186 -0
  530. package/skills/observe-ai-flows/SKILL.md +94 -0
  531. package/skills/record-replay-llm/SKILL.md +92 -0
  532. package/skills/run-ai-agent/SKILL.md +26 -1
  533. package/skills/run-ai-rag/SKILL.md +139 -0
  534. package/skills/run-ai-team/SKILL.md +107 -0
  535. package/skills/run-orchestrator/SKILL.md +2 -0
  536. package/skills/run-planner/SKILL.md +73 -8
  537. package/skills/run-supervisor/SKILL.md +20 -1
  538. package/skills/use-runtime-skills/SKILL.md +106 -0
  539. package/skills/write-system-prompt/SKILL.md +30 -1
  540. package/cjs/index.cjs.map +0 -1
  541. package/esm/contracts/result/index.d.mts +0 -15
@@ -5,8 +5,11 @@ import { PlannerPlanInvalidError } from "../errors/planner-plan-invalid-error.mj
5
5
  import { SchemaValidationError } from "../errors/schema-validation-error.mjs";
6
6
  import { accumulateCost } from "../utils/compute-cost.mjs";
7
7
  import { generateRunId } from "../utils/generate-run-id.mjs";
8
+ import { captureChildReport, withoutRunFrame } from "../utils/run-context.mjs";
8
9
  import { REPORT_SCHEMA_VERSION } from "../contracts/result/base-report.type.mjs";
9
10
  import { stampReportLineage } from "../utils/stamp-report-lineage.mjs";
11
+ import { notifyObservers } from "../observe/resolve-observers.mjs";
12
+ import { buildDag, readyNodes, sinkNodes } from "./dag-scheduler.mjs";
10
13
  import { planSchema } from "./plan-schema.mjs";
11
14
 
12
15
  //#region ../@warlock.js/ai/src/planner/planner-run.ts
@@ -40,6 +43,8 @@ var PlannerRun = class {
40
43
  };
41
44
  this.children = [];
42
45
  this.executedSteps = [];
46
+ this.awaitingApproval = false;
47
+ this.replanCount = 0;
43
48
  this.runId = args.options?.runId ?? generateRunId("planner");
44
49
  }
45
50
  /**
@@ -49,14 +54,31 @@ var PlannerRun = class {
49
54
  * `report.status`.
50
55
  */
51
56
  async run() {
57
+ const result = await this.runPlan();
58
+ await notifyObservers(this.args.config.observe, result.report);
59
+ captureChildReport(result.report);
60
+ return result;
61
+ }
62
+ /**
63
+ * Drive the planner lifecycle and return the built result WITHOUT
64
+ * routing it — `run()` owns observer routing + auto-nesting so the
65
+ * unified tree is emitted exactly once.
66
+ */
67
+ async runPlan() {
52
68
  try {
53
69
  if (this.isAborted()) {
54
70
  this.markCancelled();
55
71
  return this.buildResult();
56
72
  }
57
- const plan = await this.generatePlan();
73
+ const plan = this.args.options?.approvedPlan ?? await this.generatePlan();
58
74
  if (this.error || !plan) return this.buildResult();
75
+ this.assertPlanValid(plan);
76
+ if (this.error) return this.buildResult();
59
77
  this.plan = plan;
78
+ if (this.args.options?.mode === "plan-only" && !this.args.options?.approvedPlan) {
79
+ this.awaitingApproval = true;
80
+ return this.buildResult();
81
+ }
60
82
  await this.executePlan(plan);
61
83
  await this.finalizeOutput();
62
84
  } catch (caught) {
@@ -70,15 +92,19 @@ var PlannerRun = class {
70
92
  * agent's per-call `output`, so the model is steered to reference only
71
93
  * real capabilities. The planning trip's usage + report roll into the
72
94
  * planner's totals regardless of outcome.
95
+ *
96
+ * `feedback` is set only on a RE-plan: the regenerated request is
97
+ * seeded with the executed-step digest plus the caller's feedback so
98
+ * the planner revises the remaining work rather than starting cold.
73
99
  */
74
- async generatePlan() {
100
+ async generatePlan(feedback) {
75
101
  const schema = planSchema([...this.args.capabilities.keys()], this.args.maxSteps);
76
- const result = await this.args.planningAgent.execute(this.buildPlanPrompt(), {
102
+ const result = await withoutRunFrame(() => this.args.planningAgent.execute(this.buildPlanPrompt(feedback), {
77
103
  output: schema,
78
104
  placeholders: this.args.options?.placeholders,
79
105
  signal: this.args.options?.signal,
80
106
  sessionId: this.args.options?.sessionId
81
- });
107
+ }));
82
108
  this.absorb(result.usage, result.report);
83
109
  if (result.error) {
84
110
  this.error = result.error instanceof SchemaValidationError ? new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): the planner produced no usable plan`, {
@@ -92,43 +118,174 @@ var PlannerRun = class {
92
118
  this.error = new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): the planner produced no usable plan`, { context: { runId: this.runId } });
93
119
  return;
94
120
  }
95
- const unknownStep = plan.steps.find((step) => !this.args.capabilities.has(step.capability));
96
- if (unknownStep) {
97
- this.error = new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): plan references unknown capability "${unknownStep.capability}"`, { context: {
98
- runId: this.runId,
99
- capability: unknownStep.capability
100
- } });
121
+ this.assertPlanValid(plan);
122
+ if (this.error) return;
123
+ return plan;
124
+ }
125
+ /**
126
+ * Shared plan-validity guard — used both for a freshly generated plan
127
+ * and for a caller-supplied `approvedPlan`. Sets `this.error` to a
128
+ * typed {@link PlannerPlanInvalidError} when the plan is empty or names
129
+ * an unknown capability; a stale `approvedPlan` thus fails the same way
130
+ * a hallucinated capability does, never silently mis-dispatching.
131
+ */
132
+ assertPlanValid(plan) {
133
+ if (!Array.isArray(plan.steps) || plan.steps.length === 0) {
134
+ this.error = new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): the planner produced no usable plan`, { context: { runId: this.runId } });
101
135
  return;
102
136
  }
103
- return plan;
137
+ const unknownStep = plan.steps.find((step) => !this.args.capabilities.has(step.capability));
138
+ if (unknownStep) this.error = new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): plan references unknown capability "${unknownStep.capability}"`, { context: {
139
+ runId: this.runId,
140
+ capability: unknownStep.capability
141
+ } });
104
142
  }
105
143
  /**
106
- * Phase 2 — execute the plan's steps strictly in order, threading each
107
- * completed step's output into the next step's input context. Stops at
108
- * the first step failure (its `error` becomes the run error) or when
109
- * the abort signal fires between steps. Steps beyond `maxSteps` are
110
- * recorded as `skipped` without running.
144
+ * Phase 2 — execute the plan. Branches on `config.dag`: the default is
145
+ * the strict array-order sequential loop (byte-for-byte today's
146
+ * behavior when neither `onStep` nor `replan` is configured); `dag:
147
+ * true` schedules independent `dependsOn` branches in parallel.
111
148
  */
112
149
  async executePlan(plan) {
150
+ if (this.args.config.dag) return this.executeDag(plan);
151
+ return this.executeSequential(plan);
152
+ }
153
+ /**
154
+ * Sequential executor — the original strict array-order loop, threading
155
+ * each completed step's output into the next step's input context.
156
+ * Stops at the first step failure or when the abort signal fires
157
+ * between steps; steps beyond `maxSteps` are recorded `skipped`.
158
+ *
159
+ * **Additive hooks (inert by default).** After each step settles it
160
+ * fires the `onStep` directive hook; an `abort` directive stops the run
161
+ * like a failure, and a `replan` directive (or, when `config.replan` is
162
+ * set, an unhandled failure) regenerates the REMAINING plan instead of
163
+ * aborting. With no `onStep` and no `replan`, the behavior is identical
164
+ * to before.
165
+ */
166
+ async executeSequential(plan) {
113
167
  const previousOutputs = [];
114
- for (let index = 0; index < plan.steps.length; index++) {
115
- const step = plan.steps[index];
168
+ let steps = plan.steps;
169
+ let index = 0;
170
+ while (index < steps.length) {
171
+ const step = steps[index];
116
172
  if (index >= this.args.maxSteps) {
117
173
  this.recordSkipped(index, step);
174
+ index++;
118
175
  continue;
119
176
  }
120
177
  if (this.isAborted()) {
121
178
  this.markCancelled();
122
179
  this.recordSkipped(index, step);
180
+ index++;
181
+ continue;
182
+ }
183
+ const completed = await this.executeStep(index, step, previousOutputs);
184
+ const snapshot = this.snapshotFor(index);
185
+ const directive = snapshot ? await this.resolveDirective(snapshot, plan, completed) : void 0;
186
+ if (directive?.type === "replan") {
187
+ const remaining = await this.regeneratePlan(directive.feedback);
188
+ if (this.error || !remaining) {
189
+ this.skipRest(steps, index + 1);
190
+ return;
191
+ }
192
+ steps = remaining.steps;
193
+ index = 0;
194
+ previousOutputs.length = 0;
195
+ previousOutputs.push(...this.executedDigest());
123
196
  continue;
124
197
  }
125
- if (!await this.executeStep(index, step, previousOutputs)) {
126
- for (let rest = index + 1; rest < plan.steps.length; rest++) this.recordSkipped(rest, plan.steps[rest]);
198
+ if (directive?.type === "abort") {
199
+ this.skipRest(steps, index + 1);
127
200
  return;
128
201
  }
202
+ index++;
129
203
  }
130
204
  }
131
205
  /**
206
+ * DAG executor — schedule independent `dependsOn` branches in parallel.
207
+ *
208
+ * Builds the DAG (cycle / unknown-id → `PlannerPlanInvalidError`),
209
+ * then repeatedly computes the ready set (steps whose deps all
210
+ * completed), dispatches up to `maxConcurrency` of them with
211
+ * `Promise.all`, and feeds each step ONLY its dependencies' outputs. A
212
+ * failed step blocks just its descendants (recorded `skipped`);
213
+ * independent branches still settle. With an `output` schema set, the
214
+ * final `data` is the topological SINK's output (multiple sinks → a
215
+ * convergence error).
216
+ */
217
+ async executeDag(plan) {
218
+ const dag = buildDag(plan.steps, this.args.config.name);
219
+ const maxConcurrency = Math.max(1, this.args.config.maxConcurrency ?? 4);
220
+ const completed = /* @__PURE__ */ new Set();
221
+ const done = /* @__PURE__ */ new Set();
222
+ const outputs = /* @__PURE__ */ new Map();
223
+ const rawOutputs = /* @__PURE__ */ new Map();
224
+ let executedCount = 0;
225
+ while (done.size < dag.nodes.length) {
226
+ if (this.isAborted()) {
227
+ this.markCancelled();
228
+ this.skipDagRest(dag, done);
229
+ return;
230
+ }
231
+ const ready = readyNodes(dag, completed, done);
232
+ if (ready.length === 0) {
233
+ this.skipDagRest(dag, done);
234
+ return;
235
+ }
236
+ const batch = ready.slice(0, maxConcurrency);
237
+ const settled = await Promise.all(batch.map(async (node) => {
238
+ if (executedCount >= this.args.maxSteps) {
239
+ this.recordSkipped(node.index, node.step);
240
+ return {
241
+ node,
242
+ ran: false,
243
+ completed: false
244
+ };
245
+ }
246
+ executedCount++;
247
+ const previousOutputs = node.dependencies.map((dependency) => outputs.get(dependency));
248
+ const stepCompleted = await this.executeStep(node.index, node.step, previousOutputs);
249
+ if (stepCompleted) {
250
+ const rawOutput = this.snapshotFor(node.index)?.output;
251
+ rawOutputs.set(node.id, rawOutput);
252
+ outputs.set(node.id, this.stringifyOutput(node.step.capability, rawOutput));
253
+ }
254
+ return {
255
+ node,
256
+ ran: true,
257
+ completed: stepCompleted
258
+ };
259
+ }));
260
+ for (const entry of settled) {
261
+ done.add(entry.node.id);
262
+ if (entry.completed) completed.add(entry.node.id);
263
+ }
264
+ let replanFeedback;
265
+ let shouldAbort = false;
266
+ for (const entry of settled) {
267
+ if (!entry.ran) continue;
268
+ const snapshot = this.snapshotFor(entry.node.index);
269
+ const directive = snapshot ? await this.resolveDirective(snapshot, plan, entry.completed) : void 0;
270
+ if (directive?.type === "replan") replanFeedback = directive.feedback;
271
+ else if (directive?.type === "abort") shouldAbort = true;
272
+ }
273
+ if (shouldAbort) {
274
+ this.skipDagRest(dag, done);
275
+ return;
276
+ }
277
+ if (replanFeedback !== void 0) {
278
+ const remaining = await this.regeneratePlan(replanFeedback);
279
+ if (this.error || !remaining) {
280
+ this.skipDagRest(dag, done);
281
+ return;
282
+ }
283
+ return this.executeDag(remaining);
284
+ }
285
+ }
286
+ this.finalizeDagOutput(dag, completed, rawOutputs);
287
+ }
288
+ /**
132
289
  * Dispatch one plan step through its capability's `executable.execute()`
133
290
  * and fold the outcome into the accumulators. Returns `true` when the
134
291
  * step completed, `false` when it failed (setting the run error).
@@ -138,10 +295,10 @@ var PlannerRun = class {
138
295
  const stepStart = performance.now();
139
296
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
140
297
  const input = this.composeStepInput(step, previousOutputs);
141
- const result = await capability.executable.execute(input, {
298
+ const result = await withoutRunFrame(() => capability.executable.execute(input, {
142
299
  signal: this.args.options?.signal,
143
300
  sessionId: this.args.options?.sessionId
144
- });
301
+ }));
145
302
  const childReport = "report" in result ? result.report : void 0;
146
303
  this.absorb(result.usage, childReport);
147
304
  const output = this.extractOutput(result);
@@ -167,6 +324,104 @@ var PlannerRun = class {
167
324
  return true;
168
325
  }
169
326
  /**
327
+ * Resolve the steering directive for a just-settled step, shared by the
328
+ * sequential and DAG executors. Fires the user's `onStep` hook, then
329
+ * normalizes the result against the `replan` budget:
330
+ *
331
+ * - explicit `replan` directive — honored only when `config.replan` is
332
+ * set and the budget remains; otherwise downgraded to `continue`.
333
+ * - explicit `abort` — honored.
334
+ * - failed step with no overriding directive — auto-`replan` when
335
+ * `config.replan` is set and the budget remains (feedback = the step
336
+ * error message), else `abort` (today's abort-on-first-failure).
337
+ *
338
+ * Returns `undefined` when the run should simply continue. A returned
339
+ * `replan` directive has ALREADY consumed one unit of the replan budget.
340
+ */
341
+ async resolveDirective(snapshot, plan, completed) {
342
+ const hook = this.args.options?.onStep;
343
+ const userDirective = hook ? await hook(snapshot, plan) : void 0;
344
+ if (userDirective?.type === "replan") {
345
+ if (this.canReplan()) {
346
+ this.replanCount++;
347
+ return userDirective;
348
+ }
349
+ } else if (userDirective?.type === "abort") return { type: "abort" };
350
+ else if (userDirective?.type === "continue") return;
351
+ if (!completed) {
352
+ if (this.canReplan()) {
353
+ this.replanCount++;
354
+ return {
355
+ type: "replan",
356
+ feedback: snapshot.error?.message ?? "step failed"
357
+ };
358
+ }
359
+ return { type: "abort" };
360
+ }
361
+ }
362
+ /** Whether a re-plan is configured and the budget has room. */
363
+ canReplan() {
364
+ const replan = this.args.config.replan;
365
+ return replan !== void 0 && this.replanCount < replan.maxReplans;
366
+ }
367
+ /**
368
+ * Re-ask the planning agent for a plan over the REMAINING work — a
369
+ * second `generatePlan()` seeded with the executed-step digest plus the
370
+ * caller's feedback. Reuses the exact `generatePlan` plumbing (same
371
+ * schema, same `PlannerPlanInvalidError` handling), so a regenerated
372
+ * plan that is empty or names an unknown capability fails identically.
373
+ * The failed step's error is cleared so the regenerated plan runs
374
+ * cleanly; a fresh failure (or exhausted budget) re-sets it.
375
+ */
376
+ async regeneratePlan(feedback) {
377
+ this.error = void 0;
378
+ return this.generatePlan(feedback);
379
+ }
380
+ /**
381
+ * The executed-so-far digest — one context line per completed step, in
382
+ * execution order. Seeds the regenerated plan's first step so it builds
383
+ * on what already ran.
384
+ */
385
+ executedDigest() {
386
+ return this.executedSteps.filter((snapshot) => snapshot.status === "completed").map((snapshot) => this.stringifyOutput(snapshot.step.capability, snapshot.output));
387
+ }
388
+ /** The last-pushed snapshot for a given step index, if any. */
389
+ snapshotFor(index) {
390
+ for (let position = this.executedSteps.length - 1; position >= 0; position--) {
391
+ const snapshot = this.executedSteps[position];
392
+ if (snapshot.index === index) return snapshot;
393
+ }
394
+ }
395
+ /** Record every step from `from` onward (in a flat array plan) as skipped. */
396
+ skipRest(steps, from) {
397
+ for (let rest = from; rest < steps.length; rest++) this.recordSkipped(rest, steps[rest]);
398
+ }
399
+ /** Record every not-yet-`done` DAG node as skipped, in plan order. */
400
+ skipDagRest(dag, done) {
401
+ for (const node of dag.nodes) if (!done.has(node.id)) this.recordSkipped(node.index, node.step);
402
+ }
403
+ /**
404
+ * Set `this.data` from the DAG's topological sink for a configured
405
+ * `output` schema. "Last completed step" is meaningless under
406
+ * parallelism, so the sink (the step nothing depends on) is the
407
+ * unambiguous final output. Multiple sinks while an `output` schema is
408
+ * set is a convergence error — a typed `PlannerPlanInvalidError`.
409
+ */
410
+ finalizeDagOutput(dag, completed, rawOutputs) {
411
+ if (!(this.args.options?.output ?? this.args.config.output) || this.error) return;
412
+ const sinks = sinkNodes(dag).filter((node) => completed.has(node.id));
413
+ if (sinks.length > 1) {
414
+ this.error = new PlannerPlanInvalidError(`ai.planner("${this.args.config.name}"): DAG has multiple sinks but an \`output\` schema is set — the plan must converge to a single final step`, { context: {
415
+ runId: this.runId,
416
+ sinks: sinks.map((node) => node.id)
417
+ } });
418
+ this.data = void 0;
419
+ return;
420
+ }
421
+ const sink = sinks[0];
422
+ this.data = sink ? rawOutputs.get(sink.id) : void 0;
423
+ }
424
+ /**
170
425
  * Phase 3 — when an `output` schema is configured (factory or per-call
171
426
  * override), validate the final completed step's output into typed
172
427
  * `result.data`. A validation failure replaces the run error and flips
@@ -205,6 +460,7 @@ var PlannerRun = class {
205
460
  version: this.args.config.version,
206
461
  type: "planner",
207
462
  status,
463
+ ...this.error ? { error: this.error } : {},
208
464
  startedAt: this.startedAt,
209
465
  endedAt: (/* @__PURE__ */ new Date()).toISOString(),
210
466
  duration: performance.now() - this.startPerf,
@@ -220,27 +476,42 @@ var PlannerRun = class {
220
476
  rootRunId: this.runId,
221
477
  sessionId: this.args.options?.sessionId
222
478
  });
223
- return {
479
+ const result = {
224
480
  type: "planner",
225
481
  data: this.error ? void 0 : this.data,
226
482
  error: this.error,
227
483
  usage: this.usage,
228
484
  report
229
485
  };
486
+ if (this.awaitingApproval) result.plan = this.plan;
487
+ return result;
230
488
  }
231
489
  /**
232
- * Resolve the terminal status from the accumulated outcome. Cancelled
233
- * wins over failed (an abort that also produced a step error still
234
- * reads as cancelled); failed wins over completed.
490
+ * Resolve the terminal status from the accumulated outcome.
491
+ * `awaiting-approval` (plan-only short-circuit) wins over everything
492
+ * nothing executed, so neither cancellation nor error applies.
493
+ * Otherwise cancelled wins over failed (an abort that also produced a
494
+ * step error still reads as cancelled); failed wins over completed.
235
495
  */
236
496
  resolveStatus() {
497
+ if (this.awaitingApproval) return "awaiting-approval";
237
498
  if (this.cancelledAt !== void 0) return "cancelled";
238
499
  if (this.error) return "failed";
239
500
  return "completed";
240
501
  }
241
- /** Build the prompt handed to the planning agent — the user's goal. */
242
- buildPlanPrompt() {
243
- return this.args.goal;
502
+ /**
503
+ * Build the prompt handed to the planning agent. On the first pass this
504
+ * is just the user's goal (byte-for-byte unchanged). On a RE-plan it
505
+ * prepends the executed-step digest and the steering feedback so the
506
+ * planner revises the remaining work.
507
+ */
508
+ buildPlanPrompt(feedback) {
509
+ if (feedback === void 0) return this.args.goal;
510
+ const digest = this.executedDigest();
511
+ const sections = [`Goal: ${this.args.goal}`, ""];
512
+ if (digest.length > 0) sections.push("Steps already completed:", ...digest, "");
513
+ sections.push(`Feedback requiring a revised plan: ${feedback}`, "", "Produce a plan for the REMAINING work only.");
514
+ return sections.join("\n");
244
515
  }
245
516
  /**
246
517
  * Compose a step's effective input: the step's own `input`, prefixed
@@ -1 +1 @@
1
- {"version":3,"file":"planner-run.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/planner-run.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { PlannerCapability } from \"../contracts/planner/planner-capability.type\";\nimport type { PlannerConfig } from \"../contracts/planner/planner-config.type\";\nimport type { PlannerExecuteOptions } from \"../contracts/planner/planner-execute-options.type\";\nimport type { PlannerPlan, PlannerStep } from \"../contracts/planner/planner-plan.type\";\nimport type {\n PlannerReport,\n PlannerResult,\n PlannerStepSnapshot,\n} from \"../contracts/planner/planner-result.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport { REPORT_SCHEMA_VERSION } from \"../contracts/result/base-report.type\";\nimport type { BaseResult } from \"../contracts/result/base-result.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { AIError } from \"../errors/ai-error\";\nimport { PlannerCancelledError } from \"../errors/planner-cancelled-error\";\nimport { PlannerFailedError } from \"../errors/planner-failed-error\";\nimport { PlannerPlanInvalidError } from \"../errors/planner-plan-invalid-error\";\nimport { SchemaValidationError } from \"../errors/schema-validation-error\";\nimport { accumulateCost } from \"../utils/compute-cost\";\nimport { generateRunId } from \"../utils/generate-run-id\";\nimport { stampReportLineage } from \"../utils/stamp-report-lineage\";\nimport { planSchema } from \"./plan-schema\";\n\n/**\n * Construction args for one {@link PlannerRun}. Carries everything the\n * factory resolved once (config, capability map, signature, planning\n * agent) plus the per-call goal and options.\n */\nexport type PlannerRunArgs<TOutput> = {\n config: PlannerConfig<TOutput>;\n capabilities: Map<string, PlannerCapability>;\n maxSteps: number;\n signature: string;\n planningAgent: AgentContract<unknown>;\n goal: string;\n options?: PlannerExecuteOptions<TOutput>;\n};\n\n/**\n * Per-call orchestration state for one `planner.execute()` invocation.\n *\n * **Role.** Owns the full bounded-v1 planning lifecycle across four\n * phases that share mutable accumulators: (1) ask the LLM to GENERATE a\n * plan, (2) execute each plan step through its capability's `execute()`,\n * (3) optionally validate the final output, (4) assemble the unified\n * {@link PlannerResult}. Instantiated fresh per call inside the factory\n * so the accumulators (`usage`, `children`, `executedSteps`) are never\n * shared across runs. Unexported — callers only ever see the plain\n * {@link PlannerResult}.\n *\n * **Composition, not a fork.** Plan generation runs through a normal\n * `agent.execute()`; each step runs through the capability's own\n * `executable.execute()`. The planner adds the plan-generation brain and\n * the ordered-dispatch loop on top of the existing executable machinery —\n * it does not reimplement agent or step internals.\n */\nexport class PlannerRun<TOutput> {\n private readonly runId: string;\n private readonly startedAt = new Date().toISOString();\n private readonly startPerf = performance.now();\n\n private readonly usage: Usage = { input: 0, output: 0, total: 0 };\n private readonly children: BaseReport[] = [];\n private readonly executedSteps: PlannerStepSnapshot[] = [];\n\n private plan?: PlannerPlan;\n private data?: TOutput;\n private error?: AIError;\n private cancelledAt?: string;\n\n public constructor(private readonly args: PlannerRunArgs<TOutput>) {\n this.runId = args.options?.runId ?? generateRunId(\"planner\");\n }\n\n /**\n * Run the planner end-to-end. Never throws on runtime failure —\n * generation errors, plan-validity errors, step failures, and\n * cancellation all surface on `result.error` with a narrowing\n * `report.status`.\n */\n public async run(): Promise<PlannerResult<TOutput>> {\n try {\n if (this.isAborted()) {\n this.markCancelled();\n return this.buildResult();\n }\n\n const plan = await this.generatePlan();\n\n if (this.error || !plan) {\n return this.buildResult();\n }\n\n this.plan = plan;\n\n await this.executePlan(plan);\n\n await this.finalizeOutput();\n } catch (caught) {\n this.error = this.toAIError(caught);\n }\n\n return this.buildResult();\n }\n\n /**\n * Phase 1 — ask the planning agent for a structured plan. The plan\n * schema (built from the live capability names) is supplied as the\n * agent's per-call `output`, so the model is steered to reference only\n * real capabilities. The planning trip's usage + report roll into the\n * planner's totals regardless of outcome.\n */\n private async generatePlan(): Promise<PlannerPlan | undefined> {\n const schema = planSchema([...this.args.capabilities.keys()], this.args.maxSteps);\n\n const result = await this.args.planningAgent.execute(this.buildPlanPrompt(), {\n output: schema as StandardSchemaV1<unknown>,\n placeholders: this.args.options?.placeholders,\n signal: this.args.options?.signal,\n sessionId: this.args.options?.sessionId,\n });\n\n this.absorb(result.usage, result.report);\n\n if (result.error) {\n // A schema rejection from the planning trip (e.g. an empty\n // `steps` array tripping the plan schema) is really an invalid\n // plan — re-wrap it into the typed planner contract so callers\n // branch on `PlannerPlanInvalidError` rather than the agent's raw\n // `SchemaValidationError`. Any other child error flows through\n // unchanged.\n this.error =\n result.error instanceof SchemaValidationError\n ? new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): the planner produced no usable plan`,\n { cause: result.error, context: { runId: this.runId } },\n )\n : result.error;\n return undefined;\n }\n\n const plan = result.data as PlannerPlan | undefined;\n\n if (!plan || !Array.isArray(plan.steps) || plan.steps.length === 0) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): the planner produced no usable plan`,\n { context: { runId: this.runId } },\n );\n return undefined;\n }\n\n const unknownStep = plan.steps.find((step) => !this.args.capabilities.has(step.capability));\n\n if (unknownStep) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): plan references unknown capability \"${unknownStep.capability}\"`,\n { context: { runId: this.runId, capability: unknownStep.capability } },\n );\n return undefined;\n }\n\n return plan;\n }\n\n /**\n * Phase 2 — execute the plan's steps strictly in order, threading each\n * completed step's output into the next step's input context. Stops at\n * the first step failure (its `error` becomes the run error) or when\n * the abort signal fires between steps. Steps beyond `maxSteps` are\n * recorded as `skipped` without running.\n */\n private async executePlan(plan: PlannerPlan): Promise<void> {\n const previousOutputs: string[] = [];\n\n for (let index = 0; index < plan.steps.length; index++) {\n const step = plan.steps[index] as PlannerStep;\n\n if (index >= this.args.maxSteps) {\n this.recordSkipped(index, step);\n continue;\n }\n\n if (this.isAborted()) {\n this.markCancelled();\n this.recordSkipped(index, step);\n continue;\n }\n\n const completed = await this.executeStep(index, step, previousOutputs);\n\n if (!completed) {\n // Step failed — record the remaining steps as skipped so the\n // report still describes the whole intended plan, then stop.\n for (let rest = index + 1; rest < plan.steps.length; rest++) {\n this.recordSkipped(rest, plan.steps[rest] as PlannerStep);\n }\n return;\n }\n }\n }\n\n /**\n * Dispatch one plan step through its capability's `executable.execute()`\n * and fold the outcome into the accumulators. Returns `true` when the\n * step completed, `false` when it failed (setting the run error).\n */\n private async executeStep(\n index: number,\n step: PlannerStep,\n previousOutputs: string[],\n ): Promise<boolean> {\n const capability = this.args.capabilities.get(step.capability) as PlannerCapability;\n const stepStart = performance.now();\n const startedAt = new Date().toISOString();\n const input = this.composeStepInput(step, previousOutputs);\n\n const result = await capability.executable.execute(input, {\n signal: this.args.options?.signal,\n sessionId: this.args.options?.sessionId,\n });\n\n const childReport = \"report\" in result ? (result.report as BaseReport) : undefined;\n this.absorb(result.usage, childReport);\n\n const output = this.extractOutput(result);\n const failed = result.error !== undefined;\n\n this.executedSteps.push({\n index,\n step,\n status: failed ? \"failed\" : \"completed\",\n output: failed ? undefined : output,\n error: result.error,\n startedAt,\n endedAt: new Date().toISOString(),\n duration: performance.now() - stepStart,\n usage: result.usage,\n childReport,\n });\n\n if (failed) {\n this.error = result.error;\n return false;\n }\n\n previousOutputs.push(this.stringifyOutput(step.capability, output));\n this.data = output as TOutput;\n\n return true;\n }\n\n /**\n * Phase 3 — when an `output` schema is configured (factory or per-call\n * override), validate the final completed step's output into typed\n * `result.data`. A validation failure replaces the run error and flips\n * the status to failed.\n */\n private async finalizeOutput(): Promise<void> {\n const schema = this.args.options?.output ?? this.args.config.output;\n\n if (!schema || this.error) {\n return;\n }\n\n if (this.data === undefined) {\n // An `output` schema is configured but the final completed step\n // produced nothing to validate — returning `{ data: undefined,\n // error: undefined, status: \"completed\" }` would be a silent\n // contract violation. Surface it as an invalid plan instead.\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): plan completed without producing output for the configured \\`output\\` schema`,\n { context: { runId: this.runId } },\n );\n return;\n }\n\n const validation = await schema[\"~standard\"].validate(this.data);\n\n if (validation.issues) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): final output failed validation`,\n {\n context: {\n runId: this.runId,\n issues: validation.issues.map((issue) => issue.message),\n },\n },\n );\n this.data = undefined;\n return;\n }\n\n this.data = validation.value as TOutput;\n }\n\n /**\n * Phase 4 — fold the accumulators into the planner's own\n * {@link PlannerReport} node and the final {@link PlannerResult}, then\n * stamp lineage across the whole subtree so every child shares this\n * run's root id.\n */\n private buildResult(): PlannerResult<TOutput> {\n const status = this.resolveStatus();\n\n const report: PlannerReport = {\n runId: this.runId,\n rootRunId: this.runId,\n name: this.args.config.name,\n version: this.args.config.version,\n type: \"planner\",\n status,\n startedAt: this.startedAt,\n endedAt: new Date().toISOString(),\n duration: performance.now() - this.startPerf,\n usage: this.usage,\n children: this.children,\n signature: this.args.signature,\n plan: this.plan,\n executedSteps: this.executedSteps,\n cancelledAt: this.cancelledAt,\n reportSchemaVersion: REPORT_SCHEMA_VERSION,\n };\n\n stampReportLineage(report, {\n rootRunId: this.runId,\n sessionId: this.args.options?.sessionId,\n });\n\n return {\n type: \"planner\",\n data: this.error ? undefined : this.data,\n error: this.error,\n usage: this.usage,\n report,\n };\n }\n\n /**\n * Resolve the terminal status from the accumulated outcome. Cancelled\n * wins over failed (an abort that also produced a step error still\n * reads as cancelled); failed wins over completed.\n */\n private resolveStatus(): PlannerReport[\"status\"] {\n if (this.cancelledAt !== undefined) {\n return \"cancelled\";\n }\n\n if (this.error) {\n return \"failed\";\n }\n\n return \"completed\";\n }\n\n /** Build the prompt handed to the planning agent — the user's goal. */\n private buildPlanPrompt(): string {\n return this.args.goal;\n }\n\n /**\n * Compose a step's effective input: the step's own `input`, prefixed\n * with a compact digest of every prior step's output so a downstream\n * capability can build on what ran before it. No prior output → the\n * step's raw input.\n */\n private composeStepInput(step: PlannerStep, previousOutputs: string[]): string {\n if (previousOutputs.length === 0) {\n return step.input;\n }\n\n return [\n \"Context from earlier steps:\",\n ...previousOutputs,\n \"\",\n `Task: ${step.input}`,\n ].join(\"\\n\");\n }\n\n /**\n * Pull the usable output off a capability's result. Prefers structured\n * `data` (agents/workflows with an `output` schema, tools), and falls\n * back to an agent's raw `text` when no structured data was produced —\n * the common case for a plain text-producing capability agent.\n */\n private extractOutput(result: BaseResult): unknown {\n const shaped = result as { data?: unknown; text?: unknown };\n\n if (shaped.data !== undefined) {\n return shaped.data;\n }\n\n if (typeof shaped.text === \"string\") {\n return shaped.text;\n }\n\n return undefined;\n }\n\n /** Serialize a capability output into a single context line for the next step. */\n private stringifyOutput(capability: string, output: unknown): string {\n if (output === undefined) {\n return `- ${capability}: (no output)`;\n }\n\n if (typeof output === \"string\") {\n return `- ${capability}: ${output}`;\n }\n\n return `- ${capability}: ${JSON.stringify(output)}`;\n }\n\n /** Push a `skipped` snapshot for a step the planner never dispatched. */\n private recordSkipped(index: number, step: PlannerStep): void {\n const now = new Date().toISOString();\n\n this.executedSteps.push({\n index,\n step,\n status: \"skipped\",\n startedAt: now,\n endedAt: now,\n duration: 0,\n usage: { input: 0, output: 0, total: 0 },\n });\n }\n\n /** Fold a child's usage + report node into the planner's accumulators. */\n private absorb(usage: Usage, report: BaseReport | undefined): void {\n this.mergeUsage(this.usage, usage);\n\n if (report) {\n this.children.push(report);\n }\n }\n\n /**\n * Add a child's usage into the running total. Mirrors the batch\n * primitive's rollup: scalar token channels sum directly, optional\n * sub-channels accumulate only when reported, and the cost breakdown\n * merges via {@link accumulateCost} so one unpriced child can't erase\n * priced siblings.\n */\n private mergeUsage(target: Usage, child: Usage): void {\n target.input += child.input;\n target.output += child.output;\n target.total += child.total;\n\n if (child.cachedTokens !== undefined) {\n target.cachedTokens = (target.cachedTokens ?? 0) + child.cachedTokens;\n }\n\n if (child.reasoningTokens !== undefined) {\n target.reasoningTokens = (target.reasoningTokens ?? 0) + child.reasoningTokens;\n }\n\n if (child.cacheWriteTokens !== undefined) {\n target.cacheWriteTokens = (target.cacheWriteTokens ?? 0) + child.cacheWriteTokens;\n }\n\n const mergedCost = accumulateCost(target.cost, child.cost);\n\n if (mergedCost !== undefined) {\n target.cost = mergedCost;\n }\n }\n\n /** Whether the caller's abort signal has fired. */\n private isAborted(): boolean {\n return this.args.options?.signal?.aborted === true;\n }\n\n /** Record a cancellation observation, setting the run error once. */\n private markCancelled(): void {\n if (this.cancelledAt !== undefined) {\n return;\n }\n\n this.cancelledAt = new Date().toISOString();\n\n const reason = this.args.options?.signal?.reason;\n\n this.error = new PlannerCancelledError(\n `ai.planner(\"${this.args.config.name}\"): run cancelled`,\n {\n cancelledAt: this.cancelledAt,\n reason: typeof reason === \"string\" ? reason : undefined,\n context: { runId: this.runId },\n },\n );\n }\n\n /** Normalize any thrown value into a typed {@link AIError}. */\n private toAIError(caught: unknown): AIError {\n if (caught instanceof AIError) {\n return caught;\n }\n\n const message = caught instanceof Error ? caught.message : String(caught);\n\n return new PlannerFailedError(`ai.planner(\"${this.args.config.name}\"): ${message}`, {\n cause: caught,\n context: { runId: this.runId },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner-run.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/planner/planner-run.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { PlannerCapability } from \"../contracts/planner/planner-capability.type\";\nimport type { PlannerConfig } from \"../contracts/planner/planner-config.type\";\nimport type {\n PlannerExecuteOptions,\n PlannerStepDirective,\n} from \"../contracts/planner/planner-execute-options.type\";\nimport type { PlannerPlan, PlannerStep } from \"../contracts/planner/planner-plan.type\";\nimport type {\n PlannerReport,\n PlannerResult,\n PlannerStepSnapshot,\n} from \"../contracts/planner/planner-result.type\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport { REPORT_SCHEMA_VERSION } from \"../contracts/result/base-report.type\";\nimport type { BaseResult } from \"../contracts/result/base-result.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { AIError } from \"../errors/ai-error\";\nimport { PlannerCancelledError } from \"../errors/planner-cancelled-error\";\nimport { PlannerFailedError } from \"../errors/planner-failed-error\";\nimport { PlannerPlanInvalidError } from \"../errors/planner-plan-invalid-error\";\nimport { SchemaValidationError } from \"../errors/schema-validation-error\";\nimport { notifyObservers } from \"../observe/resolve-observers\";\nimport { accumulateCost } from \"../utils/compute-cost\";\nimport { generateRunId } from \"../utils/generate-run-id\";\nimport { captureChildReport, withoutRunFrame } from \"../utils/run-context\";\nimport { stampReportLineage } from \"../utils/stamp-report-lineage\";\nimport type { DagNode, PlannerDag } from \"./dag-scheduler\";\nimport { buildDag, readyNodes, sinkNodes } from \"./dag-scheduler\";\nimport { planSchema } from \"./plan-schema\";\n\n/**\n * Construction args for one {@link PlannerRun}. Carries everything the\n * factory resolved once (config, capability map, signature, planning\n * agent) plus the per-call goal and options.\n */\nexport type PlannerRunArgs<TOutput> = {\n config: PlannerConfig<TOutput>;\n capabilities: Map<string, PlannerCapability>;\n maxSteps: number;\n signature: string;\n planningAgent: AgentContract<unknown>;\n goal: string;\n options?: PlannerExecuteOptions<TOutput>;\n};\n\n/**\n * Per-call orchestration state for one `planner.execute()` invocation.\n *\n * **Role.** Owns the full bounded-v1 planning lifecycle across four\n * phases that share mutable accumulators: (1) ask the LLM to GENERATE a\n * plan, (2) execute each plan step through its capability's `execute()`,\n * (3) optionally validate the final output, (4) assemble the unified\n * {@link PlannerResult}. Instantiated fresh per call inside the factory\n * so the accumulators (`usage`, `children`, `executedSteps`) are never\n * shared across runs. Unexported — callers only ever see the plain\n * {@link PlannerResult}.\n *\n * **Composition, not a fork.** Plan generation runs through a normal\n * `agent.execute()`; each step runs through the capability's own\n * `executable.execute()`. The planner adds the plan-generation brain and\n * the ordered-dispatch loop on top of the existing executable machinery —\n * it does not reimplement agent or step internals.\n */\nexport class PlannerRun<TOutput> {\n private readonly runId: string;\n private readonly startedAt = new Date().toISOString();\n private readonly startPerf = performance.now();\n\n private readonly usage: Usage = { input: 0, output: 0, total: 0 };\n private readonly children: BaseReport[] = [];\n private readonly executedSteps: PlannerStepSnapshot[] = [];\n\n private plan?: PlannerPlan;\n private data?: TOutput;\n private error?: AIError;\n private cancelledAt?: string;\n\n /** Set when `mode: \"plan-only\"` short-circuited before execution. */\n private awaitingApproval = false;\n\n /** How many times the plan has been regenerated mid-run (≤ maxReplans). */\n private replanCount = 0;\n\n public constructor(private readonly args: PlannerRunArgs<TOutput>) {\n this.runId = args.options?.runId ?? generateRunId(\"planner\");\n }\n\n /**\n * Run the planner end-to-end. Never throws on runtime failure —\n * generation errors, plan-validity errors, step failures, and\n * cancellation all surface on `result.error` with a narrowing\n * `report.status`.\n */\n public async run(): Promise<PlannerResult<TOutput>> {\n const result = await this.runPlan();\n\n // Route the planner's OWN report — the planning trip plus every\n // capability step already nest under it via `absorb`, so this single\n // call surfaces the whole tree as one trace. Mirrors agent/workflow:\n // `notifyObservers` self-routes a root run under observe-all (skipped\n // when nested, via the run-frame gate), then `captureChildReport`\n // auto-nests the planner under any enclosing orchestration run. Without\n // this, observe-all would only ever see the sub-agents as standalone\n // fragments — the planner itself never appeared.\n await notifyObservers(this.args.config.observe, result.report);\n captureChildReport(result.report);\n\n return result;\n }\n\n /**\n * Drive the planner lifecycle and return the built result WITHOUT\n * routing it — `run()` owns observer routing + auto-nesting so the\n * unified tree is emitted exactly once.\n */\n private async runPlan(): Promise<PlannerResult<TOutput>> {\n try {\n if (this.isAborted()) {\n this.markCancelled();\n return this.buildResult();\n }\n\n // Approval fork — an `approvedPlan` skips generation entirely; it is\n // still validated against the live capabilities so a stale plan\n // surfaces a typed PlannerPlanInvalidError rather than mis-dispatching.\n const plan = this.args.options?.approvedPlan ?? (await this.generatePlan());\n\n if (this.error || !plan) {\n return this.buildResult();\n }\n\n this.assertPlanValid(plan);\n\n if (this.error) {\n return this.buildResult();\n }\n\n this.plan = plan;\n\n // Plan-only mode — surface the validated plan for sign-off and execute\n // NOTHING. `approvedPlan` overrides this (execute the supplied plan),\n // mirroring the documented \"approvedPlan wins\" precedence.\n if (this.args.options?.mode === \"plan-only\" && !this.args.options?.approvedPlan) {\n this.awaitingApproval = true;\n return this.buildResult();\n }\n\n await this.executePlan(plan);\n\n await this.finalizeOutput();\n } catch (caught) {\n this.error = this.toAIError(caught);\n }\n\n return this.buildResult();\n }\n\n /**\n * Phase 1 — ask the planning agent for a structured plan. The plan\n * schema (built from the live capability names) is supplied as the\n * agent's per-call `output`, so the model is steered to reference only\n * real capabilities. The planning trip's usage + report roll into the\n * planner's totals regardless of outcome.\n *\n * `feedback` is set only on a RE-plan: the regenerated request is\n * seeded with the executed-step digest plus the caller's feedback so\n * the planner revises the remaining work rather than starting cold.\n */\n private async generatePlan(feedback?: string): Promise<PlannerPlan | undefined> {\n const schema = planSchema([...this.args.capabilities.keys()], this.args.maxSteps);\n\n // `withoutRunFrame` suppresses the planning trip's own self-routing:\n // `absorb` already folds its report into `this.children`, so without\n // this the trip would ALSO route as a standalone top-level trace under\n // observe-all. The planner routes the unified tree once, in `run()`.\n const result = await withoutRunFrame(() =>\n this.args.planningAgent.execute(this.buildPlanPrompt(feedback), {\n output: schema as StandardSchemaV1<unknown>,\n placeholders: this.args.options?.placeholders,\n signal: this.args.options?.signal,\n sessionId: this.args.options?.sessionId,\n }),\n );\n\n this.absorb(result.usage, result.report);\n\n if (result.error) {\n // A schema rejection from the planning trip (e.g. an empty\n // `steps` array tripping the plan schema) is really an invalid\n // plan — re-wrap it into the typed planner contract so callers\n // branch on `PlannerPlanInvalidError` rather than the agent's raw\n // `SchemaValidationError`. Any other child error flows through\n // unchanged.\n this.error =\n result.error instanceof SchemaValidationError\n ? new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): the planner produced no usable plan`,\n { cause: result.error, context: { runId: this.runId } },\n )\n : result.error;\n return undefined;\n }\n\n const plan = result.data as PlannerPlan | undefined;\n\n if (!plan || !Array.isArray(plan.steps) || plan.steps.length === 0) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): the planner produced no usable plan`,\n { context: { runId: this.runId } },\n );\n return undefined;\n }\n\n this.assertPlanValid(plan);\n\n if (this.error) {\n return undefined;\n }\n\n return plan;\n }\n\n /**\n * Shared plan-validity guard — used both for a freshly generated plan\n * and for a caller-supplied `approvedPlan`. Sets `this.error` to a\n * typed {@link PlannerPlanInvalidError} when the plan is empty or names\n * an unknown capability; a stale `approvedPlan` thus fails the same way\n * a hallucinated capability does, never silently mis-dispatching.\n */\n private assertPlanValid(plan: PlannerPlan): void {\n if (!Array.isArray(plan.steps) || plan.steps.length === 0) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): the planner produced no usable plan`,\n { context: { runId: this.runId } },\n );\n return;\n }\n\n const unknownStep = plan.steps.find((step) => !this.args.capabilities.has(step.capability));\n\n if (unknownStep) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): plan references unknown capability \"${unknownStep.capability}\"`,\n { context: { runId: this.runId, capability: unknownStep.capability } },\n );\n }\n }\n\n /**\n * Phase 2 — execute the plan. Branches on `config.dag`: the default is\n * the strict array-order sequential loop (byte-for-byte today's\n * behavior when neither `onStep` nor `replan` is configured); `dag:\n * true` schedules independent `dependsOn` branches in parallel.\n */\n private async executePlan(plan: PlannerPlan): Promise<void> {\n if (this.args.config.dag) {\n return this.executeDag(plan);\n }\n\n return this.executeSequential(plan);\n }\n\n /**\n * Sequential executor — the original strict array-order loop, threading\n * each completed step's output into the next step's input context.\n * Stops at the first step failure or when the abort signal fires\n * between steps; steps beyond `maxSteps` are recorded `skipped`.\n *\n * **Additive hooks (inert by default).** After each step settles it\n * fires the `onStep` directive hook; an `abort` directive stops the run\n * like a failure, and a `replan` directive (or, when `config.replan` is\n * set, an unhandled failure) regenerates the REMAINING plan instead of\n * aborting. With no `onStep` and no `replan`, the behavior is identical\n * to before.\n */\n private async executeSequential(plan: PlannerPlan): Promise<void> {\n const previousOutputs: string[] = [];\n let steps = plan.steps;\n let index = 0;\n\n while (index < steps.length) {\n const step = steps[index] as PlannerStep;\n\n if (index >= this.args.maxSteps) {\n this.recordSkipped(index, step);\n index++;\n continue;\n }\n\n if (this.isAborted()) {\n this.markCancelled();\n this.recordSkipped(index, step);\n index++;\n continue;\n }\n\n const completed = await this.executeStep(index, step, previousOutputs);\n\n const snapshot = this.snapshotFor(index);\n const directive = snapshot\n ? await this.resolveDirective(snapshot, plan, completed)\n : undefined;\n\n if (directive?.type === \"replan\") {\n const remaining = await this.regeneratePlan(directive.feedback);\n\n if (this.error || !remaining) {\n this.skipRest(steps, index + 1);\n return;\n }\n\n // Replace the remaining tail with the regenerated plan and restart\n // the cursor against it (executed steps already recorded stay put).\n // Each new step gets the executed-so-far digest as its context.\n steps = remaining.steps;\n index = 0;\n previousOutputs.length = 0;\n previousOutputs.push(...this.executedDigest());\n continue;\n }\n\n if (directive?.type === \"abort\") {\n // The hook (or an unhandled failure) asked to stop — record the\n // remaining steps as skipped so the report still describes the\n // whole intended plan, then stop.\n this.skipRest(steps, index + 1);\n return;\n }\n\n index++;\n }\n }\n\n /**\n * DAG executor — schedule independent `dependsOn` branches in parallel.\n *\n * Builds the DAG (cycle / unknown-id → `PlannerPlanInvalidError`),\n * then repeatedly computes the ready set (steps whose deps all\n * completed), dispatches up to `maxConcurrency` of them with\n * `Promise.all`, and feeds each step ONLY its dependencies' outputs. A\n * failed step blocks just its descendants (recorded `skipped`);\n * independent branches still settle. With an `output` schema set, the\n * final `data` is the topological SINK's output (multiple sinks → a\n * convergence error).\n */\n private async executeDag(plan: PlannerPlan): Promise<void> {\n const dag = buildDag(plan.steps, this.args.config.name);\n const maxConcurrency = Math.max(1, this.args.config.maxConcurrency ?? 4);\n\n const completed = new Set<string>();\n const done = new Set<string>();\n const outputs = new Map<string, string>();\n const rawOutputs = new Map<string, unknown>();\n let executedCount = 0;\n\n while (done.size < dag.nodes.length) {\n if (this.isAborted()) {\n this.markCancelled();\n this.skipDagRest(dag, done);\n return;\n }\n\n const ready = readyNodes(dag, completed, done);\n\n if (ready.length === 0) {\n // No node can advance — every remaining node transitively depends\n // on a failed/skipped ancestor. Record them skipped and stop.\n this.skipDagRest(dag, done);\n return;\n }\n\n const batch = ready.slice(0, maxConcurrency);\n\n const settled = await Promise.all(\n batch.map(async (node) => {\n // `maxSteps` truncation applies to the count of DISPATCHED steps.\n if (executedCount >= this.args.maxSteps) {\n this.recordSkipped(node.index, node.step);\n return { node, ran: false, completed: false };\n }\n\n executedCount++;\n // Feed this step ONLY its dependencies' output digests — the DAG\n // fix for the sequential loop's \"all prior outputs into every\n // step\" behavior. `executeStep` pushes into the array it is\n // given, so a fresh array per node keeps branches isolated.\n const previousOutputs = node.dependencies.map(\n (dependency) => outputs.get(dependency) as string,\n );\n const stepCompleted = await this.executeStep(\n node.index,\n node.step,\n previousOutputs,\n );\n\n if (stepCompleted) {\n // Read the raw output off the snapshot (NOT shared `this.data`,\n // which races under Promise.all) for both the dependent digest\n // and the eventual sink output.\n const rawOutput = this.snapshotFor(node.index)?.output;\n rawOutputs.set(node.id, rawOutput);\n outputs.set(node.id, this.stringifyOutput(node.step.capability, rawOutput));\n }\n\n return { node, ran: true, completed: stepCompleted };\n }),\n );\n\n for (const entry of settled) {\n done.add(entry.node.id);\n\n if (entry.completed) {\n completed.add(entry.node.id);\n }\n }\n\n // Fire the per-step hook for each settled step (in dispatch order).\n let replanFeedback: string | undefined;\n let shouldAbort = false;\n\n for (const entry of settled) {\n if (!entry.ran) {\n continue;\n }\n\n const snapshot = this.snapshotFor(entry.node.index);\n const directive = snapshot\n ? await this.resolveDirective(snapshot, plan, entry.completed)\n : undefined;\n\n if (directive?.type === \"replan\") {\n replanFeedback = directive.feedback;\n } else if (directive?.type === \"abort\") {\n shouldAbort = true;\n }\n }\n\n if (shouldAbort) {\n this.skipDagRest(dag, done);\n return;\n }\n\n if (replanFeedback !== undefined) {\n const remaining = await this.regeneratePlan(replanFeedback);\n\n if (this.error || !remaining) {\n this.skipDagRest(dag, done);\n return;\n }\n\n // Re-plan in DAG mode regenerates the remaining work as a fresh\n // (sequential) plan and runs it through the DAG scheduler again.\n return this.executeDag(remaining);\n }\n }\n\n this.finalizeDagOutput(dag, completed, rawOutputs);\n }\n\n /**\n * Dispatch one plan step through its capability's `executable.execute()`\n * and fold the outcome into the accumulators. Returns `true` when the\n * step completed, `false` when it failed (setting the run error).\n */\n private async executeStep(\n index: number,\n step: PlannerStep,\n previousOutputs: string[],\n ): Promise<boolean> {\n const capability = this.args.capabilities.get(step.capability) as PlannerCapability;\n const stepStart = performance.now();\n const startedAt = new Date().toISOString();\n const input = this.composeStepInput(step, previousOutputs);\n\n // `withoutRunFrame` keeps each capability step nested under the planner\n // only — `absorb` folds its report into `this.children`, so suppressing\n // its self-route prevents a duplicate standalone trace under observe-all.\n const result = await withoutRunFrame(() =>\n capability.executable.execute(input, {\n signal: this.args.options?.signal,\n sessionId: this.args.options?.sessionId,\n }),\n );\n\n const childReport = \"report\" in result ? (result.report as BaseReport) : undefined;\n this.absorb(result.usage, childReport);\n\n const output = this.extractOutput(result);\n const failed = result.error !== undefined;\n\n this.executedSteps.push({\n index,\n step,\n status: failed ? \"failed\" : \"completed\",\n output: failed ? undefined : output,\n error: result.error,\n startedAt,\n endedAt: new Date().toISOString(),\n duration: performance.now() - stepStart,\n usage: result.usage,\n childReport,\n });\n\n if (failed) {\n this.error = result.error;\n return false;\n }\n\n previousOutputs.push(this.stringifyOutput(step.capability, output));\n this.data = output as TOutput;\n\n return true;\n }\n\n /**\n * Resolve the steering directive for a just-settled step, shared by the\n * sequential and DAG executors. Fires the user's `onStep` hook, then\n * normalizes the result against the `replan` budget:\n *\n * - explicit `replan` directive — honored only when `config.replan` is\n * set and the budget remains; otherwise downgraded to `continue`.\n * - explicit `abort` — honored.\n * - failed step with no overriding directive — auto-`replan` when\n * `config.replan` is set and the budget remains (feedback = the step\n * error message), else `abort` (today's abort-on-first-failure).\n *\n * Returns `undefined` when the run should simply continue. A returned\n * `replan` directive has ALREADY consumed one unit of the replan budget.\n */\n private async resolveDirective(\n snapshot: PlannerStepSnapshot,\n plan: PlannerPlan,\n completed: boolean,\n ): Promise<PlannerStepDirective | undefined> {\n const hook = this.args.options?.onStep;\n const userDirective = hook ? await hook(snapshot, plan) : undefined;\n\n if (userDirective?.type === \"replan\") {\n if (this.canReplan()) {\n this.replanCount++;\n return userDirective;\n }\n\n // Replan requested but unavailable (no config or budget spent) — fall\n // through to the failure/continue defaults below.\n } else if (userDirective?.type === \"abort\") {\n return { type: \"abort\" };\n } else if (userDirective?.type === \"continue\") {\n return undefined;\n }\n\n if (!completed) {\n if (this.canReplan()) {\n this.replanCount++;\n return { type: \"replan\", feedback: snapshot.error?.message ?? \"step failed\" };\n }\n\n return { type: \"abort\" };\n }\n\n return undefined;\n }\n\n /** Whether a re-plan is configured and the budget has room. */\n private canReplan(): boolean {\n const replan = this.args.config.replan;\n\n return replan !== undefined && this.replanCount < replan.maxReplans;\n }\n\n /**\n * Re-ask the planning agent for a plan over the REMAINING work — a\n * second `generatePlan()` seeded with the executed-step digest plus the\n * caller's feedback. Reuses the exact `generatePlan` plumbing (same\n * schema, same `PlannerPlanInvalidError` handling), so a regenerated\n * plan that is empty or names an unknown capability fails identically.\n * The failed step's error is cleared so the regenerated plan runs\n * cleanly; a fresh failure (or exhausted budget) re-sets it.\n */\n private async regeneratePlan(feedback: string): Promise<PlannerPlan | undefined> {\n this.error = undefined;\n return this.generatePlan(feedback);\n }\n\n /**\n * The executed-so-far digest — one context line per completed step, in\n * execution order. Seeds the regenerated plan's first step so it builds\n * on what already ran.\n */\n private executedDigest(): string[] {\n return this.executedSteps\n .filter((snapshot) => snapshot.status === \"completed\")\n .map((snapshot) => this.stringifyOutput(snapshot.step.capability, snapshot.output));\n }\n\n /** The last-pushed snapshot for a given step index, if any. */\n private snapshotFor(index: number): PlannerStepSnapshot | undefined {\n for (let position = this.executedSteps.length - 1; position >= 0; position--) {\n const snapshot = this.executedSteps[position] as PlannerStepSnapshot;\n\n if (snapshot.index === index) {\n return snapshot;\n }\n }\n\n return undefined;\n }\n\n /** Record every step from `from` onward (in a flat array plan) as skipped. */\n private skipRest(steps: PlannerStep[], from: number): void {\n for (let rest = from; rest < steps.length; rest++) {\n this.recordSkipped(rest, steps[rest] as PlannerStep);\n }\n }\n\n /** Record every not-yet-`done` DAG node as skipped, in plan order. */\n private skipDagRest(dag: PlannerDag, done: ReadonlySet<string>): void {\n for (const node of dag.nodes) {\n if (!done.has(node.id)) {\n this.recordSkipped(node.index, node.step);\n }\n }\n }\n\n /**\n * Set `this.data` from the DAG's topological sink for a configured\n * `output` schema. \"Last completed step\" is meaningless under\n * parallelism, so the sink (the step nothing depends on) is the\n * unambiguous final output. Multiple sinks while an `output` schema is\n * set is a convergence error — a typed `PlannerPlanInvalidError`.\n */\n private finalizeDagOutput(\n dag: PlannerDag,\n completed: ReadonlySet<string>,\n rawOutputs: Map<string, unknown>,\n ): void {\n const schema = this.args.options?.output ?? this.args.config.output;\n\n if (!schema || this.error) {\n return;\n }\n\n const sinks = sinkNodes(dag).filter((node) => completed.has(node.id));\n\n if (sinks.length > 1) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): DAG has multiple sinks but an \\`output\\` schema is set — the plan must converge to a single final step`,\n { context: { runId: this.runId, sinks: sinks.map((node) => node.id) } },\n );\n this.data = undefined;\n return;\n }\n\n const sink = sinks[0] as DagNode | undefined;\n this.data = (sink ? rawOutputs.get(sink.id) : undefined) as TOutput | undefined;\n }\n\n /**\n * Phase 3 — when an `output` schema is configured (factory or per-call\n * override), validate the final completed step's output into typed\n * `result.data`. A validation failure replaces the run error and flips\n * the status to failed.\n */\n private async finalizeOutput(): Promise<void> {\n const schema = this.args.options?.output ?? this.args.config.output;\n\n if (!schema || this.error) {\n return;\n }\n\n if (this.data === undefined) {\n // An `output` schema is configured but the final completed step\n // produced nothing to validate — returning `{ data: undefined,\n // error: undefined, status: \"completed\" }` would be a silent\n // contract violation. Surface it as an invalid plan instead.\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): plan completed without producing output for the configured \\`output\\` schema`,\n { context: { runId: this.runId } },\n );\n return;\n }\n\n const validation = await schema[\"~standard\"].validate(this.data);\n\n if (validation.issues) {\n this.error = new PlannerPlanInvalidError(\n `ai.planner(\"${this.args.config.name}\"): final output failed validation`,\n {\n context: {\n runId: this.runId,\n issues: validation.issues.map((issue) => issue.message),\n },\n },\n );\n this.data = undefined;\n return;\n }\n\n this.data = validation.value as TOutput;\n }\n\n /**\n * Phase 4 — fold the accumulators into the planner's own\n * {@link PlannerReport} node and the final {@link PlannerResult}, then\n * stamp lineage across the whole subtree so every child shares this\n * run's root id.\n */\n private buildResult(): PlannerResult<TOutput> {\n const status = this.resolveStatus();\n\n const report: PlannerReport = {\n runId: this.runId,\n rootRunId: this.runId,\n name: this.args.config.name,\n version: this.args.config.version,\n type: \"planner\",\n status,\n // Stamp the terminal error so the observe path surfaces it on the\n // planner span (no result envelope reaches an observer). Absent on\n // a completed run.\n ...(this.error ? { error: this.error } : {}),\n startedAt: this.startedAt,\n endedAt: new Date().toISOString(),\n duration: performance.now() - this.startPerf,\n usage: this.usage,\n children: this.children,\n signature: this.args.signature,\n plan: this.plan,\n executedSteps: this.executedSteps,\n cancelledAt: this.cancelledAt,\n reportSchemaVersion: REPORT_SCHEMA_VERSION,\n };\n\n stampReportLineage(report, {\n rootRunId: this.runId,\n sessionId: this.args.options?.sessionId,\n });\n\n const result: PlannerResult<TOutput> = {\n type: \"planner\",\n data: this.error ? undefined : this.data,\n error: this.error,\n usage: this.usage,\n report,\n };\n\n // Plan-only mode surfaces the validated plan WITHOUT execution so the\n // caller can sign off and re-run with `approvedPlan`.\n if (this.awaitingApproval) {\n result.plan = this.plan;\n }\n\n return result;\n }\n\n /**\n * Resolve the terminal status from the accumulated outcome.\n * `awaiting-approval` (plan-only short-circuit) wins over everything —\n * nothing executed, so neither cancellation nor error applies.\n * Otherwise cancelled wins over failed (an abort that also produced a\n * step error still reads as cancelled); failed wins over completed.\n */\n private resolveStatus(): PlannerReport[\"status\"] {\n if (this.awaitingApproval) {\n return \"awaiting-approval\";\n }\n\n if (this.cancelledAt !== undefined) {\n return \"cancelled\";\n }\n\n if (this.error) {\n return \"failed\";\n }\n\n return \"completed\";\n }\n\n /**\n * Build the prompt handed to the planning agent. On the first pass this\n * is just the user's goal (byte-for-byte unchanged). On a RE-plan it\n * prepends the executed-step digest and the steering feedback so the\n * planner revises the remaining work.\n */\n private buildPlanPrompt(feedback?: string): string {\n if (feedback === undefined) {\n return this.args.goal;\n }\n\n const digest = this.executedDigest();\n const sections: string[] = [`Goal: ${this.args.goal}`, \"\"];\n\n if (digest.length > 0) {\n sections.push(\"Steps already completed:\", ...digest, \"\");\n }\n\n sections.push(\n `Feedback requiring a revised plan: ${feedback}`,\n \"\",\n \"Produce a plan for the REMAINING work only.\",\n );\n\n return sections.join(\"\\n\");\n }\n\n /**\n * Compose a step's effective input: the step's own `input`, prefixed\n * with a compact digest of every prior step's output so a downstream\n * capability can build on what ran before it. No prior output → the\n * step's raw input.\n */\n private composeStepInput(step: PlannerStep, previousOutputs: string[]): string {\n if (previousOutputs.length === 0) {\n return step.input;\n }\n\n return [\n \"Context from earlier steps:\",\n ...previousOutputs,\n \"\",\n `Task: ${step.input}`,\n ].join(\"\\n\");\n }\n\n /**\n * Pull the usable output off a capability's result. Prefers structured\n * `data` (agents/workflows with an `output` schema, tools), and falls\n * back to an agent's raw `text` when no structured data was produced —\n * the common case for a plain text-producing capability agent.\n */\n private extractOutput(result: BaseResult): unknown {\n const shaped = result as { data?: unknown; text?: unknown };\n\n if (shaped.data !== undefined) {\n return shaped.data;\n }\n\n if (typeof shaped.text === \"string\") {\n return shaped.text;\n }\n\n return undefined;\n }\n\n /** Serialize a capability output into a single context line for the next step. */\n private stringifyOutput(capability: string, output: unknown): string {\n if (output === undefined) {\n return `- ${capability}: (no output)`;\n }\n\n if (typeof output === \"string\") {\n return `- ${capability}: ${output}`;\n }\n\n return `- ${capability}: ${JSON.stringify(output)}`;\n }\n\n /** Push a `skipped` snapshot for a step the planner never dispatched. */\n private recordSkipped(index: number, step: PlannerStep): void {\n const now = new Date().toISOString();\n\n this.executedSteps.push({\n index,\n step,\n status: \"skipped\",\n startedAt: now,\n endedAt: now,\n duration: 0,\n usage: { input: 0, output: 0, total: 0 },\n });\n }\n\n /** Fold a child's usage + report node into the planner's accumulators. */\n private absorb(usage: Usage, report: BaseReport | undefined): void {\n this.mergeUsage(this.usage, usage);\n\n if (report) {\n this.children.push(report);\n }\n }\n\n /**\n * Add a child's usage into the running total. Mirrors the batch\n * primitive's rollup: scalar token channels sum directly, optional\n * sub-channels accumulate only when reported, and the cost breakdown\n * merges via {@link accumulateCost} so one unpriced child can't erase\n * priced siblings.\n */\n private mergeUsage(target: Usage, child: Usage): void {\n target.input += child.input;\n target.output += child.output;\n target.total += child.total;\n\n if (child.cachedTokens !== undefined) {\n target.cachedTokens = (target.cachedTokens ?? 0) + child.cachedTokens;\n }\n\n if (child.reasoningTokens !== undefined) {\n target.reasoningTokens = (target.reasoningTokens ?? 0) + child.reasoningTokens;\n }\n\n if (child.cacheWriteTokens !== undefined) {\n target.cacheWriteTokens = (target.cacheWriteTokens ?? 0) + child.cacheWriteTokens;\n }\n\n const mergedCost = accumulateCost(target.cost, child.cost);\n\n if (mergedCost !== undefined) {\n target.cost = mergedCost;\n }\n }\n\n /** Whether the caller's abort signal has fired. */\n private isAborted(): boolean {\n return this.args.options?.signal?.aborted === true;\n }\n\n /** Record a cancellation observation, setting the run error once. */\n private markCancelled(): void {\n if (this.cancelledAt !== undefined) {\n return;\n }\n\n this.cancelledAt = new Date().toISOString();\n\n const reason = this.args.options?.signal?.reason;\n\n this.error = new PlannerCancelledError(\n `ai.planner(\"${this.args.config.name}\"): run cancelled`,\n {\n cancelledAt: this.cancelledAt,\n reason: typeof reason === \"string\" ? reason : undefined,\n context: { runId: this.runId },\n },\n );\n }\n\n /** Normalize any thrown value into a typed {@link AIError}. */\n private toAIError(caught: unknown): AIError {\n if (caught instanceof AIError) {\n return caught;\n }\n\n const message = caught instanceof Error ? caught.message : String(caught);\n\n return new PlannerFailedError(`ai.planner(\"${this.args.config.name}\"): ${message}`, {\n cause: caught,\n context: { runId: this.runId },\n });\n }\n}\n"],"mappings":"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"}
@@ -80,7 +80,7 @@ function planner(config) {
80
80
  */
81
81
  function resolvePlanningAgent(config, maxSteps) {
82
82
  if (config.planner) return config.planner;
83
- const systemPrompt = buildPlanSystemPrompt(config.capabilities, maxSteps, config.systemPrompt);
83
+ const systemPrompt = buildPlanSystemPrompt(config.capabilities, maxSteps, config.systemPrompt, config.dag === true);
84
84
  return agent({
85
85
  name: `${config.name}-planner`,
86
86
  description: "Generates an ordered execution plan over the planner's capabilities.",