promptfoo 0.125.0 → 0.125.1

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 (869) hide show
  1. package/README.md +3 -3
  2. package/dist/src/accounts-BOxNYxVN.js +229 -0
  3. package/dist/src/accounts-BezXLdAW.cjs +276 -0
  4. package/dist/src/accounts-CPISMNlh.js +227 -0
  5. package/dist/src/accounts-vJBPs89d.js +222 -0
  6. package/dist/src/agentWorkspace-Bom7SpF2.js +592 -0
  7. package/dist/src/agentWorkspace-CEomAcws.cjs +619 -0
  8. package/dist/src/agentWorkspace-DPtMLrlI.js +593 -0
  9. package/dist/src/agentWorkspace-DkAeEYLz.js +592 -0
  10. package/dist/src/agentic-utils-121v7mJo.js +197 -0
  11. package/dist/src/agentic-utils-CBWD_rcd.cjs +237 -0
  12. package/dist/src/agentic-utils-D8wyQwPG.js +198 -0
  13. package/dist/src/agentic-utils-EP1QkQCs.js +197 -0
  14. package/dist/src/agents-Br3ah8iA.js +778 -0
  15. package/dist/src/agents-C5wj_UTv.js +777 -0
  16. package/dist/src/agents-C9Efp4mC.js +266 -0
  17. package/dist/src/agents-CQYwaVCO.js +267 -0
  18. package/dist/src/agents-CjCd4Vo8.js +777 -0
  19. package/dist/src/agents-DRWiCHYz.js +266 -0
  20. package/dist/src/agents-F2rhx0iL.cjs +266 -0
  21. package/dist/src/agents-RTYyy69h.cjs +777 -0
  22. package/dist/src/agents-api-CY72O86e.js +711 -0
  23. package/dist/src/agents-api-CsSsC21b.js +710 -0
  24. package/dist/src/agents-api-DN-ibDc8.js +710 -0
  25. package/dist/src/agents-api-cNDsCCv1.cjs +710 -0
  26. package/dist/src/ai.studio-Bj6Dyi6o.js +2 -0
  27. package/dist/src/ai.studio-C-e0LzyW.js +369 -0
  28. package/dist/src/ai.studio-CR8M6Aqf.cjs +391 -0
  29. package/dist/src/ai.studio-YKk7F0tv.js +374 -0
  30. package/dist/src/aimlapi-BGunsuTu.js +30 -0
  31. package/dist/src/aimlapi-BkzcfBsL.js +29 -0
  32. package/dist/src/aimlapi-DXFcEdP8.js +28 -0
  33. package/dist/src/aimlapi-r-8iCcAw.cjs +29 -0
  34. package/dist/src/anthropicMessages-7-YNRgQR.js +114 -0
  35. package/dist/src/anthropicMessages-C8m9Whrd.cjs +114 -0
  36. package/dist/src/anthropicMessages-DS1vXD0f.js +115 -0
  37. package/dist/src/anthropicMessages-DmvGkz-0.js +114 -0
  38. package/dist/src/app/assets/index-CrdXWTXm.js +392 -0
  39. package/dist/src/app/browser-inventory.json +4 -4
  40. package/dist/src/app/index.html +1 -1
  41. package/dist/src/audio-BLgFgyw-.cjs +104 -0
  42. package/dist/src/audio-C2sibT7Q.js +104 -0
  43. package/dist/src/audio-DXEXb03H.js +104 -0
  44. package/dist/src/audio-TkvojpwO.js +105 -0
  45. package/dist/src/authoritativeMarkupInjection-BAT9B-Wj.js +79 -0
  46. package/dist/src/authoritativeMarkupInjection-B_yHETKT.js +78 -0
  47. package/dist/src/authoritativeMarkupInjection-BfjecQ3Q.cjs +78 -0
  48. package/dist/src/authoritativeMarkupInjection-D-hDKrhD.js +78 -0
  49. package/dist/src/aws-B_9unI_-.js +1149 -0
  50. package/dist/src/aws-D0FY3qkc.js +2433 -0
  51. package/dist/src/aws-Dh1-a90n.js +2433 -0
  52. package/dist/src/aws-qskKGczY.cjs +2454 -0
  53. package/dist/src/base-CaWlBkVz.js +462 -0
  54. package/dist/src/base-CcViNwVs.js +255 -0
  55. package/dist/src/base-CsVbPJkU.cjs +467 -0
  56. package/dist/src/base-DNK9py25.js +255 -0
  57. package/dist/src/base-DlH5tjEZ.js +463 -0
  58. package/dist/src/base-DyLOZ_iX.js +256 -0
  59. package/dist/src/base-RRYXfG7l.cjs +305 -0
  60. package/dist/src/base-oXVgvtVn.js +462 -0
  61. package/dist/src/bedrock-BP17ZXbR.cjs +2 -0
  62. package/dist/src/bedrock-CsjM1dOt.js +1300 -0
  63. package/dist/src/bedrock-CzPwj8GO.js +1 -0
  64. package/dist/src/bedrock-eGXZw8oh.js +1 -0
  65. package/dist/src/bedrock-tSWjmXdj.js +2 -0
  66. package/dist/src/bestOfN-BQ93nUKV.js +160 -0
  67. package/dist/src/bestOfN-ByGGwlcb.cjs +161 -0
  68. package/dist/src/bestOfN-CbP7csHr.js +159 -0
  69. package/dist/src/bestOfN-xn6i2Xs2.js +159 -0
  70. package/dist/src/cache-CHq9hPz9.js +2 -0
  71. package/dist/src/cache-D-9eZN3I.js +754 -0
  72. package/dist/src/cache-DSm6t1MZ.js +741 -0
  73. package/dist/src/cache-DeF5zIEN.js +782 -0
  74. package/dist/src/cache-iG87oYan.cjs +856 -0
  75. package/dist/src/cerebras-CTtM4yMH.js +98 -0
  76. package/dist/src/cerebras-CogcJ3ce.cjs +97 -0
  77. package/dist/src/cerebras-DmkRypTh.js +97 -0
  78. package/dist/src/cerebras-GUp0B8JY.js +97 -0
  79. package/dist/src/chat-B4ihd3fw.js +226 -0
  80. package/dist/src/chat-B9cAQ_rS.js +227 -0
  81. package/dist/src/chat-BU7EB4R-.cjs +76 -0
  82. package/dist/src/chat-C8yxJ2-s.cjs +226 -0
  83. package/dist/src/chat-ClTFM3qq.js +934 -0
  84. package/dist/src/chat-Cnq0Is68.js +123 -0
  85. package/dist/src/chat-CwrurR57.cjs +987 -0
  86. package/dist/src/chat-D0lsojPv.js +124 -0
  87. package/dist/src/chat-D7_8yFIx.js +76 -0
  88. package/dist/src/chat-DCoETlLG.js +226 -0
  89. package/dist/src/chat-DHE7xaTR.js +76 -0
  90. package/dist/src/chat-DmhT6rz2.cjs +123 -0
  91. package/dist/src/chat-DvfMe8KI.js +123 -0
  92. package/dist/src/chat-DwP5kVnl.js +935 -0
  93. package/dist/src/chat-MB7U-QE2.js +77 -0
  94. package/dist/src/chat-zCWuBKAj.js +934 -0
  95. package/dist/src/claude-agent-sdk-23bIVI75.js +999 -0
  96. package/dist/src/claude-agent-sdk-BACpnIJi.cjs +1005 -0
  97. package/dist/src/claude-agent-sdk-BlYlmcEr.js +999 -0
  98. package/dist/src/claude-agent-sdk-Cr-jqJZl.js +1000 -0
  99. package/dist/src/client-BktbiPx9.cjs +357 -0
  100. package/dist/src/client-CjztEBmW.js +351 -0
  101. package/dist/src/client-mRs2UvH9.js +351 -0
  102. package/dist/src/client-uCz0ydjC.js +352 -0
  103. package/dist/src/cloud-BtYF555L.js +2 -0
  104. package/dist/src/cloud-CVSUEmAy.js +287 -0
  105. package/dist/src/cloud-D7Ifb-Fl.js +599 -0
  106. package/dist/src/cloud-DB5oK5NX.cjs +666 -0
  107. package/dist/src/cloud-ecu989Em.js +657 -0
  108. package/dist/src/cloud-ramjGURF.js +599 -0
  109. package/dist/src/cloudflare-ai-BfDkIjO8.js +133 -0
  110. package/dist/src/cloudflare-ai-D9HaXz1M.js +134 -0
  111. package/dist/src/cloudflare-ai-HrD5WUK8.js +132 -0
  112. package/dist/src/cloudflare-ai-Qdj8aKP2.cjs +133 -0
  113. package/dist/src/cloudflare-gateway-C81uKETQ.js +276 -0
  114. package/dist/src/cloudflare-gateway-CX5Z9X0k.js +276 -0
  115. package/dist/src/cloudflare-gateway-DW-og8gb.js +277 -0
  116. package/dist/src/cloudflare-gateway-iRyXo9n2.cjs +276 -0
  117. package/dist/src/codex-app-server-BFIrSgdy.js +2155 -0
  118. package/dist/src/codex-app-server-By1eDVD4.js +2 -0
  119. package/dist/src/codex-app-server-DKsF4qmY.js +2156 -0
  120. package/dist/src/codex-app-server-n7n4uZzC.cjs +2162 -0
  121. package/dist/src/codex-app-server-xAoELVxu.js +2155 -0
  122. package/dist/src/codex-sdk-C2ZLxa6r.js +1552 -0
  123. package/dist/src/codex-sdk-CzG02tQt.cjs +1588 -0
  124. package/dist/src/codex-sdk-DNxAOhiV.js +2 -0
  125. package/dist/src/codex-sdk-DT3aQezK.js +1557 -0
  126. package/dist/src/codex-sdk-pw9DpcJP.js +1557 -0
  127. package/dist/src/codex-security-B0bLmXJF.js +406 -0
  128. package/dist/src/codex-security-BhYs-3iY.js +406 -0
  129. package/dist/src/codex-security-DQcOfxYW.js +407 -0
  130. package/dist/src/codex-security-DsCWr6GZ.cjs +411 -0
  131. package/dist/src/cometapi-B16asPLX.cjs +55 -0
  132. package/dist/src/cometapi-MgTbZA_H.js +53 -0
  133. package/dist/src/cometapi-i33vKzPV.js +55 -0
  134. package/dist/src/cometapi-wK2UWK0X.js +56 -0
  135. package/dist/src/compatible-COj8ZCy9.js +24 -0
  136. package/dist/src/compatible-CRSsIUGb.cjs +24 -0
  137. package/dist/src/compatible-Dy1vCcNF.js +25 -0
  138. package/dist/src/compatible-aUItQrpk.js +24 -0
  139. package/dist/src/completion-Bn7COFMk.js +119 -0
  140. package/dist/src/completion-Bub2N48b.js +118 -0
  141. package/dist/src/completion-Cf2G9OlM.cjs +123 -0
  142. package/dist/src/conversationScoring-BiTYJ9MD.js +374 -0
  143. package/dist/src/conversationScoring-CKL47uIu.js +373 -0
  144. package/dist/src/conversationScoring-DCvQKp6k.cjs +398 -0
  145. package/dist/src/conversationScoring-DLNJtDZI.js +373 -0
  146. package/dist/src/crescendo-5iLk9WiJ.cjs +734 -0
  147. package/dist/src/crescendo-B5ylG7kW.js +733 -0
  148. package/dist/src/crescendo-BD7k6TIx.js +730 -0
  149. package/dist/src/crescendo-DqO2Ch0P.js +732 -0
  150. package/dist/src/custom-8rv_aG2K.js +617 -0
  151. package/dist/src/custom-BOtrIHFN.js +619 -0
  152. package/dist/src/custom-BvN8seCs.cjs +620 -0
  153. package/dist/src/custom-Cld9v_Y4.js +618 -0
  154. package/dist/src/dataUrl-BdHUey2l.cjs +3187 -0
  155. package/dist/src/dataUrl-DBMifX6C.js +3133 -0
  156. package/dist/src/dataUrl-DUSr-ZvI.js +2868 -0
  157. package/dist/src/decisions-CLazADTw.js +516 -0
  158. package/dist/src/decisions-D5X93awq.js +515 -0
  159. package/dist/src/decisions-DmaeArEn.js +515 -0
  160. package/dist/src/decisions-DyQJyHJz.cjs +514 -0
  161. package/dist/src/docker-C9NYQFeu.js +94 -0
  162. package/dist/src/docker-CGq3mMol.cjs +94 -0
  163. package/dist/src/docker-DOm7nmpl.js +95 -0
  164. package/dist/src/docker-skFN-Kfo.js +93 -0
  165. package/dist/src/embedding-0UbzkTk9.js +82 -0
  166. package/dist/src/embedding-DTrSDt7k.cjs +86 -0
  167. package/dist/src/embedding-j2ORNl5H.js +81 -0
  168. package/dist/src/envoy-BvS8XTQO.js +60 -0
  169. package/dist/src/envoy-Cn6Hzw0e.js +60 -0
  170. package/dist/src/envoy-DC3KWcUY.cjs +60 -0
  171. package/dist/src/envoy-DetHjo5B.js +61 -0
  172. package/dist/src/eval-Cer9dPe9.js +1920 -0
  173. package/dist/src/eval-CytYmI2Z.js +2 -0
  174. package/dist/src/evalResult-DzOq5wt9.js +1300 -0
  175. package/dist/src/evaluator-BxCmvGtv.js +10578 -0
  176. package/dist/src/evaluator-Ct7YDELm.js +2 -0
  177. package/dist/src/evaluatorHelpers-B_AwIrsl.js +600 -0
  178. package/dist/src/evaluatorHelpers-D1Tpc7gd.js +601 -0
  179. package/dist/src/evaluatorHelpers-DRR3rLq0.cjs +622 -0
  180. package/dist/src/fetch-B5KxZuKu.js +1559 -0
  181. package/dist/src/fetch-BG_Jl7ty.js +1556 -0
  182. package/dist/src/fetch-BKlgUg08.cjs +1853 -0
  183. package/dist/src/fetch-C9Fsja0R.js +2 -0
  184. package/dist/src/fetch-CM7P8KWA.cjs +14 -0
  185. package/dist/src/fetch-D0FkIB3G.js +9 -0
  186. package/dist/src/fetch-RXHsZF-J.js +1280 -0
  187. package/dist/src/fetch-rSECy8jR.js +10 -0
  188. package/dist/src/functionCallbackUtils-BB9tmf6a.cjs +262 -0
  189. package/dist/src/functionCallbackUtils-BXk2iY01.js +246 -0
  190. package/dist/src/functionCallbackUtils-B_cYp7P5.js +245 -0
  191. package/dist/src/functionCallbackUtils-BfXnPo0o.js +245 -0
  192. package/dist/src/gemini-image-BXLMADDz.js +471 -0
  193. package/dist/src/gemini-image-BYUZyEUx.js +472 -0
  194. package/dist/src/gemini-image-DSt1QubZ.cjs +471 -0
  195. package/dist/src/gemini-image-DdNDMiZ_.js +471 -0
  196. package/dist/src/goat-9b-uU_k6.js +514 -0
  197. package/dist/src/goat-BCJuiDd0.js +515 -0
  198. package/dist/src/goat-CmAHbemm.js +512 -0
  199. package/dist/src/goat-DdOTdyoS.cjs +515 -0
  200. package/dist/src/goblin-Bp5C5lyb.js +22 -0
  201. package/dist/src/goblin-Dmr7GItI.js +23 -0
  202. package/dist/src/goblin-DpM8wxlf.cjs +22 -0
  203. package/dist/src/goblin-cJyH6Pq-.js +22 -0
  204. package/dist/src/google-B6eaPAbE.js +142 -0
  205. package/dist/src/google-D-FStdN6.cjs +142 -0
  206. package/dist/src/google-DAC7BsCW.js +142 -0
  207. package/dist/src/google-Id18H0Va.js +143 -0
  208. package/dist/src/graders-BjNQWkaB.js +2 -0
  209. package/dist/src/graders-CqdIp_vl.js +15470 -0
  210. package/dist/src/hydra-6Ouh74DE.js +610 -0
  211. package/dist/src/hydra-BHjhZnLB.cjs +612 -0
  212. package/dist/src/hydra-BL6k2REV.js +2 -0
  213. package/dist/src/hydra-BWUc0o67.js +613 -0
  214. package/dist/src/hydra-CUkEOLKw.js +612 -0
  215. package/dist/src/image-B6hG_xhb.js +481 -0
  216. package/dist/src/image-BFaq7Krd.cjs +209 -0
  217. package/dist/src/image-Bql5C0N9.cjs +504 -0
  218. package/dist/src/image-BtZfI2pT.js +163 -0
  219. package/dist/src/image-CIM4oN7Z.cjs +163 -0
  220. package/dist/src/image-CbAl7Jpu.js +209 -0
  221. package/dist/src/image-CiYm_yFw.js +209 -0
  222. package/dist/src/image-DCMNvBiV.js +163 -0
  223. package/dist/src/image-DL7pIuUZ.js +210 -0
  224. package/dist/src/image-ey0kxF8o.js +164 -0
  225. package/dist/src/image-smgIk3rE.js +482 -0
  226. package/dist/src/index.cjs +27 -27
  227. package/dist/src/index.d.cts +8 -8
  228. package/dist/src/index.js +27 -27
  229. package/dist/src/indirectWebPwn-B_-UpWY5.js +285 -0
  230. package/dist/src/indirectWebPwn-Cz3SLiEq.js +434 -0
  231. package/dist/src/indirectWebPwn-D2s8zGiM.cjs +463 -0
  232. package/dist/src/indirectWebPwn-DXbj2wGu.cjs +285 -0
  233. package/dist/src/indirectWebPwn-D_4H44E6.js +285 -0
  234. package/dist/src/indirectWebPwn-L044SrpV.js +434 -0
  235. package/dist/src/indirectWebPwn-cnmvdavH.js +435 -0
  236. package/dist/src/indirectWebPwn-zUBzsqTt.js +286 -0
  237. package/dist/src/interactions-Bu3oVQ-j.js +850 -0
  238. package/dist/src/interactions-CND010Lh.cjs +850 -0
  239. package/dist/src/interactions-DAx7tqUz.js +851 -0
  240. package/dist/src/interactions-DPkIumeh.js +850 -0
  241. package/dist/src/iterative-BO4JRnpG.js +545 -0
  242. package/dist/src/iterative-CAK-k9rz.js +548 -0
  243. package/dist/src/iterative-CDgHc0xO.cjs +549 -0
  244. package/dist/src/iterative-CXJlHLl9.js +547 -0
  245. package/dist/src/iterativeImage-BEdGKSmh.cjs +419 -0
  246. package/dist/src/iterativeImage-BfL0QZw5.js +417 -0
  247. package/dist/src/iterativeImage-C9KhnibC.js +417 -0
  248. package/dist/src/iterativeImage-btjkOfWG.js +418 -0
  249. package/dist/src/iterativeMeta-B5Bdw6QA.js +437 -0
  250. package/dist/src/iterativeMeta-C3mI4gpT.js +440 -0
  251. package/dist/src/iterativeMeta-Co2BKyqS.cjs +439 -0
  252. package/dist/src/iterativeMeta-DD8ihRWD.js +439 -0
  253. package/dist/src/iterativeTree-AMi4GV2O.js +878 -0
  254. package/dist/src/iterativeTree-C8FJOEje.cjs +879 -0
  255. package/dist/src/iterativeTree-CvrY1f2Z.js +877 -0
  256. package/dist/src/iterativeTree-bPtESmaD.js +876 -0
  257. package/dist/src/knowledgeBase-Cf5871e3.js +163 -0
  258. package/dist/src/knowledgeBase-D2PQhqLH.js +164 -0
  259. package/dist/src/knowledgeBase-DpoMw1IH.cjs +163 -0
  260. package/dist/src/knowledgeBase-npGFl763.js +163 -0
  261. package/dist/src/litellm-BBB5DQdt.cjs +146 -0
  262. package/dist/src/litellm-Bo43ow7r.js +145 -0
  263. package/dist/src/litellm-CaU8CMLS.js +146 -0
  264. package/dist/src/litellm-wY7Unh8o.js +147 -0
  265. package/dist/src/live-5g2w-M-E.js +891 -0
  266. package/dist/src/live-BfaXsDyD.cjs +891 -0
  267. package/dist/src/live-C1xewnGD.js +2 -0
  268. package/dist/src/live-DaF7nYy5.js +892 -0
  269. package/dist/src/live-lp3urLUw.js +891 -0
  270. package/dist/src/luma-ray-B7zvKGVG.js +309 -0
  271. package/dist/src/luma-ray-DCf5fnrz.cjs +309 -0
  272. package/dist/src/luma-ray-DepBcn6z.js +309 -0
  273. package/dist/src/luma-ray-XQC4M1pt.js +310 -0
  274. package/dist/src/main.js +26 -26
  275. package/dist/src/mantleChat-7xm95vSV.js +154 -0
  276. package/dist/src/mantleChat-CXhAs5RD.js +155 -0
  277. package/dist/src/mantleChat-CcE-zjfj.cjs +154 -0
  278. package/dist/src/mantleChat-Cpefl7Zm.js +154 -0
  279. package/dist/src/mcp-B0V0ikdM.js +84 -0
  280. package/dist/src/mcp-CV2k2gwj.js +85 -0
  281. package/dist/src/memoryPoisoning-BC5FQQWZ.js +111 -0
  282. package/dist/src/memoryPoisoning-BDwrtZKX.js +111 -0
  283. package/dist/src/memoryPoisoning-BFemS_FF.js +112 -0
  284. package/dist/src/memoryPoisoning-DRs2rbVV.cjs +111 -0
  285. package/dist/src/messages-Bc5oZoAJ.js +1128 -0
  286. package/dist/src/messages-BkaH8fRW.js +1127 -0
  287. package/dist/src/messages-CoHlziS5.js +1127 -0
  288. package/dist/src/messages-Cv_m6kYs.cjs +1161 -0
  289. package/dist/src/mischievousUser-BcyFxrqJ.js +51 -0
  290. package/dist/src/mischievousUser-BlhOQSd2.js +52 -0
  291. package/dist/src/mischievousUser-BuQiKE8D.js +51 -0
  292. package/dist/src/mischievousUser-ChIOk6cT.cjs +51 -0
  293. package/dist/src/modelslab-BXIWBTgX.js +171 -0
  294. package/dist/src/modelslab-ChVsUiaJ.js +170 -0
  295. package/dist/src/modelslab-DZ6BFlDv.js +170 -0
  296. package/dist/src/modelslab-DhRr-vyo.cjs +170 -0
  297. package/dist/src/nova-reel-BL8DrN4_.js +272 -0
  298. package/dist/src/nova-reel-BiOMUm5q.cjs +272 -0
  299. package/dist/src/nova-reel-CTsya1hV.js +273 -0
  300. package/dist/src/nova-reel-kgBY4Svd.js +272 -0
  301. package/dist/src/nova-sonic-CaSSA3Jq.cjs +374 -0
  302. package/dist/src/nova-sonic-DLpmoGsR.js +375 -0
  303. package/dist/src/nova-sonic-DwWc4SoN.js +374 -0
  304. package/dist/src/nova-sonic-qnReTaXm.js +374 -0
  305. package/dist/src/novita-B5mAt3Ui.js +114 -0
  306. package/dist/src/novita-D57vCjDD.js +116 -0
  307. package/dist/src/novita-ITRtG8IJ.js +115 -0
  308. package/dist/src/novita-Rh3T13YO.cjs +115 -0
  309. package/dist/src/nscale-8V7iZ_pI.js +210 -0
  310. package/dist/src/nscale-BQnMv4pH.cjs +209 -0
  311. package/dist/src/nscale-BWZXHZVF.js +209 -0
  312. package/dist/src/nscale-BqrHiUqU.js +207 -0
  313. package/dist/src/openaiResponses-BMtGTu8R.js +317 -0
  314. package/dist/src/openaiResponses-CvcI_viE.js +318 -0
  315. package/dist/src/openaiResponses-DYPZEMX1.cjs +318 -0
  316. package/dist/src/openaiResponses-DZTg1-kb.js +319 -0
  317. package/dist/src/openclaw-BeKuig4g.js +1338 -0
  318. package/dist/src/openclaw-COkdQ83y.js +1337 -0
  319. package/dist/src/openclaw-CSoX_HQ5.cjs +1344 -0
  320. package/dist/src/openclaw-DJlhPGCb.js +1336 -0
  321. package/dist/src/opencode-sdk-BEJftEs6.cjs +1018 -0
  322. package/dist/src/opencode-sdk-DMvBB3V7.js +1013 -0
  323. package/dist/src/opencode-sdk-Df7hMjLO.js +1012 -0
  324. package/dist/src/opencode-sdk-bQp5Xf3W.js +1012 -0
  325. package/dist/src/openinterpreter-B3GgVZjK.js +431 -0
  326. package/dist/src/openinterpreter-BiGcU-HN.cjs +435 -0
  327. package/dist/src/openinterpreter-Buj2l3Eh.js +432 -0
  328. package/dist/src/openinterpreter-C3_Cg5b_.js +431 -0
  329. package/dist/src/pricing-0Pampf0q.cjs +999 -0
  330. package/dist/src/pricing-B8VdhEhY.js +976 -0
  331. package/dist/src/pricing-CtLA-rKA.js +976 -0
  332. package/dist/src/promptfoo-4OkHtH9P.cjs +341 -0
  333. package/dist/src/promptfoo-Bhpm7sH6.js +286 -0
  334. package/dist/src/promptfoo-BqV8ogVA.js +285 -0
  335. package/dist/src/promptfoo-S1Q9OHk_.js +286 -0
  336. package/dist/src/providers-B5zs1ZRv.js +24437 -0
  337. package/dist/src/providers-Cd6CJh6m.js +2 -0
  338. package/dist/src/providers-CpJlgHET.js +24039 -0
  339. package/dist/src/providers-CzvLvK6G.cjs +24180 -0
  340. package/dist/src/quiverai-1E_IvLHn.js +325 -0
  341. package/dist/src/quiverai-BXH004Vv.js +325 -0
  342. package/dist/src/quiverai-Ccya2z8Y.cjs +325 -0
  343. package/dist/src/quiverai-Cez57oe-.js +326 -0
  344. package/dist/src/registry-3zX_M9Ik.js +131 -0
  345. package/dist/src/registry-AuCrKTvS.js +132 -0
  346. package/dist/src/registry-CxXWKtQG.js +131 -0
  347. package/dist/src/registry-DG3o66JQ.cjs +131 -0
  348. package/dist/src/remoteGeneration-CAtvamG6.js +370 -0
  349. package/dist/src/remoteGeneration-CF225pDl.cjs +482 -0
  350. package/dist/src/remoteGeneration-DtnqocnL.js +370 -0
  351. package/dist/src/remoteGeneration-g3KvW-sP.js +371 -0
  352. package/dist/src/responses-BMbaUXQI.js +1098 -0
  353. package/dist/src/responses-B_TOSof-.js +1099 -0
  354. package/dist/src/responses-v-yANwTA.cjs +1109 -0
  355. package/dist/src/runtimeTransform-BBZv-oUZ.js +156 -0
  356. package/dist/src/runtimeTransform-DT2v5ovW.js +156 -0
  357. package/dist/src/runtimeTransform-GXXEIXdS.cjs +161 -0
  358. package/dist/src/runtimeTransform-JTwBQc-P.js +157 -0
  359. package/dist/src/sagemaker-B8D0L4rj.cjs +716 -0
  360. package/dist/src/sagemaker-CR2_AGdB.js +713 -0
  361. package/dist/src/sagemaker-Cd9qSQUV.js +714 -0
  362. package/dist/src/sagemaker-mKlltN4p.js +713 -0
  363. package/dist/src/scanner-PG_8lh8r.js +1971 -0
  364. package/dist/src/server/index.js +55 -55
  365. package/dist/src/server-Bmh7sd9F.js +155 -0
  366. package/dist/src/server-C7b8z6aC.js +63 -0
  367. package/dist/src/server-CAcovgtL.js +2 -0
  368. package/dist/src/server-CuuMfKlh.cjs +74 -0
  369. package/dist/src/server-DMPCj9jy.js +189 -0
  370. package/dist/src/session-BksXvRH_.cjs +69 -0
  371. package/dist/src/session-DOxUjqGQ.js +63 -0
  372. package/dist/src/session-Dujsc-b9.js +62 -0
  373. package/dist/src/session-VjtIxREd.js +62 -0
  374. package/dist/src/shared-Bkyz_7e5.cjs +2185 -0
  375. package/dist/src/shared-DDJg8ycC.js +1929 -0
  376. package/dist/src/shared-Dh3yfRBd.js +1927 -0
  377. package/dist/src/shared-tfPT8Tna.js +1928 -0
  378. package/dist/src/simulatedUser-6JdkyL3k.cjs +252 -0
  379. package/dist/src/simulatedUser-CFr2mr3M.js +248 -0
  380. package/dist/src/simulatedUser-DjwwUqx-.js +247 -0
  381. package/dist/src/slack-C_gIYiUs.js +144 -0
  382. package/dist/src/slack-DhNbz9CM.cjs +144 -0
  383. package/dist/src/slack-Dm2iI1zu.js +145 -0
  384. package/dist/src/strategies-BIY-bNul.js +2248 -0
  385. package/dist/src/strategies-C1KQQj9G.cjs +2420 -0
  386. package/dist/src/strategies-DM_3mReG.js +2385 -0
  387. package/dist/src/telemetry-BhMTibZO.js +2 -0
  388. package/dist/src/telemetry-C04d25BM.cjs +216 -0
  389. package/dist/src/telemetry-CIqy4fSC.js +201 -0
  390. package/dist/src/telemetry-CXozp_6C.js +205 -0
  391. package/dist/src/telemetry-g7PkBxmY.js +205 -0
  392. package/dist/src/togetherai-BvCim68-.js +50 -0
  393. package/dist/src/togetherai-CWyDCA9m.cjs +49 -0
  394. package/dist/src/togetherai-CeSE31vK.js +49 -0
  395. package/dist/src/togetherai-_2W0URf8.js +48 -0
  396. package/dist/src/traceContext-Brw3Oe41.js +1016 -0
  397. package/dist/src/traceContext-DpAYv27G.js +1015 -0
  398. package/dist/src/traceContext-KSqhzZI2.cjs +1032 -0
  399. package/dist/src/transcription-BySopazW.js +175 -0
  400. package/dist/src/transcription-DO4UPkRI.cjs +178 -0
  401. package/dist/src/transcription-RJGBa-pC.js +176 -0
  402. package/dist/src/transcription-fZenF3G5.js +175 -0
  403. package/dist/src/transform-BzhRc5z2.js +125 -0
  404. package/dist/src/transform-CPQu05u6.cjs +154 -0
  405. package/dist/src/transform-DAED8imp.js +126 -0
  406. package/dist/src/transform-DIOIQDmM.js +125 -0
  407. package/dist/src/typesafe-ByE0Kxfg.js +253 -0
  408. package/dist/src/typesafe-CFqGFY34.js +253 -0
  409. package/dist/src/typesafe-DCWIw-CP.cjs +253 -0
  410. package/dist/src/typesafe-DyHFV5Qk.js +254 -0
  411. package/dist/src/util-BHkj9joz.js +2049 -0
  412. package/dist/src/util-CICwIpmu.cjs +934 -0
  413. package/dist/src/util-CePiY2xZ.js +286 -0
  414. package/dist/src/util-CgT3uf4p.js +743 -0
  415. package/dist/src/util-Cj9drvOY.js +1770 -0
  416. package/dist/src/util-ClJRjlQA.cjs +357 -0
  417. package/dist/src/util-Cxf8VF2M.js +395 -0
  418. package/dist/src/util-D7RdV7rS.js +395 -0
  419. package/dist/src/util-DMNFhk47.js +351 -0
  420. package/dist/src/util-DNzh3M0z.js +396 -0
  421. package/dist/src/util-Df7rfMGb.cjs +2305 -0
  422. package/dist/src/util-Kf0KnG_6.js +2051 -0
  423. package/dist/src/util-LEbeiYw_.js +743 -0
  424. package/dist/src/util-WH8CgVs4.js +352 -0
  425. package/dist/src/util-cx6Xw8Lw.cjs +478 -0
  426. package/dist/src/util-qzBqirBH.js +2050 -0
  427. package/dist/src/vertex-CBAMfRz3.js +854 -0
  428. package/dist/src/vertex-CMP2IpN9.js +2 -0
  429. package/dist/src/vertex-CZ5YOotT.js +848 -0
  430. package/dist/src/vertex-DNsh1F1M.cjs +871 -0
  431. package/dist/src/vertexLive-BTXYj3-F.js +55 -0
  432. package/dist/src/vertexLive-Ba_LAqEF.cjs +55 -0
  433. package/dist/src/vertexLive-DM4sFaaj.js +56 -0
  434. package/dist/src/vertexLive-JqZOw7HC.js +55 -0
  435. package/dist/src/video-BY7Q2Gii.cjs +706 -0
  436. package/dist/src/video-CYElP-CK.js +703 -0
  437. package/dist/src/video-C_AdEDH0.js +702 -0
  438. package/dist/src/video-DGvjQ_4j.js +702 -0
  439. package/package.json +1 -1
  440. package/dist/src/accounts-Dpb43yde.cjs +0 -276
  441. package/dist/src/accounts-GKrO1olH.js +0 -229
  442. package/dist/src/accounts-e4FGOsji.js +0 -227
  443. package/dist/src/accounts-sUiEJfkB.js +0 -222
  444. package/dist/src/agentWorkspace-B8A_wuMR.cjs +0 -619
  445. package/dist/src/agentWorkspace-DSPIscXR.js +0 -593
  446. package/dist/src/agentWorkspace-DxUqd-XK.js +0 -592
  447. package/dist/src/agentWorkspace-n0uOJXhD.js +0 -592
  448. package/dist/src/agentic-utils-9bCj4twQ.js +0 -197
  449. package/dist/src/agentic-utils-CyCLuLoj.js +0 -197
  450. package/dist/src/agentic-utils-D23qtOlx.cjs +0 -237
  451. package/dist/src/agentic-utils-DuBMMNCw.js +0 -198
  452. package/dist/src/agents-6hDRNoYD.js +0 -777
  453. package/dist/src/agents-B8w2o7Sc.cjs +0 -777
  454. package/dist/src/agents-Ck0NXl7v.js +0 -777
  455. package/dist/src/agents-CwT3B1qB.js +0 -778
  456. package/dist/src/agents-DOLjfOEq.js +0 -266
  457. package/dist/src/agents-OcF9hq--.js +0 -267
  458. package/dist/src/agents-api-CnZZt8bn.cjs +0 -710
  459. package/dist/src/agents-api-D04u3bmL.js +0 -711
  460. package/dist/src/agents-api-DWw0_Vio.js +0 -710
  461. package/dist/src/agents-api-IWHEwp8i.js +0 -710
  462. package/dist/src/agents-mHt2Mh9O.cjs +0 -266
  463. package/dist/src/agents-sICccZCA.js +0 -266
  464. package/dist/src/ai.studio-Ci4rypDT.js +0 -2
  465. package/dist/src/ai.studio-KkQ6KaHa.js +0 -369
  466. package/dist/src/ai.studio-gSXK2cGI.js +0 -374
  467. package/dist/src/ai.studio-nQF_B4DH.cjs +0 -391
  468. package/dist/src/aimlapi-BeSk5BDV.js +0 -30
  469. package/dist/src/aimlapi-CzNUhdKu.cjs +0 -29
  470. package/dist/src/aimlapi-DCkazDPI.js +0 -29
  471. package/dist/src/aimlapi-WeH5B6K1.js +0 -28
  472. package/dist/src/anthropicMessages-AcNWTpYO.js +0 -115
  473. package/dist/src/anthropicMessages-BUtvzbpL.js +0 -114
  474. package/dist/src/anthropicMessages-DTWhZDCd.js +0 -114
  475. package/dist/src/anthropicMessages-lGVnSgyx.cjs +0 -114
  476. package/dist/src/app/assets/index-CyEI5aDN.js +0 -392
  477. package/dist/src/audio-BE_Duiu1.js +0 -104
  478. package/dist/src/audio-CiUd00k2.cjs +0 -104
  479. package/dist/src/audio-Dop6omna.js +0 -105
  480. package/dist/src/audio-EZNTInr_.js +0 -104
  481. package/dist/src/authoritativeMarkupInjection-BUqH6hNk.js +0 -78
  482. package/dist/src/authoritativeMarkupInjection-BmbJdJO0.cjs +0 -78
  483. package/dist/src/authoritativeMarkupInjection-Cpz12Y3w.js +0 -78
  484. package/dist/src/authoritativeMarkupInjection-W4XfcH91.js +0 -79
  485. package/dist/src/aws-B2Jqbnet.js +0 -2433
  486. package/dist/src/aws-DHtuUIzQ.js +0 -1149
  487. package/dist/src/aws-DLqXP6wY.js +0 -2433
  488. package/dist/src/aws-DfduhmwL.cjs +0 -2454
  489. package/dist/src/base-B9L2Xvpc.js +0 -255
  490. package/dist/src/base-BTZnIsuH.cjs +0 -305
  491. package/dist/src/base-BhaWNQPJ.js +0 -462
  492. package/dist/src/base-Br-G_Xou.js +0 -256
  493. package/dist/src/base-Bzo8hiUS.cjs +0 -467
  494. package/dist/src/base-C82fd2jq.js +0 -463
  495. package/dist/src/base-CRdQwC1W.js +0 -462
  496. package/dist/src/base-CjGwZNOQ.js +0 -255
  497. package/dist/src/bedrock-BdMru_ro.js +0 -1300
  498. package/dist/src/bedrock-CBUmfLX1.cjs +0 -2
  499. package/dist/src/bedrock-DBDxBaF9.js +0 -2
  500. package/dist/src/bedrock-DDrECM21.js +0 -1
  501. package/dist/src/bedrock-DVwkgvRS.js +0 -1
  502. package/dist/src/bestOfN-AKF5beq4.js +0 -159
  503. package/dist/src/bestOfN-C1UIVGJV.js +0 -160
  504. package/dist/src/bestOfN-DlkETbXy.cjs +0 -161
  505. package/dist/src/bestOfN-XIfEgU-g.js +0 -159
  506. package/dist/src/cache-BZaVoKaA.js +0 -2
  507. package/dist/src/cache-CEYhFUsH.js +0 -741
  508. package/dist/src/cache-Cbw1zH6q.js +0 -782
  509. package/dist/src/cache-CdaZNb75.js +0 -754
  510. package/dist/src/cache-DpuIzPxh.cjs +0 -856
  511. package/dist/src/cerebras-Bpn6FPkJ.js +0 -97
  512. package/dist/src/cerebras-CqJ0BRCJ.cjs +0 -97
  513. package/dist/src/cerebras-D4ILa_TY.js +0 -97
  514. package/dist/src/cerebras-DR8uc7ee.js +0 -98
  515. package/dist/src/chat-B7PZfaYp.cjs +0 -987
  516. package/dist/src/chat-BVuSjdEb.js +0 -227
  517. package/dist/src/chat-BsaZRjXN.js +0 -76
  518. package/dist/src/chat-C5liqe3Y.js +0 -226
  519. package/dist/src/chat-C9hyHf5B.js +0 -124
  520. package/dist/src/chat-CFLalAck.js +0 -226
  521. package/dist/src/chat-CN8JGrHu.js +0 -76
  522. package/dist/src/chat-CaHBBpCb.js +0 -123
  523. package/dist/src/chat-CcbLSghx.js +0 -123
  524. package/dist/src/chat-CoSN6sr2.js +0 -934
  525. package/dist/src/chat-CsJRFX8a.cjs +0 -226
  526. package/dist/src/chat-DFoZLvO_.js +0 -934
  527. package/dist/src/chat-DiLQvL7r.js +0 -77
  528. package/dist/src/chat-F6qVSDk3.cjs +0 -123
  529. package/dist/src/chat-Oq4FaJgI.cjs +0 -76
  530. package/dist/src/chat-knMfQUKz.js +0 -935
  531. package/dist/src/claude-agent-sdk-CJkOLpnI.js +0 -999
  532. package/dist/src/claude-agent-sdk-Ckn76PRD.js +0 -999
  533. package/dist/src/claude-agent-sdk-DX0gTr11.cjs +0 -1005
  534. package/dist/src/claude-agent-sdk-LMeikxoR.js +0 -1000
  535. package/dist/src/client-BFf1r6Z8.js +0 -352
  536. package/dist/src/client-CdXyDdDi.js +0 -351
  537. package/dist/src/client-DV8XMu7i.js +0 -351
  538. package/dist/src/client-iEXtOBKW.cjs +0 -357
  539. package/dist/src/cloud-B02qcpjf.js +0 -2
  540. package/dist/src/cloud-BlHP-g1v.cjs +0 -666
  541. package/dist/src/cloud-C9BI4isF.js +0 -287
  542. package/dist/src/cloud-CTTLNdvj.js +0 -657
  543. package/dist/src/cloud-D5X5yQ_d.js +0 -599
  544. package/dist/src/cloud-QxPkpsHA.js +0 -599
  545. package/dist/src/cloudflare-ai-DRTRT1fc.js +0 -132
  546. package/dist/src/cloudflare-ai-DgaXapAV.cjs +0 -133
  547. package/dist/src/cloudflare-ai-DkuJXijS.js +0 -134
  548. package/dist/src/cloudflare-ai-wy9QCHku.js +0 -133
  549. package/dist/src/cloudflare-gateway-9cAN8g29.cjs +0 -276
  550. package/dist/src/cloudflare-gateway-BVFMD292.js +0 -277
  551. package/dist/src/cloudflare-gateway-BuUI4p6I.js +0 -276
  552. package/dist/src/cloudflare-gateway-TlYHizbW.js +0 -276
  553. package/dist/src/codex-app-server-BPz_feug.cjs +0 -2162
  554. package/dist/src/codex-app-server-C9noXM9C.js +0 -2155
  555. package/dist/src/codex-app-server-CEmD-Y5U.js +0 -2
  556. package/dist/src/codex-app-server-DZolc18r.js +0 -2156
  557. package/dist/src/codex-app-server-Dd0A37nO.js +0 -2155
  558. package/dist/src/codex-sdk-BbxjBvBk.cjs +0 -1588
  559. package/dist/src/codex-sdk-BpXeIs-_.js +0 -1557
  560. package/dist/src/codex-sdk-BtQp5X0f.js +0 -1552
  561. package/dist/src/codex-sdk-CH0v9Bk1.js +0 -2
  562. package/dist/src/codex-sdk-CgrN7JB8.js +0 -1557
  563. package/dist/src/codex-security-B5fENNUr.js +0 -406
  564. package/dist/src/codex-security-C6uuJx-y.cjs +0 -411
  565. package/dist/src/codex-security-CifWtZR_.js +0 -407
  566. package/dist/src/codex-security-Kg2bOEKy.js +0 -406
  567. package/dist/src/cometapi-BFpIDLIx.js +0 -55
  568. package/dist/src/cometapi-C6O2PIrN.js +0 -56
  569. package/dist/src/cometapi-D5Yupc6F.js +0 -53
  570. package/dist/src/cometapi-DzgIwJzJ.cjs +0 -55
  571. package/dist/src/compatible-0jhmVfOp.js +0 -25
  572. package/dist/src/compatible-DdtwWdJi.cjs +0 -24
  573. package/dist/src/compatible-Di4nR3sU.js +0 -24
  574. package/dist/src/compatible-iJKLWdnf.js +0 -24
  575. package/dist/src/completion-B0_hVUDG.js +0 -119
  576. package/dist/src/completion-BdI6v0-Q.cjs +0 -123
  577. package/dist/src/completion-CWcJscwv.js +0 -118
  578. package/dist/src/conversationScoring-99EOPJRa.js +0 -373
  579. package/dist/src/conversationScoring-BIq4J0Cq.js +0 -374
  580. package/dist/src/conversationScoring-DARyeATr.cjs +0 -398
  581. package/dist/src/conversationScoring-DS48t4Hb.js +0 -373
  582. package/dist/src/crescendo-CebvXIu4.js +0 -730
  583. package/dist/src/crescendo-CxrLS0oo.js +0 -732
  584. package/dist/src/crescendo-DZQXBSkj.js +0 -733
  585. package/dist/src/crescendo-wjEx68uD.cjs +0 -734
  586. package/dist/src/custom-BiQ-aUNw.cjs +0 -620
  587. package/dist/src/custom-ByyB5Z93.js +0 -619
  588. package/dist/src/custom-C5jOevNb.js +0 -617
  589. package/dist/src/custom-CCrsCz8o.js +0 -618
  590. package/dist/src/dataUrl-C9J7wz9H.js +0 -3133
  591. package/dist/src/dataUrl-CGsBT7UZ.cjs +0 -3187
  592. package/dist/src/dataUrl-CzKvvWNO.js +0 -2868
  593. package/dist/src/decisions-BTusXCUx.cjs +0 -514
  594. package/dist/src/decisions-BYtL9edD.js +0 -515
  595. package/dist/src/decisions-jYix_gCF.js +0 -515
  596. package/dist/src/decisions-nxxfHRAN.js +0 -516
  597. package/dist/src/docker-DDIv4zkg.js +0 -93
  598. package/dist/src/docker-DVLp_5OG.js +0 -94
  599. package/dist/src/docker-INm9w0SY.cjs +0 -94
  600. package/dist/src/docker-sGuoCul_.js +0 -95
  601. package/dist/src/embedding-CAhqLLrR.js +0 -82
  602. package/dist/src/embedding-D94GAsti.cjs +0 -86
  603. package/dist/src/embedding-zb4MAzQy.js +0 -81
  604. package/dist/src/envoy-BMPszwEa.cjs +0 -60
  605. package/dist/src/envoy-Bp-s39_8.js +0 -60
  606. package/dist/src/envoy-BswDt-Ou.js +0 -61
  607. package/dist/src/envoy-rVbYcV80.js +0 -60
  608. package/dist/src/eval-B1-XfrC7.js +0 -2
  609. package/dist/src/eval-pC4qCvLw.js +0 -1920
  610. package/dist/src/evalResult-CzjCb5bd.js +0 -1300
  611. package/dist/src/evaluator-CNq2K7J_.js +0 -10578
  612. package/dist/src/evaluator-LtfxdxEu.js +0 -2
  613. package/dist/src/evaluatorHelpers-C5J0NYpQ.js +0 -601
  614. package/dist/src/evaluatorHelpers-DcdCglCs.cjs +0 -622
  615. package/dist/src/evaluatorHelpers-Rvb88W6B.js +0 -600
  616. package/dist/src/fetch-5HtnNhHg.js +0 -1556
  617. package/dist/src/fetch-BCwjoIFd.js +0 -1559
  618. package/dist/src/fetch-BhfUnKen.js +0 -1280
  619. package/dist/src/fetch-C08w4vVl.js +0 -9
  620. package/dist/src/fetch-DBxy8Tlb.cjs +0 -14
  621. package/dist/src/fetch-DYte6oQX.cjs +0 -1853
  622. package/dist/src/fetch-ElpfcAVG.js +0 -10
  623. package/dist/src/fetch-lM1OIaSt.js +0 -2
  624. package/dist/src/functionCallbackUtils-BCAdWfHO.js +0 -246
  625. package/dist/src/functionCallbackUtils-BYq9qOhG.js +0 -245
  626. package/dist/src/functionCallbackUtils-ByWkmVud.cjs +0 -262
  627. package/dist/src/functionCallbackUtils-D_C_JaFd.js +0 -245
  628. package/dist/src/gemini-image-CAlwaJhZ.js +0 -471
  629. package/dist/src/gemini-image-DJoVoOnZ.cjs +0 -471
  630. package/dist/src/gemini-image-Waio-9Xx.js +0 -472
  631. package/dist/src/gemini-image-vbY6Ftbf.js +0 -471
  632. package/dist/src/goat-BWbtyY9c.js +0 -512
  633. package/dist/src/goat-CXzzeCOQ.cjs +0 -515
  634. package/dist/src/goat-CfgvzSgZ.js +0 -514
  635. package/dist/src/goat-DLeoIHBp.js +0 -515
  636. package/dist/src/goblin-CmfCfwqk.cjs +0 -22
  637. package/dist/src/goblin-CtcaORRH.js +0 -22
  638. package/dist/src/goblin-DF6DDhM-.js +0 -22
  639. package/dist/src/goblin-Nai0xxBV.js +0 -23
  640. package/dist/src/google-ClpkLtKL.cjs +0 -142
  641. package/dist/src/google-CrFgKu9k.js +0 -143
  642. package/dist/src/google-Dj_EIBqS.js +0 -142
  643. package/dist/src/google-e4-vARv6.js +0 -142
  644. package/dist/src/graders-BN1IIa71.js +0 -15470
  645. package/dist/src/graders-C5sCfSP5.js +0 -2
  646. package/dist/src/hydra-B7RfXVBK.js +0 -2
  647. package/dist/src/hydra-C1cFN-Jg.js +0 -613
  648. package/dist/src/hydra-CK6Uc1ia.js +0 -612
  649. package/dist/src/hydra-Dg65rAP_.js +0 -610
  650. package/dist/src/hydra-Fqx8l_Xu.cjs +0 -612
  651. package/dist/src/image-BdlUDAtp.js +0 -163
  652. package/dist/src/image-C-KwEhwt.cjs +0 -163
  653. package/dist/src/image-C76fp6NK.cjs +0 -209
  654. package/dist/src/image-D75ehv3D.js +0 -482
  655. package/dist/src/image-DKtc5v5W.js +0 -209
  656. package/dist/src/image-DT_xOkJY.js +0 -163
  657. package/dist/src/image-DVpdllEE.js +0 -209
  658. package/dist/src/image-DXZ8AzMf.js +0 -481
  659. package/dist/src/image-DZl_1mvy.js +0 -164
  660. package/dist/src/image-DcTD7Ak0.cjs +0 -504
  661. package/dist/src/image-ndxEvBKB.js +0 -210
  662. package/dist/src/indirectWebPwn-70WA5x_q.js +0 -435
  663. package/dist/src/indirectWebPwn-BRVyd3qV.cjs +0 -463
  664. package/dist/src/indirectWebPwn-BsJVsu0q.js +0 -285
  665. package/dist/src/indirectWebPwn-Cw6yJu0i.js +0 -285
  666. package/dist/src/indirectWebPwn-D-PhJzo4.js +0 -286
  667. package/dist/src/indirectWebPwn-DRPHt2I8.js +0 -434
  668. package/dist/src/indirectWebPwn-DXtfFhd9.cjs +0 -285
  669. package/dist/src/indirectWebPwn-DvpNouzc.js +0 -434
  670. package/dist/src/interactions-5ixfW7Cl.js +0 -850
  671. package/dist/src/interactions-BOUzfmg1.cjs +0 -850
  672. package/dist/src/interactions-CSSXcGNc.js +0 -851
  673. package/dist/src/interactions-WB_sgkN0.js +0 -850
  674. package/dist/src/iterative-BShRNqjC.cjs +0 -549
  675. package/dist/src/iterative-BcW_ELtB.js +0 -548
  676. package/dist/src/iterative-BpHbHz8B.js +0 -547
  677. package/dist/src/iterative-YcchP12d.js +0 -545
  678. package/dist/src/iterativeImage-BMFE5Hl7.cjs +0 -419
  679. package/dist/src/iterativeImage-CkSaYLMY.js +0 -417
  680. package/dist/src/iterativeImage-DAEUlQX_.js +0 -418
  681. package/dist/src/iterativeImage-DeUSkEnj.js +0 -417
  682. package/dist/src/iterativeMeta-DbdaKdEO.cjs +0 -439
  683. package/dist/src/iterativeMeta-DcF9JWEK.js +0 -437
  684. package/dist/src/iterativeMeta-DkfPqWIC.js +0 -439
  685. package/dist/src/iterativeMeta-DkrpnVSs.js +0 -440
  686. package/dist/src/iterativeTree-CEMY1FhE.cjs +0 -879
  687. package/dist/src/iterativeTree-Cv5W4tX9.js +0 -877
  688. package/dist/src/iterativeTree-DGvomd3M.js +0 -876
  689. package/dist/src/iterativeTree-KbtC2Mkz.js +0 -878
  690. package/dist/src/knowledgeBase-AYRXn4wO.js +0 -163
  691. package/dist/src/knowledgeBase-BNqQfx01.js +0 -163
  692. package/dist/src/knowledgeBase-C0IaCCVs.js +0 -164
  693. package/dist/src/knowledgeBase-C2uj6wK4.cjs +0 -163
  694. package/dist/src/litellm-CN1ScAwZ.js +0 -147
  695. package/dist/src/litellm-CTjwiKSa.js +0 -146
  696. package/dist/src/litellm-Cd4Nj5ue.js +0 -145
  697. package/dist/src/litellm-DMqLpEBg.cjs +0 -146
  698. package/dist/src/live-Bt50-InO.cjs +0 -891
  699. package/dist/src/live-Bu2ujadG.js +0 -2
  700. package/dist/src/live-C3M52i3p.js +0 -891
  701. package/dist/src/live-CRfHMO3B.js +0 -892
  702. package/dist/src/live-iCIpO14m.js +0 -891
  703. package/dist/src/luma-ray-B8eHC4c8.cjs +0 -309
  704. package/dist/src/luma-ray-BIvkPw0s.js +0 -309
  705. package/dist/src/luma-ray-ChsiBxMA.js +0 -309
  706. package/dist/src/luma-ray-DAvKrInz.js +0 -310
  707. package/dist/src/mantleChat-5YeEXAZI.js +0 -154
  708. package/dist/src/mantleChat-D--mW3hl.js +0 -154
  709. package/dist/src/mantleChat-DHP3siNg.cjs +0 -154
  710. package/dist/src/mantleChat-wBfAX46o.js +0 -155
  711. package/dist/src/mcp-49jlEcTQ.js +0 -85
  712. package/dist/src/mcp-__PIz81I.js +0 -84
  713. package/dist/src/memoryPoisoning-Chxge74M.js +0 -111
  714. package/dist/src/memoryPoisoning-QH6NCUVE.js +0 -112
  715. package/dist/src/memoryPoisoning-tCxZt8Nz.js +0 -111
  716. package/dist/src/memoryPoisoning-ymrRItRR.cjs +0 -111
  717. package/dist/src/messages-BE_eZ7NA.js +0 -1127
  718. package/dist/src/messages-Bo638ShI.js +0 -1127
  719. package/dist/src/messages-BzR0-NQ1.js +0 -1128
  720. package/dist/src/messages-Cbg5Pfd0.cjs +0 -1161
  721. package/dist/src/mischievousUser-BtED2Z5Z.cjs +0 -51
  722. package/dist/src/mischievousUser-KqSOjrDJ.js +0 -51
  723. package/dist/src/mischievousUser-YMD41YNZ.js +0 -51
  724. package/dist/src/mischievousUser-zBxlNdCu.js +0 -52
  725. package/dist/src/modelslab-B8gZxtfE.js +0 -171
  726. package/dist/src/modelslab-C7bmVpTB.js +0 -170
  727. package/dist/src/modelslab-CCeQCTZg.js +0 -170
  728. package/dist/src/modelslab-CvBJGv7y.cjs +0 -170
  729. package/dist/src/nova-reel-BOEWsEKA.cjs +0 -272
  730. package/dist/src/nova-reel-BtyBXq5M.js +0 -273
  731. package/dist/src/nova-reel-C1eF3-EE.js +0 -272
  732. package/dist/src/nova-reel-YhgrxEKT.js +0 -272
  733. package/dist/src/nova-sonic-BaERP20w.js +0 -374
  734. package/dist/src/nova-sonic-CxgM3O-P.cjs +0 -374
  735. package/dist/src/nova-sonic-DJS22fC3.js +0 -375
  736. package/dist/src/nova-sonic-DwvwHyRX.js +0 -374
  737. package/dist/src/novita-D1l2tG0O.js +0 -116
  738. package/dist/src/novita-D84VM3v0.cjs +0 -115
  739. package/dist/src/novita-DGInvwfR.js +0 -115
  740. package/dist/src/novita-vXHkXhTg.js +0 -114
  741. package/dist/src/nscale-CU0Ldr00.js +0 -209
  742. package/dist/src/nscale-ClfKlQeM.cjs +0 -209
  743. package/dist/src/nscale-DxaVnF0x.js +0 -210
  744. package/dist/src/nscale-_poVxIrO.js +0 -207
  745. package/dist/src/openaiResponses-CJGsneNj.js +0 -317
  746. package/dist/src/openaiResponses-CKSl5Sdg.js +0 -319
  747. package/dist/src/openaiResponses-DC8rzFUc.js +0 -318
  748. package/dist/src/openaiResponses-rMHIA3dV.cjs +0 -318
  749. package/dist/src/openclaw-CCbvsNFW.cjs +0 -1344
  750. package/dist/src/openclaw-CZw1lCDZ.js +0 -1336
  751. package/dist/src/openclaw-ChFLgC-a.js +0 -1338
  752. package/dist/src/openclaw-DrPMoRrH.js +0 -1337
  753. package/dist/src/opencode-sdk-2EfIDhFp.cjs +0 -1018
  754. package/dist/src/opencode-sdk-CHw3F845.js +0 -1013
  755. package/dist/src/opencode-sdk-D0EGGxvy.js +0 -1012
  756. package/dist/src/opencode-sdk-jSS7NI2Q.js +0 -1012
  757. package/dist/src/openinterpreter-CY622xHC.js +0 -431
  758. package/dist/src/openinterpreter-DATyhuhP.js +0 -432
  759. package/dist/src/openinterpreter-DDUMyIf1.js +0 -431
  760. package/dist/src/openinterpreter-s5Tz6Lid.cjs +0 -435
  761. package/dist/src/pricing-C498twd2.js +0 -976
  762. package/dist/src/pricing-DBd_bMIh.cjs +0 -999
  763. package/dist/src/pricing-ISrMCskv.js +0 -976
  764. package/dist/src/promptfoo-6p0WG2ih.js +0 -286
  765. package/dist/src/promptfoo-BQRfgNs_.js +0 -285
  766. package/dist/src/promptfoo-Bqo88z20.cjs +0 -341
  767. package/dist/src/promptfoo-Cq5AVI3I.js +0 -286
  768. package/dist/src/providers-ATbeMX5E.cjs +0 -24180
  769. package/dist/src/providers-B7F1FiNI.js +0 -2
  770. package/dist/src/providers-DazIw8mI.js +0 -24039
  771. package/dist/src/providers-QvGlNAD0.js +0 -24437
  772. package/dist/src/quiverai-BPlNcLkV.cjs +0 -325
  773. package/dist/src/quiverai-By99-YmJ.js +0 -325
  774. package/dist/src/quiverai-CmmByDqo.js +0 -325
  775. package/dist/src/quiverai-HZkoJJqw.js +0 -326
  776. package/dist/src/registry-BLTnTfjT.cjs +0 -131
  777. package/dist/src/registry-BMC-COHT.js +0 -132
  778. package/dist/src/registry-C8UZtmBp.js +0 -131
  779. package/dist/src/registry-CfwEUYXG.js +0 -131
  780. package/dist/src/remoteGeneration-Bgg6kC5V.js +0 -370
  781. package/dist/src/remoteGeneration-CKJFE960.cjs +0 -482
  782. package/dist/src/remoteGeneration-DaxwJDKv.js +0 -370
  783. package/dist/src/remoteGeneration-vHMGVKr1.js +0 -371
  784. package/dist/src/responses-BvnyIHrq.js +0 -1099
  785. package/dist/src/responses-CERAgvf-.js +0 -1098
  786. package/dist/src/responses-CwgjeuOg.cjs +0 -1109
  787. package/dist/src/runtimeTransform-3RF9Avyg.cjs +0 -161
  788. package/dist/src/runtimeTransform-C51Z5j4H.js +0 -156
  789. package/dist/src/runtimeTransform-CKE_Iyv8.js +0 -157
  790. package/dist/src/runtimeTransform-Cs11xJpj.js +0 -156
  791. package/dist/src/sagemaker-BJ4dOCxE.js +0 -713
  792. package/dist/src/sagemaker-Bt3JUAWq.js +0 -714
  793. package/dist/src/sagemaker-QVKyLgLF.cjs +0 -716
  794. package/dist/src/sagemaker-l3IB8iTs.js +0 -713
  795. package/dist/src/scanner-DGjIiTZ1.js +0 -1971
  796. package/dist/src/server-BNaLZH6u.js +0 -63
  797. package/dist/src/server-CBMuQul3.js +0 -189
  798. package/dist/src/server-CMKKIzKv.cjs +0 -74
  799. package/dist/src/server-CN2IS9Cs.js +0 -155
  800. package/dist/src/server-ua4cqbjC.js +0 -2
  801. package/dist/src/session-CQIjq_HZ.cjs +0 -69
  802. package/dist/src/session-FTlg8sEu.js +0 -62
  803. package/dist/src/session-GBQXtPWp.js +0 -63
  804. package/dist/src/session-_0-rTdwY.js +0 -62
  805. package/dist/src/shared-BtuO-OAM.js +0 -1927
  806. package/dist/src/shared-Ci78wTZX.js +0 -1928
  807. package/dist/src/shared-Dd3rimdM.js +0 -1929
  808. package/dist/src/shared-KAjFxRre.cjs +0 -2185
  809. package/dist/src/simulatedUser--OjW6xCx.js +0 -247
  810. package/dist/src/simulatedUser-D0-slRye.cjs +0 -252
  811. package/dist/src/simulatedUser-D1Kh_cwA.js +0 -248
  812. package/dist/src/slack-BX0FUevO.js +0 -144
  813. package/dist/src/slack-CcwXFiJE.cjs +0 -144
  814. package/dist/src/slack-CnfqKfXp.js +0 -145
  815. package/dist/src/strategies-2ntcK4tN.js +0 -2248
  816. package/dist/src/strategies-DZIW7Zcs.js +0 -2385
  817. package/dist/src/strategies-YRDF2j-N.cjs +0 -2420
  818. package/dist/src/telemetry-CL8CVA4p.js +0 -205
  819. package/dist/src/telemetry-Cix90qqz.js +0 -201
  820. package/dist/src/telemetry-CkmlqTjV.js +0 -205
  821. package/dist/src/telemetry-DQH7l5bb.js +0 -2
  822. package/dist/src/telemetry-DUCXc1-r.cjs +0 -216
  823. package/dist/src/togetherai-3yUt5Ck7.js +0 -49
  824. package/dist/src/togetherai-BJUByLwt.cjs +0 -49
  825. package/dist/src/togetherai-Bh6KZkmd.js +0 -50
  826. package/dist/src/togetherai-DDl9yk3b.js +0 -48
  827. package/dist/src/traceContext-BiJVppjT.cjs +0 -1032
  828. package/dist/src/traceContext-CKKluULP.js +0 -1016
  829. package/dist/src/traceContext-D3Sk8fO-.js +0 -1015
  830. package/dist/src/transcription-BoVQKIVz.js +0 -175
  831. package/dist/src/transcription-Bs5u8780.js +0 -175
  832. package/dist/src/transcription-Dl654d1p.cjs +0 -178
  833. package/dist/src/transcription-VEvhM1Fu.js +0 -176
  834. package/dist/src/transform-BAbkGpvl.js +0 -125
  835. package/dist/src/transform-C_j4hUH8.js +0 -126
  836. package/dist/src/transform-Da86hs4M.cjs +0 -154
  837. package/dist/src/transform-_i1raQNo.js +0 -125
  838. package/dist/src/typesafe-CKXBeh82.cjs +0 -253
  839. package/dist/src/typesafe-D3VaGeNm.js +0 -253
  840. package/dist/src/typesafe-DYM-SFNH.js +0 -253
  841. package/dist/src/typesafe-LXmSbw8F.js +0 -254
  842. package/dist/src/util-41rb0XHX.js +0 -743
  843. package/dist/src/util-B0WlHYFM.js +0 -2049
  844. package/dist/src/util-BD1R_PsR.js +0 -1770
  845. package/dist/src/util-BLbM_ItC.js +0 -395
  846. package/dist/src/util-C72P0iIa.js +0 -352
  847. package/dist/src/util-C7MpGlJ6.cjs +0 -2305
  848. package/dist/src/util-CCtqagKc.js +0 -286
  849. package/dist/src/util-CM2Ec_uY.js +0 -2051
  850. package/dist/src/util-CSSAWO8v.js +0 -351
  851. package/dist/src/util-CkQc-fx3.cjs +0 -934
  852. package/dist/src/util-DcOlFTFa.cjs +0 -478
  853. package/dist/src/util-DluGTGVB.js +0 -395
  854. package/dist/src/util-PfQ60chz.js +0 -743
  855. package/dist/src/util-f14-CPij.js +0 -396
  856. package/dist/src/util-l9pXX3Eu.cjs +0 -357
  857. package/dist/src/util-o_BnlYqS.js +0 -2050
  858. package/dist/src/vertex-B_-gQgzc.js +0 -2
  859. package/dist/src/vertex-CU4gqoYa.js +0 -854
  860. package/dist/src/vertex-DZ42UHb3.js +0 -848
  861. package/dist/src/vertex-DsYQJA0T.cjs +0 -871
  862. package/dist/src/vertexLive-BvIaHKGB.js +0 -55
  863. package/dist/src/vertexLive-CTULqNx7.js +0 -56
  864. package/dist/src/vertexLive-DjJ_YQBe.cjs +0 -55
  865. package/dist/src/vertexLive-STUGcteB.js +0 -55
  866. package/dist/src/video-CAQGmtEV.js +0 -703
  867. package/dist/src/video-_FSTWlwX.js +0 -702
  868. package/dist/src/video-aBPJPWdt.js +0 -702
  869. package/dist/src/video-gDjkWv5m.cjs +0 -706
@@ -1,1920 +0,0 @@
1
- #!/usr/bin/env node
2
- import { S as sanitizeConfigForOutput, T as sanitizeTracingConfigForPersistence, c as logger, w as sanitizeRuntimeOptions } from "./logger-pCNnmVuz.js";
3
- import { A as hashPrompt, F as HUMAN_ASSERTION_TYPE, _ as getCachedResultsCount, a as getStripFlags, c as projectPrompt, d as stripTraceLinkageFromMetadata, g as notifyEvaluationsDeleted, h as notifyEvaluationChanged, i as getResultIndexKey, l as projectTracesForOutput, n as PROMPTFOO_METADATA_KEY, o as persistRepeatMetadata, p as invalidateEvaluationCache, s as persistTraceMetadata, t as EvalResult, v as getTotalResultRowCount, y as queryTestIndicesOptimized } from "./evalResult-CzjCb5bd.js";
4
- import { N as isNonTransientHttpStatus, w as NON_TRANSIENT_HTTP_STATUSES } from "./fetch-BhfUnKen.js";
5
- import { t as invariant } from "./invariant-CbHB1xyx.js";
6
- import { a as getAuthor } from "./accounts-GKrO1olH.js";
7
- import { t as getCurrentTimestamp } from "./time-Ct6CnABs.js";
8
- import { O as ResultFailureReason, St as PLUGIN_CATEGORIES, a as evalResultsTable, c as evalsToPromptsTable, d as promptsTable, f as spansTable, g as getDb, i as datasetsTable, l as evalsToTagsTable, m as tracesTable, nt as riskCategorySeverityMap, o as evalsTable, p as tagsTable, s as evalsToDatasetsTable } from "./tables-BONxKPrt.js";
9
- import { n as sha256, t as randomSequence } from "./createHash-DqA6GWxE.js";
10
- import { n as getTraceStore } from "./store-DFoDZ_D2.js";
11
- import { c as accumulateTokenUsage, d as createEmptyTokenUsage, r as accumulateGenerationTokenUsage } from "./tokenUsageUtils-CHs91tUW.js";
12
- import { t as getActualPrompt } from "./providerResponse-ChVTuVd0.js";
13
- import { and, desc, eq, inArray, sql } from "drizzle-orm";
14
- //#region src/database/evalDeletion.ts
15
- const SQLITE_MAX_BOUND_PARAMETERS = 999;
16
- /**
17
- * Removes spans and traces tied to the given eval ids.
18
- *
19
- * `traces.evaluation_id -> evals.id` and `spans.trace_id -> traces.trace_id` are
20
- * FK-enforced (see `pragma foreign_keys = ON`) without `ON DELETE CASCADE`, so any
21
- * eval-deletion path must clear spans before traces before the eval row itself.
22
- *
23
- * Spans are removed via a correlated subquery so the query stays within SQLite's
24
- * bound-parameter limit even when an eval has many traces.
25
- */
26
- async function deleteTraceRecordsForEvals(db, evalIds) {
27
- for (let i = 0; i < evalIds.length; i += SQLITE_MAX_BOUND_PARAMETERS) {
28
- const evalIdBatch = evalIds.slice(i, i + SQLITE_MAX_BOUND_PARAMETERS);
29
- await db.delete(spansTable).where(sql`${spansTable.traceId} in (
30
- select ${tracesTable.traceId}
31
- from ${tracesTable}
32
- where ${inArray(tracesTable.evaluationId, evalIdBatch)}
33
- )`).run();
34
- await db.delete(tracesTable).where(inArray(tracesTable.evaluationId, evalIdBatch)).run();
35
- }
36
- }
37
- //#endregion
38
- //#region src/presentation/redteamMetrics.ts
39
- /** Percentage of tests that failed grading; zero when there are no tests. */
40
- function calculateAttackSuccessRate(testCount, failCount) {
41
- return testCount > 0 ? failCount / testCount * 100 : 0;
42
- }
43
- //#endregion
44
- //#region src/presentation/redteamConfig.ts
45
- function getRiskCategorySeverityMap(plugins) {
46
- const overrides = plugins?.reduce((acc, plugin) => {
47
- if (plugin.severity) {
48
- acc[plugin.id] = plugin.severity;
49
- const policyId = plugin.config?.policy?.id;
50
- if (plugin.id === "policy" && policyId) acc[policyId] = plugin.severity;
51
- }
52
- return acc;
53
- }, {}) || {};
54
- return {
55
- ...riskCategorySeverityMap,
56
- ...overrides
57
- };
58
- }
59
- //#endregion
60
- //#region src/util/calculateFilteredMetrics.ts
61
- /**
62
- * Calculate metrics for filtered evaluation results.
63
- *
64
- * This module implements optimized SQL aggregation to calculate metrics for
65
- * filtered evaluation datasets. It uses a single GROUP BY query to aggregate
66
- * ALL prompts at once, achieving significant performance improvements over
67
- * the naive approach of querying each prompt separately.
68
- *
69
- * SECURITY: This module uses Drizzle's sql template strings for parameterized queries
70
- * to prevent SQL injection. The whereSql parameter is a SQL fragment, not a string,
71
- * ensuring all user-provided values are properly escaped.
72
- *
73
- * Performance targets:
74
- * - Simple eval (2 prompts, 100 results): <50ms
75
- * - Complex eval (10 prompts, 1000 results): <150ms
76
- * - Large eval (10 prompts, 10000 results): <500ms
77
- *
78
- * Critical design decisions:
79
- * 1. Single GROUP BY query for all basic metrics + token usage
80
- * 2. SQL JSON aggregation for named scores (avoids memory issues)
81
- * 3. SQL JSON aggregation for assertions (complex nested JSON)
82
- * 4. OOM protection with MAX_RESULTS_FOR_METRICS limit
83
- */
84
- /**
85
- * Maximum number of results to process for metrics calculation.
86
- * Protects against OOM on extremely large filtered datasets.
87
- */
88
- const MAX_RESULTS_FOR_METRICS = 5e4;
89
- function jsonUsageNumber(column, usagePath, field) {
90
- return sql`COALESCE(CAST(json_extract(${column}, ${`${usagePath}.${field}`}) AS INTEGER), 0)`;
91
- }
92
- function jsonUsageTotal(column, usagePath, cachedResponsePath) {
93
- const explicitTotal = sql`CAST(json_extract(${column}, ${`${usagePath}.total`}) AS INTEGER)`;
94
- const prompt = jsonUsageNumber(column, usagePath, "prompt");
95
- const completion = jsonUsageNumber(column, usagePath, "completion");
96
- const cached = jsonUsageNumber(column, usagePath, "cached");
97
- const requests = sql`CAST(json_extract(${column}, ${`${usagePath}.numRequests`}) AS INTEGER)`;
98
- const explicitlyCached = cachedResponsePath ? sql`COALESCE(json_extract(${column}, ${cachedResponsePath}), 0) = 1` : sql`0`;
99
- return sql`CASE
100
- WHEN ${explicitlyCached} THEN
101
- CASE
102
- WHEN COALESCE(${explicitTotal}, 0) > 0 THEN ${explicitTotal}
103
- WHEN ${cached} > 0 THEN ${cached}
104
- ELSE ${prompt} + ${completion}
105
- END
106
- WHEN ${explicitTotal} IS NOT NULL THEN ${explicitTotal}
107
- WHEN ${requests} = 0 AND ${cached} > 0 AND (${prompt} + ${completion}) <= ${cached} THEN 0
108
- ELSE ${prompt} + ${completion}
109
- END`;
110
- }
111
- function jsonUsageRequests(column, usagePath, cachedResponsePath) {
112
- const explicitlyCached = cachedResponsePath ? sql`COALESCE(json_extract(${column}, ${cachedResponsePath}), 0) = 1` : sql`0`;
113
- return sql`CASE
114
- WHEN json_extract(${column}, ${usagePath}) IS NULL THEN 0
115
- WHEN ${explicitlyCached} THEN
116
- MAX(COALESCE(CAST(json_extract(${column}, ${`${usagePath}.numRequests`}) AS INTEGER), 1), 1)
117
- ELSE COALESCE(CAST(json_extract(${column}, ${`${usagePath}.numRequests`}) AS INTEGER), 1)
118
- END`;
119
- }
120
- function jsonUsageCached(column, usagePath, cachedResponsePath) {
121
- const cached = jsonUsageNumber(column, usagePath, "cached");
122
- if (!cachedResponsePath) return cached;
123
- const reportedTotal = sql`COALESCE(
124
- CAST(json_extract(${column}, ${`${usagePath}.total`}) AS INTEGER),
125
- ${jsonUsageNumber(column, usagePath, "prompt")} + ${jsonUsageNumber(column, usagePath, "completion")}
126
- )`;
127
- return sql`CASE
128
- WHEN COALESCE(json_extract(${column}, ${cachedResponsePath}), 0) = 1 THEN
129
- CASE WHEN ${cached} > 0 THEN ${cached} ELSE ${reportedTotal} END
130
- ELSE ${cached}
131
- END`;
132
- }
133
- function jsonUsageField(column, usagePath, field, cachedResponsePath) {
134
- switch (field) {
135
- case "total": return jsonUsageTotal(column, usagePath, cachedResponsePath);
136
- case "numRequests": return jsonUsageRequests(column, usagePath, cachedResponsePath);
137
- case "cached": return jsonUsageCached(column, usagePath, cachedResponsePath);
138
- default: return jsonUsageNumber(column, usagePath, field);
139
- }
140
- }
141
- function jsonIncurredUsageField(column, logicalPath, incurredPath, field, options) {
142
- const logicalUsage = jsonUsageField(column, logicalPath, field, options?.cachedResponsePath);
143
- const incurredUsage = jsonUsageField(column, incurredPath, field);
144
- const parentHasIncurredUsage = options?.parentIncurredPath ? sql`json_extract(${column}, ${options.parentIncurredPath}) IS NOT NULL` : sql`0`;
145
- const explicitlyCached = options?.cachedResponsePath ? sql`COALESCE(json_extract(${column}, ${options.cachedResponsePath}), 0) = 1` : sql`0`;
146
- return sql`CASE
147
- WHEN json_extract(${column}, ${incurredPath}) IS NOT NULL THEN ${incurredUsage}
148
- WHEN ${parentHasIncurredUsage} OR ${explicitlyCached} THEN 0
149
- ELSE ${logicalUsage}
150
- END`;
151
- }
152
- function getTokenUsageCounts(row, prefix) {
153
- return {
154
- total: row[`${prefix}total_tokens`] || 0,
155
- prompt: row[`${prefix}prompt_tokens`] || 0,
156
- completion: row[`${prefix}completion_tokens`] || 0,
157
- cached: row[`${prefix}cached_tokens`] || 0,
158
- numRequests: (prefix ? row[`${prefix}num_requests`] : row.num_requests_with_tokens) || 0
159
- };
160
- }
161
- function getFilteredTokenUsage(row) {
162
- return {
163
- ...getTokenUsageCounts(row, ""),
164
- attacker: getTokenUsageCounts(row, "attacker_"),
165
- assertions: getTokenUsageCounts(row, "grading_"),
166
- ...row.has_incurred_usage > 0 && { incurredTokenUsage: {
167
- ...getTokenUsageCounts(row, "incurred_"),
168
- attacker: getTokenUsageCounts(row, "incurred_attacker_"),
169
- assertions: getTokenUsageCounts(row, "incurred_grading_")
170
- } }
171
- };
172
- }
173
- /**
174
- * Aggregate filtered rows across all prompts. The count limit bounds the query;
175
- * three grouped queries collect row metrics, named scores, and assertion counts.
176
- */
177
- async function calculateFilteredMetrics(opts) {
178
- const { numPrompts, whereSql } = opts;
179
- try {
180
- const countResult = await getResultCount(whereSql);
181
- if (countResult > MAX_RESULTS_FOR_METRICS) {
182
- logger.warn(`Filtered result count ${countResult} exceeds limit ${MAX_RESULTS_FOR_METRICS}`, { evalId: opts.evalId });
183
- throw new Error(`Result count ${countResult} exceeds maximum ${MAX_RESULTS_FOR_METRICS}`);
184
- }
185
- return await calculateWithOptimizedQuery(opts);
186
- } catch (error) {
187
- logger.error("Failed to calculate filtered metrics", { error });
188
- return createEmptyMetricsArray(numPrompts);
189
- }
190
- }
191
- /**
192
- * Get count of filtered results (for OOM protection)
193
- *
194
- * SECURITY: Uses parameterized SQL query via Drizzle's sql template strings.
195
- */
196
- async function getResultCount(whereSql) {
197
- const db = await getDb();
198
- const query = sql`
199
- SELECT COUNT(*) as count
200
- FROM eval_results
201
- WHERE ${whereSql}
202
- `;
203
- return (await db.get(query))?.count || 0;
204
- }
205
- /** Aggregate all prompts together using parameterized SQL. */
206
- async function calculateWithOptimizedQuery(opts) {
207
- const { numPrompts, whereSql } = opts;
208
- const db = await getDb();
209
- const metrics = createEmptyMetricsArray(numPrompts);
210
- const response = sql`response`;
211
- const gradingResult = sql`grading_result`;
212
- const targetPath = "$.tokenUsage";
213
- const incurredTargetPath = "$.tokenUsage.incurredTokenUsage";
214
- const attackerPath = "$.tokenUsage.attacker";
215
- const incurredAttackerPath = "$.tokenUsage.incurredTokenUsage.attacker";
216
- const internalGradingPath = "$.tokenUsage.assertions";
217
- const incurredInternalGradingPath = "$.tokenUsage.incurredTokenUsage.assertions";
218
- const gradingPath = "$.tokensUsed";
219
- const incurredGradingPath = "$.tokensUsed.incurredTokenUsage";
220
- const gradingCachePath = "$.metadata.cachedResponse";
221
- const responseCachePath = "$.cached";
222
- const incurredTargetUsage = (field) => jsonIncurredUsageField(response, targetPath, incurredTargetPath, field, { cachedResponsePath: responseCachePath });
223
- const incurredAttackerUsage = (field) => jsonIncurredUsageField(response, attackerPath, incurredAttackerPath, field, {
224
- cachedResponsePath: responseCachePath,
225
- parentIncurredPath: incurredTargetPath
226
- });
227
- const incurredInternalGradingUsage = (field) => jsonIncurredUsageField(response, internalGradingPath, incurredInternalGradingPath, field, {
228
- cachedResponsePath: responseCachePath,
229
- parentIncurredPath: incurredTargetPath
230
- });
231
- const incurredGradingUsage = (field) => jsonIncurredUsageField(gradingResult, gradingPath, incurredGradingPath, field, { cachedResponsePath: gradingCachePath });
232
- const basicMetricsQuery = sql`
233
- SELECT
234
- prompt_idx,
235
- SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) as pass_count,
236
- SUM(CASE WHEN success = 0 AND failure_reason != ${ResultFailureReason.ERROR} THEN 1 ELSE 0 END) as fail_count,
237
- SUM(CASE WHEN failure_reason = ${ResultFailureReason.ERROR} THEN 1 ELSE 0 END) as error_count,
238
- SUM(CASE WHEN json_extract(${response}, ${responseCachePath}) = 1 THEN 1 ELSE 0 END) as cache_hit_count,
239
- SUM(score) as total_score,
240
- SUM(latency_ms) as total_latency,
241
- SUM(cost) as total_cost,
242
- SUM(CASE WHEN json_extract(response, '$.incurredCost') IS NOT NULL
243
- OR json_extract(response, '$.cached') = 1 THEN 1 ELSE 0 END) as has_incurred_cost,
244
- SUM(COALESCE(json_extract(response, '$.incurredCost'),
245
- CASE WHEN json_extract(response, '$.cached') = 1 THEN 0 ELSE cost END, 0)) as incurred_cost,
246
- -- Token usage aggregation (token usage is inside response JSON)
247
- SUM(${jsonUsageTotal(response, targetPath)}) as total_tokens,
248
- SUM(${jsonUsageNumber(response, targetPath, "prompt")}) as prompt_tokens,
249
- SUM(${jsonUsageNumber(response, targetPath, "completion")}) as completion_tokens,
250
- SUM(${jsonUsageCached(response, targetPath)}) as cached_tokens,
251
- SUM(${jsonUsageRequests(response, targetPath)}) as num_requests_with_tokens,
252
- SUM(${jsonUsageTotal(response, attackerPath)}) as attacker_total_tokens,
253
- SUM(${jsonUsageNumber(response, attackerPath, "prompt")}) as attacker_prompt_tokens,
254
- SUM(${jsonUsageNumber(response, attackerPath, "completion")}) as attacker_completion_tokens,
255
- SUM(${jsonUsageCached(response, attackerPath)}) as attacker_cached_tokens,
256
- SUM(${jsonUsageRequests(response, attackerPath)}) as attacker_num_requests,
257
- SUM(
258
- ${jsonUsageTotal(response, internalGradingPath)} +
259
- ${jsonUsageTotal(gradingResult, gradingPath, gradingCachePath)}
260
- ) as grading_total_tokens,
261
- SUM(
262
- ${jsonUsageNumber(response, internalGradingPath, "prompt")} +
263
- ${jsonUsageNumber(gradingResult, gradingPath, "prompt")}
264
- ) as grading_prompt_tokens,
265
- SUM(
266
- ${jsonUsageNumber(response, internalGradingPath, "completion")} +
267
- ${jsonUsageNumber(gradingResult, gradingPath, "completion")}
268
- ) as grading_completion_tokens,
269
- SUM(
270
- ${jsonUsageCached(response, internalGradingPath)} +
271
- ${jsonUsageCached(gradingResult, gradingPath, gradingCachePath)}
272
- ) as grading_cached_tokens,
273
- SUM(
274
- ${jsonUsageRequests(response, internalGradingPath)} +
275
- ${jsonUsageRequests(gradingResult, gradingPath, gradingCachePath)}
276
- ) as grading_num_requests,
277
- SUM(
278
- CASE
279
- WHEN json_extract(response, ${incurredTargetPath}) IS NOT NULL
280
- OR json_extract(grading_result, ${incurredGradingPath}) IS NOT NULL
281
- OR COALESCE(json_extract(response, ${responseCachePath}), 0) = 1
282
- OR COALESCE(json_extract(grading_result, ${gradingCachePath}), 0) = 1
283
- THEN 1
284
- ELSE 0
285
- END
286
- ) as has_incurred_usage,
287
- SUM(${incurredTargetUsage("total")}) as incurred_total_tokens,
288
- SUM(${incurredTargetUsage("prompt")}) as incurred_prompt_tokens,
289
- SUM(${incurredTargetUsage("completion")}) as incurred_completion_tokens,
290
- SUM(${incurredTargetUsage("cached")}) as incurred_cached_tokens,
291
- SUM(${incurredTargetUsage("numRequests")}) as incurred_num_requests,
292
- SUM(${incurredAttackerUsage("total")}) as incurred_attacker_total_tokens,
293
- SUM(${incurredAttackerUsage("prompt")}) as incurred_attacker_prompt_tokens,
294
- SUM(${incurredAttackerUsage("completion")}) as incurred_attacker_completion_tokens,
295
- SUM(${incurredAttackerUsage("cached")}) as incurred_attacker_cached_tokens,
296
- SUM(${incurredAttackerUsage("numRequests")}) as incurred_attacker_num_requests,
297
- SUM(
298
- ${incurredInternalGradingUsage("total")} + ${incurredGradingUsage("total")}
299
- ) as incurred_grading_total_tokens,
300
- SUM(
301
- ${incurredInternalGradingUsage("prompt")} + ${incurredGradingUsage("prompt")}
302
- ) as incurred_grading_prompt_tokens,
303
- SUM(
304
- ${incurredInternalGradingUsage("completion")} + ${incurredGradingUsage("completion")}
305
- ) as incurred_grading_completion_tokens,
306
- SUM(
307
- ${incurredInternalGradingUsage("cached")} + ${incurredGradingUsage("cached")}
308
- ) as incurred_grading_cached_tokens,
309
- SUM(
310
- ${incurredInternalGradingUsage("numRequests")} + ${incurredGradingUsage("numRequests")}
311
- ) as incurred_grading_num_requests
312
- FROM eval_results
313
- WHERE ${whereSql}
314
- GROUP BY prompt_idx
315
- ORDER BY prompt_idx
316
- `;
317
- const basicResults = await db.all(basicMetricsQuery);
318
- for (const row of basicResults) {
319
- const idx = row.prompt_idx;
320
- if (idx < 0 || idx >= numPrompts) {
321
- logger.warn(`Invalid prompt_idx ${idx}, expected 0-${numPrompts - 1}`);
322
- continue;
323
- }
324
- metrics[idx] = {
325
- score: row.total_score || 0,
326
- testPassCount: row.pass_count || 0,
327
- testFailCount: row.fail_count || 0,
328
- testErrorCount: row.error_count || 0,
329
- testCacheHitCount: row.cache_hit_count || 0,
330
- totalLatencyMs: row.total_latency || 0,
331
- cost: row.total_cost || 0,
332
- ...row.has_incurred_cost ? { incurredCost: row.incurred_cost || 0 } : {},
333
- tokenUsage: getFilteredTokenUsage(row),
334
- namedScores: {},
335
- namedScoresCount: {},
336
- namedScoreWeights: {},
337
- assertPassCount: 0,
338
- assertFailCount: 0
339
- };
340
- }
341
- await aggregateNamedScores(metrics, whereSql);
342
- await aggregateAssertions(metrics, whereSql);
343
- logger.debug("Filtered metrics calculated", {
344
- numPrompts,
345
- metricsCount: basicResults.length
346
- });
347
- return metrics;
348
- }
349
- /**
350
- * Aggregate named scores using SQL json_each().
351
- * This is MUCH more efficient than fetching all results and parsing in JavaScript.
352
- *
353
- * SECURITY: Uses parameterized SQL query via Drizzle's sql template strings.
354
- *
355
- * Uses SQLite's json_each() to parse JSON in the database, avoiding the need
356
- * to fetch potentially thousands of rows into memory.
357
- */
358
- async function aggregateNamedScores(metrics, whereSql) {
359
- const db = await getDb();
360
- const query = sql`
361
- SELECT
362
- prompt_idx,
363
- score_entries.key as metric_name,
364
- SUM(
365
- CASE
366
- WHEN weight_entries.value IS NOT NULL THEN
367
- CAST(score_entries.value AS REAL) * CAST(weight_entries.value AS REAL)
368
- ELSE CAST(score_entries.value AS REAL)
369
- END
370
- ) as metric_sum,
371
- COUNT(*) as metric_count,
372
- SUM(
373
- CASE
374
- WHEN weight_entries.value IS NOT NULL THEN CAST(weight_entries.value AS REAL)
375
- ELSE 1
376
- END
377
- ) as metric_weight_total
378
- FROM eval_results
379
- JOIN json_each(eval_results.named_scores) as score_entries
380
- LEFT JOIN json_each(
381
- CASE
382
- WHEN grading_result IS NOT NULL
383
- AND json_valid(grading_result)
384
- AND json_type(json_extract(grading_result, '$.namedScoreWeights')) = 'object'
385
- THEN json_extract(grading_result, '$.namedScoreWeights')
386
- ELSE json('{}')
387
- END
388
- ) as weight_entries
389
- ON weight_entries.key = score_entries.key
390
- WHERE ${whereSql}
391
- AND named_scores IS NOT NULL
392
- AND json_valid(named_scores)
393
- GROUP BY prompt_idx, score_entries.key
394
- `;
395
- const results = await db.all(query);
396
- for (const row of results) {
397
- const idx = row.prompt_idx;
398
- if (idx >= 0 && idx < metrics.length && metrics[idx]) {
399
- metrics[idx].namedScores[row.metric_name] = row.metric_sum;
400
- metrics[idx].namedScoresCount[row.metric_name] = row.metric_count;
401
- metrics[idx].namedScoreWeights ||= {};
402
- metrics[idx].namedScoreWeights[row.metric_name] = row.metric_weight_total;
403
- }
404
- }
405
- }
406
- /**
407
- * Aggregate assertion counts using SQL json_each().
408
- * This requires nested JSON extraction for componentResults.
409
- *
410
- * SECURITY: Uses parameterized SQL query via Drizzle's sql template strings.
411
- *
412
- * The grading_result structure is:
413
- * {
414
- * "componentResults": [
415
- * {"pass": true, "assertion": {...}},
416
- * {"pass": false, "assertion": {...}}
417
- * ]
418
- * }
419
- *
420
- * We need to count pass=true vs pass=false across all results.
421
- */
422
- async function aggregateAssertions(metrics, whereSql) {
423
- const db = await getDb();
424
- const query = sql`
425
- SELECT
426
- prompt_idx,
427
- SUM(
428
- CASE
429
- WHEN json_valid(grading_result) AND json_type(json_extract(grading_result, '$.componentResults')) = 'array' THEN
430
- (
431
- SELECT COUNT(*)
432
- FROM json_each(json_extract(grading_result, '$.componentResults'))
433
- WHERE CAST(json_extract(json_each.value, '$.pass') AS INTEGER) = 1
434
- )
435
- ELSE 0
436
- END
437
- ) as assert_pass_count,
438
- SUM(
439
- CASE
440
- WHEN json_valid(grading_result) AND json_type(json_extract(grading_result, '$.componentResults')) = 'array' THEN
441
- (
442
- SELECT COUNT(*)
443
- FROM json_each(json_extract(grading_result, '$.componentResults'))
444
- WHERE CAST(json_extract(json_each.value, '$.pass') AS INTEGER) = 0
445
- )
446
- ELSE 0
447
- END
448
- ) as assert_fail_count
449
- FROM eval_results
450
- WHERE ${whereSql}
451
- AND grading_result IS NOT NULL
452
- GROUP BY prompt_idx
453
- `;
454
- const results = await db.all(query);
455
- for (const row of results) {
456
- const idx = row.prompt_idx;
457
- if (idx >= 0 && idx < metrics.length && metrics[idx]) {
458
- metrics[idx].assertPassCount = row.assert_pass_count || 0;
459
- metrics[idx].assertFailCount = row.assert_fail_count || 0;
460
- }
461
- }
462
- }
463
- /**
464
- * Create empty metrics array initialized with zeros.
465
- * Used as fallback when calculation fails or no results found.
466
- */
467
- function createEmptyMetricsArray(numPrompts) {
468
- return Array.from({ length: numPrompts }, () => ({
469
- score: 0,
470
- testPassCount: 0,
471
- testFailCount: 0,
472
- testErrorCount: 0,
473
- testCacheHitCount: 0,
474
- assertPassCount: 0,
475
- assertFailCount: 0,
476
- totalLatencyMs: 0,
477
- tokenUsage: {
478
- total: 0,
479
- prompt: 0,
480
- completion: 0,
481
- cached: 0,
482
- numRequests: 0
483
- },
484
- namedScores: {},
485
- namedScoresCount: {},
486
- namedScoreWeights: {},
487
- cost: 0
488
- }));
489
- }
490
- //#endregion
491
- //#region src/presentation/evalTableCells.ts
492
- function getTableCellText(result) {
493
- let resultText;
494
- const rawOutput = result.response?.output;
495
- let outputTextDisplay;
496
- if (rawOutput !== null && typeof rawOutput === "object") outputTextDisplay = JSON.stringify(rawOutput);
497
- else if (rawOutput == null || rawOutput === "") outputTextDisplay = result.error || "";
498
- else outputTextDisplay = String(rawOutput);
499
- if (result.testCase.assert) {
500
- if (result.success) resultText = `${outputTextDisplay || result.error || ""}`;
501
- else resultText = `${outputTextDisplay}`;
502
- } else if (result.error) resultText = `${result.error}`;
503
- else resultText = outputTextDisplay;
504
- return resultText;
505
- }
506
- function getTableCellMedia(result) {
507
- return {
508
- audio: result.response?.audio ? {
509
- id: result.response.audio.id,
510
- expiresAt: result.response.audio.expiresAt,
511
- data: result.response.audio.data,
512
- blobRef: result.response.audio.blobRef,
513
- transcript: result.response.audio.transcript,
514
- format: result.response.audio.format,
515
- sampleRate: result.response.audio.sampleRate,
516
- channels: result.response.audio.channels,
517
- duration: result.response.audio.duration
518
- } : void 0,
519
- video: result.response?.video ? {
520
- id: result.response.video.id,
521
- blobRef: result.response.video.blobRef,
522
- storageRef: result.response.video.storageRef,
523
- url: result.response.video.url,
524
- format: result.response.video.format,
525
- size: result.response.video.size,
526
- duration: result.response.video.duration,
527
- thumbnail: result.response.video.thumbnail,
528
- spritesheet: result.response.video.spritesheet,
529
- model: result.response.video.model,
530
- aspectRatio: result.response.video.aspectRatio,
531
- resolution: result.response.video.resolution
532
- } : void 0,
533
- images: result.response?.images?.map((img) => ({
534
- data: img.data,
535
- blobRef: img.blobRef,
536
- mimeType: img.mimeType
537
- }))
538
- };
539
- }
540
- //#endregion
541
- //#region src/presentation/evalResults.ts
542
- /** Convert version 4+ results to display rows and ordered variable columns. */
543
- function convertResultsToTable(eval_) {
544
- invariant(eval_.prompts, `Prompts are required in this version of the results file, this needs to be results file version >= 4, version: ${eval_.version}`);
545
- const results = eval_.results;
546
- const rawPersistedVars = eval_.vars;
547
- if (rawPersistedVars !== void 0 && !Array.isArray(rawPersistedVars)) logger.warn(`[convertResultsToTable] eval.vars is ${typeof rawPersistedVars}, not string[]; falling back to alphabetical ordering`);
548
- const persistedVarSet = new Set(Array.isArray(rawPersistedVars) ? rawPersistedVars : []);
549
- const persistedVars = Array.from(persistedVarSet);
550
- const varsForHeader = new Set(persistedVars);
551
- const varValuesForRow = /* @__PURE__ */ new Map();
552
- const rowMap = {};
553
- for (const result of results.results) {
554
- for (const varName of Object.keys(result.vars || {})) varsForHeader.add(varName);
555
- const row = rowMap[result.testIdx] || {
556
- description: result.description || void 0,
557
- outputs: [],
558
- vars: [],
559
- test: result.testCase
560
- };
561
- const actualPrompt = getActualPrompt(result.response) || result.metadata?.redteamFinalPrompt;
562
- if (result.vars && actualPrompt) {
563
- const varKeys = Object.keys(result.vars);
564
- if (varKeys.length === 1 && varKeys[0] !== "harmCategory") result.vars[varKeys[0]] = actualPrompt;
565
- else if (varKeys.length > 1) {
566
- const keyToUpdate = [
567
- "prompt",
568
- "query",
569
- "question"
570
- ].find((key) => result.vars[key]);
571
- if (keyToUpdate) result.vars[keyToUpdate] = actualPrompt;
572
- }
573
- }
574
- if (!result.vars?.sessionId) {
575
- const metadataSessionIds = result.metadata?.sessionIds;
576
- if (Array.isArray(metadataSessionIds) && metadataSessionIds.length > 0) {
577
- result.vars = result.vars || {};
578
- result.vars.sessionId = metadataSessionIds.filter((id) => id != null && id !== "").map(String).join("\n");
579
- varsForHeader.add("sessionId");
580
- } else if (result.metadata?.sessionId) {
581
- result.vars = result.vars || {};
582
- result.vars.sessionId = result.metadata.sessionId;
583
- varsForHeader.add("sessionId");
584
- }
585
- }
586
- const transformDisplayVars = result.response?.metadata?.transformDisplayVars;
587
- if (transformDisplayVars) {
588
- result.vars = result.vars || {};
589
- for (const [key, value] of Object.entries(transformDisplayVars)) if (!(key in result.vars)) {
590
- result.vars[key] = value;
591
- varsForHeader.add(key);
592
- } else if (result.vars[key] !== value) logger.debug(`[convertResultsToTable] transformDisplayVars key '${key}' collides with result.vars; preserving original value`);
593
- }
594
- varValuesForRow.set(result.testIdx, result.vars);
595
- rowMap[result.testIdx] = row;
596
- const resultText = getTableCellText(result);
597
- row.outputs[result.promptIdx] = {
598
- id: result.id || `${result.testIdx}-${result.promptIdx}`,
599
- ...result,
600
- text: resultText || "",
601
- prompt: result.prompt.raw,
602
- provider: result.provider?.label || result.provider?.id || "unknown provider",
603
- pass: result.success,
604
- failureReason: result.failureReason,
605
- cost: result.cost || 0,
606
- tokenUsage: result.tokenUsage,
607
- ...getTableCellMedia(result)
608
- };
609
- invariant(result.promptId, "Prompt ID is required");
610
- row.testIdx = result.testIdx;
611
- }
612
- const rows = Object.values(rowMap);
613
- const additionalVars = [...varsForHeader].filter((name) => !persistedVarSet.has(name)).sort();
614
- const orderedVars = persistedVars.length > 0 ? [...persistedVars, ...additionalVars] : additionalVars;
615
- for (const row of rows) row.vars = orderedVars.map((varName) => {
616
- const varValue = varValuesForRow.get(row.testIdx)?.[varName] ?? "";
617
- if (typeof varValue === "string") return varValue;
618
- return JSON.stringify(varValue, null, 2);
619
- });
620
- return {
621
- head: {
622
- prompts: eval_.prompts,
623
- vars: orderedVars
624
- },
625
- body: rows
626
- };
627
- }
628
- //#endregion
629
- //#region src/util/eval/repeatStability.ts
630
- const WILSON_Z_95 = 1.959963984540054;
631
- const ERROR_FAILURE_REASON = 2;
632
- function getWilsonScoreInterval(passed, total) {
633
- if (total <= 0 || passed < 0 || passed > total) return;
634
- const proportion = passed / total;
635
- const zSquared = WILSON_Z_95 ** 2;
636
- const denominator = 1 + zSquared / total;
637
- const center = (proportion + zSquared / (2 * total)) / denominator;
638
- const margin = WILSON_Z_95 / denominator * Math.sqrt(proportion * (1 - proportion) / total + zSquared / (4 * total ** 2));
639
- return {
640
- confidenceLevel: .95,
641
- lower: Math.max(0, center - margin),
642
- upper: Math.min(1, center + margin)
643
- };
644
- }
645
- function isCachedResult(result) {
646
- if (result.response?.cached === true) return true;
647
- if (!result.gradingResult) return false;
648
- const pending = [result.gradingResult];
649
- const visited = /* @__PURE__ */ new Set();
650
- for (let index = 0; index < pending.length; index++) {
651
- const gradingResult = pending[index];
652
- if (!gradingResult || typeof gradingResult !== "object" || visited.has(gradingResult)) continue;
653
- visited.add(gradingResult);
654
- if (gradingResult.metadata?.cachedResponse === true) return true;
655
- const components = gradingResult.componentResults;
656
- if (Array.isArray(components)) for (let childIndex = 0; childIndex < components.length; childIndex++) pending.push(components[childIndex]);
657
- }
658
- return false;
659
- }
660
- function getGroupKey(result) {
661
- return `${result.repeatGroupId}\u0000${result.promptIdx}\u0000${result.provider.id}\u0000${result.provider.label}`;
662
- }
663
- var RepeatStabilityCalculator = class {
664
- groups = /* @__PURE__ */ new Map();
665
- addResults(results) {
666
- for (const result of results) this.addResult(result);
667
- }
668
- addResult(result) {
669
- if (!result.repeatGroupId || result.repeatIndex === void 0 || !Number.isInteger(result.repeatIndex) || result.repeatIndex < 0) return;
670
- const key = getGroupKey(result);
671
- const group = this.groups.get(key) ?? {
672
- repeatGroupId: result.repeatGroupId,
673
- promptIdx: result.promptIdx,
674
- provider: {
675
- id: result.provider.id,
676
- label: result.provider.label
677
- },
678
- description: result.description ?? result.testCase.description,
679
- promptLabel: result.prompt.label,
680
- repetitions: 0,
681
- passed: 0,
682
- failed: 0,
683
- errors: 0,
684
- cached: 0,
685
- scored: 0,
686
- unstable: false
687
- };
688
- group.repetitions++;
689
- if (isCachedResult(result)) group.cached++;
690
- if (result.failureReason === ERROR_FAILURE_REASON) group.errors++;
691
- else if (result.success) {
692
- group.passed++;
693
- group.scored++;
694
- } else {
695
- group.failed++;
696
- group.scored++;
697
- }
698
- group.unstable = group.passed > 0 && group.failed > 0;
699
- this.groups.set(key, group);
700
- }
701
- getSummary() {
702
- if (this.groups.size === 0) return;
703
- const groups = Array.from(this.groups.values()).map(({ scored, ...group }) => ({
704
- ...group,
705
- ...scored > 0 && { passRate: group.passed / scored },
706
- ...scored > 0 && group.cached === 0 && { passRateConfidenceInterval: getWilsonScoreInterval(group.passed, scored) }
707
- }));
708
- groups.sort((a, b) => a.repeatGroupId.localeCompare(b.repeatGroupId) || a.promptIdx - b.promptIdx || (a.provider.id ?? "").localeCompare(b.provider.id ?? "") || (a.provider.label ?? "").localeCompare(b.provider.label ?? ""));
709
- return {
710
- totalGroups: groups.length,
711
- unstableGroups: groups.filter((group) => group.unstable).length,
712
- groupsWithErrors: groups.filter((group) => group.errors > 0).length,
713
- cachedResults: groups.reduce((total, group) => total + group.cached, 0),
714
- groups
715
- };
716
- }
717
- };
718
- function calculateRepeatStability(results) {
719
- const calculator = new RepeatStabilityCalculator();
720
- calculator.addResults(results);
721
- return calculator.getSummary();
722
- }
723
- //#endregion
724
- //#region src/util/exportToFile/index.ts
725
- function convertEvalResultToTableCell(result) {
726
- const resultText = getTableCellText(result);
727
- return {
728
- ...result,
729
- id: result.id || `${result.testIdx}-${result.promptIdx}`,
730
- text: resultText || "",
731
- prompt: result.prompt.raw,
732
- provider: result.provider?.label || result.provider?.id || "unknown provider",
733
- pass: result.success,
734
- cost: result.cost || 0,
735
- ...getTableCellMedia(result)
736
- };
737
- }
738
- function convertTestResultsToTableRow(results, varsForHeader) {
739
- const row = {
740
- description: results[0].description || void 0,
741
- outputs: [],
742
- vars: Object.values(varsForHeader).map((varName) => {
743
- if (varName === "sessionId") {
744
- const sessionIdFromVars = results[0].testCase.vars?.sessionId;
745
- if (sessionIdFromVars != null && sessionIdFromVars !== "") return typeof sessionIdFromVars === "string" ? sessionIdFromVars : JSON.stringify(sessionIdFromVars);
746
- const metadataSessionIds = results[0].metadata?.sessionIds;
747
- if (Array.isArray(metadataSessionIds) && metadataSessionIds.length > 0) return metadataSessionIds.filter((id) => id != null && id !== "").map(String).join("\n");
748
- const metadataSessionId = results[0].metadata?.sessionId;
749
- if (metadataSessionId != null) return typeof metadataSessionId === "string" ? metadataSessionId : JSON.stringify(metadataSessionId);
750
- return "";
751
- }
752
- const varValue = results[0].testCase.vars?.[varName] ?? "";
753
- if (typeof varValue === "string") return varValue;
754
- return JSON.stringify(varValue);
755
- }),
756
- test: results[0].testCase,
757
- testIdx: results[0].testIdx
758
- };
759
- for (const result of results) row.outputs[result.promptIdx] = convertEvalResultToTableCell(result);
760
- return row;
761
- }
762
- //#endregion
763
- //#region src/models/eval.ts
764
- function createEvalId(createdAt = /* @__PURE__ */ new Date()) {
765
- return `eval-${randomSequence(3)}-${createdAt.toISOString().slice(0, 19)}`;
766
- }
767
- /**
768
- * Escapes a key for use in a JSON path expression.
769
- * Handles backslashes and double quotes which have special meaning in JSON paths.
770
- */
771
- function escapeJsonPathKey(key) {
772
- return key.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
773
- }
774
- /**
775
- * Builds a JSON path for use as a bound SQLite json_extract() parameter.
776
- *
777
- * The field name still needs JSON-path escaping so special characters remain
778
- * inside the quoted key. SQL safety comes from passing the returned path through
779
- * Drizzle's `sql` templates as a value, never as raw SQL.
780
- */
781
- function buildSafeJsonPath(field) {
782
- return `$."${escapeJsonPathKey(field)}"`;
783
- }
784
- /**
785
- * Combines multiple filter conditions using their associated logic operators (AND/OR).
786
- *
787
- * @param filterConditions - Array of conditions with their logic operators
788
- * @returns A single SQL fragment combining all conditions, or null if empty
789
- */
790
- function combineFilterConditions(filterConditions) {
791
- if (filterConditions.length === 0) return null;
792
- if (filterConditions.length === 1) return filterConditions[0].condition;
793
- return filterConditions.reduce((acc, { condition: cond, logicOperator }, idx) => {
794
- if (idx === 0) return cond;
795
- return typeof logicOperator === "string" && logicOperator.toUpperCase() === "OR" ? sql`${acc} OR ${cond}` : sql`${acc} AND ${cond}`;
796
- }, filterConditions[0].condition);
797
- }
798
- var EvalQueries = class {
799
- static async getVarsFromEvals(evals) {
800
- const db = await getDb();
801
- if (evals.length === 0) return {};
802
- const evalIds = evals.map((e) => e.id);
803
- const query = sql`
804
- SELECT DISTINCT j.key, eval_id
805
- FROM (
806
- SELECT eval_id, json_extract(eval_results.test_case, '$.vars') as vars
807
- FROM eval_results
808
- WHERE eval_id IN (${sql.join(evalIds, sql`, `)})
809
- ) t, json_each(t.vars) j
810
- `;
811
- const vars = (await db.all(query)).reduce((acc, r) => {
812
- acc[r.eval_id] = acc[r.eval_id] || [];
813
- acc[r.eval_id].push(r.key);
814
- return acc;
815
- }, {});
816
- for (const list of Object.values(vars)) list.sort();
817
- return vars;
818
- }
819
- static async getVarsFromEval(evalId) {
820
- const db = await getDb();
821
- const query = sql`
822
- SELECT DISTINCT j.key
823
- FROM (
824
- SELECT json_extract(eval_results.test_case, '$.vars') as vars
825
- FROM eval_results
826
- WHERE eval_results.eval_id = ${evalId}
827
- ) t, json_each(t.vars) j
828
- `;
829
- return (await db.all(query)).map((r) => r.key).sort();
830
- }
831
- static async setVars(evalId, vars) {
832
- const db = await getDb();
833
- try {
834
- await db.update(evalsTable).set({ vars }).where(eq(evalsTable.id, evalId)).run();
835
- } catch (e) {
836
- logger.error(`Error setting vars: ${vars} for eval ${evalId}: ${e}`);
837
- }
838
- }
839
- static async getMetadataKeysFromEval(evalId, comparisonEvalIds = []) {
840
- const db = await getDb();
841
- try {
842
- const allEvalIds = [evalId, ...comparisonEvalIds];
843
- const query = sql`
844
- SELECT DISTINCT j.key FROM (
845
- SELECT metadata FROM eval_results
846
- WHERE eval_id IN (${sql.join(allEvalIds, sql`, `)})
847
- AND metadata IS NOT NULL
848
- AND metadata != '{}'
849
- AND json_valid(metadata)
850
- LIMIT 10000
851
- ) t, json_each(t.metadata) j
852
- ORDER BY j.key
853
- LIMIT 1000
854
- `;
855
- return (await db.all(query)).map((r) => r.key).filter((key) => key !== PROMPTFOO_METADATA_KEY);
856
- } catch (error) {
857
- logger.error(`Error fetching metadata keys for eval ${evalId} and comparisons [${comparisonEvalIds.join(", ")}]: ${error}`);
858
- return [];
859
- }
860
- }
861
- /**
862
- * Queries all unique metadata values for a given metadata key.
863
- * @param evalId - The ID of the eval to get the metadata values from.
864
- * @param key - The key of the metadata to get the values from.
865
- * @returns An array of unique metadata values.
866
- */
867
- static async getMetadataValuesFromEval(evalId, key) {
868
- const db = await getDb();
869
- const trimmedKey = key.trim();
870
- if (!trimmedKey) return [];
871
- if (trimmedKey === "__promptfoo" || trimmedKey.startsWith(`__promptfoo.`)) return [];
872
- try {
873
- const jsonPath = buildSafeJsonPath(trimmedKey);
874
- const query = sql`
875
- SELECT DISTINCT
876
- json_extract(${evalResultsTable.metadata}, ${jsonPath}) AS value
877
- FROM ${evalResultsTable}
878
- WHERE ${evalResultsTable.evalId} = ${evalId}
879
- AND ${evalResultsTable.metadata} IS NOT NULL
880
- AND ${evalResultsTable.metadata} != '{}'
881
- AND json_valid(${evalResultsTable.metadata})
882
- AND json_extract(${evalResultsTable.metadata}, ${jsonPath}) IS NOT NULL
883
- ORDER BY value
884
- LIMIT 1000
885
- `;
886
- const values = (await db.all(query)).map(({ value }) => String(value).trim()).filter((value) => value.length > 0);
887
- return Array.from(new Set(values));
888
- } catch (error) {
889
- logger.error(`Error fetching metadata values for eval ${evalId} and key ${trimmedKey}: ${error instanceof Error ? error.message : String(error)}`);
890
- return [];
891
- }
892
- }
893
- };
894
- var Eval = class Eval {
895
- id;
896
- createdAt;
897
- author;
898
- description;
899
- config;
900
- results;
901
- datasetId;
902
- prompts;
903
- oldResults;
904
- persisted;
905
- vars;
906
- _resultsLoaded = false;
907
- runtimeOptions;
908
- _shared = false;
909
- resultPersistenceFailed = false;
910
- /**
911
- * The first non-transient HTTP status among the rows added in this run. It stands in for
912
- * the database when that cannot be queried afterwards.
913
- */
914
- observedTargetErrorStatus;
915
- failedResults = /* @__PURE__ */ new Map();
916
- failedEvalResults = /* @__PURE__ */ new Map();
917
- finalJsonlResults = /* @__PURE__ */ new Map();
918
- observedRepeatedResults = false;
919
- /** Total wall-clock duration. For redteam evals: generationDurationMs + evaluationDurationMs.
920
- * For non-redteam evals: equals evaluationDurationMs (generation phase is N/A). */
921
- durationMs;
922
- /** Time spent generating adversarial test cases (redteam only). */
923
- generationDurationMs;
924
- /** Time spent running the evaluation phase. */
925
- evaluationDurationMs;
926
- /**
927
- * The shareable URL for this evaluation, if it has been shared.
928
- * Set by the evaluate() function when sharing is enabled.
929
- */
930
- shareableUrl;
931
- static async latest() {
932
- const db_results = await (await getDb()).select({ id: evalsTable.id }).from(evalsTable).orderBy(desc(evalsTable.createdAt)).limit(1);
933
- if (db_results.length === 0) return;
934
- return await Eval.findById(db_results[0].id);
935
- }
936
- static async findById(id) {
937
- const db = await getDb();
938
- const evalData = await db.select().from(evalsTable).where(eq(evalsTable.id, id)).all();
939
- if (evalData.length === 0) return;
940
- const datasetResults = await db.select({ datasetId: evalsToDatasetsTable.datasetId }).from(evalsToDatasetsTable).where(eq(evalsToDatasetsTable.evalId, id)).limit(1).all();
941
- const eval_ = evalData[0];
942
- const datasetId = datasetResults[0]?.datasetId;
943
- const resultsObj = eval_.results;
944
- const validateDuration = (raw) => typeof raw === "number" && Number.isFinite(raw) && raw >= 0 ? raw : void 0;
945
- const rawDurationMs = validateDuration(resultsObj?.["durationMs"]);
946
- const generationDurationMs = validateDuration(resultsObj?.["generationDurationMs"]);
947
- const evaluationDurationMs = validateDuration(resultsObj?.["evaluationDurationMs"]);
948
- const durationMs = rawDurationMs ?? (generationDurationMs != null || evaluationDurationMs != null ? (generationDurationMs ?? 0) + (evaluationDurationMs ?? 0) : void 0);
949
- const evalInstance = new Eval(eval_.config, {
950
- id: eval_.id,
951
- createdAt: new Date(eval_.createdAt),
952
- author: eval_.author,
953
- description: eval_.description || void 0,
954
- prompts: eval_.prompts || [],
955
- datasetId,
956
- persisted: true,
957
- vars: eval_.vars || [],
958
- runtimeOptions: eval_.runtimeOptions ?? void 0,
959
- durationMs,
960
- generationDurationMs,
961
- evaluationDurationMs
962
- });
963
- if (eval_.results && "table" in eval_.results) evalInstance.oldResults = eval_.results;
964
- if (!eval_.vars || eval_.vars.length === 0) {
965
- const vars = await EvalQueries.getVarsFromEval(id);
966
- evalInstance.setVars(vars);
967
- await EvalQueries.setVars(id, vars);
968
- }
969
- return evalInstance;
970
- }
971
- static async getMany(limit = 100) {
972
- return (await (await getDb()).select({
973
- id: evalsTable.id,
974
- createdAt: evalsTable.createdAt,
975
- author: evalsTable.author,
976
- description: evalsTable.description,
977
- config: evalsTable.config,
978
- prompts: evalsTable.prompts
979
- }).from(evalsTable).limit(limit).orderBy(desc(evalsTable.createdAt)).all()).map((e) => new Eval(e.config, {
980
- id: e.id,
981
- createdAt: new Date(e.createdAt),
982
- author: e.author,
983
- description: e.description || void 0,
984
- prompts: e.prompts || [],
985
- persisted: true
986
- }));
987
- }
988
- static async create(config, renderedPrompts, opts) {
989
- const createdAt = opts?.createdAt || /* @__PURE__ */ new Date();
990
- const evalId = opts?.id || createEvalId(createdAt);
991
- const author = opts && "author" in opts ? opts.author ?? null : getAuthor();
992
- const db = await getDb();
993
- const datasetId = sha256(JSON.stringify(config.tests || []));
994
- const durationResults = {
995
- ...opts?.durationMs !== void 0 && { durationMs: opts.durationMs },
996
- ...opts?.generationDurationMs !== void 0 && { generationDurationMs: opts.generationDurationMs },
997
- ...opts?.evaluationDurationMs !== void 0 && { evaluationDurationMs: opts.evaluationDurationMs }
998
- };
999
- await db.transaction(async (tx) => {
1000
- await tx.insert(evalsTable).values({
1001
- id: evalId,
1002
- createdAt: createdAt.getTime(),
1003
- author,
1004
- description: config.description,
1005
- config: sanitizeTracingConfigForPersistence(config),
1006
- results: durationResults,
1007
- vars: opts?.vars || [],
1008
- runtimeOptions: sanitizeRuntimeOptions(opts?.runtimeOptions),
1009
- prompts: opts?.completedPrompts || [],
1010
- isRedteam: config.redteam !== void 0
1011
- }).run();
1012
- for (const prompt of renderedPrompts) {
1013
- const label = prompt.label || prompt.display || prompt.raw;
1014
- const promptId = hashPrompt(prompt);
1015
- await tx.insert(promptsTable).values({
1016
- id: promptId,
1017
- prompt: label
1018
- }).onConflictDoNothing().run();
1019
- await tx.insert(evalsToPromptsTable).values({
1020
- evalId,
1021
- promptId
1022
- }).onConflictDoNothing().run();
1023
- logger.debug(`Inserting prompt ${promptId}`);
1024
- }
1025
- if (opts?.results && opts.results.length > 0) {
1026
- const res = await tx.insert(evalResultsTable).values(opts.results?.map((r) => ({
1027
- ...r,
1028
- metadata: persistTraceMetadata(persistRepeatMetadata(r.metadata, r.repeatIndex, r.repeatGroupId), r.traceId, r.evaluationId),
1029
- evalId,
1030
- id: crypto.randomUUID()
1031
- }))).run();
1032
- logger.debug(`Inserted ${res.rowsAffected} eval results`);
1033
- }
1034
- await tx.insert(datasetsTable).values({
1035
- id: datasetId,
1036
- tests: config.tests
1037
- }).onConflictDoNothing().run();
1038
- await tx.insert(evalsToDatasetsTable).values({
1039
- evalId,
1040
- datasetId
1041
- }).onConflictDoNothing().run();
1042
- logger.debug(`Inserting dataset ${datasetId}`);
1043
- if (config.tags) for (const [tagKey, tagValue] of Object.entries(config.tags)) {
1044
- const tagId = sha256(`${tagKey}:${tagValue}`);
1045
- await tx.insert(tagsTable).values({
1046
- id: tagId,
1047
- name: tagKey,
1048
- value: tagValue
1049
- }).onConflictDoNothing().run();
1050
- await tx.insert(evalsToTagsTable).values({
1051
- evalId,
1052
- tagId
1053
- }).onConflictDoNothing().run();
1054
- logger.debug(`Inserting tag ${tagId}`);
1055
- }
1056
- });
1057
- invalidateEvaluationCache(evalId);
1058
- return new Eval(config, {
1059
- id: evalId,
1060
- author,
1061
- createdAt,
1062
- persisted: true,
1063
- runtimeOptions: sanitizeRuntimeOptions(opts?.runtimeOptions),
1064
- durationMs: opts?.durationMs,
1065
- generationDurationMs: opts?.generationDurationMs,
1066
- evaluationDurationMs: opts?.evaluationDurationMs
1067
- });
1068
- }
1069
- constructor(config, opts) {
1070
- const createdAt = opts?.createdAt || /* @__PURE__ */ new Date();
1071
- this.createdAt = createdAt.getTime();
1072
- this.id = opts?.id || createEvalId(createdAt);
1073
- this.author = opts?.author ?? null;
1074
- this.config = config;
1075
- this.results = [];
1076
- this.prompts = opts?.prompts || [];
1077
- this.datasetId = opts?.datasetId;
1078
- this.persisted = opts?.persisted || false;
1079
- this._resultsLoaded = false;
1080
- this.vars = opts?.vars || [];
1081
- this.runtimeOptions = opts?.runtimeOptions;
1082
- this.durationMs = opts?.durationMs;
1083
- this.generationDurationMs = opts?.generationDurationMs;
1084
- this.evaluationDurationMs = opts?.evaluationDurationMs;
1085
- }
1086
- version() {
1087
- /**
1088
- * Version 3 is the denormalized version of where the table and results are stored on the eval object.
1089
- * Version 4 is the normalized version where the results are stored in another database table and the table for visualization is generated by the app.
1090
- */
1091
- return this.oldResults && "table" in this.oldResults ? 3 : 4;
1092
- }
1093
- useOldResults() {
1094
- return this.version() < 4;
1095
- }
1096
- setTable(table) {
1097
- invariant(this.version() < 4, "Eval is not version 3");
1098
- invariant(this.oldResults, "Old results not found");
1099
- this.oldResults.table = table;
1100
- }
1101
- async save() {
1102
- const db = await getDb();
1103
- const updateObj = {
1104
- config: sanitizeTracingConfigForPersistence(this.config),
1105
- isRedteam: this.config.redteam !== void 0,
1106
- prompts: this.prompts,
1107
- description: this.config.description,
1108
- author: this.author,
1109
- updatedAt: getCurrentTimestamp(),
1110
- vars: Array.from(this.vars),
1111
- runtimeOptions: sanitizeRuntimeOptions(this.runtimeOptions)
1112
- };
1113
- if (this.useOldResults()) {
1114
- invariant(this.oldResults, "Old results not found");
1115
- updateObj.results = this.oldResults;
1116
- } else if (this.durationMs !== void 0 || this.generationDurationMs !== void 0 || this.evaluationDurationMs !== void 0) {
1117
- let expr = sql`CASE WHEN json_valid(${evalsTable.results}) AND json_type(${evalsTable.results}) = 'object' THEN ${evalsTable.results} ELSE '{}' END`;
1118
- if (this.durationMs !== void 0) expr = sql`json_set(${expr}, '$.durationMs', ${this.durationMs})`;
1119
- if (this.generationDurationMs !== void 0) expr = sql`json_set(${expr}, '$.generationDurationMs', ${this.generationDurationMs})`;
1120
- if (this.evaluationDurationMs !== void 0) expr = sql`json_set(${expr}, '$.evaluationDurationMs', ${this.evaluationDurationMs})`;
1121
- updateObj.results = expr;
1122
- }
1123
- await db.update(evalsTable).set(updateObj).where(eq(evalsTable.id, this.id)).run();
1124
- notifyEvaluationChanged(this.id);
1125
- this.persisted = true;
1126
- }
1127
- setVars(vars) {
1128
- this.vars = vars;
1129
- }
1130
- addVar(varName) {
1131
- this.vars.push(varName);
1132
- }
1133
- /** Sets the evaluation phase duration and recomputes the total. Called by the evaluator. */
1134
- setDurationMs(durationMs) {
1135
- if (!Number.isFinite(durationMs) || durationMs < 0) return;
1136
- this.evaluationDurationMs = durationMs;
1137
- this.durationMs = (this.generationDurationMs ?? 0) + durationMs;
1138
- }
1139
- /** Sets the generation phase duration and recomputes the total. Called by doRedteamRun. */
1140
- setGenerationDurationMs(durationMs) {
1141
- if (!Number.isFinite(durationMs) || durationMs < 0) return;
1142
- this.generationDurationMs = durationMs;
1143
- this.durationMs = durationMs + (this.evaluationDurationMs ?? 0);
1144
- }
1145
- getPrompts() {
1146
- if (this.useOldResults()) {
1147
- invariant(this.oldResults, "Old results not found");
1148
- return this.oldResults.table?.head.prompts || [];
1149
- }
1150
- return this.prompts;
1151
- }
1152
- async getTable() {
1153
- if (this.useOldResults()) return this.oldResults?.table || {
1154
- head: {
1155
- prompts: [],
1156
- vars: []
1157
- },
1158
- body: []
1159
- };
1160
- return convertResultsToTable(await this.toResultsFile());
1161
- }
1162
- async addResult(result) {
1163
- if (result.repeatGroupId !== void 0) this.observedRepeatedResults = true;
1164
- const httpStatus = result.response?.metadata?.http?.status;
1165
- if (this.observedTargetErrorStatus === void 0 && typeof httpStatus === "number" && isNonTransientHttpStatus(httpStatus)) this.observedTargetErrorStatus = httpStatus;
1166
- const newResult = await EvalResult.createFromEvaluateResult(this.id, result, { persist: this.persisted });
1167
- if (!this.persisted) this.results.push(newResult);
1168
- if (this.persisted) notifyEvaluationChanged(this.id);
1169
- }
1170
- recordFinalJsonlResult(result) {
1171
- this.finalJsonlResults.set(getResultIndexKey(result), result);
1172
- if (result.repeatGroupId !== void 0) this.observedRepeatedResults = true;
1173
- }
1174
- getFinalJsonlResults() {
1175
- return Array.from(this.finalJsonlResults.values());
1176
- }
1177
- async getObservedRepeatStability() {
1178
- return this.observedRepeatedResults ? this.getRepeatStability() : void 0;
1179
- }
1180
- recordResultPersistenceFailure(result) {
1181
- this.resultPersistenceFailed = true;
1182
- const key = getResultIndexKey(result);
1183
- this.failedResults.set(key, result);
1184
- this.failedEvalResults.delete(key);
1185
- }
1186
- hasResultPersistenceFailure(result) {
1187
- return this.failedResults.has(getResultIndexKey(result));
1188
- }
1189
- async getFailedResultsByTestIdx(testIdx) {
1190
- const reconstructed = [];
1191
- for (const [key, row] of this.failedResults) {
1192
- if (row.testIdx !== testIdx) continue;
1193
- let evalResult = this.failedEvalResults.get(key);
1194
- if (!evalResult) {
1195
- evalResult = await EvalResult.createFromEvaluateResult(this.id, row, { persist: false });
1196
- this.failedEvalResults.set(key, evalResult);
1197
- }
1198
- reconstructed.push(evalResult);
1199
- }
1200
- return reconstructed;
1201
- }
1202
- async *fetchResultsBatched(batchSize = 100) {
1203
- if (!this.persisted) {
1204
- for (let offset = 0; offset < this.results.length; offset += batchSize) yield this.results.slice(offset, offset + batchSize);
1205
- return;
1206
- }
1207
- for await (const batch of EvalResult.findManyByEvalIdBatched(this.id, { batchSize })) yield batch;
1208
- }
1209
- async getResultsCount() {
1210
- return getCachedResultsCount(this.id);
1211
- }
1212
- /**
1213
- * Get the total count of all result rows for this eval.
1214
- * Use this when iterating over all results (e.g., for sharing progress).
1215
- * This may be higher than getResultsCount() when there are multiple prompts/providers.
1216
- */
1217
- async getTotalResultRowCount() {
1218
- return getTotalResultRowCount(this.id);
1219
- }
1220
- /**
1221
- * Find a non-transient HTTP error status from evaluation results.
1222
- * Returns the first non-transient status (401, 403, 404, 500, 501) found, or undefined.
1223
- *
1224
- * For persisted evals: Uses efficient O(1) database query with LIMIT 1, and also scans
1225
- * the rows that could not be saved, which the database does not have.
1226
- * For non-persisted evals: Falls back to scanning in-memory results.
1227
- */
1228
- async findTargetErrorStatus() {
1229
- const scan = (results) => {
1230
- for (const result of results) {
1231
- const status = result.response?.metadata?.http?.status;
1232
- if (typeof status === "number" && isNonTransientHttpStatus(status)) return status;
1233
- }
1234
- };
1235
- const scanInMemory = () => scan(this.results);
1236
- if (!this.persisted) return scanInMemory();
1237
- const unsavedStatus = scan(this.failedResults.values());
1238
- try {
1239
- return (await (await getDb()).select({ httpStatus: sql`CAST(json_extract(${evalResultsTable.response}, '$.metadata.http.status') AS INTEGER)` }).from(evalResultsTable).where(and(eq(evalResultsTable.evalId, this.id), sql`json_extract(${evalResultsTable.response}, '$.metadata.http.status') IN (${sql.join(NON_TRANSIENT_HTTP_STATUSES.map((s) => sql`${s}`), sql`, `)})`)).limit(1).get())?.httpStatus ?? unsavedStatus;
1240
- } catch {
1241
- return scanInMemory() ?? unsavedStatus ?? this.observedTargetErrorStatus;
1242
- }
1243
- }
1244
- async fetchResultsByTestIdx(testIdx) {
1245
- return await EvalResult.findManyByEvalId(this.id, { testIdx });
1246
- }
1247
- /**
1248
- * CRITICAL: Builds the WHERE SQL clause for filtering results.
1249
- * This is the single source of truth for all filtering logic.
1250
- * Used by both queryTestIndices() (pagination) and getFilteredMetrics().
1251
- *
1252
- * SECURITY: This method uses Drizzle's sql template strings for parameterized queries
1253
- * to prevent SQL injection. All user-provided values are passed as parameters,
1254
- * not interpolated into the SQL string.
1255
- *
1256
- * Any changes to filter logic MUST be made here to ensure consistency
1257
- * between displayed rows and calculated metrics.
1258
- *
1259
- * @returns SQL fragment (without "WHERE" keyword) that can be used in queries
1260
- */
1261
- buildFilterWhereSql(opts) {
1262
- const mode = opts.filterMode ?? "all";
1263
- const conditions = [sql`eval_id = ${this.id}`];
1264
- if (mode === "errors") conditions.push(sql`failure_reason = ${ResultFailureReason.ERROR}`);
1265
- else if (mode === "failures") conditions.push(sql`success = 0 AND failure_reason != ${ResultFailureReason.ERROR}`);
1266
- else if (mode === "passes") conditions.push(sql`success = 1`);
1267
- else if (mode === "highlights") conditions.push(sql`json_extract(grading_result, '$.comment') LIKE ${"!highlight%"}`);
1268
- else if (mode === "user-rated") conditions.push(sql`
1269
- EXISTS (
1270
- SELECT 1
1271
- FROM json_each(grading_result, '$.componentResults')
1272
- WHERE json_extract(value, '$.assertion.type') = ${HUMAN_ASSERTION_TYPE}
1273
- )
1274
- `);
1275
- if (opts.filters && opts.filters.length > 0) {
1276
- const filterConditions = [];
1277
- opts.filters.forEach((filter) => {
1278
- let parsedFilter;
1279
- try {
1280
- parsedFilter = JSON.parse(filter);
1281
- } catch {
1282
- logger.warn("Ignoring malformed eval filter JSON");
1283
- return;
1284
- }
1285
- if (!parsedFilter || typeof parsedFilter !== "object" || Array.isArray(parsedFilter)) {
1286
- logger.warn("Ignoring invalid eval filter");
1287
- return;
1288
- }
1289
- const { logicOperator, type, operator, value, field } = parsedFilter;
1290
- if (typeof type !== "string" || typeof operator !== "string" || logicOperator !== void 0 && typeof logicOperator !== "string" || field !== void 0 && typeof field !== "string" || value !== void 0 && typeof value !== "string" && typeof value !== "number") {
1291
- logger.warn("Ignoring invalid eval filter fields");
1292
- return;
1293
- }
1294
- let condition = null;
1295
- if (type === "metric") {
1296
- const metricKey = field || value;
1297
- if (!metricKey) {
1298
- logger.warn("Invalid metric filter: missing field and value", { filter });
1299
- return;
1300
- }
1301
- const numericValue = typeof value === "number" ? value : Number.parseFloat(String(value));
1302
- if (operator === "is_defined" || operator === "equals" && !field) condition = sql`EXISTS (
1303
- SELECT 1
1304
- FROM json_each(named_scores)
1305
- WHERE json_each.key = ${metricKey}
1306
- )`;
1307
- else if (Number.isFinite(numericValue)) {
1308
- if (operator === "eq") condition = sql`EXISTS (
1309
- SELECT 1
1310
- FROM json_each(named_scores)
1311
- WHERE json_each.key = ${metricKey}
1312
- AND CAST(json_each.value AS REAL) = ${numericValue}
1313
- )`;
1314
- else if (operator === "neq") condition = sql`EXISTS (
1315
- SELECT 1
1316
- FROM json_each(named_scores)
1317
- WHERE json_each.key = ${metricKey}
1318
- AND CAST(json_each.value AS REAL) != ${numericValue}
1319
- )`;
1320
- else if (operator === "gt") condition = sql`EXISTS (
1321
- SELECT 1
1322
- FROM json_each(named_scores)
1323
- WHERE json_each.key = ${metricKey}
1324
- AND CAST(json_each.value AS REAL) > ${numericValue}
1325
- )`;
1326
- else if (operator === "gte") condition = sql`EXISTS (
1327
- SELECT 1
1328
- FROM json_each(named_scores)
1329
- WHERE json_each.key = ${metricKey}
1330
- AND CAST(json_each.value AS REAL) >= ${numericValue}
1331
- )`;
1332
- else if (operator === "lt") condition = sql`EXISTS (
1333
- SELECT 1
1334
- FROM json_each(named_scores)
1335
- WHERE json_each.key = ${metricKey}
1336
- AND CAST(json_each.value AS REAL) < ${numericValue}
1337
- )`;
1338
- else if (operator === "lte") condition = sql`EXISTS (
1339
- SELECT 1
1340
- FROM json_each(named_scores)
1341
- WHERE json_each.key = ${metricKey}
1342
- AND CAST(json_each.value AS REAL) <= ${numericValue}
1343
- )`;
1344
- } else {
1345
- logger.warn("Invalid numeric value in metric filter", {
1346
- metricKey,
1347
- value,
1348
- numericValue,
1349
- operator
1350
- });
1351
- return;
1352
- }
1353
- } else if (type === "metadata" && field) {
1354
- if (operator === "equals") condition = sql`EXISTS (
1355
- SELECT 1
1356
- FROM json_each(metadata)
1357
- WHERE json_each.key = ${field}
1358
- AND json_each.value = ${value}
1359
- )`;
1360
- else if (operator === "contains") condition = sql`EXISTS (
1361
- SELECT 1
1362
- FROM json_each(metadata)
1363
- WHERE json_each.key = ${field}
1364
- AND json_each.value LIKE ${`%${value}%`}
1365
- )`;
1366
- else if (operator === "not_contains") condition = sql`NOT EXISTS (
1367
- SELECT 1
1368
- FROM json_each(metadata)
1369
- WHERE json_each.key = ${field}
1370
- AND json_each.value LIKE ${`%${value}%`}
1371
- )`;
1372
- else if (operator === "exists") condition = sql`EXISTS (
1373
- SELECT 1
1374
- FROM json_each(metadata)
1375
- WHERE json_each.key = ${field}
1376
- AND LENGTH(TRIM(COALESCE(json_each.value, ''))) > 0
1377
- )`;
1378
- } else if (type === "plugin" && typeof value === "string") {
1379
- const isCategory = Object.keys(PLUGIN_CATEGORIES).includes(value);
1380
- if (operator === "equals") {
1381
- if (isCategory) condition = sql`json_extract(metadata, '$.pluginId') LIKE ${`${value}:%`}`;
1382
- else condition = sql`json_extract(metadata, '$.pluginId') = ${value}`;
1383
- } else if (operator === "not_equals") {
1384
- if (isCategory) condition = sql`(json_extract(metadata, '$.pluginId') IS NULL OR (json_extract(metadata, '$.pluginId') != ${value} AND json_extract(metadata, '$.pluginId') NOT LIKE ${`${value}:%`}))`;
1385
- else condition = sql`(json_extract(metadata, '$.pluginId') IS NULL OR json_extract(metadata, '$.pluginId') != ${value})`;
1386
- }
1387
- } else if (type === "strategy" && operator === "equals") {
1388
- if (value === "basic") condition = sql`(json_extract(metadata, '$.strategyId') IS NULL OR json_extract(metadata, '$.strategyId') = '')`;
1389
- else condition = sql`json_extract(metadata, '$.strategyId') = ${value}`;
1390
- } else if (type === "severity" && operator === "equals") {
1391
- const explicit = sql`json_extract(metadata, '$.severity') = ${value}`;
1392
- const severityMap = getRiskCategorySeverityMap(this.config?.redteam?.plugins);
1393
- const pluginConditions = Object.entries(severityMap).filter(([, severity]) => severity === value).map(([pluginId]) => pluginId).map((pluginId) => {
1394
- return pluginId.includes(":") ? sql`json_extract(metadata, '$.pluginId') = ${pluginId}` : sql`json_extract(metadata, '$.pluginId') LIKE ${`${pluginId}:%`}`;
1395
- });
1396
- if (pluginConditions.length > 0) {
1397
- const pluginMatch = sql.join(pluginConditions, sql` OR `);
1398
- const overrideOk = sql`(json_extract(metadata, '$.severity') IS NULL OR json_extract(metadata, '$.severity') = ${value})`;
1399
- condition = sql`(${explicit} OR ((${pluginMatch}) AND ${overrideOk}))`;
1400
- } else condition = sql`(${explicit})`;
1401
- } else if (type === "policy" && operator === "equals") condition = sql`(named_scores LIKE '%PolicyViolation:%' AND named_scores LIKE ${`%${value}%`})`;
1402
- if (condition) filterConditions.push({
1403
- condition,
1404
- logicOperator: logicOperator || "AND"
1405
- });
1406
- });
1407
- const filterClause = combineFilterConditions(filterConditions);
1408
- if (filterClause) conditions.push(sql`(${filterClause})`);
1409
- }
1410
- if (opts.searchQuery && opts.searchQuery.trim() !== "") {
1411
- const searchPattern = `%${opts.searchQuery}%`;
1412
- const searchConditions = [
1413
- sql`response LIKE ${searchPattern}`,
1414
- sql`json_extract(grading_result, '$.reason') LIKE ${searchPattern}`,
1415
- sql`json_extract(grading_result, '$.comment') LIKE ${searchPattern}`,
1416
- sql`json_extract(named_scores, '$') LIKE ${searchPattern}`,
1417
- sql`json_remove(metadata, ${`$.${PROMPTFOO_METADATA_KEY}`}) LIKE ${searchPattern}`,
1418
- sql`json_extract(test_case, '$.vars') LIKE ${searchPattern}`,
1419
- sql`json_extract(test_case, '$.metadata') LIKE ${searchPattern}`
1420
- ];
1421
- const searchClause = sql.join(searchConditions, sql` OR `);
1422
- conditions.push(sql`(${searchClause})`);
1423
- }
1424
- return sql.join(conditions, sql` AND `);
1425
- }
1426
- /**
1427
- * Private helper method to build filter conditions and query for test indices.
1428
- *
1429
- * SECURITY: Uses parameterized queries via Drizzle's sql template strings
1430
- * to prevent SQL injection attacks.
1431
- */
1432
- async queryTestIndices(opts) {
1433
- const db = await getDb();
1434
- const offset = opts.offset ?? 0;
1435
- const limit = opts.limit ?? 50;
1436
- const whereSql = this.buildFilterWhereSql({
1437
- filterMode: opts.filterMode,
1438
- searchQuery: opts.searchQuery,
1439
- filters: opts.filters
1440
- });
1441
- const filteredCountQuery = sql`
1442
- SELECT COUNT(DISTINCT test_idx) as count
1443
- FROM eval_results
1444
- WHERE ${whereSql}
1445
- `;
1446
- const countStart = Date.now();
1447
- const countResult = await db.get(filteredCountQuery);
1448
- const countEnd = Date.now();
1449
- logger.debug(`Count query took ${countEnd - countStart}ms`);
1450
- const filteredCount = countResult?.count || 0;
1451
- const idxQuery = sql`
1452
- SELECT DISTINCT test_idx
1453
- FROM eval_results
1454
- WHERE ${whereSql}
1455
- ORDER BY test_idx
1456
- LIMIT ${limit}
1457
- OFFSET ${offset}
1458
- `;
1459
- const idxStart = Date.now();
1460
- const rows = await db.all(idxQuery);
1461
- const idxEnd = Date.now();
1462
- logger.debug(`Index query took ${idxEnd - idxStart}ms`);
1463
- return {
1464
- testIndices: rows.map((row) => row.test_idx),
1465
- filteredCount
1466
- };
1467
- }
1468
- /**
1469
- * CRITICAL: Calculates metrics for filtered results.
1470
- * Uses the SAME WHERE clause as queryTestIndices() to ensure consistency.
1471
- *
1472
- * SECURITY: Uses parameterized SQL queries to prevent SQL injection.
1473
- *
1474
- * This method is called from the API route when filters are active to provide
1475
- * metrics that accurately reflect the filtered dataset.
1476
- *
1477
- * @returns Array of PromptMetrics, one per prompt
1478
- */
1479
- async getFilteredMetrics(opts) {
1480
- const whereSql = this.buildFilterWhereSql(opts);
1481
- return calculateFilteredMetrics({
1482
- evalId: this.id,
1483
- numPrompts: this.prompts.length,
1484
- whereSql
1485
- });
1486
- }
1487
- async getTablePage(opts) {
1488
- const totalCount = await this.getResultsCount();
1489
- let testIndices;
1490
- let filteredCount;
1491
- if (opts.testIndices && opts.testIndices.length > 0) {
1492
- testIndices = opts.testIndices;
1493
- filteredCount = testIndices.length;
1494
- } else {
1495
- const hasComplexFilters = opts.filters && opts.filters.length > 0;
1496
- let queryResult;
1497
- if (hasComplexFilters) {
1498
- logger.debug("Using original query for complex filters");
1499
- queryResult = await this.queryTestIndices({
1500
- offset: opts.offset,
1501
- limit: opts.limit,
1502
- filterMode: opts.filterMode,
1503
- searchQuery: opts.searchQuery,
1504
- filters: opts.filters
1505
- });
1506
- } else {
1507
- logger.debug("Using optimized query for table page");
1508
- queryResult = await queryTestIndicesOptimized(this.id, {
1509
- offset: opts.offset,
1510
- limit: opts.limit,
1511
- filterMode: opts.filterMode,
1512
- searchQuery: opts.searchQuery,
1513
- filters: opts.filters
1514
- });
1515
- }
1516
- testIndices = queryResult.testIndices;
1517
- filteredCount = queryResult.filteredCount;
1518
- }
1519
- const varsStart = Date.now();
1520
- const vars = Array.from(this.vars);
1521
- const varsEnd = Date.now();
1522
- logger.debug(`Vars query took ${varsEnd - varsStart}ms`);
1523
- const body = [];
1524
- const bodyStart = Date.now();
1525
- if (testIndices.length === 0) {
1526
- const bodyEnd = Date.now();
1527
- logger.debug(`Body query took ${bodyEnd - bodyStart}ms`);
1528
- return {
1529
- head: {
1530
- prompts: this.prompts,
1531
- vars
1532
- },
1533
- body,
1534
- totalCount,
1535
- filteredCount,
1536
- id: this.id
1537
- };
1538
- }
1539
- const allResults = await EvalResult.findManyByEvalIdAndTestIndices(this.id, testIndices);
1540
- if (allResults.some((result) => {
1541
- const hasSessionIds = Array.isArray(result.metadata?.sessionIds) && result.metadata.sessionIds.length > 0;
1542
- const hasSessionId = Boolean(result.metadata?.sessionId);
1543
- const notInVars = !result.testCase?.vars?.sessionId;
1544
- return (hasSessionIds || hasSessionId) && notInVars;
1545
- }) && !vars.includes("sessionId")) vars.push("sessionId");
1546
- const resultsByTestIdx = /* @__PURE__ */ new Map();
1547
- for (const result of allResults) {
1548
- if (!resultsByTestIdx.has(result.testIdx)) resultsByTestIdx.set(result.testIdx, []);
1549
- resultsByTestIdx.get(result.testIdx).push(result);
1550
- }
1551
- for (const testIdx of testIndices) {
1552
- const results = resultsByTestIdx.get(testIdx) || [];
1553
- if (results.length > 0) body.push(convertTestResultsToTableRow(results, vars));
1554
- }
1555
- const bodyEnd = Date.now();
1556
- logger.debug(`Body query took ${bodyEnd - bodyStart}ms`);
1557
- return {
1558
- head: {
1559
- prompts: this.prompts,
1560
- vars
1561
- },
1562
- body,
1563
- totalCount,
1564
- filteredCount,
1565
- id: this.id
1566
- };
1567
- }
1568
- async addPrompts(prompts) {
1569
- this.prompts = prompts;
1570
- if (this.persisted) {
1571
- await (await getDb()).update(evalsTable).set({ prompts }).where(eq(evalsTable.id, this.id)).run();
1572
- notifyEvaluationChanged(this.id);
1573
- }
1574
- }
1575
- async setResults(results) {
1576
- if (this.persisted && results.length > 0) {
1577
- await (await getDb()).insert(evalResultsTable).values(results.map((r) => ({
1578
- ...r,
1579
- metadata: persistTraceMetadata(persistRepeatMetadata(r.metadata, r.repeatIndex, r.repeatGroupId), r.traceId, r.evaluationId),
1580
- evalId: this.id
1581
- }))).run();
1582
- notifyEvaluationChanged(this.id);
1583
- }
1584
- if (this.persisted) this.clearResults();
1585
- else {
1586
- this.results = results;
1587
- this._resultsLoaded = true;
1588
- }
1589
- }
1590
- async loadResults() {
1591
- if (this.persisted) this.results = await EvalResult.findManyByEvalId(this.id);
1592
- this._resultsLoaded = true;
1593
- }
1594
- async getResults() {
1595
- if (this.useOldResults()) {
1596
- invariant(this.oldResults, "Old results not found");
1597
- return this.oldResults.results;
1598
- }
1599
- await this.loadResults();
1600
- this._resultsLoaded = true;
1601
- return this.results;
1602
- }
1603
- clearResults() {
1604
- this.results = [];
1605
- this._resultsLoaded = false;
1606
- }
1607
- getStats() {
1608
- const stats = {
1609
- successes: 0,
1610
- failures: 0,
1611
- errors: 0,
1612
- tokenUsage: createEmptyTokenUsage(),
1613
- durationMs: this.durationMs,
1614
- generationDurationMs: this.generationDurationMs,
1615
- evaluationDurationMs: this.evaluationDurationMs
1616
- };
1617
- for (const prompt of this.prompts) {
1618
- stats.successes += prompt.metrics?.testPassCount ?? 0;
1619
- stats.failures += prompt.metrics?.testFailCount ?? 0;
1620
- stats.errors += prompt.metrics?.testErrorCount ?? 0;
1621
- if (prompt.metrics?.testCacheHitCount) stats.cacheHits = (stats.cacheHits ?? 0) + prompt.metrics.testCacheHitCount;
1622
- accumulateTokenUsage(stats.tokenUsage, prompt.metrics?.tokenUsage);
1623
- }
1624
- accumulateGenerationTokenUsage(stats.tokenUsage, this.config.metadata?.generationAccounting?.tokenUsage);
1625
- return stats;
1626
- }
1627
- async getRepeatStability() {
1628
- if (this.useOldResults()) return calculateRepeatStability(this.oldResults?.results ?? []);
1629
- const calculator = new RepeatStabilityCalculator();
1630
- const recovered = new Map(this.failedResults);
1631
- for (const [key, result] of this.failedEvalResults) recovered.set(key, result);
1632
- for (const [key, result] of this.finalJsonlResults) recovered.set(key, result);
1633
- for await (const batch of this.fetchResultsBatched()) for (const result of batch) {
1634
- const key = getResultIndexKey(result);
1635
- calculator.addResult(recovered.get(key) ?? result);
1636
- recovered.delete(key);
1637
- }
1638
- calculator.addResults(recovered.values());
1639
- return calculator.getSummary();
1640
- }
1641
- async toEvaluateSummary() {
1642
- if (this.useOldResults()) {
1643
- invariant(this.oldResults, "Old results not found");
1644
- return {
1645
- version: 2,
1646
- timestamp: new Date(this.createdAt).toISOString(),
1647
- results: this.oldResults.results,
1648
- table: this.oldResults.table,
1649
- stats: this.oldResults.stats
1650
- };
1651
- }
1652
- if (this.results.length === 0) await this.loadResults();
1653
- const stats = await this.getStats();
1654
- const stripFlags = getStripFlags(this.config.env);
1655
- const prompts = this.prompts.map((p) => projectPrompt(p, stripFlags.shouldStripPromptText));
1656
- const calculator = new RepeatStabilityCalculator();
1657
- const results = this.results.map((result) => {
1658
- const exported = result.toEvaluateResult(stripFlags);
1659
- calculator.addResult({
1660
- ...exported,
1661
- gradingResult: result.gradingResult
1662
- });
1663
- return exported;
1664
- });
1665
- const repeatStability = calculator.getSummary();
1666
- return {
1667
- version: 3,
1668
- timestamp: new Date(this.createdAt).toISOString(),
1669
- prompts,
1670
- results,
1671
- stats,
1672
- ...repeatStability && { repeatStability }
1673
- };
1674
- }
1675
- async getTraces() {
1676
- try {
1677
- return (await getTraceStore().getTracesByEvaluation(this.id)).map((trace) => ({
1678
- traceId: trace.traceId,
1679
- evaluationId: trace.evaluationId,
1680
- testCaseId: trace.testCaseId,
1681
- metadata: trace.metadata,
1682
- spans: (trace.spans || []).map((span) => {
1683
- const durationMs = span.endTime && span.startTime ? (span.endTime - span.startTime) / 1e6 : void 0;
1684
- const statusCode = span.statusCode === 1 ? "ok" : span.statusCode === 2 ? "error" : "unset";
1685
- return {
1686
- spanId: span.spanId,
1687
- parentSpanId: span.parentSpanId,
1688
- name: span.name,
1689
- kind: span.kind || "unspecified",
1690
- startTime: span.startTime,
1691
- endTime: span.endTime,
1692
- durationMs,
1693
- attributes: span.attributes || {},
1694
- status: {
1695
- code: statusCode,
1696
- message: span.statusMessage
1697
- },
1698
- depth: 0,
1699
- events: span.events || []
1700
- };
1701
- })
1702
- }));
1703
- } catch (error) {
1704
- logger.debug(`Failed to fetch traces for eval ${this.id}: ${error}`);
1705
- return [];
1706
- }
1707
- }
1708
- async toResultsFile() {
1709
- const traces = await this.getTraces();
1710
- const stripFlags = getStripFlags(this.config.env);
1711
- return {
1712
- version: this.version(),
1713
- createdAt: new Date(this.createdAt).toISOString(),
1714
- results: await this.toEvaluateSummary(),
1715
- config: sanitizeConfigForOutput(this.config, stripFlags),
1716
- author: this.author || null,
1717
- prompts: this.getPrompts().map((prompt) => projectPrompt(prompt, stripFlags.shouldStripPromptText)),
1718
- ...this.vars.length > 0 && { vars: [...this.vars] },
1719
- datasetId: this.datasetId || null,
1720
- ...traces.length > 0 && { traces: projectTracesForOutput(traces, stripFlags) }
1721
- };
1722
- }
1723
- async delete({ notify = true } = {}) {
1724
- await (await getDb()).transaction(async (tx) => {
1725
- await deleteTraceRecordsForEvals(tx, [this.id]);
1726
- await tx.delete(evalsToDatasetsTable).where(eq(evalsToDatasetsTable.evalId, this.id)).run();
1727
- await tx.delete(evalsToPromptsTable).where(eq(evalsToPromptsTable.evalId, this.id)).run();
1728
- await tx.delete(evalsToTagsTable).where(eq(evalsToTagsTable.evalId, this.id)).run();
1729
- await tx.delete(evalResultsTable).where(eq(evalResultsTable.evalId, this.id)).run();
1730
- await tx.delete(evalsTable).where(eq(evalsTable.id, this.id)).run();
1731
- });
1732
- if (notify) notifyEvaluationsDeleted([this.id]);
1733
- }
1734
- /**
1735
- * Creates a deep copy of this eval including all results.
1736
- * Uses batching to avoid memory exhaustion on large evals.
1737
- * @param description - Optional description for the new eval
1738
- * @param distinctTestCount - Optional pre-computed test count to avoid duplicate query
1739
- */
1740
- async copy(description, distinctTestCount) {
1741
- const newEvalId = createEvalId(/* @__PURE__ */ new Date());
1742
- const copyDescription = description || `${this.description || "Evaluation"} (Copy)`;
1743
- const testCount = distinctTestCount ?? await this.getResultsCount();
1744
- logger.info("Starting eval copy", {
1745
- sourceEvalId: this.id,
1746
- targetEvalId: newEvalId,
1747
- distinctTestCount: testCount
1748
- });
1749
- const newConfig = structuredClone(sanitizeTracingConfigForPersistence(this.config));
1750
- newConfig.description = copyDescription;
1751
- const newPrompts = structuredClone(this.prompts);
1752
- const newVars = this.vars ? structuredClone(this.vars) : [];
1753
- const author = getAuthor();
1754
- const db = await getDb();
1755
- let copiedCount = 0;
1756
- await db.transaction(async (tx) => {
1757
- await tx.insert(evalsTable).values({
1758
- id: newEvalId,
1759
- createdAt: Date.now(),
1760
- author,
1761
- description: copyDescription,
1762
- config: sanitizeTracingConfigForPersistence(newConfig),
1763
- results: {},
1764
- prompts: newPrompts,
1765
- vars: newVars,
1766
- runtimeOptions: sanitizeRuntimeOptions(this.runtimeOptions),
1767
- isRedteam: newConfig.redteam !== void 0
1768
- }).run();
1769
- const promptRels = await tx.select().from(evalsToPromptsTable).where(eq(evalsToPromptsTable.evalId, this.id)).all();
1770
- if (promptRels.length > 0) await tx.insert(evalsToPromptsTable).values(promptRels.map((rel) => ({
1771
- evalId: newEvalId,
1772
- promptId: rel.promptId
1773
- }))).onConflictDoNothing().run();
1774
- if (this.config.tags) for (const [tagKey, tagValue] of Object.entries(this.config.tags)) {
1775
- const tagId = sha256(`${tagKey}:${tagValue}`);
1776
- await tx.insert(tagsTable).values({
1777
- id: tagId,
1778
- name: tagKey,
1779
- value: tagValue
1780
- }).onConflictDoNothing().run();
1781
- await tx.insert(evalsToTagsTable).values({
1782
- evalId: newEvalId,
1783
- tagId
1784
- }).onConflictDoNothing().run();
1785
- }
1786
- const datasetRel = await tx.select().from(evalsToDatasetsTable).where(eq(evalsToDatasetsTable.evalId, this.id)).limit(1).all();
1787
- if (datasetRel.length > 0) await tx.insert(evalsToDatasetsTable).values({
1788
- evalId: newEvalId,
1789
- datasetId: datasetRel[0].datasetId
1790
- }).onConflictDoNothing().run();
1791
- const BATCH_SIZE = 1e3;
1792
- let offset = 0;
1793
- while (true) {
1794
- const batch = await tx.select().from(evalResultsTable).where(eq(evalResultsTable.evalId, this.id)).orderBy(evalResultsTable.id).limit(BATCH_SIZE).offset(offset).all();
1795
- if (batch.length === 0) break;
1796
- const now = Date.now();
1797
- const copiedResults = batch.map((result) => ({
1798
- ...result,
1799
- id: crypto.randomUUID(),
1800
- evalId: newEvalId,
1801
- createdAt: now,
1802
- metadata: stripTraceLinkageFromMetadata(result.metadata),
1803
- updatedAt: now
1804
- }));
1805
- await tx.insert(evalResultsTable).values(copiedResults).run();
1806
- copiedCount += batch.length;
1807
- offset += BATCH_SIZE;
1808
- logger.debug("Copied batch of eval results", {
1809
- sourceEvalId: this.id,
1810
- targetEvalId: newEvalId,
1811
- batchSize: batch.length,
1812
- rowsCopied: copiedCount,
1813
- distinctTestCount: testCount
1814
- });
1815
- }
1816
- });
1817
- notifyEvaluationChanged(newEvalId);
1818
- logger.info("Eval copy completed successfully", {
1819
- sourceEvalId: this.id,
1820
- targetEvalId: newEvalId,
1821
- rowsCopied: copiedCount,
1822
- distinctTestCount: testCount
1823
- });
1824
- return await Eval.findById(newEvalId);
1825
- }
1826
- get shared() {
1827
- return this._shared;
1828
- }
1829
- set shared(shared) {
1830
- this._shared = shared;
1831
- }
1832
- };
1833
- /**
1834
- * Queries summaries of all evals, optionally for a given dataset.
1835
- *
1836
- * @param datasetId - An optional dataset ID to filter by.
1837
- * @param type - An optional eval type to filter by.
1838
- * @param includeProviders - An optional flag to include providers in the summary.
1839
- * @returns A list of eval summaries.
1840
- */
1841
- async function getEvalSummaries(datasetId, type, includeProviders = false) {
1842
- const db = await getDb();
1843
- const whereClauses = [];
1844
- if (datasetId) whereClauses.push(eq(evalsToDatasetsTable.datasetId, datasetId));
1845
- if (type) {
1846
- if (type === "redteam") whereClauses.push(eq(evalsTable.isRedteam, true));
1847
- else whereClauses.push(eq(evalsTable.isRedteam, false));
1848
- }
1849
- /**
1850
- * Deserialize the evals. A few things to note:
1851
- *
1852
- * - Test statistics are derived from the prompt metrics as this is the only reliable source of truth
1853
- * that's written to the evals table.
1854
- */
1855
- return (await db.select({
1856
- evalId: evalsTable.id,
1857
- createdAt: evalsTable.createdAt,
1858
- description: evalsTable.description,
1859
- datasetId: evalsToDatasetsTable.datasetId,
1860
- isRedteam: evalsTable.isRedteam,
1861
- prompts: evalsTable.prompts,
1862
- config: includeProviders ? evalsTable.config : sql`NULL`
1863
- }).from(evalsTable).leftJoin(evalsToDatasetsTable, eq(evalsTable.id, evalsToDatasetsTable.evalId)).where(and(...whereClauses)).orderBy(desc(evalsTable.createdAt), desc(evalsTable.id)).all()).map((result) => {
1864
- const passCount = result.prompts?.reduce((memo, prompt) => {
1865
- return memo + (prompt.metrics?.testPassCount ?? 0);
1866
- }, 0) ?? 0;
1867
- const failCount = result.prompts?.reduce((memo, prompt) => {
1868
- return memo + (prompt.metrics?.testFailCount ?? 0);
1869
- }, 0) ?? 0;
1870
- const testCounts = result.prompts?.map((p) => {
1871
- return (p.metrics?.testPassCount ?? 0) + (p.metrics?.testFailCount ?? 0) + (p.metrics?.testErrorCount ?? 0);
1872
- }) ?? [0];
1873
- const testCount = testCounts.length > 0 ? testCounts[0] : 0;
1874
- const testRunCount = testCount * (result.prompts?.length ?? 0);
1875
- const deserializedProviders = [];
1876
- const providers = result.config?.providers;
1877
- if (includeProviders) {
1878
- if (typeof providers === "string") deserializedProviders.push({
1879
- id: providers,
1880
- label: null
1881
- });
1882
- else if (Array.isArray(providers)) providers.forEach((p) => {
1883
- if (typeof p === "string") deserializedProviders.push({
1884
- id: p,
1885
- label: null
1886
- });
1887
- else if (typeof p === "object" && p) {
1888
- const keys = Object.keys(p);
1889
- if (keys.length === 1 && !("id" in p)) {
1890
- const providerId = keys[0];
1891
- const providerConfig = p[providerId];
1892
- deserializedProviders.push({
1893
- id: providerId,
1894
- label: providerConfig.label ?? null
1895
- });
1896
- } else deserializedProviders.push({
1897
- id: p.id ?? "unknown",
1898
- label: p.label ?? null
1899
- });
1900
- }
1901
- });
1902
- }
1903
- return {
1904
- evalId: result.evalId,
1905
- createdAt: result.createdAt,
1906
- description: result.description,
1907
- numTests: testCount,
1908
- datasetId: result.datasetId,
1909
- isRedteam: Boolean(result.isRedteam),
1910
- passRate: testRunCount > 0 ? passCount / testRunCount * 100 : 0,
1911
- label: result.description ? `${result.description} (${result.evalId})` : result.evalId,
1912
- providers: deserializedProviders,
1913
- attackSuccessRate: type === "redteam" ? calculateAttackSuccessRate(testRunCount, failCount) : void 0
1914
- };
1915
- });
1916
- }
1917
- //#endregion
1918
- export { createEvalId as a, deleteTraceRecordsForEvals as c, combineFilterConditions as i, EvalQueries as n, escapeJsonPathKey as o, buildSafeJsonPath as r, getEvalSummaries as s, Eval as t };
1919
-
1920
- //# sourceMappingURL=eval-pC4qCvLw.js.map