@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,104 @@
1
+ //#region ../@warlock.js/ai/src/prompt/prompt-langfuse-sync.ts
2
+ let LangfuseSdk;
3
+ let isModuleExists = null;
4
+ let loadingPromise;
5
+ const PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS = `
6
+ The prompt registry's Langfuse sync requires the langfuse package.
7
+ Install it with:
8
+
9
+ npm install langfuse
10
+
11
+ Or with your preferred package manager:
12
+
13
+ pnpm add langfuse
14
+ yarn add langfuse
15
+ `.trim();
16
+ /**
17
+ * Settle the lazy import of `langfuse` once, concurrency-safe. Only needed
18
+ * when the caller did not pass a ready `client`. A bare `catch` flips the
19
+ * flag to `false`; the curated install string surfaces at use time, never a
20
+ * raw module-resolution stack trace.
21
+ */
22
+ function loadLangfuse() {
23
+ if (isModuleExists !== null) return Promise.resolve();
24
+ if (loadingPromise) return loadingPromise;
25
+ loadingPromise = (async () => {
26
+ try {
27
+ LangfuseSdk = await import("langfuse");
28
+ isModuleExists = true;
29
+ } catch {
30
+ isModuleExists = false;
31
+ }
32
+ })();
33
+ return loadingPromise;
34
+ }
35
+ /**
36
+ * Resolve the Langfuse client — the caller-supplied one when present,
37
+ * otherwise a lazily-constructed client from credentials. Throws the curated
38
+ * install error when the SDK is missing and no client was supplied.
39
+ */
40
+ async function resolveClient(options) {
41
+ if (options.client) return options.client;
42
+ await loadLangfuse();
43
+ if (!isModuleExists) throw new Error(PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS);
44
+ return new LangfuseSdk.Langfuse({
45
+ publicKey: options.publicKey,
46
+ secretKey: options.secretKey,
47
+ baseUrl: options.baseUrl
48
+ });
49
+ }
50
+ /**
51
+ * Map one Langfuse prompt handle onto a {@link PromptEntry} version snapshot.
52
+ * Langfuse versions are numeric; they become the string `version` label.
53
+ */
54
+ function toEntry(remote) {
55
+ return {
56
+ name: remote.name,
57
+ versions: [{
58
+ version: String(remote.version),
59
+ template: remote.prompt
60
+ }]
61
+ };
62
+ }
63
+ /**
64
+ * Warm the lazy `langfuse` import without blocking — call when a registry is
65
+ * constructed with a `langfuse` option but no pre-built client, so the first
66
+ * `.sync()` does not pay the resolution cost. A bare miss is tolerated.
67
+ */
68
+ function warmLangfuse(options) {
69
+ if (!options.client) loadLangfuse();
70
+ }
71
+ /**
72
+ * Run one Langfuse-prompts sync pass.
73
+ *
74
+ * **Pull** (`direction: "pull"` | `"both"`) fetches each named prompt from
75
+ * Langfuse and hands the mapped {@link PromptEntry} to `upsert`. **Push**
76
+ * (`direction: "push"` | `"both"`) writes the latest version of each local
77
+ * entry back as a new Langfuse text prompt. Default direction is `"pull"`.
78
+ *
79
+ * Lazily imports `langfuse` (unless a `client` was supplied) and throws a
80
+ * curated install error when the peer is missing.
81
+ *
82
+ * @param options - The configured sync options (client / credentials / direction).
83
+ * @param names - The prompt names to pull (ignored for push-only).
84
+ * @param localEntries - Snapshot of the local catalog, for push.
85
+ * @param upsert - Callback receiving each pulled entry to merge into the catalog.
86
+ */
87
+ async function syncLangfusePrompts(options, names, localEntries, upsert) {
88
+ const direction = options.direction ?? "pull";
89
+ const client = await resolveClient(options);
90
+ if (direction === "pull" || direction === "both") for (const name of names) upsert(toEntry(await client.getPrompt(name)));
91
+ if (direction === "push" || direction === "both") for (const entry of localEntries) {
92
+ const latest = entry.versions[entry.versions.length - 1];
93
+ if (!latest) continue;
94
+ await client.createPrompt({
95
+ name: entry.name,
96
+ prompt: latest.template,
97
+ type: "text"
98
+ });
99
+ }
100
+ }
101
+
102
+ //#endregion
103
+ export { syncLangfusePrompts, warmLangfuse };
104
+ //# sourceMappingURL=prompt-langfuse-sync.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-langfuse-sync.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-langfuse-sync.ts"],"sourcesContent":["import type { PromptEntry, PromptLangfuseSyncOptions } from \"./prompt.type\";\nimport type {\n LangfuseClientLike,\n LangfusePromptLike,\n} from \"./prompt-langfuse-sync.type\";\n\n// ============================================================\n// Lazily-loaded langfuse SDK (OPTIONAL peer)\n// ============================================================\n\nlet LangfuseSdk: typeof import(\"langfuse\");\nlet isModuleExists: boolean | null = null;\nlet loadingPromise: Promise<void> | undefined;\n\nconst PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS = `\nThe prompt registry's Langfuse sync requires the langfuse package.\nInstall it with:\n\n npm install langfuse\n\nOr with your preferred package manager:\n\n pnpm add langfuse\n yarn add langfuse\n`.trim();\n\n/**\n * Settle the lazy import of `langfuse` once, concurrency-safe. Only needed\n * when the caller did not pass a ready `client`. A bare `catch` flips the\n * flag to `false`; the curated install string surfaces at use time, never a\n * raw module-resolution stack trace.\n */\nfunction loadLangfuse(): Promise<void> {\n if (isModuleExists !== null) {\n return Promise.resolve();\n }\n\n if (loadingPromise) {\n return loadingPromise;\n }\n\n loadingPromise = (async () => {\n try {\n LangfuseSdk = await import(\"langfuse\");\n isModuleExists = true;\n } catch {\n isModuleExists = false;\n }\n })();\n\n return loadingPromise;\n}\n\n/**\n * Resolve the Langfuse client — the caller-supplied one when present,\n * otherwise a lazily-constructed client from credentials. Throws the curated\n * install error when the SDK is missing and no client was supplied.\n */\nasync function resolveClient(\n options: PromptLangfuseSyncOptions,\n): Promise<LangfuseClientLike> {\n if (options.client) {\n return options.client;\n }\n\n await loadLangfuse();\n\n if (!isModuleExists) {\n throw new Error(PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS);\n }\n\n return new LangfuseSdk.Langfuse({\n publicKey: options.publicKey,\n secretKey: options.secretKey,\n baseUrl: options.baseUrl,\n }) as unknown as LangfuseClientLike;\n}\n\n/**\n * Map one Langfuse prompt handle onto a {@link PromptEntry} version snapshot.\n * Langfuse versions are numeric; they become the string `version` label.\n */\nfunction toEntry(remote: LangfusePromptLike): PromptEntry {\n return {\n name: remote.name,\n versions: [{ version: String(remote.version), template: remote.prompt }],\n };\n}\n\n/**\n * Warm the lazy `langfuse` import without blocking — call when a registry is\n * constructed with a `langfuse` option but no pre-built client, so the first\n * `.sync()` does not pay the resolution cost. A bare miss is tolerated.\n */\nexport function warmLangfuse(options: PromptLangfuseSyncOptions): void {\n if (!options.client) {\n void loadLangfuse();\n }\n}\n\n/**\n * Run one Langfuse-prompts sync pass.\n *\n * **Pull** (`direction: \"pull\"` | `\"both\"`) fetches each named prompt from\n * Langfuse and hands the mapped {@link PromptEntry} to `upsert`. **Push**\n * (`direction: \"push\"` | `\"both\"`) writes the latest version of each local\n * entry back as a new Langfuse text prompt. Default direction is `\"pull\"`.\n *\n * Lazily imports `langfuse` (unless a `client` was supplied) and throws a\n * curated install error when the peer is missing.\n *\n * @param options - The configured sync options (client / credentials / direction).\n * @param names - The prompt names to pull (ignored for push-only).\n * @param localEntries - Snapshot of the local catalog, for push.\n * @param upsert - Callback receiving each pulled entry to merge into the catalog.\n */\nexport async function syncLangfusePrompts(\n options: PromptLangfuseSyncOptions,\n names: string[],\n localEntries: PromptEntry[],\n upsert: (entry: PromptEntry) => void,\n): Promise<void> {\n const direction = options.direction ?? \"pull\";\n const client = await resolveClient(options);\n\n if (direction === \"pull\" || direction === \"both\") {\n for (const name of names) {\n const remote = await client.getPrompt(name);\n upsert(toEntry(remote));\n }\n }\n\n if (direction === \"push\" || direction === \"both\") {\n for (const entry of localEntries) {\n const latest = entry.versions[entry.versions.length - 1];\n\n if (!latest) {\n continue;\n }\n\n await client.createPrompt({\n name: entry.name,\n prompt: latest.template,\n type: \"text\",\n });\n }\n }\n}\n"],"mappings":";AAUA,IAAI;AACJ,IAAI,iBAAiC;AACrC,IAAI;AAEJ,MAAM,uCAAuC;;;;;;;;;;EAU3C,KAAK;;;;;;;AAQP,SAAS,eAA8B;CACrC,IAAI,mBAAmB,MACrB,OAAO,QAAQ,QAAQ;CAGzB,IAAI,gBACF,OAAO;CAGT,kBAAkB,YAAY;EAC5B,IAAI;GACF,cAAc,MAAM,OAAO;GAC3B,iBAAiB;EACnB,QAAQ;GACN,iBAAiB;EACnB;CACF,EAAC,CAAE;CAEH,OAAO;AACT;;;;;;AAOA,eAAe,cACb,SAC6B;CAC7B,IAAI,QAAQ,QACV,OAAO,QAAQ;CAGjB,MAAM,aAAa;CAEnB,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,oCAAoC;CAGtD,OAAO,IAAI,YAAY,SAAS;EAC9B,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,SAAS,QAAQ;CACnB,CAAC;AACH;;;;;AAMA,SAAS,QAAQ,QAAyC;CACxD,OAAO;EACL,MAAM,OAAO;EACb,UAAU,CAAC;GAAE,SAAS,OAAO,OAAO,OAAO;GAAG,UAAU,OAAO;EAAO,CAAC;CACzE;AACF;;;;;;AAOA,SAAgB,aAAa,SAA0C;CACrE,IAAI,CAAC,QAAQ,QACX,AAAK,aAAa;AAEtB;;;;;;;;;;;;;;;;;AAkBA,eAAsB,oBACpB,SACA,OACA,cACA,QACe;CACf,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,SAAS,MAAM,cAAc,OAAO;CAE1C,IAAI,cAAc,UAAU,cAAc,QACxC,KAAK,MAAM,QAAQ,OAEjB,OAAO,QAAQ,MADM,OAAO,UAAU,IAAI,CACrB,CAAC;CAI1B,IAAI,cAAc,UAAU,cAAc,QACxC,KAAK,MAAM,SAAS,cAAc;EAChC,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,SAAS;EAEtD,IAAI,CAAC,QACH;EAGF,MAAM,OAAO,aAAa;GACxB,MAAM,MAAM;GACZ,QAAQ,OAAO;GACf,MAAM;EACR,CAAC;CACH;AAEJ"}
@@ -0,0 +1,32 @@
1
+ //#region ../@warlock.js/ai/src/prompt/prompt-langfuse-sync.type.d.ts
2
+ /**
3
+ * Minimal structural view of the parts of the `langfuse` SDK the prompt sync
4
+ * actually calls. Declared locally (rather than importing the SDK's own types)
5
+ * so this module type-checks even when `langfuse` is not installed — it is an
6
+ * OPTIONAL peer, lazily imported at runtime. The shape tracks Langfuse SDK v3's
7
+ * prompt API: `getPrompt(name, version?)` reads a prompt and `createPrompt(...)`
8
+ * writes a new prompt version.
9
+ */
10
+ type LangfuseClientLike = {
11
+ /** Fetch a single prompt by name (optionally a specific version). */getPrompt(name: string, version?: number): Promise<LangfusePromptLike>; /** Create (push) a new text prompt version. */
12
+ createPrompt(body: LangfuseCreatePromptBody): Promise<LangfusePromptLike>;
13
+ };
14
+ /**
15
+ * A Langfuse prompt handle as returned by `getPrompt` / `createPrompt`. Only
16
+ * the `name` / `version` / `prompt` (body) fields the sync maps are modeled.
17
+ */
18
+ type LangfusePromptLike = {
19
+ /** Prompt name. */name: string; /** Numeric version assigned by Langfuse. */
20
+ version: number; /** The prompt body text (Langfuse `type: "text"` prompts). */
21
+ prompt: string;
22
+ };
23
+ /** Body accepted by `client.createPrompt(...)` for a text prompt. */
24
+ type LangfuseCreatePromptBody = {
25
+ /** Prompt name. */name: string; /** Prompt body text. */
26
+ prompt: string; /** Discriminator — always `"text"` for the bodies this sync pushes. */
27
+ type?: "text"; /** Deploy labels (e.g. `["production"]`). Optional. */
28
+ labels?: string[];
29
+ };
30
+ //#endregion
31
+ export { LangfuseClientLike };
32
+ //# sourceMappingURL=prompt-langfuse-sync.type.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-langfuse-sync.type.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-langfuse-sync.type.ts"],"mappings":";;AAQA;;;;;;;KAAY,kBAAA;EAI2C,qEAFrD,SAAA,CAAU,IAAA,UAAc,OAAA,YAAmB,OAAA,CAAQ,kBAAA,GAAnD;EAEA,YAAA,CAAa,IAAA,EAAM,wBAAA,GAA2B,OAAA,CAAQ,kBAAA;AAAA;;;;;KAO5C,kBAAA;EAPoC,mBAS9C,IAAA,UATwE;EAWxE,OAAA,UAJU;EAMV,MAAA;AAAA;;KAIU,wBAAA;EANV,mBAQA,IAAA,UANM;EAQN,MAAA,UAJU;EAMV,IAAA;EAEA,MAAA;AAAA"}
@@ -0,0 +1,170 @@
1
+ import { judge } from "../eval/judge-scorer.mjs";
2
+
3
+ //#region ../@warlock.js/ai/src/prompt/prompt-validate.ts
4
+ /**
5
+ * Placeholder matcher — kept in lock-step with the matcher
6
+ * `renderPlaceholders` uses (`src/system-prompt/render-placeholders.ts`) so the
7
+ * lint sees the same `{{key}}` / `{{a.b}}` / `{{key|default}}` set the renderer
8
+ * substitutes. Global so every occurrence is collected.
9
+ */
10
+ const PLACEHOLDER_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
11
+ /** Lower bound below which a prompt is suspiciously terse. */
12
+ const MIN_REASONABLE_LENGTH = 12;
13
+ /** Upper bound above which a prompt is likely bloated / unfocused. */
14
+ const MAX_REASONABLE_LENGTH = 8e3;
15
+ /**
16
+ * Severity rank for most-severe-first ordering. Higher sorts earlier.
17
+ */
18
+ const SEVERITY_RANK = {
19
+ error: 2,
20
+ warn: 1,
21
+ info: 0
22
+ };
23
+ /**
24
+ * The fixed rubric the LLM-as-judge grades a prompt body against. Surfaced
25
+ * here (not inline) so the static-lint pass and the judge pass document the
26
+ * same quality dimensions.
27
+ */
28
+ const PROMPT_JUDGE_RUBRIC = [
29
+ "Grade this SYSTEM PROMPT on a 0..1 scale for overall quality:",
30
+ "- Clarity: is the intent unambiguous and easy to follow?",
31
+ "- Role definition: does it clearly state who/what the assistant is?",
32
+ "- Output-format specificity: does it say how the answer should be shaped?",
33
+ "- No conflicting instructions: are any directives contradictory?",
34
+ "Score 1.0 only when all four hold; deduct for each weakness and explain why."
35
+ ].join("\n");
36
+ /**
37
+ * Heuristic role-line detector — a prompt that never says "you are …" /
38
+ * "act as …" / "your role is …" typically lacks a persona. Case-insensitive.
39
+ */
40
+ const ROLE_HINT_PATTERN = /\b(you are|act as|your role is|you're a|you will act)\b/i;
41
+ /**
42
+ * Run the cheap, model-free static lint over a prompt body. Flags:
43
+ * - length out of the reasonable band (too terse / too bloated),
44
+ * - any `{{placeholder}}` that survives (undeclared / unresolved at lint time),
45
+ * - a missing role line.
46
+ *
47
+ * Pure and synchronous — used standalone (no judge model) and merged with the
48
+ * judge findings when a model is available.
49
+ *
50
+ * @param text - The prompt body to lint.
51
+ */
52
+ function staticLint(text) {
53
+ const notes = [];
54
+ const trimmed = text.trim();
55
+ if (trimmed.length < MIN_REASONABLE_LENGTH) notes.push({
56
+ severity: "warn",
57
+ message: `Prompt is very short (${trimmed.length} chars) — it may be too vague to steer the model.`,
58
+ suggestion: "Add an explicit role and at least one concrete instruction."
59
+ });
60
+ if (trimmed.length > MAX_REASONABLE_LENGTH) notes.push({
61
+ severity: "warn",
62
+ message: `Prompt is very long (${trimmed.length} chars) — long prompts dilute focus and inflate cost.`,
63
+ suggestion: "Split into a tighter persona plus a few focused instructions."
64
+ });
65
+ const placeholders = collectPlaceholders(text);
66
+ for (const placeholder of placeholders) notes.push({
67
+ severity: "info",
68
+ message: `Unresolved placeholder "{{${placeholder}}}" — confirm it is supplied at resolve time or give it a default ("{{${placeholder}|...}}").`
69
+ });
70
+ if (!ROLE_HINT_PATTERN.test(trimmed)) notes.push({
71
+ severity: "warn",
72
+ message: "No role line found — the prompt never states who the assistant is.",
73
+ suggestion: "Open with a role, e.g. \"You are a senior support engineer for …\"."
74
+ });
75
+ return notes;
76
+ }
77
+ /**
78
+ * Collect every distinct placeholder PATH (the part before any `|default`)
79
+ * from a template, in first-seen order. Matches `renderPlaceholders`' own
80
+ * parsing so the lint never disagrees with the renderer.
81
+ */
82
+ function collectPlaceholders(template) {
83
+ const found = [];
84
+ const seen = /* @__PURE__ */ new Set();
85
+ for (const match of template.matchAll(PLACEHOLDER_PATTERN)) {
86
+ const path = match[1].split("|")[0].trim();
87
+ if (path.length > 0 && !seen.has(path)) {
88
+ seen.add(path);
89
+ found.push(path);
90
+ }
91
+ }
92
+ return found;
93
+ }
94
+ /**
95
+ * Stable, most-severe-first ordering: `error` before `warn` before `info`,
96
+ * preserving original order within a severity. Returns a fresh array.
97
+ */
98
+ function sortNotesBySeverity(notes) {
99
+ return notes.map((note, index) => ({
100
+ note,
101
+ index
102
+ })).sort((a, b) => {
103
+ const rankDiff = SEVERITY_RANK[b.note.severity] - SEVERITY_RANK[a.note.severity];
104
+ return rankDiff !== 0 ? rankDiff : a.index - b.index;
105
+ }).map((entry) => entry.note);
106
+ }
107
+ /**
108
+ * Score the static-lint findings alone, on a `0..1` scale. Starts at `1.0`
109
+ * and deducts per finding by severity, clamped at `0`. Used as the report
110
+ * score when no judge model is available.
111
+ */
112
+ function staticScore(notes) {
113
+ let score = 1;
114
+ for (const note of notes) if (note.severity === "error") score -= .4;
115
+ else if (note.severity === "warn") score -= .2;
116
+ else score -= .05;
117
+ return Math.max(0, Number(score.toFixed(4)));
118
+ }
119
+ /**
120
+ * Run the LLM-as-judge pass over `text` using a judge agent built from
121
+ * `model`, REUSING the eval `judge` scorer so there is no second judging
122
+ * path. Returns the judge `score` (`0..1`) and a single derived note carrying
123
+ * its reason (when present). The judge prompt is the prompt-quality rubric;
124
+ * the "answer to grade" is the prompt body itself.
125
+ *
126
+ * @param text - The prompt body under evaluation.
127
+ * @param model - The model that powers the judge agent.
128
+ * @param buildJudgeAgent - Factory that wraps a model into a name-bearing judge agent.
129
+ */
130
+ async function judgePrompt(text, model, buildJudgeAgent) {
131
+ const score = await judge({
132
+ agent: buildJudgeAgent(model),
133
+ rubric: PROMPT_JUDGE_RUBRIC
134
+ })({
135
+ case: {
136
+ name: "prompt-quality",
137
+ input: "Grade the system prompt below."
138
+ },
139
+ text,
140
+ result: { text },
141
+ output: void 0
142
+ });
143
+ const notes = [];
144
+ if (score.reason) notes.push({
145
+ severity: score.passed ? "info" : "warn",
146
+ message: `LLM-as-judge: ${score.reason}`
147
+ });
148
+ return {
149
+ score: score.score,
150
+ notes
151
+ };
152
+ }
153
+ /**
154
+ * Assemble the final {@link PromptValidationReport} from the static-lint
155
+ * findings and (optionally) the judge findings. Notes are merged and sorted
156
+ * most-severe-first. The score is the static score alone when no judge ran,
157
+ * else the mean of the static score and the judge score.
158
+ */
159
+ function buildValidationReport(staticNotes, judgeResult) {
160
+ const allNotes = judgeResult ? [...staticNotes, ...judgeResult.notes] : staticNotes;
161
+ const lintScore = staticScore(staticNotes);
162
+ return {
163
+ score: judgeResult ? Number(((lintScore + judgeResult.score) / 2).toFixed(4)) : lintScore,
164
+ notes: sortNotesBySeverity(allNotes)
165
+ };
166
+ }
167
+
168
+ //#endregion
169
+ export { PROMPT_JUDGE_RUBRIC, buildValidationReport, judgePrompt, staticLint };
170
+ //# sourceMappingURL=prompt-validate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-validate.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-validate.ts"],"sourcesContent":["import type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { ModelContract } from \"../contracts/model.contract\";\nimport { judge } from \"../eval/judge-scorer\";\nimport type { PromptValidationNote, PromptValidationReport } from \"./prompt.type\";\n\n/**\n * Placeholder matcher — kept in lock-step with the matcher\n * `renderPlaceholders` uses (`src/system-prompt/render-placeholders.ts`) so the\n * lint sees the same `{{key}}` / `{{a.b}}` / `{{key|default}}` set the renderer\n * substitutes. Global so every occurrence is collected.\n */\nconst PLACEHOLDER_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\n/** Lower bound below which a prompt is suspiciously terse. */\nconst MIN_REASONABLE_LENGTH = 12;\n\n/** Upper bound above which a prompt is likely bloated / unfocused. */\nconst MAX_REASONABLE_LENGTH = 8000;\n\n/**\n * Severity rank for most-severe-first ordering. Higher sorts earlier.\n */\nconst SEVERITY_RANK: Record<PromptValidationNote[\"severity\"], number> = {\n error: 2,\n warn: 1,\n info: 0,\n};\n\n/**\n * The fixed rubric the LLM-as-judge grades a prompt body against. Surfaced\n * here (not inline) so the static-lint pass and the judge pass document the\n * same quality dimensions.\n */\nexport const PROMPT_JUDGE_RUBRIC = [\n \"Grade this SYSTEM PROMPT on a 0..1 scale for overall quality:\",\n \"- Clarity: is the intent unambiguous and easy to follow?\",\n \"- Role definition: does it clearly state who/what the assistant is?\",\n \"- Output-format specificity: does it say how the answer should be shaped?\",\n \"- No conflicting instructions: are any directives contradictory?\",\n \"Score 1.0 only when all four hold; deduct for each weakness and explain why.\",\n].join(\"\\n\");\n\n/**\n * Heuristic role-line detector — a prompt that never says \"you are …\" /\n * \"act as …\" / \"your role is …\" typically lacks a persona. Case-insensitive.\n */\nconst ROLE_HINT_PATTERN = /\\b(you are|act as|your role is|you're a|you will act)\\b/i;\n\n/**\n * Run the cheap, model-free static lint over a prompt body. Flags:\n * - length out of the reasonable band (too terse / too bloated),\n * - any `{{placeholder}}` that survives (undeclared / unresolved at lint time),\n * - a missing role line.\n *\n * Pure and synchronous — used standalone (no judge model) and merged with the\n * judge findings when a model is available.\n *\n * @param text - The prompt body to lint.\n */\nexport function staticLint(text: string): PromptValidationNote[] {\n const notes: PromptValidationNote[] = [];\n const trimmed = text.trim();\n\n if (trimmed.length < MIN_REASONABLE_LENGTH) {\n notes.push({\n severity: \"warn\",\n message: `Prompt is very short (${trimmed.length} chars) — it may be too vague to steer the model.`,\n suggestion: \"Add an explicit role and at least one concrete instruction.\",\n });\n }\n\n if (trimmed.length > MAX_REASONABLE_LENGTH) {\n notes.push({\n severity: \"warn\",\n message: `Prompt is very long (${trimmed.length} chars) — long prompts dilute focus and inflate cost.`,\n suggestion: \"Split into a tighter persona plus a few focused instructions.\",\n });\n }\n\n const placeholders = collectPlaceholders(text);\n\n for (const placeholder of placeholders) {\n notes.push({\n severity: \"info\",\n message: `Unresolved placeholder \"{{${placeholder}}}\" — confirm it is supplied at resolve time or give it a default (\"{{${placeholder}|...}}\").`,\n });\n }\n\n if (!ROLE_HINT_PATTERN.test(trimmed)) {\n notes.push({\n severity: \"warn\",\n message: \"No role line found — the prompt never states who the assistant is.\",\n suggestion: 'Open with a role, e.g. \"You are a senior support engineer for …\".',\n });\n }\n\n return notes;\n}\n\n/**\n * Collect every distinct placeholder PATH (the part before any `|default`)\n * from a template, in first-seen order. Matches `renderPlaceholders`' own\n * parsing so the lint never disagrees with the renderer.\n */\nfunction collectPlaceholders(template: string): string[] {\n const found: string[] = [];\n const seen = new Set<string>();\n\n for (const match of template.matchAll(PLACEHOLDER_PATTERN)) {\n const path = match[1].split(\"|\")[0].trim();\n\n if (path.length > 0 && !seen.has(path)) {\n seen.add(path);\n found.push(path);\n }\n }\n\n return found;\n}\n\n/**\n * Stable, most-severe-first ordering: `error` before `warn` before `info`,\n * preserving original order within a severity. Returns a fresh array.\n */\nexport function sortNotesBySeverity(\n notes: PromptValidationNote[],\n): PromptValidationNote[] {\n return notes\n .map((note, index) => ({ note, index }))\n .sort((a, b) => {\n const rankDiff = SEVERITY_RANK[b.note.severity] - SEVERITY_RANK[a.note.severity];\n\n return rankDiff !== 0 ? rankDiff : a.index - b.index;\n })\n .map(entry => entry.note);\n}\n\n/**\n * Score the static-lint findings alone, on a `0..1` scale. Starts at `1.0`\n * and deducts per finding by severity, clamped at `0`. Used as the report\n * score when no judge model is available.\n */\nexport function staticScore(notes: PromptValidationNote[]): number {\n let score = 1;\n\n for (const note of notes) {\n if (note.severity === \"error\") {\n score -= 0.4;\n } else if (note.severity === \"warn\") {\n score -= 0.2;\n } else {\n score -= 0.05;\n }\n }\n\n return Math.max(0, Number(score.toFixed(4)));\n}\n\n/**\n * Run the LLM-as-judge pass over `text` using a judge agent built from\n * `model`, REUSING the eval `judge` scorer so there is no second judging\n * path. Returns the judge `score` (`0..1`) and a single derived note carrying\n * its reason (when present). The judge prompt is the prompt-quality rubric;\n * the \"answer to grade\" is the prompt body itself.\n *\n * @param text - The prompt body under evaluation.\n * @param model - The model that powers the judge agent.\n * @param buildJudgeAgent - Factory that wraps a model into a name-bearing judge agent.\n */\nexport async function judgePrompt(\n text: string,\n model: ModelContract,\n buildJudgeAgent: (model: ModelContract) => AgentContract<unknown>,\n): Promise<{ score: number; notes: PromptValidationNote[] }> {\n const judgeAgent = buildJudgeAgent(model);\n const scorer = judge({ agent: judgeAgent, rubric: PROMPT_JUDGE_RUBRIC });\n\n const score = await scorer({\n // The judge scorer only reads `case.input` / `case.expected` / `text` /\n // `output` from the context. We feed the rubric question via `input` and\n // the prompt body as the answer to grade via `text`.\n case: { name: \"prompt-quality\", input: \"Grade the system prompt below.\" },\n text,\n // `result` is unused by the judge scorer's prompt builder; a minimal\n // stand-in keeps the structural contract satisfied without a real run.\n result: { text } as never,\n output: undefined,\n });\n\n const notes: PromptValidationNote[] = [];\n\n if (score.reason) {\n notes.push({\n severity: score.passed ? \"info\" : \"warn\",\n message: `LLM-as-judge: ${score.reason}`,\n });\n }\n\n return { score: score.score, notes };\n}\n\n/**\n * Assemble the final {@link PromptValidationReport} from the static-lint\n * findings and (optionally) the judge findings. Notes are merged and sorted\n * most-severe-first. The score is the static score alone when no judge ran,\n * else the mean of the static score and the judge score.\n */\nexport function buildValidationReport(\n staticNotes: PromptValidationNote[],\n judgeResult?: { score: number; notes: PromptValidationNote[] },\n): PromptValidationReport {\n const allNotes = judgeResult\n ? [...staticNotes, ...judgeResult.notes]\n : staticNotes;\n\n const lintScore = staticScore(staticNotes);\n\n const score = judgeResult\n ? Number(((lintScore + judgeResult.score) / 2).toFixed(4))\n : lintScore;\n\n return {\n score,\n notes: sortNotesBySeverity(allNotes),\n };\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,sBAAsB;;AAG5B,MAAM,wBAAwB;;AAG9B,MAAM,wBAAwB;;;;AAK9B,MAAM,gBAAkE;CACtE,OAAO;CACP,MAAM;CACN,MAAM;AACR;;;;;;AAOA,MAAa,sBAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;;;;AAMX,MAAM,oBAAoB;;;;;;;;;;;;AAa1B,SAAgB,WAAW,MAAsC;CAC/D,MAAM,QAAgC,CAAC;CACvC,MAAM,UAAU,KAAK,KAAK;CAE1B,IAAI,QAAQ,SAAS,uBACnB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,yBAAyB,QAAQ,OAAO;EACjD,YAAY;CACd,CAAC;CAGH,IAAI,QAAQ,SAAS,uBACnB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,wBAAwB,QAAQ,OAAO;EAChD,YAAY;CACd,CAAC;CAGH,MAAM,eAAe,oBAAoB,IAAI;CAE7C,KAAK,MAAM,eAAe,cACxB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,6BAA6B,YAAY,wEAAwE,YAAY;CACxI,CAAC;CAGH,IAAI,CAAC,kBAAkB,KAAK,OAAO,GACjC,MAAM,KAAK;EACT,UAAU;EACV,SAAS;EACT,YAAY;CACd,CAAC;CAGH,OAAO;AACT;;;;;;AAOA,SAAS,oBAAoB,UAA4B;CACvD,MAAM,QAAkB,CAAC;CACzB,MAAM,uBAAO,IAAI,IAAY;CAE7B,KAAK,MAAM,SAAS,SAAS,SAAS,mBAAmB,GAAG;EAC1D,MAAM,OAAO,MAAM,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK;EAEzC,IAAI,KAAK,SAAS,KAAK,CAAC,KAAK,IAAI,IAAI,GAAG;GACtC,KAAK,IAAI,IAAI;GACb,MAAM,KAAK,IAAI;EACjB;CACF;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,oBACd,OACwB;CACxB,OAAO,MACJ,KAAK,MAAM,WAAW;EAAE;EAAM;CAAM,EAAE,CAAC,CACvC,MAAM,GAAG,MAAM;EACd,MAAM,WAAW,cAAc,EAAE,KAAK,YAAY,cAAc,EAAE,KAAK;EAEvE,OAAO,aAAa,IAAI,WAAW,EAAE,QAAQ,EAAE;CACjD,CAAC,CAAC,CACD,KAAI,UAAS,MAAM,IAAI;AAC5B;;;;;;AAOA,SAAgB,YAAY,OAAuC;CACjE,IAAI,QAAQ;CAEZ,KAAK,MAAM,QAAQ,OACjB,IAAI,KAAK,aAAa,SACpB,SAAS;MACJ,IAAI,KAAK,aAAa,QAC3B,SAAS;MAET,SAAS;CAIb,OAAO,KAAK,IAAI,GAAG,OAAO,MAAM,QAAQ,CAAC,CAAC,CAAC;AAC7C;;;;;;;;;;;;AAaA,eAAsB,YACpB,MACA,OACA,iBAC2D;CAI3D,MAAM,QAAQ,MAFC,MAAM;EAAE,OADJ,gBAAgB,KACI;EAAG,QAAQ;CAAoB,CAE7C,CAAC,CAAC;EAIzB,MAAM;GAAE,MAAM;GAAkB,OAAO;EAAiC;EACxE;EAGA,QAAQ,EAAE,KAAK;EACf,QAAQ;CACV,CAAC;CAED,MAAM,QAAgC,CAAC;CAEvC,IAAI,MAAM,QACR,MAAM,KAAK;EACT,UAAU,MAAM,SAAS,SAAS;EAClC,SAAS,iBAAiB,MAAM;CAClC,CAAC;CAGH,OAAO;EAAE,OAAO,MAAM;EAAO;CAAM;AACrC;;;;;;;AAQA,SAAgB,sBACd,aACA,aACwB;CACxB,MAAM,WAAW,cACb,CAAC,GAAG,aAAa,GAAG,YAAY,KAAK,IACrC;CAEJ,MAAM,YAAY,YAAY,WAAW;CAMzC,OAAO;EACL,OALY,cACV,SAAS,YAAY,YAAY,SAAS,EAAC,CAAE,QAAQ,CAAC,CAAC,IACvD;EAIF,OAAO,oBAAoB,QAAQ;CACrC;AACF"}
@@ -0,0 +1,54 @@
1
+ import { SystemPromptContract } from "../contracts/system-prompt.contract.mjs";
2
+ import { PromptRegistryContract, PromptRegistryOptions } from "./prompt.type.mjs";
3
+
4
+ //#region ../@warlock.js/ai/src/prompt/prompt.d.ts
5
+ /**
6
+ * Create a versioned, typed prompt registry — a thin facade over the unified
7
+ * `ai.prompts` manager.
8
+ *
9
+ * **Role.** Public factory for {@link PromptRegistryContract}. Keeps
10
+ * user-facing code free of `new` and consistent with `ai.memory`,
11
+ * `ai.orchestrator`, `ai.batch` (all return instances). Each call returns a
12
+ * fresh, isolated registry backed by its own unified manager, so parallel test
13
+ * suites and multi-tenant apps never share mutable global prompt state.
14
+ *
15
+ * @param options - Seed entries, an optional default judge model, and an
16
+ * optional Langfuse sync.
17
+ *
18
+ * @example
19
+ * const prompts = prompt({
20
+ * prompts: [
21
+ * {
22
+ * name: "support-agent",
23
+ * versions: [
24
+ * { version: "1", template: "You are support for {{product}}. Reply in {{language|English}}." },
25
+ * { version: "2", template: "You are senior support for {{product}}.", required: ["product"] },
26
+ * ],
27
+ * },
28
+ * ],
29
+ * });
30
+ *
31
+ * const resolved = prompts.resolve("support-agent", { placeholders: { product: "Warlock" } });
32
+ * const agent = ai.agent({ model, systemPrompt: resolved.toSystemPrompt() });
33
+ * // resolved.version === "2"; a missing `product` would throw PromptValidationError.
34
+ *
35
+ * @example
36
+ * // Resolve a globally-registered prompt by name from `ai.prompts`.
37
+ * ai.systemPrompt("You are support.", { name: "support" });
38
+ * const sp = ai.prompt("support"); // → the registered SystemPromptContract
39
+ */
40
+ declare function promptFactory(name: string, versionOrTag?: string): SystemPromptContract;
41
+ declare function promptFactory(options?: PromptRegistryOptions): PromptRegistryContract;
42
+ /**
43
+ * Create a versioned prompt registry, OR resolve a globally-registered prompt
44
+ * by name from `ai.prompts`.
45
+ *
46
+ * - `prompt(options?)` → a fresh, isolated {@link PromptRegistryContract}.
47
+ * - `prompt(name, versionOrTag?)` → the `SystemPromptContract` registered under
48
+ * `name` in the process-wide `ai.prompts` manager (latest version by default,
49
+ * or a specific version / pinned tag).
50
+ */
51
+ declare const prompt: typeof promptFactory;
52
+ //#endregion
53
+ export { prompt };
54
+ //# sourceMappingURL=prompt.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt.ts"],"mappings":";;;;;;AA+BuB;;;;;;;;AA+UA;AAAA;;;;;;;;AACwD;AAyB/E;;;;AAAyD;;;;;;;;;;;iBA7BhD,aAAA,CACP,IAAA,UACA,YAAA,YACC,oBAAoB;AAAA,iBACd,aAAA,CAAc,OAAA,GAAU,qBAAA,GAAwB,sBAAsB;;;;;;;;;;cAyBlE,MAAA,SAAe,aAA6B"}
@@ -0,0 +1,218 @@
1
+ import { agent } from "../agent/agent.mjs";
2
+ import { renderPlaceholders } from "../system-prompt/render-placeholders.mjs";
3
+ import { Instruction } from "../system-prompt/instruction.mjs";
4
+ import { SystemPrompt } from "../system-prompt/system-prompt.mjs";
5
+ import { buildValidationReport, judgePrompt, staticLint } from "./prompt-validate.mjs";
6
+ import { defaultPromptsManager, prompts } from "../prompts/prompts-manager.mjs";
7
+ import { PromptNotFoundError, PromptValidationError } from "./errors.mjs";
8
+ import { syncLangfusePrompts, warmLangfuse } from "./prompt-langfuse-sync.mjs";
9
+
10
+ //#region ../@warlock.js/ai/src/prompt/prompt.ts
11
+ /**
12
+ * Build the one-shot judge agent the `validate()` LLM-as-judge pass runs.
13
+ * Name-bearing (the eval `judge` scorer requires a usable agent) and seeded
14
+ * with a strict-JSON instruction so its verdict parses even without an output
15
+ * schema. Kept module-private so the registry's only model dependency is the
16
+ * `agent()` factory.
17
+ */
18
+ function buildJudgeAgent(model) {
19
+ return agent({
20
+ name: "prompt-quality-judge",
21
+ model,
22
+ systemPrompt: "You are a strict prompt-quality grader. Respond with JSON only: { \"score\": <0..1>, \"passed\": <true|false>, \"reason\": \"<short explanation>\" }."
23
+ });
24
+ }
25
+ /**
26
+ * Build the `SystemPromptContract` a single {@link PromptVersion} maps to: its
27
+ * `template` becomes one instruction block, and its `required` keys ride along
28
+ * as `meta.required` so the unified manager (and `validate`) can see them.
29
+ *
30
+ * Deliberately ANONYMOUS (no `meta.name`) so the `SystemPrompt` constructor
31
+ * never auto-registers this version into the process-wide `ai.prompts` default
32
+ * manager — each `prompt()` registry owns its OWN isolated
33
+ * {@link PromptsManagerContract}, the single storage shape behind this facade.
34
+ */
35
+ function versionToContract(version) {
36
+ return new SystemPrompt([new Instruction(version.template)], { ...version.required ? { required: version.required } : {} });
37
+ }
38
+ /**
39
+ * Legacy `PromptRegistryContract` — now a THIN FACADE over the unified
40
+ * {@link PromptsManagerContract} (`ai.prompts`).
41
+ *
42
+ * **Role.** The store behind `ai.prompt(...)`. Historically it held a private
43
+ * `Map<string, PromptVersion[]>`; it now delegates ALL storage to a private,
44
+ * per-instance {@link PromptsManagerContract}, so there is exactly ONE storage
45
+ * shape across the whole prompt surface: a `SystemPromptContract` keyed by
46
+ * `name@version`. A version's raw `template` string maps to a single
47
+ * instruction block and its `required` keys to `meta.required`.
48
+ *
49
+ * **Responsibility.**
50
+ * - Owns: the legacy method surface (`register` / `add` / `versions` /
51
+ * `resolve` / `validate` / `sync`) and the back-compat behaviors — duplicate
52
+ * version rejection, required-key assertion on `resolve()`, the
53
+ * `{ score, notes }` validation report shape, and the optional Langfuse sync.
54
+ * - Does NOT own: the actual storage (delegated to the internal manager),
55
+ * placeholder rendering (delegated to `renderPlaceholders`), or the unified
56
+ * validation primitives (delegated to `prompt-validate`).
57
+ *
58
+ * Each `prompt(options)` call builds its own isolated manager — so parallel
59
+ * test suites and multi-tenant apps never share mutable global prompt state,
60
+ * exactly as before the unification.
61
+ *
62
+ * Users construct via the `prompt()` factory — `new PromptRegistry()` is not
63
+ * the public API.
64
+ */
65
+ var PromptRegistry = class {
66
+ constructor(options = {}) {
67
+ this.options = options;
68
+ this.versionMeta = /* @__PURE__ */ new Map();
69
+ this.manager = prompts();
70
+ for (const entry of options.prompts ?? []) this.register(entry);
71
+ if (options.langfuse) warmLangfuse(options.langfuse);
72
+ }
73
+ /**
74
+ * Register a whole entry. Merges onto an existing name's history; a
75
+ * duplicate version label throws {@link PromptValidationError}.
76
+ */
77
+ register(entry) {
78
+ for (const version of entry.versions) this.add(entry.name, version);
79
+ if (!this.versionMeta.has(entry.name)) this.versionMeta.set(entry.name, []);
80
+ return this;
81
+ }
82
+ /**
83
+ * Add a new version to a name (creating it when absent). A duplicate
84
+ * version label throws {@link PromptValidationError} — never a silent
85
+ * overwrite.
86
+ */
87
+ add(name, version) {
88
+ const mirror = this.versionMeta.get(name) ?? [];
89
+ if (mirror.some((existing) => existing.version === version.version)) throw new PromptValidationError(`Prompt "${name}" already has a version labeled "${version.version}".`, { context: {
90
+ name,
91
+ version: version.version
92
+ } });
93
+ this.manager.register(versionToContract(version), {
94
+ name,
95
+ version: version.version
96
+ });
97
+ this.versionMeta.set(name, [...mirror, version]);
98
+ return this;
99
+ }
100
+ /** Whether a name is registered. */
101
+ has(name) {
102
+ return this.versionMeta.has(name);
103
+ }
104
+ /** Every registered prompt name, in registration order. */
105
+ list() {
106
+ return [...this.versionMeta.keys()];
107
+ }
108
+ /** Versions registered for a name, latest last. Throws on an unknown name. */
109
+ versions(name) {
110
+ const mirror = this.versionMeta.get(name);
111
+ if (!mirror) throw new PromptNotFoundError(name);
112
+ return [...mirror];
113
+ }
114
+ /**
115
+ * Resolve + render. Picks the requested or latest version, validates the
116
+ * version's `required` keys against the merged placeholders, then renders by
117
+ * delegating to the shared `renderPlaceholders` over the contract's text.
118
+ */
119
+ resolve(name, options = {}) {
120
+ const picked = this.pickVersion(name, options.version);
121
+ const placeholders = options.placeholders ?? {};
122
+ this.assertRequired(name, picked, placeholders);
123
+ const text = renderPlaceholders(this.manager.get(name, picked.version).blocks[0]?.text ?? picked.template, placeholders);
124
+ return {
125
+ name,
126
+ version: picked.version,
127
+ text,
128
+ toSystemPrompt: () => new SystemPrompt([new Instruction(text)])
129
+ };
130
+ }
131
+ /**
132
+ * Quality-check a raw prompt body or a registered prompt (by name). Backed by
133
+ * the unified deterministic validate primitives plus the LLM-as-judge pass,
134
+ * but returns the legacy `{ score, notes }` report shape so existing callers
135
+ * keep working.
136
+ *
137
+ * Always runs the static lint; runs the LLM-as-judge pass too when a model is
138
+ * resolvable. Never throws when no judge model is available.
139
+ */
140
+ async validate(textOrName, options = {}) {
141
+ const text = this.resolveValidationText(textOrName, options.version);
142
+ const staticNotes = staticLint(text);
143
+ const model = options.model ?? this.options.judgeModel;
144
+ if (!model) return buildValidationReport(staticNotes);
145
+ return buildValidationReport(staticNotes, await judgePrompt(text, model, buildJudgeAgent));
146
+ }
147
+ /**
148
+ * Synchronize named prompts with Langfuse-prompts. No-op (resolves) when no
149
+ * `langfuse` option was configured. The resolved (rendered) body + the
150
+ * `name@version` label are what is pushed/pulled.
151
+ */
152
+ async sync() {
153
+ if (!this.options.langfuse) return;
154
+ await syncLangfusePrompts(this.options.langfuse, this.list(), this.snapshotEntries(), (entry) => this.register(entry));
155
+ }
156
+ /**
157
+ * Pick the requested (or latest) {@link PromptVersion} for a name from the
158
+ * mirror, throwing {@link PromptNotFoundError} on an unknown name or version.
159
+ */
160
+ pickVersion(name, version) {
161
+ const mirror = this.versionMeta.get(name);
162
+ if (!mirror || mirror.length === 0) throw new PromptNotFoundError(name);
163
+ const picked = version ? mirror.find((candidate) => candidate.version === version) : mirror[mirror.length - 1];
164
+ if (!picked) throw new PromptNotFoundError(name, { context: {
165
+ name,
166
+ version
167
+ } });
168
+ return picked;
169
+ }
170
+ /**
171
+ * Resolve the text `validate()` should grade: a registered name yields its
172
+ * picked version's raw `template`; anything else is treated as the raw body.
173
+ */
174
+ resolveValidationText(textOrName, version) {
175
+ const mirror = this.versionMeta.get(textOrName);
176
+ if (!mirror || mirror.length === 0) return textOrName;
177
+ const picked = version ? mirror.find((candidate) => candidate.version === version) : mirror[mirror.length - 1];
178
+ return picked ? picked.template : textOrName;
179
+ }
180
+ /**
181
+ * Throw {@link PromptValidationError} listing every `required` key absent
182
+ * from the merged placeholders. A no-op when the version declares none.
183
+ */
184
+ assertRequired(name, version, placeholders) {
185
+ if (!version.required || version.required.length === 0) return;
186
+ const missing = version.required.filter((key) => placeholders[key] === void 0 || placeholders[key] === null || placeholders[key] === "");
187
+ if (missing.length > 0) throw new PromptValidationError(`Prompt "${name}" version "${version.version}" is missing required placeholder${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}.`, { context: {
188
+ name,
189
+ version: version.version,
190
+ missing
191
+ } });
192
+ }
193
+ /** Snapshot the catalog as `PromptEntry[]` (for the Langfuse push path). */
194
+ snapshotEntries() {
195
+ return [...this.versionMeta.entries()].map(([name, versions]) => ({
196
+ name,
197
+ versions: [...versions]
198
+ }));
199
+ }
200
+ };
201
+ function promptFactory(first, versionOrTag) {
202
+ if (typeof first === "string") return defaultPromptsManager().get(first, versionOrTag);
203
+ return new PromptRegistry(first);
204
+ }
205
+ /**
206
+ * Create a versioned prompt registry, OR resolve a globally-registered prompt
207
+ * by name from `ai.prompts`.
208
+ *
209
+ * - `prompt(options?)` → a fresh, isolated {@link PromptRegistryContract}.
210
+ * - `prompt(name, versionOrTag?)` → the `SystemPromptContract` registered under
211
+ * `name` in the process-wide `ai.prompts` manager (latest version by default,
212
+ * or a specific version / pinned tag).
213
+ */
214
+ const prompt = promptFactory;
215
+
216
+ //#endregion
217
+ export { prompt };
218
+ //# sourceMappingURL=prompt.mjs.map