@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
@@ -0,0 +1,27 @@
1
+ import { VectorStore } from "./vector-store.contract.mjs";
2
+ import { CacheDriver } from "@warlock.js/cache";
3
+
4
+ //#region ../@warlock.js/ai/src/rag/store/cache-vector-store.d.ts
5
+ /**
6
+ * Adapt any `@warlock.js/cache` `CacheDriver` to the {@link VectorStore}
7
+ * narrowing the RAG pipeline depends on. The cache driver IS the vector
8
+ * store — exactly as `SemanticMemory` and `semanticCache` already use it:
9
+ *
10
+ * - `upsert` → `driver.set(key, value, { vector, tags })`
11
+ * - `query` → `driver.similar<T>(vector, { topK, threshold, tags })`
12
+ * - `removeNamespace` → `driver.removeNamespace(namespace)`
13
+ *
14
+ * Drivers without similarity support throw `CacheUnsupportedError` from
15
+ * `set({ vector })` / `similar()`; the error surfaces unchanged so the
16
+ * caller sees the cache layer's own message (pointing at the `pg` /
17
+ * `redis` drivers for production-scale similarity).
18
+ *
19
+ * @example
20
+ * const store = cacheVectorStore(new MemoryCacheDriver());
21
+ * await store.upsert("ai.rag.docs.guide.0", { text: "…" }, vector);
22
+ * const hits = await store.query(queryVector, { topK: 5, threshold: 0.5 });
23
+ */
24
+ declare function cacheVectorStore(driver: CacheDriver<any, any>): VectorStore;
25
+ //#endregion
26
+ export { cacheVectorStore };
27
+ //# sourceMappingURL=cache-vector-store.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-vector-store.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/store/cache-vector-store.ts"],"mappings":";;;;;;AAsBA;;;;;;;;AAA4E;;;;;;;;;iBAA5D,gBAAA,CAAiB,MAAA,EAAQ,WAAA,aAAwB,WAAW"}
@@ -0,0 +1,48 @@
1
+ //#region ../@warlock.js/ai/src/rag/store/cache-vector-store.ts
2
+ /**
3
+ * Adapt any `@warlock.js/cache` `CacheDriver` to the {@link VectorStore}
4
+ * narrowing the RAG pipeline depends on. The cache driver IS the vector
5
+ * store — exactly as `SemanticMemory` and `semanticCache` already use it:
6
+ *
7
+ * - `upsert` → `driver.set(key, value, { vector, tags })`
8
+ * - `query` → `driver.similar<T>(vector, { topK, threshold, tags })`
9
+ * - `removeNamespace` → `driver.removeNamespace(namespace)`
10
+ *
11
+ * Drivers without similarity support throw `CacheUnsupportedError` from
12
+ * `set({ vector })` / `similar()`; the error surfaces unchanged so the
13
+ * caller sees the cache layer's own message (pointing at the `pg` /
14
+ * `redis` drivers for production-scale similarity).
15
+ *
16
+ * @example
17
+ * const store = cacheVectorStore(new MemoryCacheDriver());
18
+ * await store.upsert("ai.rag.docs.guide.0", { text: "…" }, vector);
19
+ * const hits = await store.query(queryVector, { topK: 5, threshold: 0.5 });
20
+ */
21
+ function cacheVectorStore(driver) {
22
+ return {
23
+ async upsert(key, value, vector, tags) {
24
+ await driver.set(key, value, tags && tags.length > 0 ? {
25
+ vector,
26
+ tags
27
+ } : { vector });
28
+ },
29
+ async query(vector, options) {
30
+ return (await driver.similar(vector, {
31
+ topK: options.topK,
32
+ threshold: options.threshold,
33
+ tags: options.tags
34
+ })).map((hit) => ({
35
+ key: hit.key,
36
+ value: hit.value,
37
+ score: hit.score
38
+ }));
39
+ },
40
+ async removeNamespace(namespace) {
41
+ await driver.removeNamespace(namespace);
42
+ }
43
+ };
44
+ }
45
+
46
+ //#endregion
47
+ export { cacheVectorStore };
48
+ //# sourceMappingURL=cache-vector-store.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-vector-store.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/store/cache-vector-store.ts"],"sourcesContent":["import type { CacheDriver } from \"@warlock.js/cache\";\nimport type { VectorStore } from \"./vector-store.contract\";\n\n/**\n * Adapt any `@warlock.js/cache` `CacheDriver` to the {@link VectorStore}\n * narrowing the RAG pipeline depends on. The cache driver IS the vector\n * store — exactly as `SemanticMemory` and `semanticCache` already use it:\n *\n * - `upsert` → `driver.set(key, value, { vector, tags })`\n * - `query` → `driver.similar<T>(vector, { topK, threshold, tags })`\n * - `removeNamespace` → `driver.removeNamespace(namespace)`\n *\n * Drivers without similarity support throw `CacheUnsupportedError` from\n * `set({ vector })` / `similar()`; the error surfaces unchanged so the\n * caller sees the cache layer's own message (pointing at the `pg` /\n * `redis` drivers for production-scale similarity).\n *\n * @example\n * const store = cacheVectorStore(new MemoryCacheDriver());\n * await store.upsert(\"ai.rag.docs.guide.0\", { text: \"…\" }, vector);\n * const hits = await store.query(queryVector, { topK: 5, threshold: 0.5 });\n */\nexport function cacheVectorStore(driver: CacheDriver<any, any>): VectorStore {\n return {\n async upsert(\n key: string,\n value: unknown,\n vector: number[],\n tags?: string[],\n ): Promise<void> {\n await driver.set(key, value, tags && tags.length > 0 ? { vector, tags } : { vector });\n },\n\n async query<T>(\n vector: number[],\n options: { topK: number; threshold?: number; tags?: string[] },\n ): Promise<{ key: string; value: T; score: number }[]> {\n const hits = await driver.similar<T>(vector, {\n topK: options.topK,\n threshold: options.threshold,\n tags: options.tags,\n });\n\n return hits.map((hit: { key: string; value: T; score: number }) => ({\n key: hit.key,\n value: hit.value,\n score: hit.score,\n }));\n },\n\n async removeNamespace(namespace: string): Promise<void> {\n await driver.removeNamespace(namespace);\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,iBAAiB,QAA4C;CAC3E,OAAO;EACL,MAAM,OACJ,KACA,OACA,QACA,MACe;GACf,MAAM,OAAO,IAAI,KAAK,OAAO,QAAQ,KAAK,SAAS,IAAI;IAAE;IAAQ;GAAK,IAAI,EAAE,OAAO,CAAC;EACtF;EAEA,MAAM,MACJ,QACA,SACqD;GAOrD,QAAO,MANY,OAAO,QAAW,QAAQ;IAC3C,MAAM,QAAQ;IACd,WAAW,QAAQ;IACnB,MAAM,QAAQ;GAChB,CAAC,EAEU,CAAC,KAAK,SAAmD;IAClE,KAAK,IAAI;IACT,OAAO,IAAI;IACX,OAAO,IAAI;GACb,EAAE;EACJ;EAEA,MAAM,gBAAgB,WAAkC;GACtD,MAAM,OAAO,gBAAgB,SAAS;EACxC;CACF;AACF"}
@@ -0,0 +1,139 @@
1
+ import { VectorStore } from "./vector-store.contract.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/rag/store/pg-vector-store.d.ts
4
+ /**
5
+ * Minimal `pg`-compatible client surface the Postgres {@link VectorStore}
6
+ * depends on. Both `pg.Pool` and `pg.Client` satisfy it — the store only
7
+ * ever calls `query`.
8
+ *
9
+ * `@warlock.js/ai` takes **no** hard dependency on `pg`; the dev installs
10
+ * it (an optional peer) and passes the client in. Structurally identical
11
+ * to the snapshot / human-interrupt stores' `PgClientLike`, so a single
12
+ * pool can back the orchestrator checkpoint/snapshot tables, the
13
+ * interrupt table, and this vectors table alike.
14
+ */
15
+ interface PgClientLike {
16
+ query(text: string, params?: unknown[]): Promise<{
17
+ rows: unknown[];
18
+ }>;
19
+ }
20
+ /**
21
+ * Options for the Postgres {@link VectorStore}.
22
+ *
23
+ * Two mutually-supportive ways to supply the connection (mirroring
24
+ * `ai.human.interrupt.pg`):
25
+ * - **`client`** — pass an already-built `pg.Pool` / `pg.Client` (anything
26
+ * satisfying {@link PgClientLike}). The store only ever calls `query`
27
+ * and never opens or closes it; one pool can back several stores.
28
+ * - **`connectionString`** — let the store lazily `import("pg")` and build
29
+ * its own `Pool`. `@warlock.js/ai` takes **no** hard dependency on
30
+ * `pg` (an optional peer); when it is absent the store throws a curated
31
+ * install string at first use, never a raw module-resolution stack trace
32
+ * at import.
33
+ *
34
+ * Exactly one of the two must be present.
35
+ */
36
+ interface PgVectorStoreOptions {
37
+ /** An already-built `pg.Pool` / `pg.Client` — anything matching {@link PgClientLike}. */
38
+ client?: PgClientLike;
39
+ /** Connection string the store passes to a lazily-imported `pg.Pool`. */
40
+ connectionString?: string;
41
+ /**
42
+ * Backing table name. Defaults to `warlock_ai_rag_vectors`. Must be a
43
+ * safe SQL identifier — it is interpolated into DDL/DML.
44
+ */
45
+ table?: string;
46
+ /**
47
+ * Embedding dimensionality used in the `CREATE TABLE` DDL emitted by
48
+ * {@link VectorStore.schema | ensureSchema}. Defaults to `1536`
49
+ * (OpenAI `text-embedding-3-small`). The column is declared
50
+ * `vector(N)`; queries and upserts never re-state it, so an existing
51
+ * table provisioned at a different size is unaffected — only the DDL
52
+ * helper reads this.
53
+ */
54
+ dimensions?: number;
55
+ /**
56
+ * Approximate-nearest-neighbour index strategy baked into the DDL
57
+ * emitted by {@link VectorStore.schema | ensureSchema}. Defaults to
58
+ * `"hnsw"` (better recall/latency on modern pgvector). Use `"ivfflat"`
59
+ * for the classic list-partitioned index, or `"none"` to emit no ANN
60
+ * index (exact scan — correct, but linear in row count).
61
+ */
62
+ index?: "hnsw" | "ivfflat" | "none";
63
+ /**
64
+ * `lists` parameter for an `ivfflat` index (ignored for `hnsw` / `none`).
65
+ * Defaults to `100`. Tune toward `rows / 1000` for large tables.
66
+ */
67
+ ivfflatLists?: number;
68
+ }
69
+ /**
70
+ * Serialize a JS `number[]` to the pgvector text literal: `[1,2,3]`.
71
+ * pgvector accepts a vector either as this bracketed literal or via a
72
+ * typed parameter; passing the literal string + an explicit `::vector`
73
+ * cast keeps the store driver-agnostic (no dependency on a registered
74
+ * `pg` type parser).
75
+ *
76
+ * Non-finite components (`NaN` / `±Infinity`) are rejected — pgvector
77
+ * stores only finite floats, and silently coercing them would corrupt the
78
+ * index. The check is cheap relative to the embed call that produced the
79
+ * vector.
80
+ *
81
+ * @example
82
+ * vectorLiteral([1, 0.5, -2]); // "[1,0.5,-2]"
83
+ */
84
+ declare function vectorLiteral(vector: number[]): string;
85
+ /**
86
+ * The {@link VectorStore} surface plus the pg store's extra DDL helpers.
87
+ * `schema()` / `ensureSchema()` are not part of the base contract (the
88
+ * cache store has no backing table), so the factory's return type widens
89
+ * it for callers that want the migration SQL.
90
+ */
91
+ interface PgVectorStoreInstance extends VectorStore {
92
+ /** Reference migration DDL (extension + table + indexes). Never executed. */
93
+ schema(): string;
94
+ /** Alias for {@link PgVectorStoreInstance.schema} — reads better in a migration script. */
95
+ ensureSchema(): string;
96
+ }
97
+ /**
98
+ * Create a Postgres + pgvector-backed {@link VectorStore} for the RAG
99
+ * pipeline. Either pass a live `pg.Pool` / `pg.Client` (`{ client }`) —
100
+ * `@warlock.js/ai` never imports `pg` in that case — or a
101
+ * `{ connectionString }` and let the store lazily `import("pg")` to build
102
+ * its own pool. When `pg` is not installed, a curated install string
103
+ * surfaces on first use, never at import.
104
+ *
105
+ * Run {@link PgVectorStoreInstance.ensureSchema} through your migration
106
+ * tool once before use (it enables the `vector` extension, creates the
107
+ * table, and builds the tag + ANN indexes); the store never auto-migrates.
108
+ *
109
+ * Index and query MUST use the same embedding model — the `vector(N)`
110
+ * column width is fixed at table-creation time from `dimensions`.
111
+ *
112
+ * @example
113
+ * import { Pool } from "pg";
114
+ * import { ai } from "@warlock.js/ai";
115
+ *
116
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
117
+ * const store = ai.rag.pgVectorStore({ client: pool, dimensions: 1536 });
118
+ *
119
+ * // Once, via your migration tooling:
120
+ * // await pool.query(store.ensureSchema());
121
+ *
122
+ * const kb = ai.rag({
123
+ * name: "docs",
124
+ * embedder: openai.embedder({ name: "text-embedding-3-small" }),
125
+ * store,
126
+ * });
127
+ *
128
+ * @example
129
+ * // Let the store build its own pool from a connection string:
130
+ * const store = ai.rag.pgVectorStore({
131
+ * connectionString: process.env.DATABASE_URL,
132
+ * index: "ivfflat",
133
+ * ivfflatLists: 200,
134
+ * });
135
+ */
136
+ declare function pgVectorStore(options: PgVectorStoreOptions): PgVectorStoreInstance;
137
+ //#endregion
138
+ export { PgClientLike, PgVectorStoreInstance, PgVectorStoreOptions, pgVectorStore, vectorLiteral };
139
+ //# sourceMappingURL=pg-vector-store.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-vector-store.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/store/pg-vector-store.ts"],"mappings":";;;;;AAaA;;;;;;;;;UAAiB,YAAA;EACf,KAAA,CAAM,IAAA,UAAc,MAAA,eAAqB,OAAO;IAAG,IAAA;EAAA;AAAA;;;;;;;;;;AAuDvC;AA4Fd;;;;AAA8C;AA6U9C;UA7ciB,oBAAA;;EAEf,MAAA,GAAS,YAAY;EA2cwB;EAxc7C,gBAAA;EA4cA;;AAAY;AA0Cd;EAhfE,KAAA;;;;;;;AAgfiF;;EAtejF,UAAA;;;;;;;;EASA,KAAA;;;;;EAMA,YAAA;AAAA;;;;;;;;;;;;;;;;iBA4Fc,aAAA,CAAc,MAAgB;;;;;;;UA6U7B,qBAAA,SAA8B,WAAW;;EAExD,MAAA;;EAEA,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0Cc,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,qBAAqB"}
@@ -0,0 +1,328 @@
1
+ //#region ../@warlock.js/ai/src/rag/store/pg-vector-store.ts
2
+ /**
3
+ * Default backing table — provisions the store with no extra config when
4
+ * the dev runs {@link VectorStore.schema | ensureSchema} through their
5
+ * migration tool.
6
+ */
7
+ const DEFAULT_TABLE = "warlock_ai_rag_vectors";
8
+ /** Default embedding width baked into the DDL (OpenAI `text-embedding-3-small`). */
9
+ const DEFAULT_DIMENSIONS = 1536;
10
+ /** Default `ivfflat` list count when that index strategy is chosen. */
11
+ const DEFAULT_IVFFLAT_LISTS = 100;
12
+ /**
13
+ * Allowed characters in a Postgres identifier (table name). The table name
14
+ * is interpolated into DDL/DML, so anything outside this conservative
15
+ * ASCII subset is rejected — interpolating an arbitrary string would be a
16
+ * SQL-injection footgun (mirrors the snapshot / human-interrupt pg stores
17
+ * and `@warlock.js/cache`'s `PgCacheDriver`).
18
+ */
19
+ const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
20
+ /**
21
+ * Module specifier for the optional `pg` driver. Held in a `string`
22
+ * variable so the dynamic `import()` is not statically resolved at compile
23
+ * time — `pg` is an optional peer that need not be installed for this
24
+ * package to type-check or for a cache-only consumer to run.
25
+ */
26
+ const PG_MODULE = "pg";
27
+ /**
28
+ * Curated install string surfaced (at use time) when a `connectionString`
29
+ * is configured but the optional `pg` driver is absent. Never thrown at
30
+ * import — a cache-only consumer must be able to load this module.
31
+ */
32
+ const PG_INSTALL_INSTRUCTIONS = `
33
+ The @warlock.js/ai Postgres vector store requires the pg package and a
34
+ Postgres database with the pgvector extension. Install the driver with:
35
+
36
+ npm install pg
37
+
38
+ Or with your preferred package manager:
39
+
40
+ pnpm add pg
41
+ yarn add pg
42
+ `.trim();
43
+ /**
44
+ * Lazily import `pg` and return a `Pool` built from `connectionString`. A
45
+ * bare `catch` rethrows the curated install string — a missing optional
46
+ * peer surfaces as actionable guidance, never a raw resolution error.
47
+ */
48
+ async function buildPgClient(connectionString) {
49
+ let sdk;
50
+ try {
51
+ sdk = await import(PG_MODULE);
52
+ } catch {
53
+ throw new Error(PG_INSTALL_INSTRUCTIONS);
54
+ }
55
+ return new sdk.Pool({ connectionString });
56
+ }
57
+ /**
58
+ * Serialize a JS `number[]` to the pgvector text literal: `[1,2,3]`.
59
+ * pgvector accepts a vector either as this bracketed literal or via a
60
+ * typed parameter; passing the literal string + an explicit `::vector`
61
+ * cast keeps the store driver-agnostic (no dependency on a registered
62
+ * `pg` type parser).
63
+ *
64
+ * Non-finite components (`NaN` / `±Infinity`) are rejected — pgvector
65
+ * stores only finite floats, and silently coercing them would corrupt the
66
+ * index. The check is cheap relative to the embed call that produced the
67
+ * vector.
68
+ *
69
+ * @example
70
+ * vectorLiteral([1, 0.5, -2]); // "[1,0.5,-2]"
71
+ */
72
+ function vectorLiteral(vector) {
73
+ let literal = "[";
74
+ for (let index = 0; index < vector.length; index++) {
75
+ const component = vector[index];
76
+ if (!Number.isFinite(component)) throw new TypeError(`pgVectorStore: embedding component at index ${index} is not finite (${component}); pgvector stores only finite floats.`);
77
+ if (index > 0) literal += ",";
78
+ literal += String(component);
79
+ }
80
+ return literal + "]";
81
+ }
82
+ /**
83
+ * Coerce a `value` JSONB column back into the stored payload. node-postgres
84
+ * parses `JSONB` into a JS value already, but some pool wrappers hand back
85
+ * the raw string — be defensive across both (mirrors the snapshot store's
86
+ * `parsePayload`).
87
+ */
88
+ function parseValue(value) {
89
+ if (typeof value === "string") return JSON.parse(value);
90
+ return value;
91
+ }
92
+ /**
93
+ * Coerce a pgvector cosine **distance** (`<=>`, in `[0, 2]`, 0 = identical)
94
+ * into the cosine **similarity** score the {@link VectorStore} contract
95
+ * declares (`[0, 1]`, 1 = identical). `pg` returns the computed distance
96
+ * column as a string for `double precision`; parse then map `1 - distance`,
97
+ * clamped to `[0, 1]` so a tiny floating-point overshoot never yields a
98
+ * score just outside the contract's range.
99
+ */
100
+ function distanceToScore(distance) {
101
+ const score = 1 - (typeof distance === "string" ? Number(distance) : distance);
102
+ if (score < 0) return 0;
103
+ if (score > 1) return 1;
104
+ return score;
105
+ }
106
+ /**
107
+ * Postgres + pgvector-backed {@link VectorStore} — one durable row per
108
+ * indexed chunk, keyed by the RAG pipeline's dotted `key`
109
+ * (`ai.rag.<name>.<sourceId>.<chunkIndex>`), with the chunk payload in a
110
+ * `value` JSONB column and the embedding in a `vector` column.
111
+ *
112
+ * Owns: the three RAG vector operations against a pgvector index —
113
+ * `upsert` (INSERT … ON CONFLICT DO UPDATE), `query` (cosine
114
+ * `ORDER BY embedding <=> $vec` with a `threshold` floor + optional `tags`
115
+ * overlap filter, capped at `topK`), and `removeNamespace` (prefix DELETE).
116
+ * Also emits the reference DDL via {@link PgVectorStore.schema} (alias
117
+ * {@link PgVectorStore.ensureSchema}).
118
+ *
119
+ * Does NOT own: the connection lifecycle (a dev-supplied `client` is never
120
+ * closed; a store-built `Pool` from a `connectionString` is also left open
121
+ * for the process to reuse) or schema migration — the dev runs the DDL
122
+ * through their own tool; the framework never auto-migrates.
123
+ *
124
+ * Front it with the {@link pgVectorStore} factory — callers never `new` it.
125
+ */
126
+ var PgVectorStore = class {
127
+ constructor(options) {
128
+ const table = options.table ?? DEFAULT_TABLE;
129
+ if (!SAFE_IDENTIFIER.test(table)) throw new TypeError(`pgVectorStore: invalid table name '${table}'. Allowed: [A-Za-z_][A-Za-z0-9_]*.`);
130
+ this.table = table;
131
+ this.dimensions = options.dimensions ?? DEFAULT_DIMENSIONS;
132
+ this.index = options.index ?? "hnsw";
133
+ this.ivfflatLists = options.ivfflatLists ?? DEFAULT_IVFFLAT_LISTS;
134
+ if (options.client) {
135
+ if (typeof options.client.query !== "function") throw new TypeError("pgVectorStore requires a 'client' option implementing { query(text, params) } — pass a pg.Pool or pg.Client.");
136
+ this.clientPromise = Promise.resolve(options.client);
137
+ return;
138
+ }
139
+ if (options.connectionString) {
140
+ this.clientPromise = buildPgClient(options.connectionString);
141
+ return;
142
+ }
143
+ throw new TypeError("pgVectorStore requires either a 'client' or a 'connectionString' option.");
144
+ }
145
+ /**
146
+ * Resolve the backing client, surfacing the lazy `pg` import's curated
147
+ * install string on the first call that needs it.
148
+ */
149
+ client() {
150
+ return this.clientPromise;
151
+ }
152
+ /**
153
+ * Index `value` under `key` with its embedding `vector`. Upserts on the
154
+ * `key` primary key — re-indexing the same chunk overwrites its payload,
155
+ * embedding, and tags rather than appending a duplicate row. Optional
156
+ * `tags` ride a `text[]` column so {@link query} can restrict the
157
+ * candidate set with an array-overlap filter.
158
+ *
159
+ * The embedding is sent as a pgvector text literal (`$3`) cast to
160
+ * `::vector`, so the store needs no registered `pg` type parser. `tags`
161
+ * defaults to an empty array (never `NULL`) to keep the overlap filter's
162
+ * `&&` semantics simple.
163
+ */
164
+ async upsert(key, value, vector, tags) {
165
+ await (await this.client()).query(`INSERT INTO ${this.table} (key, value, embedding, tags)
166
+ VALUES ($1, $2::jsonb, $3::vector, $4::text[])
167
+ ON CONFLICT (key) DO UPDATE
168
+ SET value = EXCLUDED.value,
169
+ embedding = EXCLUDED.embedding,
170
+ tags = EXCLUDED.tags`, [
171
+ key,
172
+ JSON.stringify(value),
173
+ vectorLiteral(vector),
174
+ tags ?? []
175
+ ]);
176
+ }
177
+ /**
178
+ * Return the cosine-nearest rows to `vector`, mapped to the contract's
179
+ * `{ key, value, score }` shape. The SQL:
180
+ *
181
+ * - computes `embedding <=> $1::vector` (cosine **distance**) once, aliased
182
+ * `distance`, and `ORDER BY` it ascending (nearest first);
183
+ * - applies the `threshold` floor as `distance <= 1 - threshold`
184
+ * (similarity `>=` threshold), so the default `0.5` floor maps to a
185
+ * `<= 0.5` distance bound — the filter runs in SQL, not in JS, so a
186
+ * below-floor row never crosses the wire;
187
+ * - when `tags` are given, restricts to rows whose `tags` array overlaps
188
+ * the requested set via `tags && $tags::text[]` (one-of semantics,
189
+ * matching the cache store);
190
+ * - caps the result at `topK` with `LIMIT`.
191
+ *
192
+ * The returned `score` is `1 - distance`, clamped to `[0, 1]`, so callers
193
+ * see the same cosine-similarity scale the cache store emits.
194
+ */
195
+ async query(vector, options) {
196
+ const client = await this.client();
197
+ const params = [vectorLiteral(vector), options.topK];
198
+ const conditions = [];
199
+ if (options.threshold !== void 0) {
200
+ params.push(1 - options.threshold);
201
+ conditions.push(`(embedding <=> $1::vector) <= $${params.length}`);
202
+ }
203
+ if (options.tags !== void 0 && options.tags.length > 0) {
204
+ params.push(options.tags);
205
+ conditions.push(`tags && $${params.length}::text[]`);
206
+ }
207
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
208
+ const { rows } = await client.query(`SELECT key, value, (embedding <=> $1::vector) AS distance
209
+ FROM ${this.table}
210
+ ${where}
211
+ ORDER BY embedding <=> $1::vector
212
+ LIMIT $2`, params);
213
+ return rows.map((row) => ({
214
+ key: row.key,
215
+ value: parseValue(row.value),
216
+ score: distanceToScore(row.distance)
217
+ }));
218
+ }
219
+ /**
220
+ * Drop every entry written under `namespace`. The RAG pipeline keys
221
+ * chunks as `<namespace>.<sourceId>.<chunkIndex>`, so a row belongs to
222
+ * the namespace when its `key` equals it OR begins with `<namespace>.`
223
+ * — deleting `ai.rag.docs` must not also catch `ai.rag.docs2`. The `_`
224
+ * and `%` LIKE wildcards in the namespace are escaped so a namespace
225
+ * that happens to contain them is matched literally.
226
+ */
227
+ async removeNamespace(namespace) {
228
+ const client = await this.client();
229
+ const escaped = namespace.replace(/\\/g, "\\\\").replace(/_/g, "\\_").replace(/%/g, "\\%");
230
+ await client.query(`DELETE FROM ${this.table}
231
+ WHERE key = $1 OR key LIKE $2 ESCAPE '\\'`, [namespace, `${escaped}.%`]);
232
+ }
233
+ /**
234
+ * Return the reference migration DDL for this store's backing table,
235
+ * interpolating the configured table name, embedding width, and ANN
236
+ * index strategy. The dev runs it once through their migration tool —
237
+ * the framework never auto-migrates.
238
+ *
239
+ * The emitted statements:
240
+ * 1. `CREATE EXTENSION IF NOT EXISTS vector;` — enables pgvector (needs
241
+ * a superuser or a role with `CREATE` on the database the first time).
242
+ * 2. `CREATE TABLE IF NOT EXISTS <table> (key TEXT PRIMARY KEY, value
243
+ * JSONB NOT NULL, embedding vector(<dimensions>) NOT NULL, tags
244
+ * text[] NOT NULL DEFAULT '{}');`
245
+ * 3. A GIN index on `tags` so the array-overlap filter stays sargable.
246
+ * 4. The chosen ANN index over `embedding` using `vector_cosine_ops`:
247
+ * - `"hnsw"` → `USING hnsw (embedding vector_cosine_ops)`;
248
+ * - `"ivfflat"` → `USING ivfflat (embedding vector_cosine_ops)
249
+ * WITH (lists = <ivfflatLists>)`;
250
+ * - `"none"` → emitted as a comment (exact scan, no ANN index).
251
+ *
252
+ * @example
253
+ * const store = pgVectorStore({ client: pool, dimensions: 1536 });
254
+ * await pool.query(store.ensureSchema());
255
+ */
256
+ schema() {
257
+ const lines = [
258
+ `CREATE EXTENSION IF NOT EXISTS vector;`,
259
+ `CREATE TABLE IF NOT EXISTS ${this.table} (`,
260
+ ` key TEXT PRIMARY KEY,`,
261
+ ` value JSONB NOT NULL,`,
262
+ ` embedding vector(${this.dimensions}) NOT NULL,`,
263
+ ` tags TEXT[] NOT NULL DEFAULT '{}'`,
264
+ `);`,
265
+ `CREATE INDEX IF NOT EXISTS idx_${this.table}_tags`,
266
+ ` ON ${this.table} USING gin (tags);`
267
+ ];
268
+ if (this.index === "hnsw") lines.push(`CREATE INDEX IF NOT EXISTS idx_${this.table}_embedding`, ` ON ${this.table} USING hnsw (embedding vector_cosine_ops);`);
269
+ else if (this.index === "ivfflat") lines.push(`CREATE INDEX IF NOT EXISTS idx_${this.table}_embedding`, ` ON ${this.table} USING ivfflat (embedding vector_cosine_ops)`, ` WITH (lists = ${this.ivfflatLists});`);
270
+ else lines.push(`-- No ANN index requested (index: "none"): cosine queries fall back`, `-- to an exact sequential scan, which is correct but linear in rows.`);
271
+ return lines.join("\n");
272
+ }
273
+ /**
274
+ * Alias for {@link PgVectorStore.schema} — reads more naturally in a
275
+ * migration script (`await pool.query(store.ensureSchema())`). Returns
276
+ * the identical DDL string; it does NOT execute anything against the
277
+ * database (the store never auto-migrates).
278
+ */
279
+ ensureSchema() {
280
+ return this.schema();
281
+ }
282
+ };
283
+ /**
284
+ * Create a Postgres + pgvector-backed {@link VectorStore} for the RAG
285
+ * pipeline. Either pass a live `pg.Pool` / `pg.Client` (`{ client }`) —
286
+ * `@warlock.js/ai` never imports `pg` in that case — or a
287
+ * `{ connectionString }` and let the store lazily `import("pg")` to build
288
+ * its own pool. When `pg` is not installed, a curated install string
289
+ * surfaces on first use, never at import.
290
+ *
291
+ * Run {@link PgVectorStoreInstance.ensureSchema} through your migration
292
+ * tool once before use (it enables the `vector` extension, creates the
293
+ * table, and builds the tag + ANN indexes); the store never auto-migrates.
294
+ *
295
+ * Index and query MUST use the same embedding model — the `vector(N)`
296
+ * column width is fixed at table-creation time from `dimensions`.
297
+ *
298
+ * @example
299
+ * import { Pool } from "pg";
300
+ * import { ai } from "@warlock.js/ai";
301
+ *
302
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
303
+ * const store = ai.rag.pgVectorStore({ client: pool, dimensions: 1536 });
304
+ *
305
+ * // Once, via your migration tooling:
306
+ * // await pool.query(store.ensureSchema());
307
+ *
308
+ * const kb = ai.rag({
309
+ * name: "docs",
310
+ * embedder: openai.embedder({ name: "text-embedding-3-small" }),
311
+ * store,
312
+ * });
313
+ *
314
+ * @example
315
+ * // Let the store build its own pool from a connection string:
316
+ * const store = ai.rag.pgVectorStore({
317
+ * connectionString: process.env.DATABASE_URL,
318
+ * index: "ivfflat",
319
+ * ivfflatLists: 200,
320
+ * });
321
+ */
322
+ function pgVectorStore(options) {
323
+ return new PgVectorStore(options);
324
+ }
325
+
326
+ //#endregion
327
+ export { pgVectorStore, vectorLiteral };
328
+ //# sourceMappingURL=pg-vector-store.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-vector-store.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/store/pg-vector-store.ts"],"sourcesContent":["import type { VectorStore } from \"./vector-store.contract\";\n\n/**\n * Minimal `pg`-compatible client surface the Postgres {@link VectorStore}\n * depends on. Both `pg.Pool` and `pg.Client` satisfy it — the store only\n * ever calls `query`.\n *\n * `@warlock.js/ai` takes **no** hard dependency on `pg`; the dev installs\n * it (an optional peer) and passes the client in. Structurally identical\n * to the snapshot / human-interrupt stores' `PgClientLike`, so a single\n * pool can back the orchestrator checkpoint/snapshot tables, the\n * interrupt table, and this vectors table alike.\n */\nexport interface PgClientLike {\n query(text: string, params?: unknown[]): Promise<{ rows: unknown[] }>;\n}\n\n/**\n * Options for the Postgres {@link VectorStore}.\n *\n * Two mutually-supportive ways to supply the connection (mirroring\n * `ai.human.interrupt.pg`):\n * - **`client`** — pass an already-built `pg.Pool` / `pg.Client` (anything\n * satisfying {@link PgClientLike}). The store only ever calls `query`\n * and never opens or closes it; one pool can back several stores.\n * - **`connectionString`** — let the store lazily `import(\"pg\")` and build\n * its own `Pool`. `@warlock.js/ai` takes **no** hard dependency on\n * `pg` (an optional peer); when it is absent the store throws a curated\n * install string at first use, never a raw module-resolution stack trace\n * at import.\n *\n * Exactly one of the two must be present.\n */\nexport interface PgVectorStoreOptions {\n /** An already-built `pg.Pool` / `pg.Client` — anything matching {@link PgClientLike}. */\n client?: PgClientLike;\n\n /** Connection string the store passes to a lazily-imported `pg.Pool`. */\n connectionString?: string;\n\n /**\n * Backing table name. Defaults to `warlock_ai_rag_vectors`. Must be a\n * safe SQL identifier — it is interpolated into DDL/DML.\n */\n table?: string;\n\n /**\n * Embedding dimensionality used in the `CREATE TABLE` DDL emitted by\n * {@link VectorStore.schema | ensureSchema}. Defaults to `1536`\n * (OpenAI `text-embedding-3-small`). The column is declared\n * `vector(N)`; queries and upserts never re-state it, so an existing\n * table provisioned at a different size is unaffected — only the DDL\n * helper reads this.\n */\n dimensions?: number;\n\n /**\n * Approximate-nearest-neighbour index strategy baked into the DDL\n * emitted by {@link VectorStore.schema | ensureSchema}. Defaults to\n * `\"hnsw\"` (better recall/latency on modern pgvector). Use `\"ivfflat\"`\n * for the classic list-partitioned index, or `\"none\"` to emit no ANN\n * index (exact scan — correct, but linear in row count).\n */\n index?: \"hnsw\" | \"ivfflat\" | \"none\";\n\n /**\n * `lists` parameter for an `ivfflat` index (ignored for `hnsw` / `none`).\n * Defaults to `100`. Tune toward `rows / 1000` for large tables.\n */\n ivfflatLists?: number;\n}\n\n/**\n * Default backing table — provisions the store with no extra config when\n * the dev runs {@link VectorStore.schema | ensureSchema} through their\n * migration tool.\n */\nconst DEFAULT_TABLE = \"warlock_ai_rag_vectors\";\n\n/** Default embedding width baked into the DDL (OpenAI `text-embedding-3-small`). */\nconst DEFAULT_DIMENSIONS = 1536;\n\n/** Default `ivfflat` list count when that index strategy is chosen. */\nconst DEFAULT_IVFFLAT_LISTS = 100;\n\n/**\n * Allowed characters in a Postgres identifier (table name). The table name\n * is interpolated into DDL/DML, so anything outside this conservative\n * ASCII subset is rejected — interpolating an arbitrary string would be a\n * SQL-injection footgun (mirrors the snapshot / human-interrupt pg stores\n * and `@warlock.js/cache`'s `PgCacheDriver`).\n */\nconst SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Module specifier for the optional `pg` driver. Held in a `string`\n * variable so the dynamic `import()` is not statically resolved at compile\n * time — `pg` is an optional peer that need not be installed for this\n * package to type-check or for a cache-only consumer to run.\n */\nconst PG_MODULE = \"pg\";\n\n/**\n * Curated install string surfaced (at use time) when a `connectionString`\n * is configured but the optional `pg` driver is absent. Never thrown at\n * import — a cache-only consumer must be able to load this module.\n */\nconst PG_INSTALL_INSTRUCTIONS = `\nThe @warlock.js/ai Postgres vector store requires the pg package and a\nPostgres database with the pgvector extension. Install the driver with:\n\n npm install pg\n\nOr with your preferred package manager:\n\n pnpm add pg\n yarn add pg\n`.trim();\n\n/**\n * Minimal structural view of a `pg.Pool` constructor — just enough of the\n * `pg` module surface for the store to build a client when handed a\n * `connectionString`. Declared locally (rather than `typeof import(\"pg\")`)\n * so this module type-checks even when `pg` is not installed.\n */\ninterface PgModuleLike {\n Pool: new (config: { connectionString: string }) => PgClientLike;\n}\n\n/**\n * Lazily import `pg` and return a `Pool` built from `connectionString`. A\n * bare `catch` rethrows the curated install string — a missing optional\n * peer surfaces as actionable guidance, never a raw resolution error.\n */\nasync function buildPgClient(connectionString: string): Promise<PgClientLike> {\n let sdk: PgModuleLike;\n\n try {\n sdk = (await import(PG_MODULE)) as unknown as PgModuleLike;\n } catch {\n throw new Error(PG_INSTALL_INSTRUCTIONS);\n }\n\n return new sdk.Pool({ connectionString });\n}\n\n/**\n * Serialize a JS `number[]` to the pgvector text literal: `[1,2,3]`.\n * pgvector accepts a vector either as this bracketed literal or via a\n * typed parameter; passing the literal string + an explicit `::vector`\n * cast keeps the store driver-agnostic (no dependency on a registered\n * `pg` type parser).\n *\n * Non-finite components (`NaN` / `±Infinity`) are rejected — pgvector\n * stores only finite floats, and silently coercing them would corrupt the\n * index. The check is cheap relative to the embed call that produced the\n * vector.\n *\n * @example\n * vectorLiteral([1, 0.5, -2]); // \"[1,0.5,-2]\"\n */\nexport function vectorLiteral(vector: number[]): string {\n let literal = \"[\";\n\n for (let index = 0; index < vector.length; index++) {\n const component = vector[index];\n\n if (!Number.isFinite(component)) {\n throw new TypeError(\n `pgVectorStore: embedding component at index ${index} is not finite (${component}); pgvector stores only finite floats.`,\n );\n }\n\n if (index > 0) {\n literal += \",\";\n }\n\n literal += String(component);\n }\n\n return literal + \"]\";\n}\n\n/**\n * Coerce a `value` JSONB column back into the stored payload. node-postgres\n * parses `JSONB` into a JS value already, but some pool wrappers hand back\n * the raw string — be defensive across both (mirrors the snapshot store's\n * `parsePayload`).\n */\nfunction parseValue<T>(value: unknown): T {\n if (typeof value === \"string\") {\n return JSON.parse(value) as T;\n }\n\n return value as T;\n}\n\n/**\n * Coerce a pgvector cosine **distance** (`<=>`, in `[0, 2]`, 0 = identical)\n * into the cosine **similarity** score the {@link VectorStore} contract\n * declares (`[0, 1]`, 1 = identical). `pg` returns the computed distance\n * column as a string for `double precision`; parse then map `1 - distance`,\n * clamped to `[0, 1]` so a tiny floating-point overshoot never yields a\n * score just outside the contract's range.\n */\nfunction distanceToScore(distance: unknown): number {\n const value = typeof distance === \"string\" ? Number(distance) : (distance as number);\n const score = 1 - value;\n\n if (score < 0) {\n return 0;\n }\n\n if (score > 1) {\n return 1;\n }\n\n return score;\n}\n\n/**\n * Postgres + pgvector-backed {@link VectorStore} — one durable row per\n * indexed chunk, keyed by the RAG pipeline's dotted `key`\n * (`ai.rag.<name>.<sourceId>.<chunkIndex>`), with the chunk payload in a\n * `value` JSONB column and the embedding in a `vector` column.\n *\n * Owns: the three RAG vector operations against a pgvector index —\n * `upsert` (INSERT … ON CONFLICT DO UPDATE), `query` (cosine\n * `ORDER BY embedding <=> $vec` with a `threshold` floor + optional `tags`\n * overlap filter, capped at `topK`), and `removeNamespace` (prefix DELETE).\n * Also emits the reference DDL via {@link PgVectorStore.schema} (alias\n * {@link PgVectorStore.ensureSchema}).\n *\n * Does NOT own: the connection lifecycle (a dev-supplied `client` is never\n * closed; a store-built `Pool` from a `connectionString` is also left open\n * for the process to reuse) or schema migration — the dev runs the DDL\n * through their own tool; the framework never auto-migrates.\n *\n * Front it with the {@link pgVectorStore} factory — callers never `new` it.\n */\nclass PgVectorStore implements VectorStore {\n /** Validated backing table name, safe to interpolate into SQL. */\n private readonly table: string;\n\n /** Embedding width baked into the DDL. */\n private readonly dimensions: number;\n\n /** ANN index strategy baked into the DDL. */\n private readonly index: \"hnsw\" | \"ivfflat\" | \"none\";\n\n /** `lists` parameter for an `ivfflat` index. */\n private readonly ivfflatLists: number;\n\n /**\n * A ready client, or a promise resolving to one the store builds lazily\n * from a `connectionString`. Resolved once and memoized so the optional\n * `pg` import happens at most once.\n */\n private readonly clientPromise: Promise<PgClientLike>;\n\n public constructor(options: PgVectorStoreOptions) {\n const table = options.table ?? DEFAULT_TABLE;\n\n if (!SAFE_IDENTIFIER.test(table)) {\n throw new TypeError(\n `pgVectorStore: invalid table name '${table}'. Allowed: [A-Za-z_][A-Za-z0-9_]*.`,\n );\n }\n\n this.table = table;\n this.dimensions = options.dimensions ?? DEFAULT_DIMENSIONS;\n this.index = options.index ?? \"hnsw\";\n this.ivfflatLists = options.ivfflatLists ?? DEFAULT_IVFFLAT_LISTS;\n\n if (options.client) {\n if (typeof options.client.query !== \"function\") {\n throw new TypeError(\n \"pgVectorStore requires a 'client' option implementing { query(text, params) } — pass a pg.Pool or pg.Client.\",\n );\n }\n\n this.clientPromise = Promise.resolve(options.client);\n\n return;\n }\n\n if (options.connectionString) {\n // Defer the optional `pg` import to first use — a curated install\n // string surfaces from `buildPgClient`, not at construction.\n this.clientPromise = buildPgClient(options.connectionString);\n\n return;\n }\n\n throw new TypeError(\n \"pgVectorStore requires either a 'client' or a 'connectionString' option.\",\n );\n }\n\n /**\n * Resolve the backing client, surfacing the lazy `pg` import's curated\n * install string on the first call that needs it.\n */\n private client(): Promise<PgClientLike> {\n return this.clientPromise;\n }\n\n /**\n * Index `value` under `key` with its embedding `vector`. Upserts on the\n * `key` primary key — re-indexing the same chunk overwrites its payload,\n * embedding, and tags rather than appending a duplicate row. Optional\n * `tags` ride a `text[]` column so {@link query} can restrict the\n * candidate set with an array-overlap filter.\n *\n * The embedding is sent as a pgvector text literal (`$3`) cast to\n * `::vector`, so the store needs no registered `pg` type parser. `tags`\n * defaults to an empty array (never `NULL`) to keep the overlap filter's\n * `&&` semantics simple.\n */\n public async upsert(\n key: string,\n value: unknown,\n vector: number[],\n tags?: string[],\n ): Promise<void> {\n const client = await this.client();\n\n await client.query(\n `INSERT INTO ${this.table} (key, value, embedding, tags)\n VALUES ($1, $2::jsonb, $3::vector, $4::text[])\n ON CONFLICT (key) DO UPDATE\n SET value = EXCLUDED.value,\n embedding = EXCLUDED.embedding,\n tags = EXCLUDED.tags`,\n [key, JSON.stringify(value), vectorLiteral(vector), tags ?? []],\n );\n }\n\n /**\n * Return the cosine-nearest rows to `vector`, mapped to the contract's\n * `{ key, value, score }` shape. The SQL:\n *\n * - computes `embedding <=> $1::vector` (cosine **distance**) once, aliased\n * `distance`, and `ORDER BY` it ascending (nearest first);\n * - applies the `threshold` floor as `distance <= 1 - threshold`\n * (similarity `>=` threshold), so the default `0.5` floor maps to a\n * `<= 0.5` distance bound — the filter runs in SQL, not in JS, so a\n * below-floor row never crosses the wire;\n * - when `tags` are given, restricts to rows whose `tags` array overlaps\n * the requested set via `tags && $tags::text[]` (one-of semantics,\n * matching the cache store);\n * - caps the result at `topK` with `LIMIT`.\n *\n * The returned `score` is `1 - distance`, clamped to `[0, 1]`, so callers\n * see the same cosine-similarity scale the cache store emits.\n */\n public async query<T>(\n vector: number[],\n options: { topK: number; threshold?: number; tags?: string[] },\n ): Promise<{ key: string; value: T; score: number }[]> {\n const client = await this.client();\n const queryVector = vectorLiteral(vector);\n\n // $1 = query vector, $2 = topK. Optional threshold + tags are appended\n // as $3 / $4 only when present, so the prepared statement carries no\n // unused placeholders.\n const params: unknown[] = [queryVector, options.topK];\n const conditions: string[] = [];\n\n if (options.threshold !== undefined) {\n params.push(1 - options.threshold);\n conditions.push(`(embedding <=> $1::vector) <= $${params.length}`);\n }\n\n if (options.tags !== undefined && options.tags.length > 0) {\n params.push(options.tags);\n conditions.push(`tags && $${params.length}::text[]`);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n\n const { rows } = await client.query(\n `SELECT key, value, (embedding <=> $1::vector) AS distance\n FROM ${this.table}\n ${where}\n ORDER BY embedding <=> $1::vector\n LIMIT $2`,\n params,\n );\n\n return (rows as Record<string, unknown>[]).map((row) => ({\n key: row.key as string,\n value: parseValue<T>(row.value),\n score: distanceToScore(row.distance),\n }));\n }\n\n /**\n * Drop every entry written under `namespace`. The RAG pipeline keys\n * chunks as `<namespace>.<sourceId>.<chunkIndex>`, so a row belongs to\n * the namespace when its `key` equals it OR begins with `<namespace>.`\n * — deleting `ai.rag.docs` must not also catch `ai.rag.docs2`. The `_`\n * and `%` LIKE wildcards in the namespace are escaped so a namespace\n * that happens to contain them is matched literally.\n */\n public async removeNamespace(namespace: string): Promise<void> {\n const client = await this.client();\n\n const escaped = namespace\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/_/g, \"\\\\_\")\n .replace(/%/g, \"\\\\%\");\n\n await client.query(\n `DELETE FROM ${this.table}\n WHERE key = $1 OR key LIKE $2 ESCAPE '\\\\'`,\n [namespace, `${escaped}.%`],\n );\n }\n\n /**\n * Return the reference migration DDL for this store's backing table,\n * interpolating the configured table name, embedding width, and ANN\n * index strategy. The dev runs it once through their migration tool —\n * the framework never auto-migrates.\n *\n * The emitted statements:\n * 1. `CREATE EXTENSION IF NOT EXISTS vector;` — enables pgvector (needs\n * a superuser or a role with `CREATE` on the database the first time).\n * 2. `CREATE TABLE IF NOT EXISTS <table> (key TEXT PRIMARY KEY, value\n * JSONB NOT NULL, embedding vector(<dimensions>) NOT NULL, tags\n * text[] NOT NULL DEFAULT '{}');`\n * 3. A GIN index on `tags` so the array-overlap filter stays sargable.\n * 4. The chosen ANN index over `embedding` using `vector_cosine_ops`:\n * - `\"hnsw\"` → `USING hnsw (embedding vector_cosine_ops)`;\n * - `\"ivfflat\"` → `USING ivfflat (embedding vector_cosine_ops)\n * WITH (lists = <ivfflatLists>)`;\n * - `\"none\"` → emitted as a comment (exact scan, no ANN index).\n *\n * @example\n * const store = pgVectorStore({ client: pool, dimensions: 1536 });\n * await pool.query(store.ensureSchema());\n */\n public schema(): string {\n const lines = [\n `CREATE EXTENSION IF NOT EXISTS vector;`,\n `CREATE TABLE IF NOT EXISTS ${this.table} (`,\n ` key TEXT PRIMARY KEY,`,\n ` value JSONB NOT NULL,`,\n ` embedding vector(${this.dimensions}) NOT NULL,`,\n ` tags TEXT[] NOT NULL DEFAULT '{}'`,\n `);`,\n `CREATE INDEX IF NOT EXISTS idx_${this.table}_tags`,\n ` ON ${this.table} USING gin (tags);`,\n ];\n\n if (this.index === \"hnsw\") {\n lines.push(\n `CREATE INDEX IF NOT EXISTS idx_${this.table}_embedding`,\n ` ON ${this.table} USING hnsw (embedding vector_cosine_ops);`,\n );\n } else if (this.index === \"ivfflat\") {\n lines.push(\n `CREATE INDEX IF NOT EXISTS idx_${this.table}_embedding`,\n ` ON ${this.table} USING ivfflat (embedding vector_cosine_ops)`,\n ` WITH (lists = ${this.ivfflatLists});`,\n );\n } else {\n lines.push(\n `-- No ANN index requested (index: \"none\"): cosine queries fall back`,\n `-- to an exact sequential scan, which is correct but linear in rows.`,\n );\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Alias for {@link PgVectorStore.schema} — reads more naturally in a\n * migration script (`await pool.query(store.ensureSchema())`). Returns\n * the identical DDL string; it does NOT execute anything against the\n * database (the store never auto-migrates).\n */\n public ensureSchema(): string {\n return this.schema();\n }\n}\n\n/**\n * The {@link VectorStore} surface plus the pg store's extra DDL helpers.\n * `schema()` / `ensureSchema()` are not part of the base contract (the\n * cache store has no backing table), so the factory's return type widens\n * it for callers that want the migration SQL.\n */\nexport interface PgVectorStoreInstance extends VectorStore {\n /** Reference migration DDL (extension + table + indexes). Never executed. */\n schema(): string;\n /** Alias for {@link PgVectorStoreInstance.schema} — reads better in a migration script. */\n ensureSchema(): string;\n}\n\n/**\n * Create a Postgres + pgvector-backed {@link VectorStore} for the RAG\n * pipeline. Either pass a live `pg.Pool` / `pg.Client` (`{ client }`) —\n * `@warlock.js/ai` never imports `pg` in that case — or a\n * `{ connectionString }` and let the store lazily `import(\"pg\")` to build\n * its own pool. When `pg` is not installed, a curated install string\n * surfaces on first use, never at import.\n *\n * Run {@link PgVectorStoreInstance.ensureSchema} through your migration\n * tool once before use (it enables the `vector` extension, creates the\n * table, and builds the tag + ANN indexes); the store never auto-migrates.\n *\n * Index and query MUST use the same embedding model — the `vector(N)`\n * column width is fixed at table-creation time from `dimensions`.\n *\n * @example\n * import { Pool } from \"pg\";\n * import { ai } from \"@warlock.js/ai\";\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const store = ai.rag.pgVectorStore({ client: pool, dimensions: 1536 });\n *\n * // Once, via your migration tooling:\n * // await pool.query(store.ensureSchema());\n *\n * const kb = ai.rag({\n * name: \"docs\",\n * embedder: openai.embedder({ name: \"text-embedding-3-small\" }),\n * store,\n * });\n *\n * @example\n * // Let the store build its own pool from a connection string:\n * const store = ai.rag.pgVectorStore({\n * connectionString: process.env.DATABASE_URL,\n * index: \"ivfflat\",\n * ivfflatLists: 200,\n * });\n */\nexport function pgVectorStore(options: PgVectorStoreOptions): PgVectorStoreInstance {\n return new PgVectorStore(options);\n}\n"],"mappings":";;;;;;AA6EA,MAAM,gBAAgB;;AAGtB,MAAM,qBAAqB;;AAG3B,MAAM,wBAAwB;;;;;;;;AAS9B,MAAM,kBAAkB;;;;;;;AAQxB,MAAM,YAAY;;;;;;AAOlB,MAAM,0BAA0B;;;;;;;;;;EAU9B,KAAK;;;;;;AAiBP,eAAe,cAAc,kBAAiD;CAC5E,IAAI;CAEJ,IAAI;EACF,MAAO,MAAM,OAAO;CACtB,QAAQ;EACN,MAAM,IAAI,MAAM,uBAAuB;CACzC;CAEA,OAAO,IAAI,IAAI,KAAK,EAAE,iBAAiB,CAAC;AAC1C;;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,QAA0B;CACtD,IAAI,UAAU;CAEd,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS;EAClD,MAAM,YAAY,OAAO;EAEzB,IAAI,CAAC,OAAO,SAAS,SAAS,GAC5B,MAAM,IAAI,UACR,+CAA+C,MAAM,kBAAkB,UAAU,uCACnF;EAGF,IAAI,QAAQ,GACV,WAAW;EAGb,WAAW,OAAO,SAAS;CAC7B;CAEA,OAAO,UAAU;AACnB;;;;;;;AAQA,SAAS,WAAc,OAAmB;CACxC,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,MAAM,KAAK;CAGzB,OAAO;AACT;;;;;;;;;AAUA,SAAS,gBAAgB,UAA2B;CAElD,MAAM,QAAQ,KADA,OAAO,aAAa,WAAW,OAAO,QAAQ,IAAK;CAGjE,IAAI,QAAQ,GACV,OAAO;CAGT,IAAI,QAAQ,GACV,OAAO;CAGT,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAM,gBAAN,MAA2C;CAoBzC,AAAO,YAAY,SAA+B;EAChD,MAAM,QAAQ,QAAQ,SAAS;EAE/B,IAAI,CAAC,gBAAgB,KAAK,KAAK,GAC7B,MAAM,IAAI,UACR,sCAAsC,MAAM,oCAC9C;EAGF,KAAK,QAAQ;EACb,KAAK,aAAa,QAAQ,cAAc;EACxC,KAAK,QAAQ,QAAQ,SAAS;EAC9B,KAAK,eAAe,QAAQ,gBAAgB;EAE5C,IAAI,QAAQ,QAAQ;GAClB,IAAI,OAAO,QAAQ,OAAO,UAAU,YAClC,MAAM,IAAI,UACR,8GACF;GAGF,KAAK,gBAAgB,QAAQ,QAAQ,QAAQ,MAAM;GAEnD;EACF;EAEA,IAAI,QAAQ,kBAAkB;GAG5B,KAAK,gBAAgB,cAAc,QAAQ,gBAAgB;GAE3D;EACF;EAEA,MAAM,IAAI,UACR,0EACF;CACF;;;;;CAMA,AAAQ,SAAgC;EACtC,OAAO,KAAK;CACd;;;;;;;;;;;;;CAcA,MAAa,OACX,KACA,OACA,QACA,MACe;EAGf,OAAM,MAFe,KAAK,OAAO,EAErB,CAAC,MACX,eAAe,KAAK,MAAM;;;;;oCAM1B;GAAC;GAAK,KAAK,UAAU,KAAK;GAAG,cAAc,MAAM;GAAG,QAAQ,CAAC;EAAC,CAChE;CACF;;;;;;;;;;;;;;;;;;;CAoBA,MAAa,MACX,QACA,SACqD;EACrD,MAAM,SAAS,MAAM,KAAK,OAAO;EAMjC,MAAM,SAAoB,CALN,cAAc,MAKG,GAAG,QAAQ,IAAI;EACpD,MAAM,aAAuB,CAAC;EAE9B,IAAI,QAAQ,cAAc,QAAW;GACnC,OAAO,KAAK,IAAI,QAAQ,SAAS;GACjC,WAAW,KAAK,kCAAkC,OAAO,QAAQ;EACnE;EAEA,IAAI,QAAQ,SAAS,UAAa,QAAQ,KAAK,SAAS,GAAG;GACzD,OAAO,KAAK,QAAQ,IAAI;GACxB,WAAW,KAAK,YAAY,OAAO,OAAO,SAAS;EACrD;EAEA,MAAM,QAAQ,WAAW,SAAS,IAAI,SAAS,WAAW,KAAK,OAAO,MAAM;EAE5E,MAAM,EAAE,SAAS,MAAM,OAAO,MAC5B;cACQ,KAAK,MAAM;SAChB,MAAM;;kBAGT,MACF;EAEA,OAAQ,KAAmC,KAAK,SAAS;GACvD,KAAK,IAAI;GACT,OAAO,WAAc,IAAI,KAAK;GAC9B,OAAO,gBAAgB,IAAI,QAAQ;EACrC,EAAE;CACJ;;;;;;;;;CAUA,MAAa,gBAAgB,WAAkC;EAC7D,MAAM,SAAS,MAAM,KAAK,OAAO;EAEjC,MAAM,UAAU,UACb,QAAQ,OAAO,MAAM,CAAC,CACtB,QAAQ,MAAM,KAAK,CAAC,CACpB,QAAQ,MAAM,KAAK;EAEtB,MAAM,OAAO,MACX,eAAe,KAAK,MAAM;mDAE1B,CAAC,WAAW,GAAG,QAAQ,GAAG,CAC5B;CACF;;;;;;;;;;;;;;;;;;;;;;;;CAyBA,AAAO,SAAiB;EACtB,MAAM,QAAQ;GACZ;GACA,8BAA8B,KAAK,MAAM;GACzC;GACA;GACA,uBAAuB,KAAK,WAAW;GACvC;GACA;GACA,kCAAkC,KAAK,MAAM;GAC7C,QAAQ,KAAK,MAAM;EACrB;EAEA,IAAI,KAAK,UAAU,QACjB,MAAM,KACJ,kCAAkC,KAAK,MAAM,aAC7C,QAAQ,KAAK,MAAM,2CACrB;OACK,IAAI,KAAK,UAAU,WACxB,MAAM,KACJ,kCAAkC,KAAK,MAAM,aAC7C,QAAQ,KAAK,MAAM,+CACnB,mBAAmB,KAAK,aAAa,GACvC;OAEA,MAAM,KACJ,uEACA,sEACF;EAGF,OAAO,MAAM,KAAK,IAAI;CACxB;;;;;;;CAQA,AAAO,eAAuB;EAC5B,OAAO,KAAK,OAAO;CACrB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,cAAc,SAAsD;CAClF,OAAO,IAAI,cAAc,OAAO;AAClC"}
@@ -0,0 +1,38 @@
1
+ //#region ../@warlock.js/ai/src/rag/store/vector-store.contract.d.ts
2
+ /**
3
+ * The three vector operations the RAG pipeline needs, expressed as a thin
4
+ * structural narrowing of the `@warlock.js/cache` `CacheDriver` surface
5
+ * (`set({ vector })` + `similar()` + `removeNamespace()`).
6
+ *
7
+ * This is NOT a new storage engine — v1 has exactly one implementation,
8
+ * {@link cacheVectorStore}, which adapts any `CacheDriver`. The contract
9
+ * exists so a future non-cache backend can be swapped in without touching
10
+ * the pipeline. Cache stays embedding-agnostic; the RAG vocabulary
11
+ * (`upsert` / `query`) lives here, in the rag feature.
12
+ */
13
+ interface VectorStore {
14
+ /**
15
+ * Index a value under `key` with its embedding vector. Optional `tags`
16
+ * are stored alongside the entry so `query({ tags })` can restrict the
17
+ * candidate set to a subset of sources.
18
+ */
19
+ upsert(key: string, value: unknown, vector: number[], tags?: string[]): Promise<void>;
20
+ /**
21
+ * Cosine-nearest entries to `vector` clearing `threshold`, capped at
22
+ * `topK`, optionally restricted to entries carrying one of `tags`.
23
+ */
24
+ query<T>(vector: number[], options: {
25
+ topK: number;
26
+ threshold?: number;
27
+ tags?: string[];
28
+ }): Promise<{
29
+ key: string;
30
+ value: T;
31
+ score: number;
32
+ }[]>;
33
+ /** Drop every entry written under `namespace`. */
34
+ removeNamespace(namespace: string): Promise<void>;
35
+ }
36
+ //#endregion
37
+ export { VectorStore };
38
+ //# sourceMappingURL=vector-store.contract.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.contract.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/store/vector-store.contract.ts"],"mappings":";;AAWA;;;;;;;;;;UAAiB,WAAA;EAMK;;;;;EAApB,MAAA,CAAO,GAAA,UAAa,KAAA,WAAgB,MAAA,YAAkB,IAAA,cAAkB,OAAA;EAMtE;;;;EADF,KAAA,IACE,MAAA,YACA,OAAA;IAAW,IAAA;IAAc,SAAA;IAAoB,IAAA;EAAA,IAC5C,OAAA;IAAU,GAAA;IAAa,KAAA,EAAO,CAAA;IAAG,KAAA;EAAA;EAEO;EAA3C,eAAA,CAAgB,SAAA,WAAoB,OAAA;AAAA"}