@warlock.js/ai 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (648) hide show
  1. package/CHANGELOG.md +63 -52
  2. package/cjs/index.cjs +240 -14147
  3. package/cjs/src-Bmajk4Qg.cjs +30 -0
  4. package/cjs/src-OZyDYHxm.cjs +25089 -0
  5. package/cjs/src-OZyDYHxm.cjs.map +1 -0
  6. package/esm/agent/agent-config.type.d.mts +119 -1
  7. package/esm/agent/agent-config.type.d.mts.map +1 -1
  8. package/esm/agent/agent-input-builder.mjs +27 -6
  9. package/esm/agent/agent-input-builder.mjs.map +1 -1
  10. package/esm/agent/agent.d.mts +40 -1
  11. package/esm/agent/agent.d.mts.map +1 -1
  12. package/esm/agent/agent.mjs +328 -36
  13. package/esm/agent/agent.mjs.map +1 -1
  14. package/esm/agent/index.d.mts +2 -1
  15. package/esm/agent/index.mjs +1 -0
  16. package/esm/agent/judge-config.type.d.mts +33 -0
  17. package/esm/agent/judge-config.type.d.mts.map +1 -0
  18. package/esm/agent/judge-config.type.mjs +13 -0
  19. package/esm/agent/judge-config.type.mjs.map +1 -0
  20. package/esm/agent/signature.mjs +57 -0
  21. package/esm/agent/signature.mjs.map +1 -0
  22. package/esm/agent/snapshot.mjs +101 -0
  23. package/esm/agent/snapshot.mjs.map +1 -0
  24. package/esm/ai-openai/src/embedder.mjs +4 -0
  25. package/esm/ai-openai/src/image.mjs +5 -0
  26. package/esm/ai-openai/src/index.mjs +7 -0
  27. package/esm/ai-openai/src/model.mjs +5 -0
  28. package/esm/ai-openai/src/sdk.mjs +9 -0
  29. package/esm/ai-openai/src/speech.mjs +5 -0
  30. package/esm/ai-openai/src/transcription.mjs +6 -0
  31. package/esm/ai-openai/src/utils/index.mjs +5 -0
  32. package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
  33. package/esm/ai-openai/src/utils/to-openai-tools.mjs +3 -0
  34. package/esm/ai-openai/src/utils/wrap-openai-error.mjs +4 -0
  35. package/esm/ai.d.mts +164 -53
  36. package/esm/ai.d.mts.map +1 -1
  37. package/esm/ai.mjs +79 -8
  38. package/esm/ai.mjs.map +1 -1
  39. package/esm/batch/batch.d.mts.map +1 -1
  40. package/esm/batch/batch.mjs +21 -1
  41. package/esm/batch/batch.mjs.map +1 -1
  42. package/esm/batch/batch.type.d.mts +11 -4
  43. package/esm/batch/batch.type.d.mts.map +1 -1
  44. package/esm/config.d.mts +39 -3
  45. package/esm/config.d.mts.map +1 -1
  46. package/esm/config.mjs +26 -2
  47. package/esm/config.mjs.map +1 -1
  48. package/esm/contracts/agent/agent-options.type.d.mts +33 -5
  49. package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
  50. package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
  51. package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
  52. package/esm/contracts/agent/agent.contract.d.mts +29 -1
  53. package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
  54. package/esm/contracts/agent/eval.type.d.mts +43 -2
  55. package/esm/contracts/agent/eval.type.d.mts.map +1 -1
  56. package/esm/contracts/agent/index.d.mts +2 -1
  57. package/esm/contracts/attachment-policy.type.d.mts +51 -0
  58. package/esm/contracts/attachment-policy.type.d.mts.map +1 -0
  59. package/esm/contracts/attachment.type.d.mts +16 -7
  60. package/esm/contracts/attachment.type.d.mts.map +1 -1
  61. package/esm/contracts/content-part.type.d.mts +14 -5
  62. package/esm/contracts/content-part.type.d.mts.map +1 -1
  63. package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -1
  64. package/esm/contracts/image-model.contract.d.mts +156 -0
  65. package/esm/contracts/image-model.contract.d.mts.map +1 -0
  66. package/esm/contracts/index.d.mts +13 -6
  67. package/esm/contracts/model.contract.d.mts +11 -8
  68. package/esm/contracts/model.contract.d.mts.map +1 -1
  69. package/esm/contracts/orchestrator/index.d.mts +1 -0
  70. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +31 -2
  71. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
  72. package/esm/contracts/orchestrator/session-lock.contract.d.mts +47 -0
  73. package/esm/contracts/orchestrator/session-lock.contract.d.mts.map +1 -0
  74. package/esm/contracts/planner/index.d.mts +3 -2
  75. package/esm/contracts/planner/planner-config.type.d.mts +61 -0
  76. package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
  77. package/esm/contracts/planner/planner-execute-options.type.d.mts +60 -1
  78. package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
  79. package/esm/contracts/planner/planner-result.type.d.mts +8 -0
  80. package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
  81. package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
  82. package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
  83. package/esm/contracts/planner/planner.contract.d.mts +21 -1
  84. package/esm/contracts/planner/planner.contract.d.mts.map +1 -1
  85. package/esm/contracts/result/agent-result.type.d.mts +6 -4
  86. package/esm/contracts/result/agent-result.type.d.mts.map +1 -1
  87. package/esm/contracts/result/base-report.type.d.mts +21 -3
  88. package/esm/contracts/result/base-report.type.d.mts.map +1 -1
  89. package/esm/contracts/result/base-report.type.mjs.map +1 -1
  90. package/esm/contracts/result/execution-report.type.d.mts +53 -1
  91. package/esm/contracts/result/execution-report.type.d.mts.map +1 -1
  92. package/esm/contracts/result/supervisor-result.type.d.mts +14 -2
  93. package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
  94. package/esm/contracts/result/workflow-result.type.d.mts +2 -1
  95. package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
  96. package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
  97. package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
  98. package/esm/contracts/speech-model.contract.d.mts +97 -0
  99. package/esm/contracts/speech-model.contract.d.mts.map +1 -0
  100. package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
  101. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  102. package/esm/contracts/system-prompt.contract.d.mts +103 -1
  103. package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
  104. package/esm/contracts/team/index.d.mts +1 -0
  105. package/esm/contracts/team/team-config.type.d.mts +127 -0
  106. package/esm/contracts/team/team-config.type.d.mts.map +1 -0
  107. package/esm/contracts/tool.contract.d.mts +4 -2
  108. package/esm/contracts/tool.contract.d.mts.map +1 -1
  109. package/esm/contracts/transcription-model.contract.d.mts +101 -0
  110. package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
  111. package/esm/contracts/workflow/step.contract.d.mts +30 -5
  112. package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
  113. package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
  114. package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
  115. package/esm/errors/agent-drift-error.d.mts +32 -0
  116. package/esm/errors/agent-drift-error.d.mts.map +1 -0
  117. package/esm/errors/agent-drift-error.mjs +31 -0
  118. package/esm/errors/agent-drift-error.mjs.map +1 -0
  119. package/esm/errors/error-code.type.d.mts +1 -1
  120. package/esm/errors/index.d.mts +3 -0
  121. package/esm/errors/index.mjs +3 -0
  122. package/esm/errors/outbound-policy-error.d.mts +27 -0
  123. package/esm/errors/outbound-policy-error.d.mts.map +1 -0
  124. package/esm/errors/outbound-policy-error.mjs +32 -0
  125. package/esm/errors/outbound-policy-error.mjs.map +1 -0
  126. package/esm/errors/planner-drift-error.d.mts +34 -0
  127. package/esm/errors/planner-drift-error.d.mts.map +1 -0
  128. package/esm/errors/planner-drift-error.mjs +33 -0
  129. package/esm/errors/planner-drift-error.mjs.map +1 -0
  130. package/esm/eval/dataset.d.mts +28 -0
  131. package/esm/eval/dataset.d.mts.map +1 -0
  132. package/esm/eval/dataset.mjs +112 -0
  133. package/esm/eval/dataset.mjs.map +1 -0
  134. package/esm/eval/dataset.type.d.mts +53 -0
  135. package/esm/eval/dataset.type.d.mts.map +1 -0
  136. package/esm/eval/eval-runner.d.mts.map +1 -1
  137. package/esm/eval/eval-runner.mjs +16 -2
  138. package/esm/eval/eval-runner.mjs.map +1 -1
  139. package/esm/eval/index.d.mts +20 -1
  140. package/esm/eval/index.d.mts.map +1 -1
  141. package/esm/eval/index.mjs +20 -2
  142. package/esm/eval/index.mjs.map +1 -1
  143. package/esm/eval/regression.d.mts +30 -0
  144. package/esm/eval/regression.d.mts.map +1 -0
  145. package/esm/eval/regression.mjs +51 -0
  146. package/esm/eval/regression.mjs.map +1 -0
  147. package/esm/eval/report-json.d.mts +30 -0
  148. package/esm/eval/report-json.d.mts.map +1 -0
  149. package/esm/eval/report-json.mjs +33 -0
  150. package/esm/eval/report-json.mjs.map +1 -0
  151. package/esm/eval/report-junit.d.mts +22 -0
  152. package/esm/eval/report-junit.d.mts.map +1 -0
  153. package/esm/eval/report-junit.mjs +60 -0
  154. package/esm/eval/report-junit.mjs.map +1 -0
  155. package/esm/guard/contracts/guard-options.type.d.mts +165 -0
  156. package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
  157. package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
  158. package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
  159. package/esm/guard/contracts/index.d.mts +4 -0
  160. package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
  161. package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
  162. package/esm/guard/contracts/verdict.type.d.mts +76 -0
  163. package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
  164. package/esm/guard/detectors/index.d.mts +4 -0
  165. package/esm/guard/detectors/index.mjs +6 -0
  166. package/esm/guard/detectors/injection.d.mts +34 -0
  167. package/esm/guard/detectors/injection.d.mts.map +1 -0
  168. package/esm/guard/detectors/injection.mjs +254 -0
  169. package/esm/guard/detectors/injection.mjs.map +1 -0
  170. package/esm/guard/detectors/moderation.d.mts +32 -0
  171. package/esm/guard/detectors/moderation.d.mts.map +1 -0
  172. package/esm/guard/detectors/moderation.mjs +134 -0
  173. package/esm/guard/detectors/moderation.mjs.map +1 -0
  174. package/esm/guard/detectors/pii.d.mts +41 -0
  175. package/esm/guard/detectors/pii.d.mts.map +1 -0
  176. package/esm/guard/detectors/pii.mjs +199 -0
  177. package/esm/guard/detectors/pii.mjs.map +1 -0
  178. package/esm/guard/detectors/topic.d.mts +29 -0
  179. package/esm/guard/detectors/topic.d.mts.map +1 -0
  180. package/esm/guard/detectors/topic.mjs +99 -0
  181. package/esm/guard/detectors/topic.mjs.map +1 -0
  182. package/esm/guard/errors.d.mts +12 -0
  183. package/esm/guard/errors.d.mts.map +1 -0
  184. package/esm/guard/errors.mjs +18 -0
  185. package/esm/guard/errors.mjs.map +1 -0
  186. package/esm/guard/guard.d.mts +67 -0
  187. package/esm/guard/guard.d.mts.map +1 -0
  188. package/esm/guard/guard.mjs +209 -0
  189. package/esm/guard/guard.mjs.map +1 -0
  190. package/esm/guard/guardrail.d.mts +39 -0
  191. package/esm/guard/guardrail.d.mts.map +1 -0
  192. package/esm/guard/guardrail.mjs +22 -0
  193. package/esm/guard/guardrail.mjs.map +1 -0
  194. package/esm/human/contracts/approval.type.d.mts +154 -0
  195. package/esm/human/contracts/approval.type.d.mts.map +1 -0
  196. package/esm/human/contracts/human-approval.type.d.mts +38 -0
  197. package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
  198. package/esm/human/contracts/index.d.mts +4 -0
  199. package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
  200. package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
  201. package/esm/human/contracts/resume.type.d.mts +77 -0
  202. package/esm/human/contracts/resume.type.d.mts.map +1 -0
  203. package/esm/human/errors.d.mts +84 -0
  204. package/esm/human/errors.d.mts.map +1 -0
  205. package/esm/human/errors.mjs +60 -0
  206. package/esm/human/errors.mjs.map +1 -0
  207. package/esm/human/human-approval.d.mts +57 -0
  208. package/esm/human/human-approval.d.mts.map +1 -0
  209. package/esm/human/human-approval.mjs +170 -0
  210. package/esm/human/human-approval.mjs.map +1 -0
  211. package/esm/human/policy.d.mts +55 -0
  212. package/esm/human/policy.d.mts.map +1 -0
  213. package/esm/human/policy.mjs +67 -0
  214. package/esm/human/policy.mjs.map +1 -0
  215. package/esm/human/register.mjs +37 -0
  216. package/esm/human/register.mjs.map +1 -0
  217. package/esm/human/resume-seed.mjs +53 -0
  218. package/esm/human/resume-seed.mjs.map +1 -0
  219. package/esm/human/resume.d.mts +54 -0
  220. package/esm/human/resume.d.mts.map +1 -0
  221. package/esm/human/resume.mjs +121 -0
  222. package/esm/human/resume.mjs.map +1 -0
  223. package/esm/human/stores/index.mjs +5 -0
  224. package/esm/human/stores/memory.d.mts +30 -0
  225. package/esm/human/stores/memory.d.mts.map +1 -0
  226. package/esm/human/stores/memory.mjs +91 -0
  227. package/esm/human/stores/memory.mjs.map +1 -0
  228. package/esm/human/stores/pg.d.mts +59 -0
  229. package/esm/human/stores/pg.d.mts.map +1 -0
  230. package/esm/human/stores/pg.mjs +220 -0
  231. package/esm/human/stores/pg.mjs.map +1 -0
  232. package/esm/human/stores/redis.d.mts +56 -0
  233. package/esm/human/stores/redis.d.mts.map +1 -0
  234. package/esm/human/stores/redis.mjs +201 -0
  235. package/esm/human/stores/redis.mjs.map +1 -0
  236. package/esm/image/image-cost.d.mts +32 -0
  237. package/esm/image/image-cost.d.mts.map +1 -0
  238. package/esm/image/image-cost.mjs +55 -0
  239. package/esm/image/image-cost.mjs.map +1 -0
  240. package/esm/image/image.d.mts +92 -0
  241. package/esm/image/image.d.mts.map +1 -0
  242. package/esm/image/image.mjs +113 -0
  243. package/esm/image/image.mjs.map +1 -0
  244. package/esm/image/index.mjs +4 -0
  245. package/esm/index.d.mts +137 -24
  246. package/esm/index.mjs +101 -11
  247. package/esm/middleware/builtins/budget.mjs +6 -2
  248. package/esm/middleware/builtins/budget.mjs.map +1 -1
  249. package/esm/middleware/utils/extract-user-text.d.mts +8 -1
  250. package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
  251. package/esm/middleware/utils/extract-user-text.mjs +8 -1
  252. package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
  253. package/esm/mock/index.d.mts +3 -0
  254. package/esm/mock/index.mjs +3 -0
  255. package/esm/mock/mock-config.type.d.mts +22 -0
  256. package/esm/mock/mock-config.type.d.mts.map +1 -1
  257. package/esm/mock/mock-image-model.d.mts +41 -0
  258. package/esm/mock/mock-image-model.d.mts.map +1 -0
  259. package/esm/mock/mock-image-model.mjs +52 -0
  260. package/esm/mock/mock-image-model.mjs.map +1 -0
  261. package/esm/mock/mock-sdk.d.mts +7 -1
  262. package/esm/mock/mock-sdk.d.mts.map +1 -1
  263. package/esm/mock/mock-sdk.mjs +27 -0
  264. package/esm/mock/mock-sdk.mjs.map +1 -1
  265. package/esm/mock/mock-speech-model.d.mts +31 -0
  266. package/esm/mock/mock-speech-model.d.mts.map +1 -0
  267. package/esm/mock/mock-speech-model.mjs +39 -0
  268. package/esm/mock/mock-speech-model.mjs.map +1 -0
  269. package/esm/mock/mock-transcription-model.d.mts +32 -0
  270. package/esm/mock/mock-transcription-model.d.mts.map +1 -0
  271. package/esm/mock/mock-transcription-model.mjs +36 -0
  272. package/esm/mock/mock-transcription-model.mjs.map +1 -0
  273. package/esm/object-stream/index.d.mts +2 -0
  274. package/esm/object-stream/index.mjs +4 -0
  275. package/esm/object-stream/parse-partial-json.d.mts +22 -0
  276. package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
  277. package/esm/object-stream/parse-partial-json.mjs +78 -0
  278. package/esm/object-stream/parse-partial-json.mjs.map +1 -0
  279. package/esm/object-stream/stream-object.d.mts +68 -0
  280. package/esm/object-stream/stream-object.d.mts.map +1 -0
  281. package/esm/object-stream/stream-object.mjs +104 -0
  282. package/esm/object-stream/stream-object.mjs.map +1 -0
  283. package/esm/observe/index.mjs +4 -0
  284. package/esm/observe/observer-registry.d.mts +30 -0
  285. package/esm/observe/observer-registry.d.mts.map +1 -0
  286. package/esm/observe/observer-registry.mjs +51 -0
  287. package/esm/observe/observer-registry.mjs.map +1 -0
  288. package/esm/observe/observer.contract.d.mts +40 -0
  289. package/esm/observe/observer.contract.d.mts.map +1 -0
  290. package/esm/observe/resolve-observers.d.mts +40 -0
  291. package/esm/observe/resolve-observers.d.mts.map +1 -0
  292. package/esm/observe/resolve-observers.mjs +73 -0
  293. package/esm/observe/resolve-observers.mjs.map +1 -0
  294. package/esm/orchestrator/execution.d.mts.map +1 -1
  295. package/esm/orchestrator/execution.mjs +5 -2
  296. package/esm/orchestrator/execution.mjs.map +1 -1
  297. package/esm/orchestrator/index.d.mts +1 -0
  298. package/esm/orchestrator/index.mjs +1 -0
  299. package/esm/orchestrator/orchestrator.d.mts.map +1 -1
  300. package/esm/orchestrator/orchestrator.mjs +39 -6
  301. package/esm/orchestrator/orchestrator.mjs.map +1 -1
  302. package/esm/orchestrator/session-lock.d.mts +25 -0
  303. package/esm/orchestrator/session-lock.d.mts.map +1 -0
  304. package/esm/orchestrator/session-lock.mjs +83 -0
  305. package/esm/orchestrator/session-lock.mjs.map +1 -0
  306. package/esm/planner/dag-scheduler.mjs +97 -0
  307. package/esm/planner/dag-scheduler.mjs.map +1 -0
  308. package/esm/planner/plan-prompt.d.mts +1 -1
  309. package/esm/planner/plan-prompt.d.mts.map +1 -1
  310. package/esm/planner/plan-prompt.mjs +2 -1
  311. package/esm/planner/plan-prompt.mjs.map +1 -1
  312. package/esm/planner/planner-run.d.mts +8 -0
  313. package/esm/planner/planner-run.d.mts.map +1 -1
  314. package/esm/planner/planner-run.mjs +457 -31
  315. package/esm/planner/planner-run.mjs.map +1 -1
  316. package/esm/planner/planner.d.mts.map +1 -1
  317. package/esm/planner/planner.mjs +26 -2
  318. package/esm/planner/planner.mjs.map +1 -1
  319. package/esm/planner/snapshot.mjs +95 -0
  320. package/esm/planner/snapshot.mjs.map +1 -0
  321. package/esm/prompt/errors.d.mts +57 -0
  322. package/esm/prompt/errors.d.mts.map +1 -0
  323. package/esm/prompt/errors.mjs +73 -0
  324. package/esm/prompt/errors.mjs.map +1 -0
  325. package/esm/prompt/index.d.mts +3 -0
  326. package/esm/prompt/index.mjs +4 -0
  327. package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
  328. package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
  329. package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
  330. package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
  331. package/esm/prompt/prompt-validate.mjs +170 -0
  332. package/esm/prompt/prompt-validate.mjs.map +1 -0
  333. package/esm/prompt/prompt.d.mts +54 -0
  334. package/esm/prompt/prompt.d.mts.map +1 -0
  335. package/esm/prompt/prompt.mjs +218 -0
  336. package/esm/prompt/prompt.mjs.map +1 -0
  337. package/esm/prompt/prompt.type.d.mts +174 -0
  338. package/esm/prompt/prompt.type.d.mts.map +1 -0
  339. package/esm/prompts/index.d.mts +3 -0
  340. package/esm/prompts/index.mjs +3 -0
  341. package/esm/prompts/prompts-manager.contract.d.mts +154 -0
  342. package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
  343. package/esm/prompts/prompts-manager.d.mts +38 -0
  344. package/esm/prompts/prompts-manager.d.mts.map +1 -0
  345. package/esm/prompts/prompts-manager.mjs +410 -0
  346. package/esm/prompts/prompts-manager.mjs.map +1 -0
  347. package/esm/prompts/prompts-manager.type.d.mts +172 -0
  348. package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
  349. package/esm/prompts/prompts-validate.mjs +200 -0
  350. package/esm/prompts/prompts-validate.mjs.map +1 -0
  351. package/esm/rag/as-tool.mjs +48 -0
  352. package/esm/rag/as-tool.mjs.map +1 -0
  353. package/esm/rag/chunk/chunk.d.mts +24 -0
  354. package/esm/rag/chunk/chunk.d.mts.map +1 -0
  355. package/esm/rag/chunk/chunk.mjs +44 -0
  356. package/esm/rag/chunk/chunk.mjs.map +1 -0
  357. package/esm/rag/chunk/fixed.mjs +32 -0
  358. package/esm/rag/chunk/fixed.mjs.map +1 -0
  359. package/esm/rag/chunk/markdown.mjs +75 -0
  360. package/esm/rag/chunk/markdown.mjs.map +1 -0
  361. package/esm/rag/chunk/recursive.mjs +132 -0
  362. package/esm/rag/chunk/recursive.mjs.map +1 -0
  363. package/esm/rag/chunk/sentence.mjs +73 -0
  364. package/esm/rag/chunk/sentence.mjs.map +1 -0
  365. package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
  366. package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
  367. package/esm/rag/contracts/citation.type.d.mts +35 -0
  368. package/esm/rag/contracts/citation.type.d.mts.map +1 -0
  369. package/esm/rag/contracts/index.d.mts +4 -0
  370. package/esm/rag/contracts/rag-config.type.d.mts +68 -0
  371. package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
  372. package/esm/rag/contracts/rag-document.type.d.mts +21 -0
  373. package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
  374. package/esm/rag/hybrid/bm25.d.mts +23 -0
  375. package/esm/rag/hybrid/bm25.d.mts.map +1 -0
  376. package/esm/rag/hybrid/bm25.mjs +51 -0
  377. package/esm/rag/hybrid/bm25.mjs.map +1 -0
  378. package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
  379. package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
  380. package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
  381. package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
  382. package/esm/rag/hybrid/rrf.d.mts +25 -0
  383. package/esm/rag/hybrid/rrf.d.mts.map +1 -0
  384. package/esm/rag/hybrid/rrf.mjs +30 -0
  385. package/esm/rag/hybrid/rrf.mjs.map +1 -0
  386. package/esm/rag/index.d.mts +22 -0
  387. package/esm/rag/index.mjs +18 -0
  388. package/esm/rag/loaders/errors.d.mts +19 -0
  389. package/esm/rag/loaders/errors.d.mts.map +1 -0
  390. package/esm/rag/loaders/errors.mjs +25 -0
  391. package/esm/rag/loaders/errors.mjs.map +1 -0
  392. package/esm/rag/loaders/index.mjs +7 -0
  393. package/esm/rag/loaders/load-html.d.mts +26 -0
  394. package/esm/rag/loaders/load-html.d.mts.map +1 -0
  395. package/esm/rag/loaders/load-html.mjs +138 -0
  396. package/esm/rag/loaders/load-html.mjs.map +1 -0
  397. package/esm/rag/loaders/load-pdf.d.mts +38 -0
  398. package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
  399. package/esm/rag/loaders/load-pdf.mjs +150 -0
  400. package/esm/rag/loaders/load-pdf.mjs.map +1 -0
  401. package/esm/rag/loaders/load-text.d.mts +47 -0
  402. package/esm/rag/loaders/load-text.d.mts.map +1 -0
  403. package/esm/rag/loaders/load-text.mjs +60 -0
  404. package/esm/rag/loaders/load-text.mjs.map +1 -0
  405. package/esm/rag/loaders/load-web.d.mts +42 -0
  406. package/esm/rag/loaders/load-web.d.mts.map +1 -0
  407. package/esm/rag/loaders/load-web.mjs +89 -0
  408. package/esm/rag/loaders/load-web.mjs.map +1 -0
  409. package/esm/rag/loaders/loader.type.d.mts +89 -0
  410. package/esm/rag/loaders/loader.type.d.mts.map +1 -0
  411. package/esm/rag/rag.d.mts +38 -0
  412. package/esm/rag/rag.d.mts.map +1 -0
  413. package/esm/rag/rag.mjs +126 -0
  414. package/esm/rag/rag.mjs.map +1 -0
  415. package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
  416. package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
  417. package/esm/rag/rerank/keyword-reranker.mjs +58 -0
  418. package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
  419. package/esm/rag/rerank/llm-reranker.d.mts +36 -0
  420. package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
  421. package/esm/rag/rerank/llm-reranker.mjs +85 -0
  422. package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
  423. package/esm/rag/rerank/reranker.contract.d.mts +28 -0
  424. package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
  425. package/esm/rag/retrieve.mjs +68 -0
  426. package/esm/rag/retrieve.mjs.map +1 -0
  427. package/esm/rag/store/cache-vector-store.d.mts +27 -0
  428. package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
  429. package/esm/rag/store/cache-vector-store.mjs +48 -0
  430. package/esm/rag/store/cache-vector-store.mjs.map +1 -0
  431. package/esm/rag/store/pg-vector-store.d.mts +139 -0
  432. package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
  433. package/esm/rag/store/pg-vector-store.mjs +328 -0
  434. package/esm/rag/store/pg-vector-store.mjs.map +1 -0
  435. package/esm/rag/store/vector-store.contract.d.mts +38 -0
  436. package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
  437. package/esm/rag/transforms/multi-query.d.mts +27 -0
  438. package/esm/rag/transforms/multi-query.d.mts.map +1 -0
  439. package/esm/rag/transforms/multi-query.mjs +41 -0
  440. package/esm/rag/transforms/multi-query.mjs.map +1 -0
  441. package/esm/security/index.mjs +5 -0
  442. package/esm/security/outbound-policy.d.mts +46 -0
  443. package/esm/security/outbound-policy.d.mts.map +1 -0
  444. package/esm/security/outbound-policy.mjs +187 -0
  445. package/esm/security/outbound-policy.mjs.map +1 -0
  446. package/esm/security/outbound-policy.type.d.mts +74 -0
  447. package/esm/security/outbound-policy.type.d.mts.map +1 -0
  448. package/esm/security/private-ip.d.mts +15 -0
  449. package/esm/security/private-ip.d.mts.map +1 -0
  450. package/esm/security/private-ip.mjs +48 -0
  451. package/esm/security/private-ip.mjs.map +1 -0
  452. package/esm/security/redact.d.mts +59 -0
  453. package/esm/security/redact.d.mts.map +1 -0
  454. package/esm/security/redact.mjs +122 -0
  455. package/esm/security/redact.mjs.map +1 -0
  456. package/esm/serve/serve.d.mts +50 -0
  457. package/esm/serve/serve.d.mts.map +1 -0
  458. package/esm/serve/serve.mjs +90 -0
  459. package/esm/serve/serve.mjs.map +1 -0
  460. package/esm/serve/sse.d.mts +20 -0
  461. package/esm/serve/sse.d.mts.map +1 -0
  462. package/esm/serve/sse.mjs +25 -0
  463. package/esm/serve/sse.mjs.map +1 -0
  464. package/esm/serve/stream-to-sse.d.mts +29 -0
  465. package/esm/serve/stream-to-sse.d.mts.map +1 -0
  466. package/esm/serve/stream-to-sse.mjs +37 -0
  467. package/esm/serve/stream-to-sse.mjs.map +1 -0
  468. package/esm/skills/catalog.d.mts +49 -0
  469. package/esm/skills/catalog.d.mts.map +1 -0
  470. package/esm/skills/catalog.mjs +140 -0
  471. package/esm/skills/catalog.mjs.map +1 -0
  472. package/esm/skills/contracts/skill-record.type.d.mts +37 -0
  473. package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
  474. package/esm/skills/contracts/skills-config.type.d.mts +108 -0
  475. package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
  476. package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
  477. package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
  478. package/esm/skills/contracts/skills.contract.d.mts +43 -0
  479. package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
  480. package/esm/skills/index.d.mts +16 -0
  481. package/esm/skills/index.mjs +14 -0
  482. package/esm/skills/load-skill-tool.d.mts +38 -0
  483. package/esm/skills/load-skill-tool.d.mts.map +1 -0
  484. package/esm/skills/load-skill-tool.mjs +65 -0
  485. package/esm/skills/load-skill-tool.mjs.map +1 -0
  486. package/esm/skills/review-gate.d.mts +33 -0
  487. package/esm/skills/review-gate.d.mts.map +1 -0
  488. package/esm/skills/review-gate.mjs +60 -0
  489. package/esm/skills/review-gate.mjs.map +1 -0
  490. package/esm/skills/save-skill-tool.d.mts +39 -0
  491. package/esm/skills/save-skill-tool.d.mts.map +1 -0
  492. package/esm/skills/save-skill-tool.mjs +65 -0
  493. package/esm/skills/save-skill-tool.mjs.map +1 -0
  494. package/esm/skills/skills.d.mts +33 -0
  495. package/esm/skills/skills.d.mts.map +1 -0
  496. package/esm/skills/skills.mjs +109 -0
  497. package/esm/skills/skills.mjs.map +1 -0
  498. package/esm/skills/sources/directory-source.d.mts +19 -0
  499. package/esm/skills/sources/directory-source.d.mts.map +1 -0
  500. package/esm/skills/sources/directory-source.mjs +108 -0
  501. package/esm/skills/sources/directory-source.mjs.map +1 -0
  502. package/esm/skills/sources/index.d.mts +18 -0
  503. package/esm/skills/sources/index.d.mts.map +1 -0
  504. package/esm/skills/sources/index.mjs +27 -0
  505. package/esm/skills/sources/index.mjs.map +1 -0
  506. package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
  507. package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
  508. package/esm/skills/sources/parse-frontmatter.mjs +46 -0
  509. package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
  510. package/esm/skills/sources/store-source.d.mts +14 -0
  511. package/esm/skills/sources/store-source.d.mts.map +1 -0
  512. package/esm/skills/sources/store-source.mjs +15 -0
  513. package/esm/skills/sources/store-source.mjs.map +1 -0
  514. package/esm/skills/sources/url-source.d.mts +29 -0
  515. package/esm/skills/sources/url-source.d.mts.map +1 -0
  516. package/esm/skills/sources/url-source.mjs +117 -0
  517. package/esm/skills/sources/url-source.mjs.map +1 -0
  518. package/esm/skills/store/mock-skills-store.d.mts +57 -0
  519. package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
  520. package/esm/skills/store/mock-skills-store.mjs +100 -0
  521. package/esm/skills/store/mock-skills-store.mjs.map +1 -0
  522. package/esm/skills/store/procedural-skill-store.d.mts +30 -0
  523. package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
  524. package/esm/skills/store/procedural-skill-store.mjs +125 -0
  525. package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
  526. package/esm/speech/index.mjs +3 -0
  527. package/esm/speech/speech.d.mts +65 -0
  528. package/esm/speech/speech.d.mts.map +1 -0
  529. package/esm/speech/speech.mjs +123 -0
  530. package/esm/speech/speech.mjs.map +1 -0
  531. package/esm/supervisor/as-tool.mjs +2 -2
  532. package/esm/supervisor/as-tool.mjs.map +1 -1
  533. package/esm/supervisor/entries.mjs +2 -2
  534. package/esm/supervisor/entries.mjs.map +1 -1
  535. package/esm/supervisor/execution.d.mts.map +1 -1
  536. package/esm/supervisor/execution.mjs +31 -28
  537. package/esm/supervisor/execution.mjs.map +1 -1
  538. package/esm/supervisor/supervisor.d.mts.map +1 -1
  539. package/esm/supervisor/supervisor.mjs +8 -3
  540. package/esm/supervisor/supervisor.mjs.map +1 -1
  541. package/esm/system-prompt/index.d.mts +4 -0
  542. package/esm/system-prompt/system-prompt.d.mts +68 -4
  543. package/esm/system-prompt/system-prompt.d.mts.map +1 -1
  544. package/esm/system-prompt/system-prompt.mjs +89 -5
  545. package/esm/system-prompt/system-prompt.mjs.map +1 -1
  546. package/esm/team/gates.mjs +48 -0
  547. package/esm/team/gates.mjs.map +1 -0
  548. package/esm/team/index.d.mts +1 -0
  549. package/esm/team/index.mjs +3 -0
  550. package/esm/team/team.d.mts +42 -0
  551. package/esm/team/team.d.mts.map +1 -0
  552. package/esm/team/team.mjs +94 -0
  553. package/esm/team/team.mjs.map +1 -0
  554. package/esm/tool/executable-as-tool.d.mts.map +1 -1
  555. package/esm/tool/executable-as-tool.mjs +2 -2
  556. package/esm/tool/executable-as-tool.mjs.map +1 -1
  557. package/esm/tool/tool.d.mts.map +1 -1
  558. package/esm/tool/tool.mjs +2 -2
  559. package/esm/tool/tool.mjs.map +1 -1
  560. package/esm/transcribe/audio-input.d.mts +47 -0
  561. package/esm/transcribe/audio-input.d.mts.map +1 -0
  562. package/esm/transcribe/audio-input.mjs +84 -0
  563. package/esm/transcribe/audio-input.mjs.map +1 -0
  564. package/esm/transcribe/index.mjs +4 -0
  565. package/esm/transcribe/transcribe.d.mts +64 -0
  566. package/esm/transcribe/transcribe.d.mts.map +1 -0
  567. package/esm/transcribe/transcribe.mjs +128 -0
  568. package/esm/transcribe/transcribe.mjs.map +1 -0
  569. package/esm/utils/compute-cost.d.mts +17 -1
  570. package/esm/utils/compute-cost.d.mts.map +1 -1
  571. package/esm/utils/compute-cost.mjs +26 -1
  572. package/esm/utils/compute-cost.mjs.map +1 -1
  573. package/esm/utils/extract-json-lenient.d.mts +42 -0
  574. package/esm/utils/extract-json-lenient.d.mts.map +1 -0
  575. package/esm/utils/extract-json-lenient.mjs +97 -0
  576. package/esm/utils/extract-json-lenient.mjs.map +1 -0
  577. package/esm/utils/index.d.mts +4 -2
  578. package/esm/utils/index.mjs +3 -1
  579. package/esm/utils/json-schema.d.mts +1 -1
  580. package/esm/utils/prepare-attachment-part.d.mts +10 -1
  581. package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
  582. package/esm/utils/prepare-attachment-part.mjs +103 -11
  583. package/esm/utils/prepare-attachment-part.mjs.map +1 -1
  584. package/esm/utils/resolve-attachment.d.mts +4 -3
  585. package/esm/utils/resolve-attachment.d.mts.map +1 -1
  586. package/esm/utils/resolve-attachment.mjs +4 -3
  587. package/esm/utils/resolve-attachment.mjs.map +1 -1
  588. package/esm/utils/run-context.d.mts +94 -0
  589. package/esm/utils/run-context.d.mts.map +1 -0
  590. package/esm/utils/run-context.mjs +98 -0
  591. package/esm/utils/run-context.mjs.map +1 -0
  592. package/esm/vcr/cassette-io.mjs +57 -0
  593. package/esm/vcr/cassette-io.mjs.map +1 -0
  594. package/esm/vcr/errors.d.mts +42 -0
  595. package/esm/vcr/errors.d.mts.map +1 -0
  596. package/esm/vcr/errors.mjs +37 -0
  597. package/esm/vcr/errors.mjs.map +1 -0
  598. package/esm/vcr/hash-request.d.mts +28 -0
  599. package/esm/vcr/hash-request.d.mts.map +1 -0
  600. package/esm/vcr/hash-request.mjs +118 -0
  601. package/esm/vcr/hash-request.mjs.map +1 -0
  602. package/esm/vcr/index.d.mts +4 -0
  603. package/esm/vcr/index.mjs +5 -0
  604. package/esm/vcr/vcr.d.mts +32 -0
  605. package/esm/vcr/vcr.d.mts.map +1 -0
  606. package/esm/vcr/vcr.mjs +248 -0
  607. package/esm/vcr/vcr.mjs.map +1 -0
  608. package/esm/vcr/vcr.type.d.mts +118 -0
  609. package/esm/vcr/vcr.type.d.mts.map +1 -0
  610. package/esm/workflow/as-tool.mjs +2 -2
  611. package/esm/workflow/as-tool.mjs.map +1 -1
  612. package/esm/workflow/engine.mjs +1 -0
  613. package/esm/workflow/engine.mjs.map +1 -1
  614. package/esm/workflow/step-runner.mjs +19 -20
  615. package/esm/workflow/step-runner.mjs.map +1 -1
  616. package/esm/workflow/workflow.d.mts.map +1 -1
  617. package/esm/workflow/workflow.mjs +8 -3
  618. package/esm/workflow/workflow.mjs.map +1 -1
  619. package/llms-full.txt +2572 -204
  620. package/llms.txt +21 -4
  621. package/package.json +7 -3
  622. package/skills/README.md +44 -4
  623. package/skills/ai-dx-helpers/SKILL.md +2 -2
  624. package/skills/approve-tool-calls/SKILL.md +134 -0
  625. package/skills/attach-ai-middleware/SKILL.md +1 -1
  626. package/skills/detect-and-redact-pii/SKILL.md +104 -0
  627. package/skills/durable-agent-runs/SKILL.md +135 -0
  628. package/skills/durable-resume/SKILL.md +128 -0
  629. package/skills/escalate-block-to-human/SKILL.md +85 -0
  630. package/skills/eval-datasets-and-ci/SKILL.md +117 -0
  631. package/skills/generate-images/SKILL.md +138 -0
  632. package/skills/generate-speech/SKILL.md +139 -0
  633. package/skills/guard-input-output/SKILL.md +117 -0
  634. package/skills/manage-prompts/SKILL.md +186 -0
  635. package/skills/observe-ai-flows/SKILL.md +94 -0
  636. package/skills/rag-loaders-and-stores/SKILL.md +164 -0
  637. package/skills/record-replay-llm/SKILL.md +92 -0
  638. package/skills/run-ai-agent/SKILL.md +26 -1
  639. package/skills/run-ai-rag/SKILL.md +139 -0
  640. package/skills/run-ai-team/SKILL.md +107 -0
  641. package/skills/run-orchestrator/SKILL.md +2 -0
  642. package/skills/run-planner/SKILL.md +73 -8
  643. package/skills/run-supervisor/SKILL.md +20 -1
  644. package/skills/transcribe-audio/SKILL.md +157 -0
  645. package/skills/use-runtime-skills/SKILL.md +106 -0
  646. package/skills/write-system-prompt/SKILL.md +30 -1
  647. package/cjs/index.cjs.map +0 -1
  648. package/esm/contracts/result/index.d.mts +0 -15
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-attachment.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/utils/resolve-attachment.ts"],"sourcesContent":["import type {\n Attachment,\n AttachmentSource,\n ResolvedAttachment,\n} from \"../contracts/attachment.type\";\nimport { InvalidRequestError } from \"../errors\";\n\nconst REMOTE_URL_PATTERN = /^https?:\\/\\//i;\n\n/**\n * Normalize a user-supplied `Attachment` (or bare `AttachmentSource`)\n * into a `ResolvedAttachment` the agent can hand to file-reading code\n * without re-discriminating the input variant.\n *\n * Resolution rules:\n * - `{ base64, mediaType }` → `{ type: \"base64\", value, mediaType }`.\n * - `StorageFileShape` (`{ url?, absolutePath? }`) → URL wins over\n * absolute path. URL becomes `{ type: \"url\" }`; absolute path\n * becomes `{ type: \"path\" }`.\n * - String starting with `http://` / `https://` → `{ type: \"url\" }`.\n * - Any other string → `{ type: \"path\" }`.\n * - Tagged `{ type: \"image\" | \"text\", source }` → recurses into `source`.\n *\n * Throws `InvalidRequestError` on obviously invalid input (empty\n * string, storage object with neither url nor absolutePath, missing\n * source field).\n *\n * @example\n * resolveAttachment(\"https://cdn.example.com/doc.pdf\");\n * // → { type: \"url\", value: \"https://cdn.example.com/doc.pdf\" }\n *\n * @example\n * resolveAttachment({ type: \"image\", source: \"/tmp/x.png\" });\n * // → { type: \"path\", value: \"/tmp/x.png\" }\n */\nexport function resolveAttachment(attachment: Attachment): ResolvedAttachment {\n if (\n typeof attachment === \"object\" &&\n attachment !== null &&\n \"type\" in attachment\n ) {\n return resolveSource(attachment.source);\n }\n\n return resolveSource(attachment);\n}\n\nfunction resolveSource(source: AttachmentSource): ResolvedAttachment {\n if (typeof source === \"string\") {\n if (!source) {\n throw new InvalidRequestError(\"Cannot resolve empty attachment string\");\n }\n\n if (REMOTE_URL_PATTERN.test(source)) {\n return { type: \"url\", value: source };\n }\n\n return { type: \"path\", value: source };\n }\n\n // StorageFile objects (from @warlock.js/core) can expose a `base64`\n // property alongside `url` / `absolutePath`. Check storage shape\n // first so we don't treat a StorageFile as an inline-bytes payload.\n if (\"url\" in source || \"absolutePath\" in source) {\n const storage = source as { url?: string; absolutePath?: string };\n\n if (storage.absolutePath) {\n return { type: \"path\", value: storage.absolutePath };\n }\n\n if (storage.url) {\n return { type: \"url\", value: storage.url };\n }\n\n throw new InvalidRequestError(\n \"Storage attachment has neither url nor absolutePath\",\n );\n }\n\n if (\"base64\" in source) {\n if (!source.base64 || !source.mediaType) {\n throw new InvalidRequestError(\n \"Inline attachment requires both `base64` and `mediaType`\",\n );\n }\n\n return {\n type: \"base64\",\n value: source.base64,\n mediaType: source.mediaType,\n };\n }\n\n throw new InvalidRequestError(\n \"Unrecognized attachment source — expected a string path/URL, a StorageFile, or `{ base64, mediaType }`\",\n );\n}\n"],"mappings":";;;;AAOA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B3B,SAAgB,kBAAkB,YAA4C;CAC5E,IACE,OAAO,eAAe,YACtB,eAAe,QACf,UAAU,YAEV,OAAO,cAAc,WAAW,MAAM;CAGxC,OAAO,cAAc,UAAU;AACjC;AAEA,SAAS,cAAc,QAA8C;CACnE,IAAI,OAAO,WAAW,UAAU;EAC9B,IAAI,CAAC,QACH,MAAM,IAAI,oBAAoB,wCAAwC;EAGxE,IAAI,mBAAmB,KAAK,MAAM,GAChC,OAAO;GAAE,MAAM;GAAO,OAAO;EAAO;EAGtC,OAAO;GAAE,MAAM;GAAQ,OAAO;EAAO;CACvC;CAKA,IAAI,SAAS,UAAU,kBAAkB,QAAQ;EAC/C,MAAM,UAAU;EAEhB,IAAI,QAAQ,cACV,OAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;EAAa;EAGrD,IAAI,QAAQ,KACV,OAAO;GAAE,MAAM;GAAO,OAAO,QAAQ;EAAI;EAG3C,MAAM,IAAI,oBACR,qDACF;CACF;CAEA,IAAI,YAAY,QAAQ;EACtB,IAAI,CAAC,OAAO,UAAU,CAAC,OAAO,WAC5B,MAAM,IAAI,oBACR,0DACF;EAGF,OAAO;GACL,MAAM;GACN,OAAO,OAAO;GACd,WAAW,OAAO;EACpB;CACF;CAEA,MAAM,IAAI,oBACR,wGACF;AACF"}
1
+ {"version":3,"file":"resolve-attachment.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/utils/resolve-attachment.ts"],"sourcesContent":["import type {\n Attachment,\n AttachmentSource,\n ResolvedAttachment,\n} from \"../contracts/attachment.type\";\nimport { InvalidRequestError } from \"../errors\";\n\nconst REMOTE_URL_PATTERN = /^https?:\\/\\//i;\n\n/**\n * Normalize a user-supplied `Attachment` (or bare `AttachmentSource`)\n * into a `ResolvedAttachment` the agent can hand to file-reading code\n * without re-discriminating the input variant.\n *\n * Resolution rules:\n * - `{ base64, mediaType }` → `{ type: \"base64\", value, mediaType }`.\n * - `StorageFileShape` (`{ url?, absolutePath? }`) → `absolutePath` wins\n * over `url` when both are present (prefer the local file over an extra\n * remote hop). Absolute path becomes `{ type: \"path\" }`; url becomes\n * `{ type: \"url\" }`.\n * - String starting with `http://` / `https://` → `{ type: \"url\" }`.\n * - Any other string → `{ type: \"path\" }`.\n * - Tagged `{ type: \"image\" | \"text\", source }` → recurses into `source`.\n *\n * Throws `InvalidRequestError` on obviously invalid input (empty\n * string, storage object with neither url nor absolutePath, missing\n * source field).\n *\n * @example\n * resolveAttachment(\"https://cdn.example.com/doc.pdf\");\n * // → { type: \"url\", value: \"https://cdn.example.com/doc.pdf\" }\n *\n * @example\n * resolveAttachment({ type: \"image\", source: \"/tmp/x.png\" });\n * // → { type: \"path\", value: \"/tmp/x.png\" }\n */\nexport function resolveAttachment(attachment: Attachment): ResolvedAttachment {\n if (\n typeof attachment === \"object\" &&\n attachment !== null &&\n \"type\" in attachment\n ) {\n return resolveSource(attachment.source);\n }\n\n return resolveSource(attachment);\n}\n\nfunction resolveSource(source: AttachmentSource): ResolvedAttachment {\n if (typeof source === \"string\") {\n if (!source) {\n throw new InvalidRequestError(\"Cannot resolve empty attachment string\");\n }\n\n if (REMOTE_URL_PATTERN.test(source)) {\n return { type: \"url\", value: source };\n }\n\n return { type: \"path\", value: source };\n }\n\n // StorageFile objects (from @warlock.js/core) can expose a `base64`\n // property alongside `url` / `absolutePath`. Check storage shape\n // first so we don't treat a StorageFile as an inline-bytes payload.\n if (\"url\" in source || \"absolutePath\" in source) {\n const storage = source as { url?: string; absolutePath?: string };\n\n if (storage.absolutePath) {\n return { type: \"path\", value: storage.absolutePath };\n }\n\n if (storage.url) {\n return { type: \"url\", value: storage.url };\n }\n\n throw new InvalidRequestError(\n \"Storage attachment has neither url nor absolutePath\",\n );\n }\n\n if (\"base64\" in source) {\n if (!source.base64 || !source.mediaType) {\n throw new InvalidRequestError(\n \"Inline attachment requires both `base64` and `mediaType`\",\n );\n }\n\n return {\n type: \"base64\",\n value: source.base64,\n mediaType: source.mediaType,\n };\n }\n\n throw new InvalidRequestError(\n \"Unrecognized attachment source — expected a string path/URL, a StorageFile, or `{ base64, mediaType }`\",\n );\n}\n"],"mappings":";;;;AAOA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B3B,SAAgB,kBAAkB,YAA4C;CAC5E,IACE,OAAO,eAAe,YACtB,eAAe,QACf,UAAU,YAEV,OAAO,cAAc,WAAW,MAAM;CAGxC,OAAO,cAAc,UAAU;AACjC;AAEA,SAAS,cAAc,QAA8C;CACnE,IAAI,OAAO,WAAW,UAAU;EAC9B,IAAI,CAAC,QACH,MAAM,IAAI,oBAAoB,wCAAwC;EAGxE,IAAI,mBAAmB,KAAK,MAAM,GAChC,OAAO;GAAE,MAAM;GAAO,OAAO;EAAO;EAGtC,OAAO;GAAE,MAAM;GAAQ,OAAO;EAAO;CACvC;CAKA,IAAI,SAAS,UAAU,kBAAkB,QAAQ;EAC/C,MAAM,UAAU;EAEhB,IAAI,QAAQ,cACV,OAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;EAAa;EAGrD,IAAI,QAAQ,KACV,OAAO;GAAE,MAAM;GAAO,OAAO,QAAQ;EAAI;EAG3C,MAAM,IAAI,oBACR,qDACF;CACF;CAEA,IAAI,YAAY,QAAQ;EACtB,IAAI,CAAC,OAAO,UAAU,CAAC,OAAO,WAC5B,MAAM,IAAI,oBACR,0DACF;EAGF,OAAO;GACL,MAAM;GACN,OAAO,OAAO;GACd,WAAW,OAAO;EACpB;CACF;CAEA,MAAM,IAAI,oBACR,wGACF;AACF"}
@@ -0,0 +1,94 @@
1
+ import { BaseReport } from "../contracts/result/base-report.type.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/utils/run-context.d.ts
4
+ /**
5
+ * The ambient run frame an executable reads when it finishes building
6
+ * its report. When present, a child execution (an `agent.execute()`,
7
+ * `workflow.execute()`, `supervisor.execute()` call) auto-attaches its
8
+ * report to `sink` and inherits the frame's `rootRunId` / `sessionId`
9
+ * lineage — so reports nest under the enclosing run with NO manual id
10
+ * threading by the dev.
11
+ *
12
+ * Installed by orchestration primitives (supervisor / orchestrator /
13
+ * team) around the synchronous + async body of an intent's callback,
14
+ * so any agent the callback invokes directly — `agent.execute(...)`
15
+ * rather than `ctx.run(...)` — still lands in the trace tree.
16
+ */
17
+ type RunFrame = {
18
+ /**
19
+ * The `children[]` array of the enclosing report node. A child
20
+ * execution pushes its assembled report here on completion.
21
+ */
22
+ sink: BaseReport[];
23
+ /**
24
+ * The outermost run-id this subtree belongs to. Propagated onto the
25
+ * child report's `rootRunId` so flat-row consumers group it with the
26
+ * enclosing run.
27
+ */
28
+ rootRunId: string;
29
+ /**
30
+ * Run-id of the enclosing node (the immediate parent of any child
31
+ * captured through this frame). Stamped onto the child's
32
+ * `parentRunId`.
33
+ */
34
+ parentRunId: string;
35
+ /**
36
+ * Session identifier propagated onto the captured child's subtree.
37
+ * `undefined` when the enclosing run had none.
38
+ */
39
+ sessionId?: string;
40
+ };
41
+ /**
42
+ * Run `fn` with `frame` installed as the ambient {@link RunFrame} for
43
+ * the entire async subtree it spawns. Restores the previous frame (or
44
+ * none) when `fn` settles. Returns whatever `fn` returns.
45
+ *
46
+ * Nesting is natural: a callback that itself dispatches a nested
47
+ * supervisor installs a fresh frame for the inner run, and the inner
48
+ * frame shadows the outer one for the inner subtree only — exactly the
49
+ * tree shape the report models.
50
+ */
51
+ declare function withRunFrame<T>(frame: RunFrame, fn: () => T): T;
52
+ /**
53
+ * Run `fn` with NO ambient {@link RunFrame} installed for its async
54
+ * subtree, restoring the previous frame when `fn` settles. Used by the
55
+ * supervisor's EXPLICIT capture paths (`ctx.run(...)` /
56
+ * `ctx.intents.X.execute()`) — those already push the child report onto
57
+ * the callback's `children[]` themselves, so the child must NOT also
58
+ * self-capture via the ambient frame (which would double-count it).
59
+ */
60
+ declare function withoutRunFrame<T>(fn: () => T): T;
61
+ /**
62
+ * Read the current ambient {@link RunFrame}, or `undefined` when no
63
+ * orchestration callback is on the stack. An executable calls this at
64
+ * report-build time: a present frame means "you were invoked inside a
65
+ * callback — attach yourself to its tree".
66
+ */
67
+ declare function currentRunFrame(): RunFrame | undefined;
68
+ /**
69
+ * Capture a freshly-built child `report` onto the current ambient
70
+ * {@link RunFrame} when one is installed. Pushes the report onto the
71
+ * frame's `sink` so it nests under the enclosing node, and rewrites the
72
+ * report's lineage (`rootRunId`, `parentRunId`, `sessionId`) to the
73
+ * frame's — mirroring how `step.agent` / `ctx.run` capture child
74
+ * reports explicitly, but driven ambiently.
75
+ *
76
+ * No-op (returns `false`) when no frame is installed — a standalone
77
+ * `agent.execute()` keeps its self-root untouched. Returns `true` when
78
+ * the report was captured so the caller can suppress its own terminal
79
+ * lineage stamp if needed.
80
+ *
81
+ * The lineage rewrite is intentionally shallow on the root + deep on
82
+ * descendants would double-stamp; callers pass the already-lineage-
83
+ * stamped subtree (self-root), and this relinks only the root's
84
+ * `rootRunId` / `parentRunId` / `sessionId`. Descendants already carry
85
+ * the child's own self-root as their `rootRunId`; the enclosing
86
+ * primitive's terminal `stampReportLineage` pass (run once on the
87
+ * outer tree) rewrites the whole subtree to the true outer root. This
88
+ * keeps capture cheap and defers the single authoritative relink to
89
+ * the outer build.
90
+ */
91
+ declare function captureChildReport(report: BaseReport): boolean;
92
+ //#endregion
93
+ export { RunFrame, captureChildReport, currentRunFrame, withRunFrame, withoutRunFrame };
94
+ //# sourceMappingURL=run-context.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-context.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/utils/run-context.ts"],"mappings":";;;;;AAgBA;;;;;;;;;;AAsBW;KAtBC,QAAA;EAqDgB;;;;EAhD1B,IAAA,EAAM,UAAU;EAgD8C;;;;;EA1C9D,SAAA;EA0C+C;;;AAAe;AAYhE;EAhDE,WAAA;EAgD6B;;;;EA3C7B,SAAA;AAAA;;AA2CgD;AAUlD;;;;AAA2C;AAsC3C;;;iBA5DgB,YAAA,IAAgB,KAAA,EAAO,QAAA,EAAU,EAAA,QAAU,CAAA,GAAI,CAAA;AA4DV;;;;;;;;AAAA,iBAhDrC,eAAA,IAAmB,EAAA,QAAU,CAAA,GAAI,CAAC;;;;;;;iBAUlC,eAAA,IAAmB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;iBAsC3B,kBAAA,CAAmB,MAAkB,EAAV,UAAU"}
@@ -0,0 +1,98 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ //#region ../@warlock.js/ai/src/utils/run-context.ts
4
+ /**
5
+ * Process-wide async-local store holding the current {@link RunFrame}.
6
+ * A single shared instance so a frame installed by the supervisor is
7
+ * visible to an agent running several `await`s deep inside a callback,
8
+ * across module boundaries. Empty (returns `undefined`) outside any
9
+ * orchestration callback — standalone `agent.execute()` is unaffected.
10
+ */
11
+ const runFrameStore = new AsyncLocalStorage();
12
+ /**
13
+ * A second async-local flag set whenever execution is nested inside a
14
+ * parent capture — by BOTH {@link withRunFrame} (ambient capture) and
15
+ * {@link withoutRunFrame} (explicit parent capture, which clears the frame).
16
+ * Lets the `observeAll` gate skip self-routing a nested run regardless of
17
+ * which capture path its parent uses — the parent already captures it.
18
+ */
19
+ const nestedStore = new AsyncLocalStorage();
20
+ /**
21
+ * Run `fn` with `frame` installed as the ambient {@link RunFrame} for
22
+ * the entire async subtree it spawns. Restores the previous frame (or
23
+ * none) when `fn` settles. Returns whatever `fn` returns.
24
+ *
25
+ * Nesting is natural: a callback that itself dispatches a nested
26
+ * supervisor installs a fresh frame for the inner run, and the inner
27
+ * frame shadows the outer one for the inner subtree only — exactly the
28
+ * tree shape the report models.
29
+ */
30
+ function withRunFrame(frame, fn) {
31
+ return nestedStore.run(true, () => runFrameStore.run(frame, fn));
32
+ }
33
+ /**
34
+ * Run `fn` with NO ambient {@link RunFrame} installed for its async
35
+ * subtree, restoring the previous frame when `fn` settles. Used by the
36
+ * supervisor's EXPLICIT capture paths (`ctx.run(...)` /
37
+ * `ctx.intents.X.execute()`) — those already push the child report onto
38
+ * the callback's `children[]` themselves, so the child must NOT also
39
+ * self-capture via the ambient frame (which would double-count it).
40
+ */
41
+ function withoutRunFrame(fn) {
42
+ return nestedStore.run(true, () => runFrameStore.run(void 0, fn));
43
+ }
44
+ /**
45
+ * Read the current ambient {@link RunFrame}, or `undefined` when no
46
+ * orchestration callback is on the stack. An executable calls this at
47
+ * report-build time: a present frame means "you were invoked inside a
48
+ * callback — attach yourself to its tree".
49
+ */
50
+ function currentRunFrame() {
51
+ return runFrameStore.getStore();
52
+ }
53
+ /**
54
+ * `true` when execution is nested inside a parent capture — set by
55
+ * {@link withRunFrame} (ambient) or {@link withoutRunFrame} (explicit). Read
56
+ * by the observe-all gate so a nested run, which its parent already captures
57
+ * into the trace tree, is not also self-routed as a standalone top-level
58
+ * trace. `false` for a standalone (root) run.
59
+ */
60
+ function isNestedRun() {
61
+ return nestedStore.getStore() === true;
62
+ }
63
+ /**
64
+ * Capture a freshly-built child `report` onto the current ambient
65
+ * {@link RunFrame} when one is installed. Pushes the report onto the
66
+ * frame's `sink` so it nests under the enclosing node, and rewrites the
67
+ * report's lineage (`rootRunId`, `parentRunId`, `sessionId`) to the
68
+ * frame's — mirroring how `step.agent` / `ctx.run` capture child
69
+ * reports explicitly, but driven ambiently.
70
+ *
71
+ * No-op (returns `false`) when no frame is installed — a standalone
72
+ * `agent.execute()` keeps its self-root untouched. Returns `true` when
73
+ * the report was captured so the caller can suppress its own terminal
74
+ * lineage stamp if needed.
75
+ *
76
+ * The lineage rewrite is intentionally shallow on the root + deep on
77
+ * descendants would double-stamp; callers pass the already-lineage-
78
+ * stamped subtree (self-root), and this relinks only the root's
79
+ * `rootRunId` / `parentRunId` / `sessionId`. Descendants already carry
80
+ * the child's own self-root as their `rootRunId`; the enclosing
81
+ * primitive's terminal `stampReportLineage` pass (run once on the
82
+ * outer tree) rewrites the whole subtree to the true outer root. This
83
+ * keeps capture cheap and defers the single authoritative relink to
84
+ * the outer build.
85
+ */
86
+ function captureChildReport(report) {
87
+ const frame = runFrameStore.getStore();
88
+ if (!frame) return false;
89
+ report.parentRunId = frame.parentRunId;
90
+ report.rootRunId = frame.rootRunId;
91
+ if (frame.sessionId !== void 0) report.sessionId = frame.sessionId;
92
+ frame.sink.push(report);
93
+ return true;
94
+ }
95
+
96
+ //#endregion
97
+ export { captureChildReport, currentRunFrame, isNestedRun, withRunFrame, withoutRunFrame };
98
+ //# sourceMappingURL=run-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-context.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/utils/run-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\n\n/**\n * The ambient run frame an executable reads when it finishes building\n * its report. When present, a child execution (an `agent.execute()`,\n * `workflow.execute()`, `supervisor.execute()` call) auto-attaches its\n * report to `sink` and inherits the frame's `rootRunId` / `sessionId`\n * lineage — so reports nest under the enclosing run with NO manual id\n * threading by the dev.\n *\n * Installed by orchestration primitives (supervisor / orchestrator /\n * team) around the synchronous + async body of an intent's callback,\n * so any agent the callback invokes directly — `agent.execute(...)`\n * rather than `ctx.run(...)` — still lands in the trace tree.\n */\nexport type RunFrame = {\n /**\n * The `children[]` array of the enclosing report node. A child\n * execution pushes its assembled report here on completion.\n */\n sink: BaseReport[];\n /**\n * The outermost run-id this subtree belongs to. Propagated onto the\n * child report's `rootRunId` so flat-row consumers group it with the\n * enclosing run.\n */\n rootRunId: string;\n /**\n * Run-id of the enclosing node (the immediate parent of any child\n * captured through this frame). Stamped onto the child's\n * `parentRunId`.\n */\n parentRunId: string;\n /**\n * Session identifier propagated onto the captured child's subtree.\n * `undefined` when the enclosing run had none.\n */\n sessionId?: string;\n};\n\n/**\n * Process-wide async-local store holding the current {@link RunFrame}.\n * A single shared instance so a frame installed by the supervisor is\n * visible to an agent running several `await`s deep inside a callback,\n * across module boundaries. Empty (returns `undefined`) outside any\n * orchestration callback — standalone `agent.execute()` is unaffected.\n */\nconst runFrameStore = new AsyncLocalStorage<RunFrame | undefined>();\n\n/**\n * A second async-local flag set whenever execution is nested inside a\n * parent capture — by BOTH {@link withRunFrame} (ambient capture) and\n * {@link withoutRunFrame} (explicit parent capture, which clears the frame).\n * Lets the `observeAll` gate skip self-routing a nested run regardless of\n * which capture path its parent uses — the parent already captures it.\n */\nconst nestedStore = new AsyncLocalStorage<boolean>();\n\n/**\n * Run `fn` with `frame` installed as the ambient {@link RunFrame} for\n * the entire async subtree it spawns. Restores the previous frame (or\n * none) when `fn` settles. Returns whatever `fn` returns.\n *\n * Nesting is natural: a callback that itself dispatches a nested\n * supervisor installs a fresh frame for the inner run, and the inner\n * frame shadows the outer one for the inner subtree only — exactly the\n * tree shape the report models.\n */\nexport function withRunFrame<T>(frame: RunFrame, fn: () => T): T {\n return nestedStore.run(true, () => runFrameStore.run(frame, fn));\n}\n\n/**\n * Run `fn` with NO ambient {@link RunFrame} installed for its async\n * subtree, restoring the previous frame when `fn` settles. Used by the\n * supervisor's EXPLICIT capture paths (`ctx.run(...)` /\n * `ctx.intents.X.execute()`) — those already push the child report onto\n * the callback's `children[]` themselves, so the child must NOT also\n * self-capture via the ambient frame (which would double-count it).\n */\nexport function withoutRunFrame<T>(fn: () => T): T {\n return nestedStore.run(true, () => runFrameStore.run(undefined, fn));\n}\n\n/**\n * Read the current ambient {@link RunFrame}, or `undefined` when no\n * orchestration callback is on the stack. An executable calls this at\n * report-build time: a present frame means \"you were invoked inside a\n * callback — attach yourself to its tree\".\n */\nexport function currentRunFrame(): RunFrame | undefined {\n return runFrameStore.getStore();\n}\n\n/**\n * `true` when execution is nested inside a parent capture — set by\n * {@link withRunFrame} (ambient) or {@link withoutRunFrame} (explicit). Read\n * by the observe-all gate so a nested run, which its parent already captures\n * into the trace tree, is not also self-routed as a standalone top-level\n * trace. `false` for a standalone (root) run.\n */\nexport function isNestedRun(): boolean {\n return nestedStore.getStore() === true;\n}\n\n/**\n * Capture a freshly-built child `report` onto the current ambient\n * {@link RunFrame} when one is installed. Pushes the report onto the\n * frame's `sink` so it nests under the enclosing node, and rewrites the\n * report's lineage (`rootRunId`, `parentRunId`, `sessionId`) to the\n * frame's — mirroring how `step.agent` / `ctx.run` capture child\n * reports explicitly, but driven ambiently.\n *\n * No-op (returns `false`) when no frame is installed — a standalone\n * `agent.execute()` keeps its self-root untouched. Returns `true` when\n * the report was captured so the caller can suppress its own terminal\n * lineage stamp if needed.\n *\n * The lineage rewrite is intentionally shallow on the root + deep on\n * descendants would double-stamp; callers pass the already-lineage-\n * stamped subtree (self-root), and this relinks only the root's\n * `rootRunId` / `parentRunId` / `sessionId`. Descendants already carry\n * the child's own self-root as their `rootRunId`; the enclosing\n * primitive's terminal `stampReportLineage` pass (run once on the\n * outer tree) rewrites the whole subtree to the true outer root. This\n * keeps capture cheap and defers the single authoritative relink to\n * the outer build.\n */\nexport function captureChildReport(report: BaseReport): boolean {\n const frame = runFrameStore.getStore();\n\n if (!frame) {\n return false;\n }\n\n report.parentRunId = frame.parentRunId;\n report.rootRunId = frame.rootRunId;\n\n if (frame.sessionId !== undefined) {\n report.sessionId = frame.sessionId;\n }\n\n frame.sink.push(report);\n\n return true;\n}\n"],"mappings":";;;;;;;;;;AAgDA,MAAM,gBAAgB,IAAI,kBAAwC;;;;;;;;AASlE,MAAM,cAAc,IAAI,kBAA2B;;;;;;;;;;;AAYnD,SAAgB,aAAgB,OAAiB,IAAgB;CAC/D,OAAO,YAAY,IAAI,YAAY,cAAc,IAAI,OAAO,EAAE,CAAC;AACjE;;;;;;;;;AAUA,SAAgB,gBAAmB,IAAgB;CACjD,OAAO,YAAY,IAAI,YAAY,cAAc,IAAI,QAAW,EAAE,CAAC;AACrE;;;;;;;AAQA,SAAgB,kBAAwC;CACtD,OAAO,cAAc,SAAS;AAChC;;;;;;;;AASA,SAAgB,cAAuB;CACrC,OAAO,YAAY,SAAS,MAAM;AACpC;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,mBAAmB,QAA6B;CAC9D,MAAM,QAAQ,cAAc,SAAS;CAErC,IAAI,CAAC,OACH,OAAO;CAGT,OAAO,cAAc,MAAM;CAC3B,OAAO,YAAY,MAAM;CAEzB,IAAI,MAAM,cAAc,QACtB,OAAO,YAAY,MAAM;CAG3B,MAAM,KAAK,KAAK,MAAM;CAEtB,OAAO;AACT"}
@@ -0,0 +1,57 @@
1
+ //#region ../@warlock.js/ai/src/vcr/cassette-io.ts
2
+ let fsModule;
3
+ /**
4
+ * Resolve `node:fs/promises` once and memoize it.
5
+ */
6
+ async function loadFs() {
7
+ if (!fsModule) fsModule = await import("node:fs/promises");
8
+ return fsModule;
9
+ }
10
+ /**
11
+ * Build a fresh, empty cassette for a model identity. Used when the path
12
+ * does not exist yet (first record run).
13
+ */
14
+ function emptyCassette(model, provider) {
15
+ return {
16
+ version: 1,
17
+ model,
18
+ provider,
19
+ entries: []
20
+ };
21
+ }
22
+ /**
23
+ * Load a cassette from disk. Returns a fresh empty cassette (not an error)
24
+ * when the file does not exist — the common first-record case. Any other I/O
25
+ * or parse failure rejects so corruption is never silently swallowed.
26
+ */
27
+ async function loadCassette(path, model, provider) {
28
+ const fs = await loadFs();
29
+ let raw;
30
+ try {
31
+ raw = await fs.readFile(path, "utf8");
32
+ } catch (error) {
33
+ if (error.code === "ENOENT") return emptyCassette(model, provider);
34
+ throw error;
35
+ }
36
+ const parsed = JSON.parse(raw);
37
+ return {
38
+ version: 1,
39
+ model: parsed.model ?? model,
40
+ provider: parsed.provider ?? provider,
41
+ entries: Array.isArray(parsed.entries) ? parsed.entries : []
42
+ };
43
+ }
44
+ /**
45
+ * Write a cassette to disk as pretty-printed JSON, creating the parent
46
+ * directory if needed so a brand-new `./cassettes/foo.json` path just works.
47
+ */
48
+ async function saveCassette(path, cassette) {
49
+ const fs = await loadFs();
50
+ const dir = (await import("node:path")).dirname(path);
51
+ if (dir && dir !== "." && dir !== path) await fs.mkdir(dir, { recursive: true });
52
+ await fs.writeFile(path, JSON.stringify(cassette, void 0, 2), "utf8");
53
+ }
54
+
55
+ //#endregion
56
+ export { emptyCassette, loadCassette, saveCassette };
57
+ //# sourceMappingURL=cassette-io.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette-io.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/cassette-io.ts"],"sourcesContent":["import type { Cassette } from \"./vcr.type\";\n\n/**\n * Lazily-resolved `node:fs/promises` module. VCR cassette I/O only touches\n * disk on construct (load) and on `save()` — keeping the import lazy means\n * importing the `vcr` factory never eagerly pulls `node:fs`, which keeps the\n * surface usable in non-node bundles that never call a disk path.\n */\ntype FsPromises = typeof import(\"node:fs/promises\");\n\nlet fsModule: FsPromises | undefined;\n\n/**\n * Resolve `node:fs/promises` once and memoize it.\n */\nasync function loadFs(): Promise<FsPromises> {\n if (!fsModule) {\n fsModule = await import(\"node:fs/promises\");\n }\n\n return fsModule;\n}\n\n/**\n * Build a fresh, empty cassette for a model identity. Used when the path\n * does not exist yet (first record run).\n */\nexport function emptyCassette(model: string, provider: string): Cassette {\n return {\n version: 1,\n model,\n provider,\n entries: [],\n };\n}\n\n/**\n * Load a cassette from disk. Returns a fresh empty cassette (not an error)\n * when the file does not exist — the common first-record case. Any other I/O\n * or parse failure rejects so corruption is never silently swallowed.\n */\nexport async function loadCassette(\n path: string,\n model: string,\n provider: string,\n): Promise<Cassette> {\n const fs = await loadFs();\n\n let raw: string;\n\n try {\n raw = await fs.readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return emptyCassette(model, provider);\n }\n\n throw error;\n }\n\n const parsed = JSON.parse(raw) as Cassette;\n\n return {\n version: 1,\n model: parsed.model ?? model,\n provider: parsed.provider ?? provider,\n entries: Array.isArray(parsed.entries) ? parsed.entries : [],\n };\n}\n\n/**\n * Write a cassette to disk as pretty-printed JSON, creating the parent\n * directory if needed so a brand-new `./cassettes/foo.json` path just works.\n */\nexport async function saveCassette(path: string, cassette: Cassette): Promise<void> {\n const fs = await loadFs();\n const nodePath = await import(\"node:path\");\n const dir = nodePath.dirname(path);\n\n if (dir && dir !== \".\" && dir !== path) {\n await fs.mkdir(dir, { recursive: true });\n }\n\n await fs.writeFile(path, JSON.stringify(cassette, undefined, 2), \"utf8\");\n}\n"],"mappings":";AAUA,IAAI;;;;AAKJ,eAAe,SAA8B;CAC3C,IAAI,CAAC,UACH,WAAW,MAAM,OAAO;CAG1B,OAAO;AACT;;;;;AAMA,SAAgB,cAAc,OAAe,UAA4B;CACvE,OAAO;EACL,SAAS;EACT;EACA;EACA,SAAS,CAAC;CACZ;AACF;;;;;;AAOA,eAAsB,aACpB,MACA,OACA,UACmB;CACnB,MAAM,KAAK,MAAM,OAAO;CAExB,IAAI;CAEJ,IAAI;EACF,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM;CACtC,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAC5C,OAAO,cAAc,OAAO,QAAQ;EAGtC,MAAM;CACR;CAEA,MAAM,SAAS,KAAK,MAAM,GAAG;CAE7B,OAAO;EACL,SAAS;EACT,OAAO,OAAO,SAAS;EACvB,UAAU,OAAO,YAAY;EAC7B,SAAS,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;CAC7D;AACF;;;;;AAMA,eAAsB,aAAa,MAAc,UAAmC;CAClF,MAAM,KAAK,MAAM,OAAO;CAExB,MAAM,OAAM,MADW,OAAO,aACV,CAAC,QAAQ,IAAI;CAEjC,IAAI,OAAO,QAAQ,OAAO,QAAQ,MAChC,MAAM,GAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;CAGzC,MAAM,GAAG,UAAU,MAAM,KAAK,UAAU,UAAU,QAAW,CAAC,GAAG,MAAM;AACzE"}
@@ -0,0 +1,42 @@
1
+ import { AIError, AIErrorOptions } from "../errors/ai-error.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/vcr/errors.d.ts
4
+ /**
5
+ * Payload for {@link VcrCassetteMissError}. Carries the looked-up request
6
+ * hash and the cassette path so a failing CI run names exactly which call
7
+ * was not recorded.
8
+ */
9
+ type VcrCassetteMissErrorOptions = AIErrorOptions & {
10
+ /** The normalized request hash that found no matching cassette entry. */requestHash?: string; /** Cassette file path the lookup ran against. */
11
+ path?: string;
12
+ };
13
+ /**
14
+ * Thrown when a `vcr(model, { mode: "replay" })` call finds no cassette
15
+ * entry matching the request hash.
16
+ *
17
+ * **The whole point of deterministic tests.** VCR in `replay` mode never
18
+ * falls back to a live provider call on a miss — that would silently
19
+ * re-introduce network/non-determinism into a test that asked for the
20
+ * opposite. Instead it throws this error so the run fails loud, telling
21
+ * the developer to re-record the cassette (run once in `record`/`auto`).
22
+ *
23
+ * Extends {@link AIError} directly (not `ProviderError`) — a cassette miss
24
+ * is a harness/config failure, not a provider failure.
25
+ *
26
+ * @example
27
+ * try {
28
+ * await vcrModel.complete(messages);
29
+ * } catch (error) {
30
+ * if (error instanceof VcrCassetteMissError) {
31
+ * console.error("Re-record the cassette:", error.path);
32
+ * }
33
+ * }
34
+ */
35
+ declare class VcrCassetteMissError extends AIError {
36
+ readonly requestHash?: string;
37
+ readonly path?: string;
38
+ constructor(message: string, options?: VcrCassetteMissErrorOptions);
39
+ }
40
+ //#endregion
41
+ export { VcrCassetteMissError, VcrCassetteMissErrorOptions };
42
+ //# sourceMappingURL=errors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/errors.ts"],"mappings":";;;;AAQA;;;;KAAY,2BAAA,GAA8B,cAAc;EAEtD,yEAAA,WAAA,WAEI;EAAJ,IAAA;AAAA;;;;;;;;;;;;AA6ByE;;;;;;;;;;;cAJ9D,oBAAA,SAA6B,OAAO;EAAA,SAC/B,WAAA;EAAA,SACA,IAAA;cAEG,OAAA,UAAiB,OAAA,GAAU,2BAAA;AAAA"}
@@ -0,0 +1,37 @@
1
+ import { AIError } from "../errors/ai-error.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/vcr/errors.ts
4
+ /**
5
+ * Thrown when a `vcr(model, { mode: "replay" })` call finds no cassette
6
+ * entry matching the request hash.
7
+ *
8
+ * **The whole point of deterministic tests.** VCR in `replay` mode never
9
+ * falls back to a live provider call on a miss — that would silently
10
+ * re-introduce network/non-determinism into a test that asked for the
11
+ * opposite. Instead it throws this error so the run fails loud, telling
12
+ * the developer to re-record the cassette (run once in `record`/`auto`).
13
+ *
14
+ * Extends {@link AIError} directly (not `ProviderError`) — a cassette miss
15
+ * is a harness/config failure, not a provider failure.
16
+ *
17
+ * @example
18
+ * try {
19
+ * await vcrModel.complete(messages);
20
+ * } catch (error) {
21
+ * if (error instanceof VcrCassetteMissError) {
22
+ * console.error("Re-record the cassette:", error.path);
23
+ * }
24
+ * }
25
+ */
26
+ var VcrCassetteMissError = class extends AIError {
27
+ constructor(message, options) {
28
+ super("VCR_CASSETTE_MISS", message, options);
29
+ this.name = "VcrCassetteMissError";
30
+ this.requestHash = options?.requestHash;
31
+ this.path = options?.path;
32
+ }
33
+ };
34
+
35
+ //#endregion
36
+ export { VcrCassetteMissError };
37
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/errors.ts"],"sourcesContent":["import { AIError } from \"../errors/ai-error\";\nimport type { AIErrorOptions } from \"../errors/ai-error\";\n\n/**\n * Payload for {@link VcrCassetteMissError}. Carries the looked-up request\n * hash and the cassette path so a failing CI run names exactly which call\n * was not recorded.\n */\nexport type VcrCassetteMissErrorOptions = AIErrorOptions & {\n /** The normalized request hash that found no matching cassette entry. */\n requestHash?: string;\n /** Cassette file path the lookup ran against. */\n path?: string;\n};\n\n/**\n * Thrown when a `vcr(model, { mode: \"replay\" })` call finds no cassette\n * entry matching the request hash.\n *\n * **The whole point of deterministic tests.** VCR in `replay` mode never\n * falls back to a live provider call on a miss — that would silently\n * re-introduce network/non-determinism into a test that asked for the\n * opposite. Instead it throws this error so the run fails loud, telling\n * the developer to re-record the cassette (run once in `record`/`auto`).\n *\n * Extends {@link AIError} directly (not `ProviderError`) — a cassette miss\n * is a harness/config failure, not a provider failure.\n *\n * @example\n * try {\n * await vcrModel.complete(messages);\n * } catch (error) {\n * if (error instanceof VcrCassetteMissError) {\n * console.error(\"Re-record the cassette:\", error.path);\n * }\n * }\n */\nexport class VcrCassetteMissError extends AIError {\n public readonly requestHash?: string;\n public readonly path?: string;\n\n public constructor(message: string, options?: VcrCassetteMissErrorOptions) {\n super(\"VCR_CASSETTE_MISS\", message, options);\n this.name = \"VcrCassetteMissError\";\n this.requestHash = options?.requestHash;\n this.path = options?.path;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,IAAa,uBAAb,cAA0C,QAAQ;CAIhD,AAAO,YAAY,SAAiB,SAAuC;EACzE,MAAM,qBAAqB,SAAS,OAAO;EAC3C,KAAK,OAAO;EACZ,KAAK,cAAc,SAAS;EAC5B,KAAK,OAAO,SAAS;CACvB;AACF"}
@@ -0,0 +1,28 @@
1
+ import { Message } from "../contracts/conversation-message.type.mjs";
2
+ import { ModelCallOptions } from "../contracts/model.contract.mjs";
3
+
4
+ //#region ../@warlock.js/ai/src/vcr/hash-request.d.ts
5
+ /**
6
+ * Default `ModelCallOptions` fields folded into the request hash. These are
7
+ * the inputs that materially change the model's output; everything else
8
+ * (notably `signal` and unknown provider keys) is excluded so an otherwise
9
+ * identical logical call still matches its recording.
10
+ */
11
+ declare const DEFAULT_HASH_OPTIONS: readonly string[];
12
+ /**
13
+ * Compute the stable VCR request hash for a model call.
14
+ *
15
+ * The hash covers the full `messages` array plus the picked, normalized
16
+ * `options` subset (see {@link DEFAULT_HASH_OPTIONS}). Inputs are
17
+ * canonicalized (recursive key sort) before serialization so property order
18
+ * never affects the result. `signal` and unknown provider keys are excluded.
19
+ *
20
+ * @example
21
+ * const a = hashRequest(messages, { temperature: 0.2 });
22
+ * const b = hashRequest(messages, { temperature: 0.2, signal });
23
+ * // a === b — signal is excluded.
24
+ */
25
+ declare function hashRequest(messages: Message[], options?: ModelCallOptions, hashOptions?: readonly string[]): string;
26
+ //#endregion
27
+ export { DEFAULT_HASH_OPTIONS, hashRequest };
28
+ //# sourceMappingURL=hash-request.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-request.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/hash-request.ts"],"mappings":";;;;;;AAUA;;;;cAAa,oBAAA;AAiJb;;;;;;;;;;AAGuD;;;AAHvD,iBAAgB,WAAA,CACd,QAAA,EAAU,OAAA,IACV,OAAA,GAAU,gBAAgB,EAC1B,WAAA"}
@@ -0,0 +1,118 @@
1
+ //#region ../@warlock.js/ai/src/vcr/hash-request.ts
2
+ /**
3
+ * Default `ModelCallOptions` fields folded into the request hash. These are
4
+ * the inputs that materially change the model's output; everything else
5
+ * (notably `signal` and unknown provider keys) is excluded so an otherwise
6
+ * identical logical call still matches its recording.
7
+ */
8
+ const DEFAULT_HASH_OPTIONS = [
9
+ "temperature",
10
+ "maxTokens",
11
+ "responseSchema",
12
+ "tools",
13
+ "reasoning"
14
+ ];
15
+ /**
16
+ * Reduce a tool to the parts the model actually conditions on: its name,
17
+ * description, and the *shape* of its input schema. Two tools that differ
18
+ * only by object identity (a fresh schema instance per import) hash
19
+ * identically; a real contract change (renamed field, new description)
20
+ * invalidates the recording.
21
+ *
22
+ * The input schema is fingerprinted structurally — a Standard Schema is an
23
+ * opaque object, so we serialize its enumerable own keys rather than
24
+ * attempting to read its internals.
25
+ */
26
+ function fingerprintTool(tool) {
27
+ return {
28
+ name: tool.name,
29
+ description: tool.description,
30
+ input: tool.input ? schemaShape(tool.input) : void 0
31
+ };
32
+ }
33
+ /**
34
+ * Produce a stable, JSON-safe fingerprint of an arbitrary schema object.
35
+ * Records only the structural skeleton (own enumerable keys, recursively)
36
+ * so harmless instance differences don't perturb the hash while a genuine
37
+ * structural change does.
38
+ */
39
+ function schemaShape(value, depth = 0) {
40
+ if (depth > 6 || value === null || typeof value !== "object") return typeof value;
41
+ if (Array.isArray(value)) return value.map((item) => schemaShape(item, depth + 1));
42
+ const out = {};
43
+ for (const key of Object.keys(value).sort()) out[key] = schemaShape(value[key], depth + 1);
44
+ return out;
45
+ }
46
+ /**
47
+ * Pick the hashable subset of `options`, normalizing `tools` into their
48
+ * name+description+schema-shape fingerprint. `signal` and any field not in
49
+ * `hashOptions` are dropped.
50
+ */
51
+ function pickOptions(options, hashOptions) {
52
+ if (!options) return {};
53
+ const picked = {};
54
+ for (const key of hashOptions) {
55
+ const value = options[key];
56
+ if (value === void 0) continue;
57
+ if (key === "tools" && Array.isArray(value)) {
58
+ picked[key] = value.map(fingerprintTool);
59
+ continue;
60
+ }
61
+ picked[key] = value;
62
+ }
63
+ return picked;
64
+ }
65
+ /**
66
+ * Recursively sort object keys so two logically-equal payloads serialize to
67
+ * byte-identical JSON regardless of property insertion order.
68
+ */
69
+ function canonicalize(value) {
70
+ if (value === null || typeof value !== "object") return value;
71
+ if (Array.isArray(value)) return value.map(canonicalize);
72
+ const out = {};
73
+ for (const key of Object.keys(value).sort()) out[key] = canonicalize(value[key]);
74
+ return out;
75
+ }
76
+ /**
77
+ * Non-cryptographic 53-bit string hash (FNV-style, cyrb53). Deterministic
78
+ * across runs and platforms; collision-resistant enough for a per-cassette
79
+ * keyspace. Returned as a base-36 string.
80
+ */
81
+ function hashString(input) {
82
+ let h1 = 3735928559;
83
+ let h2 = 1103547991;
84
+ for (let i = 0; i < input.length; i++) {
85
+ const ch = input.charCodeAt(i);
86
+ h1 = Math.imul(h1 ^ ch, 2654435761);
87
+ h2 = Math.imul(h2 ^ ch, 1597334677);
88
+ }
89
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
90
+ h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
91
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
92
+ h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
93
+ return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
94
+ }
95
+ /**
96
+ * Compute the stable VCR request hash for a model call.
97
+ *
98
+ * The hash covers the full `messages` array plus the picked, normalized
99
+ * `options` subset (see {@link DEFAULT_HASH_OPTIONS}). Inputs are
100
+ * canonicalized (recursive key sort) before serialization so property order
101
+ * never affects the result. `signal` and unknown provider keys are excluded.
102
+ *
103
+ * @example
104
+ * const a = hashRequest(messages, { temperature: 0.2 });
105
+ * const b = hashRequest(messages, { temperature: 0.2, signal });
106
+ * // a === b — signal is excluded.
107
+ */
108
+ function hashRequest(messages, options, hashOptions = DEFAULT_HASH_OPTIONS) {
109
+ const payload = canonicalize({
110
+ messages,
111
+ options: pickOptions(options, hashOptions)
112
+ });
113
+ return hashString(JSON.stringify(payload));
114
+ }
115
+
116
+ //#endregion
117
+ export { DEFAULT_HASH_OPTIONS, hashRequest };
118
+ //# sourceMappingURL=hash-request.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-request.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/hash-request.ts"],"sourcesContent":["import type { Message } from \"../contracts/conversation-message.type\";\nimport type { ModelCallOptions } from \"../contracts/model.contract\";\nimport type { ToolConfig } from \"../contracts/tool.contract\";\n\n/**\n * Default `ModelCallOptions` fields folded into the request hash. These are\n * the inputs that materially change the model's output; everything else\n * (notably `signal` and unknown provider keys) is excluded so an otherwise\n * identical logical call still matches its recording.\n */\nexport const DEFAULT_HASH_OPTIONS: readonly string[] = [\n \"temperature\",\n \"maxTokens\",\n \"responseSchema\",\n \"tools\",\n \"reasoning\",\n];\n\n/**\n * Reduce a tool to the parts the model actually conditions on: its name,\n * description, and the *shape* of its input schema. Two tools that differ\n * only by object identity (a fresh schema instance per import) hash\n * identically; a real contract change (renamed field, new description)\n * invalidates the recording.\n *\n * The input schema is fingerprinted structurally — a Standard Schema is an\n * opaque object, so we serialize its enumerable own keys rather than\n * attempting to read its internals.\n */\nfunction fingerprintTool(tool: ToolConfig<unknown, unknown>): unknown {\n return {\n name: tool.name,\n description: tool.description,\n input: tool.input ? schemaShape(tool.input) : undefined,\n };\n}\n\n/**\n * Produce a stable, JSON-safe fingerprint of an arbitrary schema object.\n * Records only the structural skeleton (own enumerable keys, recursively)\n * so harmless instance differences don't perturb the hash while a genuine\n * structural change does.\n */\nfunction schemaShape(value: unknown, depth = 0): unknown {\n if (depth > 6 || value === null || typeof value !== \"object\") {\n return typeof value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => schemaShape(item, depth + 1));\n }\n\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = schemaShape((value as Record<string, unknown>)[key], depth + 1);\n }\n\n return out;\n}\n\n/**\n * Pick the hashable subset of `options`, normalizing `tools` into their\n * name+description+schema-shape fingerprint. `signal` and any field not in\n * `hashOptions` are dropped.\n */\nfunction pickOptions(\n options: ModelCallOptions | undefined,\n hashOptions: readonly string[],\n): Record<string, unknown> {\n if (!options) {\n return {};\n }\n\n const picked: Record<string, unknown> = {};\n\n for (const key of hashOptions) {\n const value = options[key];\n\n if (value === undefined) {\n continue;\n }\n\n if (key === \"tools\" && Array.isArray(value)) {\n picked[key] = (value as ToolConfig<unknown, unknown>[]).map(fingerprintTool);\n continue;\n }\n\n picked[key] = value;\n }\n\n return picked;\n}\n\n/**\n * Recursively sort object keys so two logically-equal payloads serialize to\n * byte-identical JSON regardless of property insertion order.\n */\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(canonicalize);\n }\n\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = canonicalize((value as Record<string, unknown>)[key]);\n }\n\n return out;\n}\n\n/**\n * Non-cryptographic 53-bit string hash (FNV-style, cyrb53). Deterministic\n * across runs and platforms; collision-resistant enough for a per-cassette\n * keyspace. Returned as a base-36 string.\n */\nfunction hashString(input: string): string {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n\n for (let i = 0; i < input.length; i++) {\n const ch = input.charCodeAt(i);\n\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);\n h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);\n h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n\n const combined = 4294967296 * (2097151 & h2) + (h1 >>> 0);\n\n return combined.toString(36);\n}\n\n/**\n * Compute the stable VCR request hash for a model call.\n *\n * The hash covers the full `messages` array plus the picked, normalized\n * `options` subset (see {@link DEFAULT_HASH_OPTIONS}). Inputs are\n * canonicalized (recursive key sort) before serialization so property order\n * never affects the result. `signal` and unknown provider keys are excluded.\n *\n * @example\n * const a = hashRequest(messages, { temperature: 0.2 });\n * const b = hashRequest(messages, { temperature: 0.2, signal });\n * // a === b — signal is excluded.\n */\nexport function hashRequest(\n messages: Message[],\n options?: ModelCallOptions,\n hashOptions: readonly string[] = DEFAULT_HASH_OPTIONS,\n): string {\n const payload = canonicalize({\n messages,\n options: pickOptions(options, hashOptions),\n });\n\n return hashString(JSON.stringify(payload));\n}\n"],"mappings":";;;;;;;AAUA,MAAa,uBAA0C;CACrD;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;AAaA,SAAS,gBAAgB,MAA6C;CACpE,OAAO;EACL,MAAM,KAAK;EACX,aAAa,KAAK;EAClB,OAAO,KAAK,QAAQ,YAAY,KAAK,KAAK,IAAI;CAChD;AACF;;;;;;;AAQA,SAAS,YAAY,OAAgB,QAAQ,GAAY;CACvD,IAAI,QAAQ,KAAK,UAAU,QAAQ,OAAO,UAAU,UAClD,OAAO,OAAO;CAGhB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,KAAK,SAAS,YAAY,MAAM,QAAQ,CAAC,CAAC;CAGzD,MAAM,MAA+B,CAAC;CAEtC,KAAK,MAAM,OAAO,OAAO,KAAK,KAAgC,CAAC,CAAC,KAAK,GACnE,IAAI,OAAO,YAAa,MAAkC,MAAM,QAAQ,CAAC;CAG3E,OAAO;AACT;;;;;;AAOA,SAAS,YACP,SACA,aACyB;CACzB,IAAI,CAAC,SACH,OAAO,CAAC;CAGV,MAAM,SAAkC,CAAC;CAEzC,KAAK,MAAM,OAAO,aAAa;EAC7B,MAAM,QAAQ,QAAQ;EAEtB,IAAI,UAAU,QACZ;EAGF,IAAI,QAAQ,WAAW,MAAM,QAAQ,KAAK,GAAG;GAC3C,OAAO,OAAQ,MAAyC,IAAI,eAAe;GAC3E;EACF;EAEA,OAAO,OAAO;CAChB;CAEA,OAAO;AACT;;;;;AAMA,SAAS,aAAa,OAAyB;CAC7C,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAGT,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,IAAI,YAAY;CAG/B,MAAM,MAA+B,CAAC;CAEtC,KAAK,MAAM,OAAO,OAAO,KAAK,KAAgC,CAAC,CAAC,KAAK,GACnE,IAAI,OAAO,aAAc,MAAkC,IAAI;CAGjE,OAAO;AACT;;;;;;AAOA,SAAS,WAAW,OAAuB;CACzC,IAAI,KAAK;CACT,IAAI,KAAK;CAET,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,KAAK,MAAM,WAAW,CAAC;EAE7B,KAAK,KAAK,KAAK,KAAK,IAAI,UAAU;EAClC,KAAK,KAAK,KAAK,KAAK,IAAI,UAAU;CACpC;CAEA,KAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CAC3C,MAAM,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CAC5C,KAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CAC3C,MAAM,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CAI5C,QAFiB,cAAc,UAAU,OAAO,OAAO,GAExC,CAAC,SAAS,EAAE;AAC7B;;;;;;;;;;;;;;AAeA,SAAgB,YACd,UACA,SACA,cAAiC,sBACzB;CACR,MAAM,UAAU,aAAa;EAC3B;EACA,SAAS,YAAY,SAAS,WAAW;CAC3C,CAAC;CAED,OAAO,WAAW,KAAK,UAAU,OAAO,CAAC;AAC3C"}
@@ -0,0 +1,4 @@
1
+ import { Cassette, CassetteEntry, VcrMode, VcrModel, VcrOptions } from "./vcr.type.mjs";
2
+ import { vcr } from "./vcr.mjs";
3
+ import { VcrCassetteMissError, VcrCassetteMissErrorOptions } from "./errors.mjs";
4
+ import { DEFAULT_HASH_OPTIONS, hashRequest } from "./hash-request.mjs";
@@ -0,0 +1,5 @@
1
+ import { VcrCassetteMissError } from "./errors.mjs";
2
+ import { DEFAULT_HASH_OPTIONS, hashRequest } from "./hash-request.mjs";
3
+ import { vcr } from "./vcr.mjs";
4
+
5
+ export { };
@@ -0,0 +1,32 @@
1
+ import { ModelContract } from "../contracts/model.contract.mjs";
2
+ import { VcrModel, VcrOptions } from "./vcr.type.mjs";
3
+
4
+ //#region ../@warlock.js/ai/src/vcr/vcr.d.ts
5
+ /**
6
+ * Wrap any `ModelContract` in a record/replay decorator backed by a JSON
7
+ * cassette on disk.
8
+ *
9
+ * **What it does.** Intercepts only `complete()`/`stream()` — the single
10
+ * seam every agent trip funnels through — and delegates `name`, `provider`,
11
+ * `capabilities`, and `pricing` to the inner model untouched. On a call it
12
+ * computes a stable hash over `{ messages, picked options }` and, depending
13
+ * on `mode`:
14
+ *
15
+ * - **`record`** — always calls the inner model and appends a cassette entry.
16
+ * - **`replay`** — returns the matching entry (or re-yields its chunks /
17
+ * re-throws its error); a miss throws `VcrCassetteMissError`, never a live
18
+ * call.
19
+ * - **`auto`** (default) — replays a hit, records a miss.
20
+ *
21
+ * Composes *below* `fallbackModel` and works with any adapter because it
22
+ * depends only on `ModelContract`. Call `save()` to flush new entries.
23
+ *
24
+ * @example
25
+ * const model = vcr(liveModel, { path: "./cassettes/support.json" });
26
+ * const response = await model.complete(messages);
27
+ * await model.save(); // first run records; later runs replay deterministically.
28
+ */
29
+ declare function vcr(model: ModelContract, options: VcrOptions): VcrModel;
30
+ //#endregion
31
+ export { vcr };
32
+ //# sourceMappingURL=vcr.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vcr.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/vcr/vcr.ts"],"mappings":";;;;;;AA8UA;;;;;;;;;;;;;;AAAwE;;;;;;;;iBAAxD,GAAA,CAAI,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,UAAA,GAAa,QAAA"}