@warlock.js/ai 4.4.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 (535) hide show
  1. package/CHANGELOG.md +52 -55
  2. package/cjs/index.cjs +221 -14147
  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 +8 -0
  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/supervisor-result.type.d.mts +14 -2
  75. package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
  76. package/esm/contracts/result/workflow-result.type.d.mts +2 -1
  77. package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
  78. package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
  79. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  80. package/esm/contracts/system-prompt.contract.d.mts +103 -1
  81. package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
  82. package/esm/contracts/team/index.d.mts +1 -0
  83. package/esm/contracts/team/team-config.type.d.mts +127 -0
  84. package/esm/contracts/team/team-config.type.d.mts.map +1 -0
  85. package/esm/contracts/tool.contract.d.mts +4 -2
  86. package/esm/contracts/tool.contract.d.mts.map +1 -1
  87. package/esm/contracts/workflow/step.contract.d.mts +30 -5
  88. package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
  89. package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
  90. package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
  91. package/esm/errors/error-code.type.d.mts +1 -1
  92. package/esm/errors/index.d.mts +1 -0
  93. package/esm/errors/index.mjs +1 -0
  94. package/esm/errors/outbound-policy-error.d.mts +27 -0
  95. package/esm/errors/outbound-policy-error.d.mts.map +1 -0
  96. package/esm/errors/outbound-policy-error.mjs +32 -0
  97. package/esm/errors/outbound-policy-error.mjs.map +1 -0
  98. package/esm/eval/dataset.d.mts +28 -0
  99. package/esm/eval/dataset.d.mts.map +1 -0
  100. package/esm/eval/dataset.mjs +112 -0
  101. package/esm/eval/dataset.mjs.map +1 -0
  102. package/esm/eval/dataset.type.d.mts +53 -0
  103. package/esm/eval/dataset.type.d.mts.map +1 -0
  104. package/esm/eval/eval-runner.d.mts.map +1 -1
  105. package/esm/eval/eval-runner.mjs +16 -2
  106. package/esm/eval/eval-runner.mjs.map +1 -1
  107. package/esm/eval/index.d.mts +20 -1
  108. package/esm/eval/index.d.mts.map +1 -1
  109. package/esm/eval/index.mjs +20 -2
  110. package/esm/eval/index.mjs.map +1 -1
  111. package/esm/eval/regression.d.mts +30 -0
  112. package/esm/eval/regression.d.mts.map +1 -0
  113. package/esm/eval/regression.mjs +51 -0
  114. package/esm/eval/regression.mjs.map +1 -0
  115. package/esm/eval/report-json.d.mts +30 -0
  116. package/esm/eval/report-json.d.mts.map +1 -0
  117. package/esm/eval/report-json.mjs +33 -0
  118. package/esm/eval/report-json.mjs.map +1 -0
  119. package/esm/eval/report-junit.d.mts +22 -0
  120. package/esm/eval/report-junit.d.mts.map +1 -0
  121. package/esm/eval/report-junit.mjs +60 -0
  122. package/esm/eval/report-junit.mjs.map +1 -0
  123. package/esm/guard/contracts/guard-options.type.d.mts +165 -0
  124. package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
  125. package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
  126. package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
  127. package/esm/guard/contracts/index.d.mts +4 -0
  128. package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
  129. package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
  130. package/esm/guard/contracts/verdict.type.d.mts +76 -0
  131. package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
  132. package/esm/guard/detectors/index.d.mts +4 -0
  133. package/esm/guard/detectors/index.mjs +6 -0
  134. package/esm/guard/detectors/injection.d.mts +34 -0
  135. package/esm/guard/detectors/injection.d.mts.map +1 -0
  136. package/esm/guard/detectors/injection.mjs +254 -0
  137. package/esm/guard/detectors/injection.mjs.map +1 -0
  138. package/esm/guard/detectors/moderation.d.mts +32 -0
  139. package/esm/guard/detectors/moderation.d.mts.map +1 -0
  140. package/esm/guard/detectors/moderation.mjs +134 -0
  141. package/esm/guard/detectors/moderation.mjs.map +1 -0
  142. package/esm/guard/detectors/pii.d.mts +41 -0
  143. package/esm/guard/detectors/pii.d.mts.map +1 -0
  144. package/esm/guard/detectors/pii.mjs +199 -0
  145. package/esm/guard/detectors/pii.mjs.map +1 -0
  146. package/esm/guard/detectors/topic.d.mts +29 -0
  147. package/esm/guard/detectors/topic.d.mts.map +1 -0
  148. package/esm/guard/detectors/topic.mjs +99 -0
  149. package/esm/guard/detectors/topic.mjs.map +1 -0
  150. package/esm/guard/errors.d.mts +12 -0
  151. package/esm/guard/errors.d.mts.map +1 -0
  152. package/esm/guard/errors.mjs +18 -0
  153. package/esm/guard/errors.mjs.map +1 -0
  154. package/esm/guard/guard.d.mts +67 -0
  155. package/esm/guard/guard.d.mts.map +1 -0
  156. package/esm/guard/guard.mjs +209 -0
  157. package/esm/guard/guard.mjs.map +1 -0
  158. package/esm/guard/guardrail.d.mts +39 -0
  159. package/esm/guard/guardrail.d.mts.map +1 -0
  160. package/esm/guard/guardrail.mjs +22 -0
  161. package/esm/guard/guardrail.mjs.map +1 -0
  162. package/esm/human/contracts/approval.type.d.mts +154 -0
  163. package/esm/human/contracts/approval.type.d.mts.map +1 -0
  164. package/esm/human/contracts/human-approval.type.d.mts +38 -0
  165. package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
  166. package/esm/human/contracts/index.d.mts +4 -0
  167. package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
  168. package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
  169. package/esm/human/contracts/resume.type.d.mts +77 -0
  170. package/esm/human/contracts/resume.type.d.mts.map +1 -0
  171. package/esm/human/errors.d.mts +84 -0
  172. package/esm/human/errors.d.mts.map +1 -0
  173. package/esm/human/errors.mjs +60 -0
  174. package/esm/human/errors.mjs.map +1 -0
  175. package/esm/human/human-approval.d.mts +57 -0
  176. package/esm/human/human-approval.d.mts.map +1 -0
  177. package/esm/human/human-approval.mjs +170 -0
  178. package/esm/human/human-approval.mjs.map +1 -0
  179. package/esm/human/policy.d.mts +55 -0
  180. package/esm/human/policy.d.mts.map +1 -0
  181. package/esm/human/policy.mjs +67 -0
  182. package/esm/human/policy.mjs.map +1 -0
  183. package/esm/human/register.mjs +37 -0
  184. package/esm/human/register.mjs.map +1 -0
  185. package/esm/human/resume-seed.mjs +53 -0
  186. package/esm/human/resume-seed.mjs.map +1 -0
  187. package/esm/human/resume.d.mts +54 -0
  188. package/esm/human/resume.d.mts.map +1 -0
  189. package/esm/human/resume.mjs +121 -0
  190. package/esm/human/resume.mjs.map +1 -0
  191. package/esm/human/stores/index.mjs +5 -0
  192. package/esm/human/stores/memory.d.mts +30 -0
  193. package/esm/human/stores/memory.d.mts.map +1 -0
  194. package/esm/human/stores/memory.mjs +91 -0
  195. package/esm/human/stores/memory.mjs.map +1 -0
  196. package/esm/human/stores/pg.d.mts +59 -0
  197. package/esm/human/stores/pg.d.mts.map +1 -0
  198. package/esm/human/stores/pg.mjs +220 -0
  199. package/esm/human/stores/pg.mjs.map +1 -0
  200. package/esm/human/stores/redis.d.mts +56 -0
  201. package/esm/human/stores/redis.d.mts.map +1 -0
  202. package/esm/human/stores/redis.mjs +201 -0
  203. package/esm/human/stores/redis.mjs.map +1 -0
  204. package/esm/index.d.mts +113 -22
  205. package/esm/index.mjs +82 -11
  206. package/esm/middleware/builtins/budget.mjs +6 -2
  207. package/esm/middleware/builtins/budget.mjs.map +1 -1
  208. package/esm/middleware/utils/extract-user-text.d.mts +8 -1
  209. package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
  210. package/esm/middleware/utils/extract-user-text.mjs +8 -1
  211. package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
  212. package/esm/object-stream/index.d.mts +2 -0
  213. package/esm/object-stream/index.mjs +4 -0
  214. package/esm/object-stream/parse-partial-json.d.mts +22 -0
  215. package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
  216. package/esm/object-stream/parse-partial-json.mjs +78 -0
  217. package/esm/object-stream/parse-partial-json.mjs.map +1 -0
  218. package/esm/object-stream/stream-object.d.mts +68 -0
  219. package/esm/object-stream/stream-object.d.mts.map +1 -0
  220. package/esm/object-stream/stream-object.mjs +104 -0
  221. package/esm/object-stream/stream-object.mjs.map +1 -0
  222. package/esm/observe/index.mjs +4 -0
  223. package/esm/observe/observer-registry.d.mts +30 -0
  224. package/esm/observe/observer-registry.d.mts.map +1 -0
  225. package/esm/observe/observer-registry.mjs +51 -0
  226. package/esm/observe/observer-registry.mjs.map +1 -0
  227. package/esm/observe/observer.contract.d.mts +40 -0
  228. package/esm/observe/observer.contract.d.mts.map +1 -0
  229. package/esm/observe/resolve-observers.d.mts +40 -0
  230. package/esm/observe/resolve-observers.d.mts.map +1 -0
  231. package/esm/observe/resolve-observers.mjs +73 -0
  232. package/esm/observe/resolve-observers.mjs.map +1 -0
  233. package/esm/orchestrator/execution.d.mts.map +1 -1
  234. package/esm/orchestrator/execution.mjs +5 -2
  235. package/esm/orchestrator/execution.mjs.map +1 -1
  236. package/esm/orchestrator/index.d.mts +1 -0
  237. package/esm/orchestrator/index.mjs +1 -0
  238. package/esm/orchestrator/orchestrator.d.mts.map +1 -1
  239. package/esm/orchestrator/orchestrator.mjs +39 -6
  240. package/esm/orchestrator/orchestrator.mjs.map +1 -1
  241. package/esm/orchestrator/session-lock.d.mts +25 -0
  242. package/esm/orchestrator/session-lock.d.mts.map +1 -0
  243. package/esm/orchestrator/session-lock.mjs +83 -0
  244. package/esm/orchestrator/session-lock.mjs.map +1 -0
  245. package/esm/planner/dag-scheduler.mjs +97 -0
  246. package/esm/planner/dag-scheduler.mjs.map +1 -0
  247. package/esm/planner/plan-prompt.d.mts +1 -1
  248. package/esm/planner/plan-prompt.d.mts.map +1 -1
  249. package/esm/planner/plan-prompt.mjs +2 -1
  250. package/esm/planner/plan-prompt.mjs.map +1 -1
  251. package/esm/planner/planner-run.d.mts.map +1 -1
  252. package/esm/planner/planner-run.mjs +300 -29
  253. package/esm/planner/planner-run.mjs.map +1 -1
  254. package/esm/planner/planner.mjs +1 -1
  255. package/esm/planner/planner.mjs.map +1 -1
  256. package/esm/prompt/errors.d.mts +57 -0
  257. package/esm/prompt/errors.d.mts.map +1 -0
  258. package/esm/prompt/errors.mjs +73 -0
  259. package/esm/prompt/errors.mjs.map +1 -0
  260. package/esm/prompt/index.d.mts +3 -0
  261. package/esm/prompt/index.mjs +4 -0
  262. package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
  263. package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
  264. package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
  265. package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
  266. package/esm/prompt/prompt-validate.mjs +170 -0
  267. package/esm/prompt/prompt-validate.mjs.map +1 -0
  268. package/esm/prompt/prompt.d.mts +54 -0
  269. package/esm/prompt/prompt.d.mts.map +1 -0
  270. package/esm/prompt/prompt.mjs +218 -0
  271. package/esm/prompt/prompt.mjs.map +1 -0
  272. package/esm/prompt/prompt.type.d.mts +174 -0
  273. package/esm/prompt/prompt.type.d.mts.map +1 -0
  274. package/esm/prompts/index.d.mts +3 -0
  275. package/esm/prompts/index.mjs +3 -0
  276. package/esm/prompts/prompts-manager.contract.d.mts +154 -0
  277. package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
  278. package/esm/prompts/prompts-manager.d.mts +38 -0
  279. package/esm/prompts/prompts-manager.d.mts.map +1 -0
  280. package/esm/prompts/prompts-manager.mjs +410 -0
  281. package/esm/prompts/prompts-manager.mjs.map +1 -0
  282. package/esm/prompts/prompts-manager.type.d.mts +172 -0
  283. package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
  284. package/esm/prompts/prompts-validate.mjs +200 -0
  285. package/esm/prompts/prompts-validate.mjs.map +1 -0
  286. package/esm/rag/as-tool.mjs +48 -0
  287. package/esm/rag/as-tool.mjs.map +1 -0
  288. package/esm/rag/chunk/chunk.d.mts +24 -0
  289. package/esm/rag/chunk/chunk.d.mts.map +1 -0
  290. package/esm/rag/chunk/chunk.mjs +44 -0
  291. package/esm/rag/chunk/chunk.mjs.map +1 -0
  292. package/esm/rag/chunk/fixed.mjs +32 -0
  293. package/esm/rag/chunk/fixed.mjs.map +1 -0
  294. package/esm/rag/chunk/markdown.mjs +75 -0
  295. package/esm/rag/chunk/markdown.mjs.map +1 -0
  296. package/esm/rag/chunk/recursive.mjs +132 -0
  297. package/esm/rag/chunk/recursive.mjs.map +1 -0
  298. package/esm/rag/chunk/sentence.mjs +73 -0
  299. package/esm/rag/chunk/sentence.mjs.map +1 -0
  300. package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
  301. package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
  302. package/esm/rag/contracts/citation.type.d.mts +35 -0
  303. package/esm/rag/contracts/citation.type.d.mts.map +1 -0
  304. package/esm/rag/contracts/index.d.mts +4 -0
  305. package/esm/rag/contracts/rag-config.type.d.mts +68 -0
  306. package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
  307. package/esm/rag/contracts/rag-document.type.d.mts +21 -0
  308. package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
  309. package/esm/rag/hybrid/bm25.d.mts +23 -0
  310. package/esm/rag/hybrid/bm25.d.mts.map +1 -0
  311. package/esm/rag/hybrid/bm25.mjs +51 -0
  312. package/esm/rag/hybrid/bm25.mjs.map +1 -0
  313. package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
  314. package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
  315. package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
  316. package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
  317. package/esm/rag/hybrid/rrf.d.mts +25 -0
  318. package/esm/rag/hybrid/rrf.d.mts.map +1 -0
  319. package/esm/rag/hybrid/rrf.mjs +30 -0
  320. package/esm/rag/hybrid/rrf.mjs.map +1 -0
  321. package/esm/rag/index.d.mts +15 -0
  322. package/esm/rag/index.mjs +11 -0
  323. package/esm/rag/rag.d.mts +38 -0
  324. package/esm/rag/rag.d.mts.map +1 -0
  325. package/esm/rag/rag.mjs +126 -0
  326. package/esm/rag/rag.mjs.map +1 -0
  327. package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
  328. package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
  329. package/esm/rag/rerank/keyword-reranker.mjs +58 -0
  330. package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
  331. package/esm/rag/rerank/llm-reranker.d.mts +36 -0
  332. package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
  333. package/esm/rag/rerank/llm-reranker.mjs +85 -0
  334. package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
  335. package/esm/rag/rerank/reranker.contract.d.mts +28 -0
  336. package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
  337. package/esm/rag/retrieve.mjs +68 -0
  338. package/esm/rag/retrieve.mjs.map +1 -0
  339. package/esm/rag/store/cache-vector-store.d.mts +27 -0
  340. package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
  341. package/esm/rag/store/cache-vector-store.mjs +48 -0
  342. package/esm/rag/store/cache-vector-store.mjs.map +1 -0
  343. package/esm/rag/store/vector-store.contract.d.mts +38 -0
  344. package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
  345. package/esm/rag/transforms/multi-query.d.mts +27 -0
  346. package/esm/rag/transforms/multi-query.d.mts.map +1 -0
  347. package/esm/rag/transforms/multi-query.mjs +41 -0
  348. package/esm/rag/transforms/multi-query.mjs.map +1 -0
  349. package/esm/security/index.mjs +5 -0
  350. package/esm/security/outbound-policy.d.mts +46 -0
  351. package/esm/security/outbound-policy.d.mts.map +1 -0
  352. package/esm/security/outbound-policy.mjs +187 -0
  353. package/esm/security/outbound-policy.mjs.map +1 -0
  354. package/esm/security/outbound-policy.type.d.mts +74 -0
  355. package/esm/security/outbound-policy.type.d.mts.map +1 -0
  356. package/esm/security/private-ip.d.mts +15 -0
  357. package/esm/security/private-ip.d.mts.map +1 -0
  358. package/esm/security/private-ip.mjs +48 -0
  359. package/esm/security/private-ip.mjs.map +1 -0
  360. package/esm/security/redact.d.mts +59 -0
  361. package/esm/security/redact.d.mts.map +1 -0
  362. package/esm/security/redact.mjs +122 -0
  363. package/esm/security/redact.mjs.map +1 -0
  364. package/esm/serve/serve.d.mts +50 -0
  365. package/esm/serve/serve.d.mts.map +1 -0
  366. package/esm/serve/serve.mjs +90 -0
  367. package/esm/serve/serve.mjs.map +1 -0
  368. package/esm/serve/sse.d.mts +20 -0
  369. package/esm/serve/sse.d.mts.map +1 -0
  370. package/esm/serve/sse.mjs +25 -0
  371. package/esm/serve/sse.mjs.map +1 -0
  372. package/esm/serve/stream-to-sse.d.mts +29 -0
  373. package/esm/serve/stream-to-sse.d.mts.map +1 -0
  374. package/esm/serve/stream-to-sse.mjs +37 -0
  375. package/esm/serve/stream-to-sse.mjs.map +1 -0
  376. package/esm/skills/catalog.d.mts +49 -0
  377. package/esm/skills/catalog.d.mts.map +1 -0
  378. package/esm/skills/catalog.mjs +140 -0
  379. package/esm/skills/catalog.mjs.map +1 -0
  380. package/esm/skills/contracts/skill-record.type.d.mts +37 -0
  381. package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
  382. package/esm/skills/contracts/skills-config.type.d.mts +108 -0
  383. package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
  384. package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
  385. package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
  386. package/esm/skills/contracts/skills.contract.d.mts +43 -0
  387. package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
  388. package/esm/skills/index.d.mts +16 -0
  389. package/esm/skills/index.mjs +14 -0
  390. package/esm/skills/load-skill-tool.d.mts +38 -0
  391. package/esm/skills/load-skill-tool.d.mts.map +1 -0
  392. package/esm/skills/load-skill-tool.mjs +65 -0
  393. package/esm/skills/load-skill-tool.mjs.map +1 -0
  394. package/esm/skills/review-gate.d.mts +33 -0
  395. package/esm/skills/review-gate.d.mts.map +1 -0
  396. package/esm/skills/review-gate.mjs +60 -0
  397. package/esm/skills/review-gate.mjs.map +1 -0
  398. package/esm/skills/save-skill-tool.d.mts +39 -0
  399. package/esm/skills/save-skill-tool.d.mts.map +1 -0
  400. package/esm/skills/save-skill-tool.mjs +65 -0
  401. package/esm/skills/save-skill-tool.mjs.map +1 -0
  402. package/esm/skills/skills.d.mts +33 -0
  403. package/esm/skills/skills.d.mts.map +1 -0
  404. package/esm/skills/skills.mjs +109 -0
  405. package/esm/skills/skills.mjs.map +1 -0
  406. package/esm/skills/sources/directory-source.d.mts +19 -0
  407. package/esm/skills/sources/directory-source.d.mts.map +1 -0
  408. package/esm/skills/sources/directory-source.mjs +108 -0
  409. package/esm/skills/sources/directory-source.mjs.map +1 -0
  410. package/esm/skills/sources/index.d.mts +18 -0
  411. package/esm/skills/sources/index.d.mts.map +1 -0
  412. package/esm/skills/sources/index.mjs +27 -0
  413. package/esm/skills/sources/index.mjs.map +1 -0
  414. package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
  415. package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
  416. package/esm/skills/sources/parse-frontmatter.mjs +46 -0
  417. package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
  418. package/esm/skills/sources/store-source.d.mts +14 -0
  419. package/esm/skills/sources/store-source.d.mts.map +1 -0
  420. package/esm/skills/sources/store-source.mjs +15 -0
  421. package/esm/skills/sources/store-source.mjs.map +1 -0
  422. package/esm/skills/sources/url-source.d.mts +29 -0
  423. package/esm/skills/sources/url-source.d.mts.map +1 -0
  424. package/esm/skills/sources/url-source.mjs +117 -0
  425. package/esm/skills/sources/url-source.mjs.map +1 -0
  426. package/esm/skills/store/mock-skills-store.d.mts +57 -0
  427. package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
  428. package/esm/skills/store/mock-skills-store.mjs +100 -0
  429. package/esm/skills/store/mock-skills-store.mjs.map +1 -0
  430. package/esm/skills/store/procedural-skill-store.d.mts +30 -0
  431. package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
  432. package/esm/skills/store/procedural-skill-store.mjs +125 -0
  433. package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
  434. package/esm/supervisor/as-tool.mjs +2 -2
  435. package/esm/supervisor/as-tool.mjs.map +1 -1
  436. package/esm/supervisor/execution.d.mts.map +1 -1
  437. package/esm/supervisor/execution.mjs +31 -28
  438. package/esm/supervisor/execution.mjs.map +1 -1
  439. package/esm/supervisor/supervisor.d.mts.map +1 -1
  440. package/esm/supervisor/supervisor.mjs +8 -3
  441. package/esm/supervisor/supervisor.mjs.map +1 -1
  442. package/esm/system-prompt/index.d.mts +4 -0
  443. package/esm/system-prompt/system-prompt.d.mts +68 -4
  444. package/esm/system-prompt/system-prompt.d.mts.map +1 -1
  445. package/esm/system-prompt/system-prompt.mjs +89 -5
  446. package/esm/system-prompt/system-prompt.mjs.map +1 -1
  447. package/esm/team/gates.mjs +48 -0
  448. package/esm/team/gates.mjs.map +1 -0
  449. package/esm/team/index.d.mts +1 -0
  450. package/esm/team/index.mjs +3 -0
  451. package/esm/team/team.d.mts +42 -0
  452. package/esm/team/team.d.mts.map +1 -0
  453. package/esm/team/team.mjs +94 -0
  454. package/esm/team/team.mjs.map +1 -0
  455. package/esm/tool/executable-as-tool.d.mts.map +1 -1
  456. package/esm/tool/executable-as-tool.mjs +2 -2
  457. package/esm/tool/executable-as-tool.mjs.map +1 -1
  458. package/esm/tool/tool.d.mts.map +1 -1
  459. package/esm/tool/tool.mjs +2 -2
  460. package/esm/tool/tool.mjs.map +1 -1
  461. package/esm/utils/compute-cost.d.mts +17 -1
  462. package/esm/utils/compute-cost.d.mts.map +1 -1
  463. package/esm/utils/compute-cost.mjs +26 -1
  464. package/esm/utils/compute-cost.mjs.map +1 -1
  465. package/esm/utils/extract-json-lenient.d.mts +42 -0
  466. package/esm/utils/extract-json-lenient.d.mts.map +1 -0
  467. package/esm/utils/extract-json-lenient.mjs +97 -0
  468. package/esm/utils/extract-json-lenient.mjs.map +1 -0
  469. package/esm/utils/index.d.mts +4 -2
  470. package/esm/utils/index.mjs +3 -1
  471. package/esm/utils/json-schema.d.mts +1 -1
  472. package/esm/utils/prepare-attachment-part.d.mts +10 -1
  473. package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
  474. package/esm/utils/prepare-attachment-part.mjs +103 -11
  475. package/esm/utils/prepare-attachment-part.mjs.map +1 -1
  476. package/esm/utils/resolve-attachment.d.mts +4 -3
  477. package/esm/utils/resolve-attachment.d.mts.map +1 -1
  478. package/esm/utils/resolve-attachment.mjs +4 -3
  479. package/esm/utils/resolve-attachment.mjs.map +1 -1
  480. package/esm/utils/run-context.d.mts +94 -0
  481. package/esm/utils/run-context.d.mts.map +1 -0
  482. package/esm/utils/run-context.mjs +98 -0
  483. package/esm/utils/run-context.mjs.map +1 -0
  484. package/esm/vcr/cassette-io.mjs +57 -0
  485. package/esm/vcr/cassette-io.mjs.map +1 -0
  486. package/esm/vcr/errors.d.mts +42 -0
  487. package/esm/vcr/errors.d.mts.map +1 -0
  488. package/esm/vcr/errors.mjs +37 -0
  489. package/esm/vcr/errors.mjs.map +1 -0
  490. package/esm/vcr/hash-request.d.mts +28 -0
  491. package/esm/vcr/hash-request.d.mts.map +1 -0
  492. package/esm/vcr/hash-request.mjs +118 -0
  493. package/esm/vcr/hash-request.mjs.map +1 -0
  494. package/esm/vcr/index.d.mts +4 -0
  495. package/esm/vcr/index.mjs +5 -0
  496. package/esm/vcr/vcr.d.mts +32 -0
  497. package/esm/vcr/vcr.d.mts.map +1 -0
  498. package/esm/vcr/vcr.mjs +248 -0
  499. package/esm/vcr/vcr.mjs.map +1 -0
  500. package/esm/vcr/vcr.type.d.mts +118 -0
  501. package/esm/vcr/vcr.type.d.mts.map +1 -0
  502. package/esm/workflow/as-tool.mjs +2 -2
  503. package/esm/workflow/as-tool.mjs.map +1 -1
  504. package/esm/workflow/engine.mjs +1 -0
  505. package/esm/workflow/engine.mjs.map +1 -1
  506. package/esm/workflow/step-runner.mjs +19 -20
  507. package/esm/workflow/step-runner.mjs.map +1 -1
  508. package/esm/workflow/workflow.d.mts.map +1 -1
  509. package/esm/workflow/workflow.mjs +8 -3
  510. package/esm/workflow/workflow.mjs.map +1 -1
  511. package/llms-full.txt +1683 -68
  512. package/llms.txt +16 -4
  513. package/package.json +7 -3
  514. package/skills/README.md +40 -4
  515. package/skills/ai-dx-helpers/SKILL.md +2 -2
  516. package/skills/approve-tool-calls/SKILL.md +134 -0
  517. package/skills/attach-ai-middleware/SKILL.md +1 -1
  518. package/skills/detect-and-redact-pii/SKILL.md +104 -0
  519. package/skills/durable-resume/SKILL.md +128 -0
  520. package/skills/escalate-block-to-human/SKILL.md +85 -0
  521. package/skills/eval-datasets-and-ci/SKILL.md +117 -0
  522. package/skills/guard-input-output/SKILL.md +117 -0
  523. package/skills/manage-prompts/SKILL.md +186 -0
  524. package/skills/observe-ai-flows/SKILL.md +94 -0
  525. package/skills/record-replay-llm/SKILL.md +92 -0
  526. package/skills/run-ai-agent/SKILL.md +26 -1
  527. package/skills/run-ai-rag/SKILL.md +139 -0
  528. package/skills/run-ai-team/SKILL.md +107 -0
  529. package/skills/run-orchestrator/SKILL.md +2 -0
  530. package/skills/run-planner/SKILL.md +73 -8
  531. package/skills/run-supervisor/SKILL.md +20 -1
  532. package/skills/use-runtime-skills/SKILL.md +106 -0
  533. package/skills/write-system-prompt/SKILL.md +30 -1
  534. package/cjs/index.cjs.map +0 -1
  535. package/esm/contracts/result/index.d.mts +0 -15
@@ -16,12 +16,19 @@ import { Message } from "../../contracts/conversation-message.type.mjs";
16
16
  * wins (correct when the agent has history + a fresh prompt).
17
17
  * - Returns a plain string directly when `content` is a string.
18
18
  * - Joins `text` parts with `"\n"` when `content` is a multipart
19
- * `ContentPart[]`. Non-text parts (images, audio) are skipped —
19
+ * `ContentPart[]`. Non-text parts (images, audio, pdf) are skipped —
20
20
  * callers concerned with multimodal content inspect `request`
21
21
  * / attachments separately.
22
22
  * - Returns `""` when there is no user message at all (e.g. a trip
23
23
  * composed entirely of tool results).
24
24
  *
25
+ * **Coverage limit (D3).** Because only `text` parts are extracted, any
26
+ * guardrail / PII detector built on this helper inspects **text only** —
27
+ * image / PDF / audio attachment content is NOT scanned. A guardrail is
28
+ * therefore not a multimodal safety control: for non-text inputs add an
29
+ * attachment-level policy (e.g. an OCR / moderation pass before the call)
30
+ * rather than relying on input detectors.
31
+ *
25
32
  * @example
26
33
  * const prompt = extractUserText(context.messages);
27
34
  * if (!prompt) return;
@@ -1 +1 @@
1
- {"version":3,"file":"extract-user-text.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/middleware/utils/extract-user-text.ts"],"mappings":";;;;;AA4BA;;;;;;;;AAAgE;;;;;;;;;;;;;;;;iBAAhD,eAAA,CAAgB,QAAA,EAAU,aAAa,CAAC,OAAA"}
1
+ {"version":3,"file":"extract-user-text.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/middleware/utils/extract-user-text.ts"],"mappings":";;;;;AAmCA;;;;;;;;AAAgE;;;;;;;;;;;;;;;;;;;;;;;iBAAhD,eAAA,CAAgB,QAAA,EAAU,aAAa,CAAC,OAAA"}
@@ -14,12 +14,19 @@
14
14
  * wins (correct when the agent has history + a fresh prompt).
15
15
  * - Returns a plain string directly when `content` is a string.
16
16
  * - Joins `text` parts with `"\n"` when `content` is a multipart
17
- * `ContentPart[]`. Non-text parts (images, audio) are skipped —
17
+ * `ContentPart[]`. Non-text parts (images, audio, pdf) are skipped —
18
18
  * callers concerned with multimodal content inspect `request`
19
19
  * / attachments separately.
20
20
  * - Returns `""` when there is no user message at all (e.g. a trip
21
21
  * composed entirely of tool results).
22
22
  *
23
+ * **Coverage limit (D3).** Because only `text` parts are extracted, any
24
+ * guardrail / PII detector built on this helper inspects **text only** —
25
+ * image / PDF / audio attachment content is NOT scanned. A guardrail is
26
+ * therefore not a multimodal safety control: for non-text inputs add an
27
+ * attachment-level policy (e.g. an OCR / moderation pass before the call)
28
+ * rather than relying on input detectors.
29
+ *
23
30
  * @example
24
31
  * const prompt = extractUserText(context.messages);
25
32
  * if (!prompt) return;
@@ -1 +1 @@
1
- {"version":3,"file":"extract-user-text.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/middleware/utils/extract-user-text.ts"],"sourcesContent":["import type { Message } from \"../../contracts/conversation-message.type\";\n\n/**\n * Pull the text a content-inspection middleware should care about\n * from the outbound message list.\n *\n * **Role.** Built-ins that inspect \"what the user just said\" — the\n * guardrail on `trip.before`, the semantic cache on `trip.before`,\n * future consumers like PII redactors — all need the same string:\n * the most recent `user`-role message's text content. This helper\n * is the single authority on how that string is resolved.\n *\n * **Behavior.**\n * - Walks `messages` from the end backwards so the LAST user turn\n * wins (correct when the agent has history + a fresh prompt).\n * - Returns a plain string directly when `content` is a string.\n * - Joins `text` parts with `\"\\n\"` when `content` is a multipart\n * `ContentPart[]`. Non-text parts (images, audio) are skipped —\n * callers concerned with multimodal content inspect `request`\n * / attachments separately.\n * - Returns `\"\"` when there is no user message at all (e.g. a trip\n * composed entirely of tool results).\n *\n * @example\n * const prompt = extractUserText(context.messages);\n * if (!prompt) return;\n * const verdict = await inputCheck(prompt);\n */\nexport function extractUserText(messages: ReadonlyArray<Message>): string {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n\n if (message.role !== \"user\") {\n continue;\n }\n\n if (typeof message.content === \"string\") {\n return message.content;\n }\n\n if (Array.isArray(message.content)) {\n return message.content\n .filter((part) => part.type === \"text\")\n .map((part) => (part as { text: string }).text)\n .join(\"\\n\");\n }\n }\n\n return \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,gBAAgB,UAA0C;CACxE,KAAK,IAAI,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;EACzD,MAAM,UAAU,SAAS;EAEzB,IAAI,QAAQ,SAAS,QACnB;EAGF,IAAI,OAAO,QAAQ,YAAY,UAC7B,OAAO,QAAQ;EAGjB,IAAI,MAAM,QAAQ,QAAQ,OAAO,GAC/B,OAAO,QAAQ,QACZ,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,KAAK,SAAU,KAA0B,IAAI,CAAC,CAC9C,KAAK,IAAI;CAEhB;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"extract-user-text.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/middleware/utils/extract-user-text.ts"],"sourcesContent":["import type { Message } from \"../../contracts/conversation-message.type\";\n\n/**\n * Pull the text a content-inspection middleware should care about\n * from the outbound message list.\n *\n * **Role.** Built-ins that inspect \"what the user just said\" — the\n * guardrail on `trip.before`, the semantic cache on `trip.before`,\n * future consumers like PII redactors — all need the same string:\n * the most recent `user`-role message's text content. This helper\n * is the single authority on how that string is resolved.\n *\n * **Behavior.**\n * - Walks `messages` from the end backwards so the LAST user turn\n * wins (correct when the agent has history + a fresh prompt).\n * - Returns a plain string directly when `content` is a string.\n * - Joins `text` parts with `\"\\n\"` when `content` is a multipart\n * `ContentPart[]`. Non-text parts (images, audio, pdf) are skipped —\n * callers concerned with multimodal content inspect `request`\n * / attachments separately.\n * - Returns `\"\"` when there is no user message at all (e.g. a trip\n * composed entirely of tool results).\n *\n * **Coverage limit (D3).** Because only `text` parts are extracted, any\n * guardrail / PII detector built on this helper inspects **text only** —\n * image / PDF / audio attachment content is NOT scanned. A guardrail is\n * therefore not a multimodal safety control: for non-text inputs add an\n * attachment-level policy (e.g. an OCR / moderation pass before the call)\n * rather than relying on input detectors.\n *\n * @example\n * const prompt = extractUserText(context.messages);\n * if (!prompt) return;\n * const verdict = await inputCheck(prompt);\n */\nexport function extractUserText(messages: ReadonlyArray<Message>): string {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n\n if (message.role !== \"user\") {\n continue;\n }\n\n if (typeof message.content === \"string\") {\n return message.content;\n }\n\n if (Array.isArray(message.content)) {\n return message.content\n .filter((part) => part.type === \"text\")\n .map((part) => (part as { text: string }).text)\n .join(\"\\n\");\n }\n }\n\n return \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,gBAAgB,UAA0C;CACxE,KAAK,IAAI,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;EACzD,MAAM,UAAU,SAAS;EAEzB,IAAI,QAAQ,SAAS,QACnB;EAGF,IAAI,OAAO,QAAQ,YAAY,UAC7B,OAAO,QAAQ;EAGjB,IAAI,MAAM,QAAQ,QAAQ,OAAO,GAC/B,OAAO,QAAQ,QACZ,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,KAAK,SAAU,KAA0B,IAAI,CAAC,CAC9C,KAAK,IAAI;CAEhB;CAEA,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ import { ObjectStreamEvent, StreamObjectParams, collectStreamObject, streamObject } from "./stream-object.mjs";
2
+ import { parsePartialJson } from "./parse-partial-json.mjs";
@@ -0,0 +1,4 @@
1
+ import { parsePartialJson } from "./parse-partial-json.mjs";
2
+ import { collectStreamObject, streamObject } from "./stream-object.mjs";
3
+
4
+ export { };
@@ -0,0 +1,22 @@
1
+ //#region ../@warlock.js/ai/src/object-stream/parse-partial-json.d.ts
2
+ /**
3
+ * Best-effort parse of a possibly-truncated JSON string into the value it
4
+ * is "on its way to" becoming. Used by {@link streamObject} to emit a
5
+ * partial object snapshot from each streamed delta before the full reply
6
+ * has arrived.
7
+ *
8
+ * Returns `undefined` when the prefix can't yet be coerced into a value
9
+ * (so the caller simply waits for more text). The FINAL parse in
10
+ * `streamObject` is always strict `JSON.parse` — this tolerant parser only
11
+ * powers the in-flight snapshots, so a too-clever completion never affects
12
+ * the authoritative result.
13
+ *
14
+ * @example
15
+ * parsePartialJson('{"name":"Al'); // → { name: "Al" }
16
+ * parsePartialJson('{"items":[1,2,'); // → { items: [1, 2] }
17
+ * parsePartialJson('{"a":1,"b"'); // → { a: 1 } (drops the dangling key)
18
+ */
19
+ declare function parsePartialJson(text: string): unknown | undefined;
20
+ //#endregion
21
+ export { parsePartialJson };
22
+ //# sourceMappingURL=parse-partial-json.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-partial-json.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/object-stream/parse-partial-json.ts"],"mappings":";;AAiBA;;;;AAA6C;;;;;;;;;;;;iBAA7B,gBAAA,CAAiB,IAAY"}
@@ -0,0 +1,78 @@
1
+ //#region ../@warlock.js/ai/src/object-stream/parse-partial-json.ts
2
+ /**
3
+ * Best-effort parse of a possibly-truncated JSON string into the value it
4
+ * is "on its way to" becoming. Used by {@link streamObject} to emit a
5
+ * partial object snapshot from each streamed delta before the full reply
6
+ * has arrived.
7
+ *
8
+ * Returns `undefined` when the prefix can't yet be coerced into a value
9
+ * (so the caller simply waits for more text). The FINAL parse in
10
+ * `streamObject` is always strict `JSON.parse` — this tolerant parser only
11
+ * powers the in-flight snapshots, so a too-clever completion never affects
12
+ * the authoritative result.
13
+ *
14
+ * @example
15
+ * parsePartialJson('{"name":"Al'); // → { name: "Al" }
16
+ * parsePartialJson('{"items":[1,2,'); // → { items: [1, 2] }
17
+ * parsePartialJson('{"a":1,"b"'); // → { a: 1 } (drops the dangling key)
18
+ */
19
+ function parsePartialJson(text) {
20
+ const trimmed = text.trim();
21
+ if (!trimmed) return void 0;
22
+ const direct = tryParse(trimmed);
23
+ if (direct.ok) return direct.value;
24
+ const completed = completePartialJson(trimmed);
25
+ if (completed === void 0) return void 0;
26
+ const parsed = tryParse(completed);
27
+ return parsed.ok ? parsed.value : void 0;
28
+ }
29
+ function tryParse(text) {
30
+ try {
31
+ return {
32
+ ok: true,
33
+ value: JSON.parse(text)
34
+ };
35
+ } catch {
36
+ return { ok: false };
37
+ }
38
+ }
39
+ /**
40
+ * Reconstruct a parseable JSON string from a truncated prefix by closing
41
+ * open strings/containers and trimming dangling separators, keys, and
42
+ * partial literals. Tries the most faithful completion first, then falls
43
+ * back to dropping the unfinished tail.
44
+ */
45
+ function completePartialJson(text) {
46
+ const stack = [];
47
+ let inString = false;
48
+ let escaped = false;
49
+ for (const ch of text) {
50
+ if (inString) {
51
+ if (escaped) escaped = false;
52
+ else if (ch === "\\") escaped = true;
53
+ else if (ch === "\"") inString = false;
54
+ continue;
55
+ }
56
+ if (ch === "\"") inString = true;
57
+ else if (ch === "{" || ch === "[") stack.push(ch);
58
+ else if (ch === "}" || ch === "]") stack.pop();
59
+ }
60
+ const closers = () => stack.map((c) => c === "{" ? "}" : "]").reverse().join("");
61
+ let core = text;
62
+ if (inString) core += "\"";
63
+ core = core.replace(/\s+$/, "");
64
+ if (core.endsWith(",")) core = core.slice(0, -1);
65
+ if (core.endsWith(":")) core += "null";
66
+ const attempts = [core + closers()];
67
+ if (stack[stack.length - 1] === "{") {
68
+ const droppedKey = core.replace(/,?\s*"(?:[^"\\]|\\.)*"\s*$/, "");
69
+ attempts.push(droppedKey.replace(/,\s*$/, "") + closers());
70
+ }
71
+ const droppedLiteral = core.replace(/[:,]?\s*[A-Za-z0-9.+\-eE]+$/, (match) => match.trimStart().startsWith(":") ? ":null" : "");
72
+ attempts.push(droppedLiteral.replace(/,\s*$/, "") + closers());
73
+ for (const candidate of attempts) if (tryParse(candidate).ok) return candidate;
74
+ }
75
+
76
+ //#endregion
77
+ export { parsePartialJson };
78
+ //# sourceMappingURL=parse-partial-json.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-partial-json.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/object-stream/parse-partial-json.ts"],"sourcesContent":["/**\n * Best-effort parse of a possibly-truncated JSON string into the value it\n * is \"on its way to\" becoming. Used by {@link streamObject} to emit a\n * partial object snapshot from each streamed delta before the full reply\n * has arrived.\n *\n * Returns `undefined` when the prefix can't yet be coerced into a value\n * (so the caller simply waits for more text). The FINAL parse in\n * `streamObject` is always strict `JSON.parse` — this tolerant parser only\n * powers the in-flight snapshots, so a too-clever completion never affects\n * the authoritative result.\n *\n * @example\n * parsePartialJson('{\"name\":\"Al'); // → { name: \"Al\" }\n * parsePartialJson('{\"items\":[1,2,'); // → { items: [1, 2] }\n * parsePartialJson('{\"a\":1,\"b\"'); // → { a: 1 } (drops the dangling key)\n */\nexport function parsePartialJson(text: string): unknown | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n\n // Fast path: already-valid JSON.\n const direct = tryParse(trimmed);\n if (direct.ok) return direct.value;\n\n const completed = completePartialJson(trimmed);\n if (completed === undefined) return undefined;\n\n const parsed = tryParse(completed);\n return parsed.ok ? parsed.value : undefined;\n}\n\nfunction tryParse(text: string): { ok: true; value: unknown } | { ok: false } {\n try {\n return { ok: true, value: JSON.parse(text) };\n } catch {\n return { ok: false };\n }\n}\n\n/**\n * Reconstruct a parseable JSON string from a truncated prefix by closing\n * open strings/containers and trimming dangling separators, keys, and\n * partial literals. Tries the most faithful completion first, then falls\n * back to dropping the unfinished tail.\n */\nfunction completePartialJson(text: string): string | undefined {\n const stack: Array<\"{\" | \"[\"> = [];\n let inString = false;\n let escaped = false;\n\n for (const ch of text) {\n if (inString) {\n if (escaped) escaped = false;\n else if (ch === \"\\\\\") escaped = true;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') inString = true;\n else if (ch === \"{\" || ch === \"[\") stack.push(ch);\n else if (ch === \"}\" || ch === \"]\") stack.pop();\n }\n\n const closers = () =>\n stack\n .map(c => (c === \"{\" ? \"}\" : \"]\"))\n .reverse()\n .join(\"\");\n\n // Faithful completion: close an open string, drop a trailing comma,\n // fill a dangling `key:` with null, then close containers.\n let core = text;\n if (inString) core += '\"';\n core = core.replace(/\\s+$/, \"\");\n if (core.endsWith(\",\")) core = core.slice(0, -1);\n if (core.endsWith(\":\")) core += \"null\";\n\n const attempts: string[] = [core + closers()];\n\n // Fallback 1: drop a dangling object key (a `\"...\"` with no value yet).\n if (stack[stack.length - 1] === \"{\") {\n const droppedKey = core.replace(/,?\\s*\"(?:[^\"\\\\]|\\\\.)*\"\\s*$/, \"\");\n attempts.push(droppedKey.replace(/,\\s*$/, \"\") + closers());\n }\n\n // Fallback 2: drop a partial trailing literal / number (e.g. `tr`, `12.`).\n const droppedLiteral = core.replace(/[:,]?\\s*[A-Za-z0-9.+\\-eE]+$/, match =>\n match.trimStart().startsWith(\":\") ? \":null\" : \"\",\n );\n attempts.push(droppedLiteral.replace(/,\\s*$/, \"\") + closers());\n\n for (const candidate of attempts) {\n if (tryParse(candidate).ok) return candidate;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,iBAAiB,MAAmC;CAClE,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO;CAGrB,MAAM,SAAS,SAAS,OAAO;CAC/B,IAAI,OAAO,IAAI,OAAO,OAAO;CAE7B,MAAM,YAAY,oBAAoB,OAAO;CAC7C,IAAI,cAAc,QAAW,OAAO;CAEpC,MAAM,SAAS,SAAS,SAAS;CACjC,OAAO,OAAO,KAAK,OAAO,QAAQ;AACpC;AAEA,SAAS,SAAS,MAA4D;CAC5E,IAAI;EACF,OAAO;GAAE,IAAI;GAAM,OAAO,KAAK,MAAM,IAAI;EAAE;CAC7C,QAAQ;EACN,OAAO,EAAE,IAAI,MAAM;CACrB;AACF;;;;;;;AAQA,SAAS,oBAAoB,MAAkC;CAC7D,MAAM,QAA0B,CAAC;CACjC,IAAI,WAAW;CACf,IAAI,UAAU;CAEd,KAAK,MAAM,MAAM,MAAM;EACrB,IAAI,UAAU;GACZ,IAAI,SAAS,UAAU;QAClB,IAAI,OAAO,MAAM,UAAU;QAC3B,IAAI,OAAO,MAAK,WAAW;GAChC;EACF;EACA,IAAI,OAAO,MAAK,WAAW;OACtB,IAAI,OAAO,OAAO,OAAO,KAAK,MAAM,KAAK,EAAE;OAC3C,IAAI,OAAO,OAAO,OAAO,KAAK,MAAM,IAAI;CAC/C;CAEA,MAAM,gBACJ,MACG,KAAI,MAAM,MAAM,MAAM,MAAM,GAAI,CAAC,CACjC,QAAQ,CAAC,CACT,KAAK,EAAE;CAIZ,IAAI,OAAO;CACX,IAAI,UAAU,QAAQ;CACtB,OAAO,KAAK,QAAQ,QAAQ,EAAE;CAC9B,IAAI,KAAK,SAAS,GAAG,GAAG,OAAO,KAAK,MAAM,GAAG,EAAE;CAC/C,IAAI,KAAK,SAAS,GAAG,GAAG,QAAQ;CAEhC,MAAM,WAAqB,CAAC,OAAO,QAAQ,CAAC;CAG5C,IAAI,MAAM,MAAM,SAAS,OAAO,KAAK;EACnC,MAAM,aAAa,KAAK,QAAQ,8BAA8B,EAAE;EAChE,SAAS,KAAK,WAAW,QAAQ,SAAS,EAAE,IAAI,QAAQ,CAAC;CAC3D;CAGA,MAAM,iBAAiB,KAAK,QAAQ,gCAA+B,UACjE,MAAM,UAAU,CAAC,CAAC,WAAW,GAAG,IAAI,UAAU,EAChD;CACA,SAAS,KAAK,eAAe,QAAQ,SAAS,EAAE,IAAI,QAAQ,CAAC;CAE7D,KAAK,MAAM,aAAa,UACtB,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI,OAAO;AAIvC"}
@@ -0,0 +1,68 @@
1
+ import { Message } from "../contracts/conversation-message.type.mjs";
2
+ import { AIError } from "../errors/ai-error.mjs";
3
+ import { Usage } from "../contracts/result/usage.type.mjs";
4
+ import { ModelCallOptions, ModelContract } from "../contracts/model.contract.mjs";
5
+ import { StandardSchemaV1 } from "@standard-schema/spec";
6
+
7
+ //#region ../@warlock.js/ai/src/object-stream/stream-object.d.ts
8
+ /**
9
+ * One event in a {@link streamObject} run.
10
+ *
11
+ * - `text-delta` — the raw token text as it streams (for a "typing" view).
12
+ * - `partial` — a best-effort snapshot of the object so far, re-parsed
13
+ * from the accumulated text on each delta (only emitted when it changed).
14
+ * - `done` — terminal: the final text is strictly parsed and validated
15
+ * against the schema. `valid` + `value` on success; `valid: false` +
16
+ * `error` when the output wasn't valid JSON or failed the schema.
17
+ */
18
+ type ObjectStreamEvent<T> = {
19
+ type: "text-delta";
20
+ delta: string;
21
+ } | {
22
+ type: "partial";
23
+ value: unknown;
24
+ } | {
25
+ type: "done";
26
+ valid: true;
27
+ value: T;
28
+ usage: Usage;
29
+ } | {
30
+ type: "done";
31
+ valid: false;
32
+ error: AIError;
33
+ usage: Usage;
34
+ };
35
+ /** Parameters for {@link streamObject}. */
36
+ type StreamObjectParams<T> = {
37
+ /** The model to stream from (e.g. `sdk.model({ name })`). */model: ModelContract; /** The prompt messages. */
38
+ messages: Message[]; /** Standard Schema the final object is validated against. */
39
+ schema: StandardSchemaV1<T>; /** Extra model call options (e.g. `responseSchema`, `temperature`). */
40
+ options?: ModelCallOptions;
41
+ };
42
+ /**
43
+ * Stream a structured object: emit raw token deltas, progressively-parsed
44
+ * partial-object snapshots, and a final strictly-validated object — the
45
+ * first-class structured-output streaming primitive (A1). Reuses the
46
+ * model's existing `stream()` seam; the partial snapshots come from a
47
+ * tolerant {@link parsePartialJson}, while the terminal `done` event is a
48
+ * strict `JSON.parse` + schema validation, so an over-eager partial parse
49
+ * never affects the authoritative result.
50
+ *
51
+ * Pair it with a `structuredOutput`-capable model and a `responseSchema`
52
+ * (via `options`) for the cleanest JSON; otherwise prompt the model to
53
+ * reply with JSON only.
54
+ *
55
+ * @example
56
+ * for await (const event of streamObject({ model, messages, schema })) {
57
+ * if (event.type === "partial") render(event.value); // live UI
58
+ * if (event.type === "done" && event.valid) save(event.value); // final
59
+ * }
60
+ */
61
+ declare function streamObject<T>(params: StreamObjectParams<T>): AsyncIterable<ObjectStreamEvent<T>>;
62
+ /** Collect a {@link streamObject} run down to just its terminal event. */
63
+ declare function collectStreamObject<T>(stream: AsyncIterable<ObjectStreamEvent<T>>): Promise<Extract<ObjectStreamEvent<T>, {
64
+ type: "done";
65
+ }>>;
66
+ //#endregion
67
+ export { ObjectStreamEvent, StreamObjectParams, collectStreamObject, streamObject };
68
+ //# sourceMappingURL=stream-object.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-object.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/object-stream/stream-object.ts"],"mappings":";;;;;;;;;;AAiBA;;;;;;;KAAY,iBAAA;EACN,IAAA;EAAoB,KAAA;AAAA;EACpB,IAAA;EAAiB,KAAA;AAAA;EACjB,IAAA;EAAc,KAAA;EAAa,KAAA,EAAO,CAAA;EAAG,KAAA,EAAO,KAAA;AAAA;EAC5C,IAAA;EAAc,KAAA;EAAc,KAAA,EAAO,OAAA;EAAS,KAAA,EAAO,KAAA;AAAA;;KAG7C,kBAAA;EAHkD,6DAK5D,KAAA,EAAO,aAAA,EAFG;EAIV,QAAA,EAAU,OAAA,IAJkB;EAM5B,MAAA,EAAQ,gBAAA,CAAiB,CAAA,GAFf;EAIV,OAAA,GAAU,gBAAA;AAAA;;;;;;;;;;;;;;;AAAgB;AAsB5B;;;;iBAAuB,YAAA,IACrB,MAAA,EAAQ,kBAAA,CAAmB,CAAA,IAC1B,aAAA,CAAc,iBAAA,CAAkB,CAAA;;iBAoEb,mBAAA,IACpB,MAAA,EAAQ,aAAA,CAAc,iBAAA,CAAkB,CAAA,KACvC,OAAA,CAAQ,OAAA,CAAQ,iBAAA,CAAkB,CAAA;EAAM,IAAA;AAAA"}
@@ -0,0 +1,104 @@
1
+ import { SchemaValidationError } from "../errors/schema-validation-error.mjs";
2
+ import "../errors/index.mjs";
3
+ import { parsePartialJson } from "./parse-partial-json.mjs";
4
+
5
+ //#region ../@warlock.js/ai/src/object-stream/stream-object.ts
6
+ /**
7
+ * Stream a structured object: emit raw token deltas, progressively-parsed
8
+ * partial-object snapshots, and a final strictly-validated object — the
9
+ * first-class structured-output streaming primitive (A1). Reuses the
10
+ * model's existing `stream()` seam; the partial snapshots come from a
11
+ * tolerant {@link parsePartialJson}, while the terminal `done` event is a
12
+ * strict `JSON.parse` + schema validation, so an over-eager partial parse
13
+ * never affects the authoritative result.
14
+ *
15
+ * Pair it with a `structuredOutput`-capable model and a `responseSchema`
16
+ * (via `options`) for the cleanest JSON; otherwise prompt the model to
17
+ * reply with JSON only.
18
+ *
19
+ * @example
20
+ * for await (const event of streamObject({ model, messages, schema })) {
21
+ * if (event.type === "partial") render(event.value); // live UI
22
+ * if (event.type === "done" && event.valid) save(event.value); // final
23
+ * }
24
+ */
25
+ async function* streamObject(params) {
26
+ const { model, messages, schema, options } = params;
27
+ let accumulated = "";
28
+ let lastPartialKey;
29
+ let usage = {
30
+ input: 0,
31
+ output: 0,
32
+ total: 0
33
+ };
34
+ for await (const chunk of model.stream(messages, options)) if (chunk.type === "delta") {
35
+ accumulated += chunk.content;
36
+ yield {
37
+ type: "text-delta",
38
+ delta: chunk.content
39
+ };
40
+ const partial = parsePartialJson(accumulated);
41
+ if (partial !== void 0) {
42
+ const key = safeStringify(partial);
43
+ if (key !== lastPartialKey) {
44
+ lastPartialKey = key;
45
+ yield {
46
+ type: "partial",
47
+ value: partial
48
+ };
49
+ }
50
+ }
51
+ } else if (chunk.type === "done") usage = chunk.usage;
52
+ yield await finalize(accumulated, schema, usage);
53
+ }
54
+ /** Strict parse + schema validation of the complete streamed text. */
55
+ async function finalize(text, schema, usage) {
56
+ const cleaned = stripJsonFences(text).trim();
57
+ let parsed;
58
+ try {
59
+ parsed = JSON.parse(cleaned);
60
+ } catch (cause) {
61
+ return {
62
+ type: "done",
63
+ valid: false,
64
+ error: new SchemaValidationError("streamObject: the final streamed output was not valid JSON", { cause }),
65
+ usage
66
+ };
67
+ }
68
+ const result = await schema["~standard"].validate(parsed);
69
+ if ("issues" in result && result.issues) return {
70
+ type: "done",
71
+ valid: false,
72
+ error: new SchemaValidationError("streamObject: the streamed object failed schema validation", { issues: result.issues }),
73
+ usage
74
+ };
75
+ return {
76
+ type: "done",
77
+ valid: true,
78
+ value: result.value,
79
+ usage
80
+ };
81
+ }
82
+ /** Collect a {@link streamObject} run down to just its terminal event. */
83
+ async function collectStreamObject(stream) {
84
+ let done;
85
+ for await (const event of stream) if (event.type === "done") done = event;
86
+ if (!done) throw new SchemaValidationError("streamObject: stream ended without a terminal event");
87
+ return done;
88
+ }
89
+ /** Strip a leading/trailing ```json fence the model may wrap output in. */
90
+ function stripJsonFences(text) {
91
+ const fenced = text.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
92
+ return fenced ? fenced[1] : text;
93
+ }
94
+ function safeStringify(value) {
95
+ try {
96
+ return JSON.stringify(value);
97
+ } catch {
98
+ return String(value);
99
+ }
100
+ }
101
+
102
+ //#endregion
103
+ export { collectStreamObject, streamObject };
104
+ //# sourceMappingURL=stream-object.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-object.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/object-stream/stream-object.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Message } from \"../contracts/conversation-message.type\";\nimport type { ModelCallOptions, ModelContract } from \"../contracts/model.contract\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { AIError, SchemaValidationError } from \"../errors\";\nimport { parsePartialJson } from \"./parse-partial-json\";\n\n/**\n * One event in a {@link streamObject} run.\n *\n * - `text-delta` — the raw token text as it streams (for a \"typing\" view).\n * - `partial` — a best-effort snapshot of the object so far, re-parsed\n * from the accumulated text on each delta (only emitted when it changed).\n * - `done` — terminal: the final text is strictly parsed and validated\n * against the schema. `valid` + `value` on success; `valid: false` +\n * `error` when the output wasn't valid JSON or failed the schema.\n */\nexport type ObjectStreamEvent<T> =\n | { type: \"text-delta\"; delta: string }\n | { type: \"partial\"; value: unknown }\n | { type: \"done\"; valid: true; value: T; usage: Usage }\n | { type: \"done\"; valid: false; error: AIError; usage: Usage };\n\n/** Parameters for {@link streamObject}. */\nexport type StreamObjectParams<T> = {\n /** The model to stream from (e.g. `sdk.model({ name })`). */\n model: ModelContract;\n /** The prompt messages. */\n messages: Message[];\n /** Standard Schema the final object is validated against. */\n schema: StandardSchemaV1<T>;\n /** Extra model call options (e.g. `responseSchema`, `temperature`). */\n options?: ModelCallOptions;\n};\n\n/**\n * Stream a structured object: emit raw token deltas, progressively-parsed\n * partial-object snapshots, and a final strictly-validated object — the\n * first-class structured-output streaming primitive (A1). Reuses the\n * model's existing `stream()` seam; the partial snapshots come from a\n * tolerant {@link parsePartialJson}, while the terminal `done` event is a\n * strict `JSON.parse` + schema validation, so an over-eager partial parse\n * never affects the authoritative result.\n *\n * Pair it with a `structuredOutput`-capable model and a `responseSchema`\n * (via `options`) for the cleanest JSON; otherwise prompt the model to\n * reply with JSON only.\n *\n * @example\n * for await (const event of streamObject({ model, messages, schema })) {\n * if (event.type === \"partial\") render(event.value); // live UI\n * if (event.type === \"done\" && event.valid) save(event.value); // final\n * }\n */\nexport async function* streamObject<T>(\n params: StreamObjectParams<T>,\n): AsyncIterable<ObjectStreamEvent<T>> {\n const { model, messages, schema, options } = params;\n\n let accumulated = \"\";\n let lastPartialKey: string | undefined;\n let usage: Usage = { input: 0, output: 0, total: 0 };\n\n for await (const chunk of model.stream(messages, options)) {\n if (chunk.type === \"delta\") {\n accumulated += chunk.content;\n yield { type: \"text-delta\", delta: chunk.content };\n\n const partial = parsePartialJson(accumulated);\n if (partial !== undefined) {\n const key = safeStringify(partial);\n if (key !== lastPartialKey) {\n lastPartialKey = key;\n yield { type: \"partial\", value: partial };\n }\n }\n } else if (chunk.type === \"done\") {\n usage = chunk.usage;\n }\n }\n\n yield await finalize(accumulated, schema, usage);\n}\n\n/** Strict parse + schema validation of the complete streamed text. */\nasync function finalize<T>(\n text: string,\n schema: StandardSchemaV1<T>,\n usage: Usage,\n): Promise<ObjectStreamEvent<T>> {\n const cleaned = stripJsonFences(text).trim();\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(cleaned);\n } catch (cause) {\n return {\n type: \"done\",\n valid: false,\n error: new SchemaValidationError(\n \"streamObject: the final streamed output was not valid JSON\",\n { cause },\n ),\n usage,\n };\n }\n\n const result = await schema[\"~standard\"].validate(parsed);\n if (\"issues\" in result && result.issues) {\n return {\n type: \"done\",\n valid: false,\n error: new SchemaValidationError(\n \"streamObject: the streamed object failed schema validation\",\n { issues: result.issues },\n ),\n usage,\n };\n }\n\n return { type: \"done\", valid: true, value: (result as { value: T }).value, usage };\n}\n\n/** Collect a {@link streamObject} run down to just its terminal event. */\nexport async function collectStreamObject<T>(\n stream: AsyncIterable<ObjectStreamEvent<T>>,\n): Promise<Extract<ObjectStreamEvent<T>, { type: \"done\" }>> {\n let done: Extract<ObjectStreamEvent<T>, { type: \"done\" }> | undefined;\n for await (const event of stream) {\n if (event.type === \"done\") done = event;\n }\n if (!done) {\n throw new SchemaValidationError(\"streamObject: stream ended without a terminal event\");\n }\n return done;\n}\n\n/** Strip a leading/trailing ```json fence the model may wrap output in. */\nfunction stripJsonFences(text: string): string {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n return fenced ? fenced[1] : text;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsDA,gBAAuB,aACrB,QACqC;CACrC,MAAM,EAAE,OAAO,UAAU,QAAQ,YAAY;CAE7C,IAAI,cAAc;CAClB,IAAI;CACJ,IAAI,QAAe;EAAE,OAAO;EAAG,QAAQ;EAAG,OAAO;CAAE;CAEnD,WAAW,MAAM,SAAS,MAAM,OAAO,UAAU,OAAO,GACtD,IAAI,MAAM,SAAS,SAAS;EAC1B,eAAe,MAAM;EACrB,MAAM;GAAE,MAAM;GAAc,OAAO,MAAM;EAAQ;EAEjD,MAAM,UAAU,iBAAiB,WAAW;EAC5C,IAAI,YAAY,QAAW;GACzB,MAAM,MAAM,cAAc,OAAO;GACjC,IAAI,QAAQ,gBAAgB;IAC1B,iBAAiB;IACjB,MAAM;KAAE,MAAM;KAAW,OAAO;IAAQ;GAC1C;EACF;CACF,OAAO,IAAI,MAAM,SAAS,QACxB,QAAQ,MAAM;CAIlB,MAAM,MAAM,SAAS,aAAa,QAAQ,KAAK;AACjD;;AAGA,eAAe,SACb,MACA,QACA,OAC+B;CAC/B,MAAM,UAAU,gBAAgB,IAAI,CAAC,CAAC,KAAK;CAE3C,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,OAAO;CAC7B,SAAS,OAAO;EACd,OAAO;GACL,MAAM;GACN,OAAO;GACP,OAAO,IAAI,sBACT,8DACA,EAAE,MAAM,CACV;GACA;EACF;CACF;CAEA,MAAM,SAAS,MAAM,OAAO,YAAY,CAAC,SAAS,MAAM;CACxD,IAAI,YAAY,UAAU,OAAO,QAC/B,OAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO,IAAI,sBACT,8DACA,EAAE,QAAQ,OAAO,OAAO,CAC1B;EACA;CACF;CAGF,OAAO;EAAE,MAAM;EAAQ,OAAO;EAAM,OAAQ,OAAwB;EAAO;CAAM;AACnF;;AAGA,eAAsB,oBACpB,QAC0D;CAC1D,IAAI;CACJ,WAAW,MAAM,SAAS,QACxB,IAAI,MAAM,SAAS,QAAQ,OAAO;CAEpC,IAAI,CAAC,MACH,MAAM,IAAI,sBAAsB,qDAAqD;CAEvF,OAAO;AACT;;AAGA,SAAS,gBAAgB,MAAsB;CAC7C,MAAM,SAAS,KAAK,MAAM,kCAAkC;CAC5D,OAAO,SAAS,OAAO,KAAK;AAC9B;AAEA,SAAS,cAAc,OAAwB;CAC7C,IAAI;EACF,OAAO,KAAK,UAAU,KAAK;CAC7B,QAAQ;EACN,OAAO,OAAO,KAAK;CACrB;AACF"}
@@ -0,0 +1,4 @@
1
+ import { getObservers, isObserveAll, registerObserver, setObserveAll } from "./observer-registry.mjs";
2
+ import { notifyObservers, resolveObservers } from "./resolve-observers.mjs";
3
+
4
+ export { };
@@ -0,0 +1,30 @@
1
+ import { Observer } from "./observer.contract.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/observe/observer-registry.d.ts
4
+ /**
5
+ * Register a global {@link Observer}. Every flow that resolves to
6
+ * "observed" (via `observeAll` or `observe: true`) routes its completed
7
+ * report to it. An observability tool registers its collector here once,
8
+ * when its config is applied.
9
+ */
10
+ declare function registerObserver(observer: Observer): void;
11
+ /**
12
+ * The currently registered global observers. Returned as a read-only
13
+ * snapshot reference — callers must not mutate it; use
14
+ * {@link registerObserver} to add and {@link clearObservers} (test-only)
15
+ * to reset.
16
+ */
17
+ declare function getObservers(): readonly Observer[];
18
+ /**
19
+ * Set the global "observe every flow by default" flag. An observability
20
+ * tool flips this on when configured with its own observe-all option.
21
+ */
22
+ declare function setObserveAll(value: boolean): void;
23
+ /**
24
+ * Read the global "observe every flow by default" flag. Consulted by the
25
+ * observe-resolution helper when a flow left `observe` undefined.
26
+ */
27
+ declare function isObserveAll(): boolean;
28
+ //#endregion
29
+ export { getObservers, isObserveAll, registerObserver, setObserveAll };
30
+ //# sourceMappingURL=observer-registry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer-registry.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/observe/observer-registry.ts"],"mappings":";;;;;AAwBA;;;;iBAAgB,gBAAA,CAAiB,QAAkB,EAAR,QAAQ;AAUnD;;;;AAAiD;AAQjD;AARA,iBAAgB,YAAA,aAAyB,QAAQ;;;AAQL;AAQ5C;iBARgB,aAAA,CAAc,KAAc;;;AAQhB;;iBAAZ,YAAA"}
@@ -0,0 +1,51 @@
1
+ //#region ../@warlock.js/ai/src/observe/observer-registry.ts
2
+ /**
3
+ * Module-level list of globally registered {@link Observer}s. A flow
4
+ * that resolves to "observed" hands its finished report to every entry
5
+ * here. An observability tool (panoptic, …) registers exactly one
6
+ * collector when its config is applied.
7
+ */
8
+ const observers = [];
9
+ /**
10
+ * Global "observe every flow by default" flag. When `true`, a flow that
11
+ * did not set its own `observe` option is observed (routed to the
12
+ * globally registered observers). Individual flows opt out with
13
+ * `observe: false`. Default `false` — opt-in observability.
14
+ */
15
+ let observeAll = false;
16
+ /**
17
+ * Register a global {@link Observer}. Every flow that resolves to
18
+ * "observed" (via `observeAll` or `observe: true`) routes its completed
19
+ * report to it. An observability tool registers its collector here once,
20
+ * when its config is applied.
21
+ */
22
+ function registerObserver(observer) {
23
+ observers.push(observer);
24
+ }
25
+ /**
26
+ * The currently registered global observers. Returned as a read-only
27
+ * snapshot reference — callers must not mutate it; use
28
+ * {@link registerObserver} to add and {@link clearObservers} (test-only)
29
+ * to reset.
30
+ */
31
+ function getObservers() {
32
+ return observers;
33
+ }
34
+ /**
35
+ * Set the global "observe every flow by default" flag. An observability
36
+ * tool flips this on when configured with its own observe-all option.
37
+ */
38
+ function setObserveAll(value) {
39
+ observeAll = value;
40
+ }
41
+ /**
42
+ * Read the global "observe every flow by default" flag. Consulted by the
43
+ * observe-resolution helper when a flow left `observe` undefined.
44
+ */
45
+ function isObserveAll() {
46
+ return observeAll;
47
+ }
48
+
49
+ //#endregion
50
+ export { getObservers, isObserveAll, registerObserver, setObserveAll };
51
+ //# sourceMappingURL=observer-registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer-registry.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/observe/observer-registry.ts"],"sourcesContent":["import type { Observer } from \"./observer.contract\";\n\n/**\n * Module-level list of globally registered {@link Observer}s. A flow\n * that resolves to \"observed\" hands its finished report to every entry\n * here. An observability tool (panoptic, …) registers exactly one\n * collector when its config is applied.\n */\nconst observers: Observer[] = [];\n\n/**\n * Global \"observe every flow by default\" flag. When `true`, a flow that\n * did not set its own `observe` option is observed (routed to the\n * globally registered observers). Individual flows opt out with\n * `observe: false`. Default `false` — opt-in observability.\n */\nlet observeAll = false;\n\n/**\n * Register a global {@link Observer}. Every flow that resolves to\n * \"observed\" (via `observeAll` or `observe: true`) routes its completed\n * report to it. An observability tool registers its collector here once,\n * when its config is applied.\n */\nexport function registerObserver(observer: Observer): void {\n observers.push(observer);\n}\n\n/**\n * The currently registered global observers. Returned as a read-only\n * snapshot reference — callers must not mutate it; use\n * {@link registerObserver} to add and {@link clearObservers} (test-only)\n * to reset.\n */\nexport function getObservers(): readonly Observer[] {\n return observers;\n}\n\n/**\n * Set the global \"observe every flow by default\" flag. An observability\n * tool flips this on when configured with its own observe-all option.\n */\nexport function setObserveAll(value: boolean): void {\n observeAll = value;\n}\n\n/**\n * Read the global \"observe every flow by default\" flag. Consulted by the\n * observe-resolution helper when a flow left `observe` undefined.\n */\nexport function isObserveAll(): boolean {\n return observeAll;\n}\n\n/**\n * Reset the registry to its initial empty state — clears all registered\n * observers and turns off the observe-all flag. Internal: intended for\n * test isolation so one spec's registrations don't leak into the next.\n * Not part of the public surface.\n */\nexport function clearObservers(): void {\n observers.length = 0;\n observeAll = false;\n}\n"],"mappings":";;;;;;;AAQA,MAAM,YAAwB,CAAC;;;;;;;AAQ/B,IAAI,aAAa;;;;;;;AAQjB,SAAgB,iBAAiB,UAA0B;CACzD,UAAU,KAAK,QAAQ;AACzB;;;;;;;AAQA,SAAgB,eAAoC;CAClD,OAAO;AACT;;;;;AAMA,SAAgB,cAAc,OAAsB;CAClD,aAAa;AACf;;;;;AAMA,SAAgB,eAAwB;CACtC,OAAO;AACT"}
@@ -0,0 +1,40 @@
1
+ import { ExecutionReport } from "../contracts/result/execution-report.type.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/observe/observer.contract.d.ts
4
+ /**
5
+ * Generic, panoptic-agnostic observability seam. A flow that resolves
6
+ * to "observed" hands its completed {@link ExecutionReport} to every
7
+ * registered `Observer`. Core depends only on this structural shape and
8
+ * `ExecutionReport` — it never imports any observability package
9
+ * (panoptic, OTel, Langfuse, …). An observability tool implements
10
+ * `Observer` and registers itself via {@link registerObserver}, so
11
+ * `observe: true` / `observeAll` route reports without coupling core to
12
+ * the tool. This is the dependency inversion that keeps the two sides
13
+ * decoupled.
14
+ *
15
+ * The object form of a flow's `observe` option is typed as this same
16
+ * structural `Observer` (NOT a panoptic-specific options type), so a
17
+ * panoptic flow-local collector — which implements `Observer` — can be
18
+ * passed directly.
19
+ *
20
+ * @example
21
+ * const collector: Observer = {
22
+ * collect(report) {
23
+ * // forward the finished report to a store / exporter
24
+ * },
25
+ * };
26
+ * registerObserver(collector);
27
+ */
28
+ interface Observer {
29
+ /**
30
+ * Receive a completed flow's report. May be sync or async — the flow
31
+ * awaits it. A throw is **isolated** (never breaks the run) but no
32
+ * longer **silent**: it is surfaced via `notifyObservers`' `onError`
33
+ * hook, or warned once per observer, so a broken exporter can't vanish
34
+ * from production with no signal (C5).
35
+ */
36
+ collect(report: ExecutionReport): void | Promise<void>;
37
+ }
38
+ //#endregion
39
+ export { Observer };
40
+ //# sourceMappingURL=observer.contract.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer.contract.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/observe/observer.contract.ts"],"mappings":";;;;;AA0BA;;;;;;;;;AAQkD;;;;;;;;;;;;;UARjC,QAAA;;;;;;;;EAQf,OAAA,CAAQ,MAAA,EAAQ,eAAA,UAAyB,OAAO;AAAA"}
@@ -0,0 +1,40 @@
1
+ import { Observer } from "./observer.contract.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/observe/resolve-observers.d.ts
4
+ /**
5
+ * The value a flow's `observe` config option may take. Additive and
6
+ * gated — when `undefined` (the default), behavior follows the global
7
+ * observe-all flag, so a flow that never sets `observe` behaves exactly
8
+ * as before unless an observability tool turned observe-all on.
9
+ *
10
+ * - `true` → route this flow to the globally registered observers,
11
+ * even when observe-all is off.
12
+ * - `false` → opt this flow out entirely, even when observe-all is on.
13
+ * - an {@link Observer} object → a flow-local collector; only this flow's
14
+ * report is routed, and only to it (the global observers are skipped).
15
+ * A panoptic flow-local collector implements `Observer`, so it can be
16
+ * passed here directly — core stays panoptic-agnostic.
17
+ * - `undefined` → follow the global observe-all flag.
18
+ */
19
+ type FlowObserveOption = boolean | Observer;
20
+ /**
21
+ * Resolve a flow's `observe` option into the concrete list of
22
+ * {@link Observer}s to notify with that flow's completed report:
23
+ *
24
+ * - `false` → `[]` (opted out).
25
+ * - `true` → the globally registered observers.
26
+ * - an `Observer` object → just that one (flow-local).
27
+ * - `undefined` → the globally registered observers when observe-all is
28
+ * on AND this is a ROOT run, otherwise `[]`.
29
+ *
30
+ * Reads the ambient {@link currentRunFrame} for the observe-all path:
31
+ * flows call it at completion, so a present frame means the run is nested
32
+ * inside an orchestration callback and is already attached to its parent's
33
+ * report tree — self-routing it again would double-count it as a separate
34
+ * top-level trace (and double its tokens/cost in the aggregate). Explicit
35
+ * `observe: true` / an `Observer` still route regardless of nesting.
36
+ */
37
+ declare function resolveObservers(observe: FlowObserveOption | undefined): readonly Observer[];
38
+ //#endregion
39
+ export { FlowObserveOption, resolveObservers };
40
+ //# sourceMappingURL=resolve-observers.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-observers.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/observe/resolve-observers.ts"],"mappings":";;;;;AAmBA;;;;AAAkD;AAmBlD;;;;;;;;KAnBY,iBAAA,aAA8B,QAAQ;;;;;;;;;;;;;;;;;;iBAmBlC,gBAAA,CAAiB,OAAA,EAAS,iBAAA,wBAAyC,QAAQ"}