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
@@ -0,0 +1,1928 @@
1
+ import { v as BaseTokenUsageSchema } from "./shared-DS0YmCOx.js";
2
+ import { G as getEnvInt, M as isProviderOptions, R as safeJsonStringify, U as getEnvBool, W as getEnvFloat, j as isApiProvider, o as logger, rt as state } from "./logger-CNHLbG5Y.js";
3
+ import { t as invariant } from "./invariant-CHP0zrix.js";
4
+ import { K as sanitizeProviderIdForLog } from "./dataUrl-DUSr-ZvI.js";
5
+ import { A as isTransientConnectionError, I as cloudConfig, N as parseRateLimitHeaders, O as isHttpRateLimitError, P as parseRetryAfter, l as withFetchRetryContext } from "./fetch-BG_Jl7ty.js";
6
+ import "./tables-CpHZEDfI.js";
7
+ import "./shared-CAXFSQC3.js";
8
+ import { S as isCallerAbortError } from "./shared-BnN4RWgk.js";
9
+ import { s as isLoggedIntoCloud } from "./accounts-vJBPs89d.js";
10
+ import { X as isSafeCost, Z as isSafeTokenCount } from "./util-CeGgoYs1.js";
11
+ import { h as remoteGenerationContextPayload } from "./remoteGeneration-CAtvamG6.js";
12
+ import { n as isBlobStorageEnabled, t as extractAndStoreBinaryData } from "./extractor-wLjTmXQ-.js";
13
+ import { a as accumulateGradingResponseTokenUsage, c as accumulateTokenUsage, d as createEmptyTokenUsage, s as accumulateResponseTokenUsage } from "./tokenUsageUtils-C51DmahQ.js";
14
+ import { a as createResponseHeadersObserver, c as preserveResponseHeadersObserverError, i as composeResponseHeadersObservers, l as preserveResponseHeadersObserverErrorResponse, o as isResponseHeadersObserverError, s as isResponseHeadersObserverErrorResponse, t as OpenAiChatCompletionProvider } from "./chat-zCWuBKAj.js";
15
+ import { t as PromptfooChatCompletionProvider } from "./promptfoo-Bhpm7sH6.js";
16
+ import { o as transform, r as TransformInputType } from "./transform-gJysRqu9.js";
17
+ import { AsyncLocalStorage } from "node:async_hooks";
18
+ import { createHash, randomUUID } from "crypto";
19
+ import { EventEmitter } from "events";
20
+ //#region src/scheduler/providerCallExecutionContext.ts
21
+ const providerCallExecutionContext = new AsyncLocalStorage();
22
+ const providerCallTracingContext = new AsyncLocalStorage();
23
+ function getProviderCallExecutionContext() {
24
+ return providerCallExecutionContext.getStore();
25
+ }
26
+ function withProviderCallExecutionContext(context, fn) {
27
+ return providerCallExecutionContext.run(context, fn);
28
+ }
29
+ function runProviderCallWithAbort(call, signal) {
30
+ if (!signal) return call();
31
+ signal.throwIfAborted();
32
+ return new Promise((resolve, reject) => {
33
+ let settled = false;
34
+ let pendingAbort;
35
+ const finish = (complete) => {
36
+ if (settled) return;
37
+ settled = true;
38
+ signal.removeEventListener("abort", onAbort);
39
+ if (pendingAbort) clearImmediate(pendingAbort);
40
+ complete();
41
+ };
42
+ const onAbort = () => {
43
+ pendingAbort = setImmediate(() => finish(() => reject(signal.reason)));
44
+ };
45
+ signal.addEventListener("abort", onAbort, { once: true });
46
+ try {
47
+ call().then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
48
+ } catch (error) {
49
+ finish(() => reject(error));
50
+ }
51
+ });
52
+ }
53
+ function getProviderCallTracingContext() {
54
+ return providerCallTracingContext.getStore();
55
+ }
56
+ function withProviderCallTracingContext(tracingContext, fn) {
57
+ return providerCallTracingContext.run(tracingContext, fn);
58
+ }
59
+ //#endregion
60
+ //#region src/scheduler/types.ts
61
+ /**
62
+ * Shared types for the scheduler module.
63
+ */
64
+ const HTTP_429_RE = /\b429\b/;
65
+ /**
66
+ * Default rate limit detection for ProviderResponse.
67
+ *
68
+ * Returns true when a result/error indicates a *retryable* rate limit. Hard
69
+ * quota failures (billing exhaustion, daily limits) match the same `429` /
70
+ * `too many requests` substrings but must NOT be classified as retryable —
71
+ * doing so amplifies load against an exhausted account, which is the exact
72
+ * regression PR 8896 closes at the transport layer. The result-path check
73
+ * here mirrors that fail-fast contract for providers that fold the
74
+ * structured error into `ProviderResponse.error`.
75
+ */
76
+ function isProviderResponseRateLimited(result, error) {
77
+ if (isResponseHeadersObserverErrorResponse(result)) return false;
78
+ const responseError = result?.metadata?.errorOrigin === "tool" ? void 0 : result?.error;
79
+ if (result?.metadata?.rateLimitRetryable === false || result?.metadata?.rateLimitKind === "quota") return false;
80
+ if (result?.metadata?.rateLimitKind === "rate_limit") return true;
81
+ if (isHttpRateLimitError(error) && error.kind === "quota") return false;
82
+ if (responseError?.includes("Quota exceeded:")) return false;
83
+ if (error?.message?.includes("Quota exceeded:")) return false;
84
+ return Boolean(result?.metadata?.http?.status === 429 || HTTP_429_RE.test(responseError ?? "") || responseError?.toLowerCase?.().includes?.("rate limit") || HTTP_429_RE.test(error?.message ?? "") || error?.message?.toLowerCase().includes("rate limit") || error?.message?.toLowerCase().includes("too many requests"));
85
+ }
86
+ /**
87
+ * Extract rate limit headers from ProviderResponse.
88
+ * Headers can be at metadata.http.headers or metadata.headers.
89
+ */
90
+ function getProviderResponseHeaders(result) {
91
+ return result?.metadata?.http?.headers || result?.metadata?.headers;
92
+ }
93
+ //#endregion
94
+ //#region src/scheduler/providerWrapper.ts
95
+ /**
96
+ * Provider wrapper that adds rate limiting to any ApiProvider.
97
+ *
98
+ * Use this to wrap providers before passing them to redteam/assertion
99
+ * code paths that bypass the main evaluator.
100
+ */
101
+ /**
102
+ * Symbol to mark providers that have already been wrapped.
103
+ * Prevents double-wrapping which could cause issues.
104
+ */
105
+ const WRAPPED_SYMBOL = Symbol.for("promptfoo.rateLimitWrapped");
106
+ const TOKEN_USAGE_FIELDS = [
107
+ "prompt",
108
+ "completion",
109
+ "cached",
110
+ "total"
111
+ ];
112
+ const COMPLETION_DETAIL_FIELDS = [
113
+ "reasoning",
114
+ "acceptedPrediction",
115
+ "rejectedPrediction",
116
+ "cacheReadInputTokens",
117
+ "cacheCreationInputTokens"
118
+ ];
119
+ function addSafeTokenMetric(current, value) {
120
+ if (!isSafeTokenCount(value)) return;
121
+ const total = (current ?? 0) + value;
122
+ return Number.isSafeInteger(total) ? total : void 0;
123
+ }
124
+ function accumulateRetryTokenUsage(target, response) {
125
+ const usage = response.tokenUsage;
126
+ for (const field of TOKEN_USAGE_FIELDS) {
127
+ const total = addSafeTokenMetric(target[field], usage?.[field]);
128
+ if (total !== void 0) target[field] = total;
129
+ }
130
+ for (const field of COMPLETION_DETAIL_FIELDS) {
131
+ const value = usage?.completionDetails?.[field];
132
+ const total = addSafeTokenMetric(target.completionDetails?.[field], value);
133
+ if (total !== void 0) {
134
+ target.completionDetails ??= {};
135
+ target.completionDetails[field] = total;
136
+ }
137
+ }
138
+ const requests = response.cached ? 0 : isSafeTokenCount(usage?.numRequests) ? usage.numRequests : 1;
139
+ const totalRequests = addSafeTokenMetric(target.numRequests, requests);
140
+ if (totalRequests !== void 0) target.numRequests = totalRequests;
141
+ }
142
+ /**
143
+ * Check if a provider is already wrapped with rate limiting.
144
+ */
145
+ function isRateLimitWrapped(provider) {
146
+ return provider[WRAPPED_SYMBOL] === true;
147
+ }
148
+ /**
149
+ * Create rate limit detection options for ProviderResponse.
150
+ * Shared between providerWrapper and evaluator for consistency.
151
+ */
152
+ function createProviderRateLimitOptions(abortSignal) {
153
+ return {
154
+ ...abortSignal && { abortSignal },
155
+ onRateLimitExhausted: (result, error) => result.error ? result : {
156
+ ...result,
157
+ error: error.message
158
+ },
159
+ getHeaders: (result) => result?.metadata?.rateLimitRetryable === false || result?.metadata?.rateLimitKind === "quota" ? void 0 : getProviderResponseHeaders(result),
160
+ isRateLimited: isProviderResponseRateLimited,
161
+ getRetryAfter: (result, error) => {
162
+ if (result?.metadata?.rateLimitRetryable === false) return;
163
+ const rawHeaders = getProviderResponseHeaders(result);
164
+ if (rawHeaders) {
165
+ const headers = {};
166
+ for (const [key, value] of Object.entries(rawHeaders)) headers[key.toLowerCase()] = value;
167
+ if (headers["retry-after-ms"]) {
168
+ const ms = Number.parseInt(headers["retry-after-ms"], 10);
169
+ if (Number.isFinite(ms) && ms >= 0) return ms;
170
+ }
171
+ if (headers["retry-after"]) {
172
+ const parsed = parseRetryAfter(headers["retry-after"]);
173
+ if (parsed !== null) return parsed;
174
+ }
175
+ }
176
+ const match = error?.message?.match(/\bretry after (\d+)\b/i);
177
+ if (match) {
178
+ const retryAfterMs = Number.parseInt(match[1], 10) * 1e3;
179
+ return Number.isFinite(retryAfterMs) ? retryAfterMs : void 0;
180
+ }
181
+ },
182
+ isRetryableResult: (result) => {
183
+ return result.metadata?.retryableErrorKind === "transient_availability";
184
+ },
185
+ finalizeResult: (result, retryResults) => {
186
+ if (retryResults.length === 0) return result;
187
+ const tokenUsage = {};
188
+ let combinedCost = 0;
189
+ let hasCost = false;
190
+ for (const response of [...retryResults, result]) {
191
+ accumulateRetryTokenUsage(tokenUsage, response);
192
+ if (isSafeCost(response.cost)) {
193
+ combinedCost += response.cost;
194
+ hasCost = true;
195
+ }
196
+ }
197
+ const resultWithoutCost = { ...result };
198
+ delete resultWithoutCost.cost;
199
+ return {
200
+ ...resultWithoutCost,
201
+ tokenUsage,
202
+ ...hasCost && Number.isFinite(combinedCost) && { cost: combinedCost }
203
+ };
204
+ }
205
+ };
206
+ }
207
+ /**
208
+ * Wrap a provider with rate limiting.
209
+ *
210
+ * The wrapped provider will use the registry for all callApi calls,
211
+ * automatically handling rate limits, retries, and adaptive concurrency.
212
+ *
213
+ * @param provider - The provider to wrap
214
+ * @param registry - The rate limit registry to use
215
+ * @returns A wrapped provider that applies rate limiting
216
+ */
217
+ function wrapProviderWithRateLimiting(provider, registry) {
218
+ if (isRateLimitWrapped(provider)) return provider;
219
+ const originalCallApi = provider.callApi.bind(provider);
220
+ const wrappedProvider = {
221
+ ...provider,
222
+ id: () => provider.id(),
223
+ callApi: async (prompt, context, options) => {
224
+ return registry.execute(provider, (onResponseHeaders) => originalCallApi(prompt, context, onResponseHeaders ? {
225
+ ...options,
226
+ onResponseHeaders: composeResponseHeadersObservers(onResponseHeaders, options?.onResponseHeaders)
227
+ } : options), createProviderRateLimitOptions(options?.abortSignal));
228
+ }
229
+ };
230
+ wrappedProvider[WRAPPED_SYMBOL] = true;
231
+ return wrappedProvider;
232
+ }
233
+ //#endregion
234
+ //#region src/blobs/remoteUpload.ts
235
+ function buildRemoteUploadTarget() {
236
+ if (getEnvBool("PROMPTFOO_DISABLE_SHARING")) return null;
237
+ const baseUrl = cloudConfig.getApiHost();
238
+ const authHeaders = cloudConfig.getAuthHeaders();
239
+ if (!baseUrl || !authHeaders || !isLoggedIntoCloud()) return null;
240
+ try {
241
+ return {
242
+ url: new URL("/api/blobs", baseUrl).toString(),
243
+ authHeaders
244
+ };
245
+ } catch (error) {
246
+ logger.debug("[RemoteBlob] Invalid remote blob URL", {
247
+ error: error instanceof Error ? error.message : String(error),
248
+ baseUrl
249
+ });
250
+ return null;
251
+ }
252
+ }
253
+ function shouldAttemptRemoteBlobUpload() {
254
+ return buildRemoteUploadTarget() !== null;
255
+ }
256
+ async function uploadBlobRemote(buffer, mimeType, context) {
257
+ const target = buildRemoteUploadTarget();
258
+ if (!target) return null;
259
+ try {
260
+ const { fetchWithProxy } = await import("./fetch-BG_Jl7ty.js").then((n) => n.i);
261
+ const response = await fetchWithProxy(target.url, {
262
+ method: "POST",
263
+ headers: {
264
+ "Content-Type": "application/json",
265
+ ...target.authHeaders
266
+ },
267
+ body: JSON.stringify({
268
+ data: buffer.toString("base64"),
269
+ mimeType,
270
+ context
271
+ })
272
+ });
273
+ if (response.status === 404 || response.status === 400) {
274
+ logger.debug("[RemoteBlob] Remote blob upload unavailable", { status: response.status });
275
+ return null;
276
+ }
277
+ if (!response.ok) {
278
+ const text = await response.text();
279
+ logger.debug("[RemoteBlob] Failed to upload blob", {
280
+ status: response.status,
281
+ statusText: response.statusText,
282
+ body: text
283
+ });
284
+ return null;
285
+ }
286
+ const data = await response.json();
287
+ if (!data?.ref?.hash) {
288
+ logger.debug("[RemoteBlob] Remote upload returned malformed response");
289
+ return null;
290
+ }
291
+ return data;
292
+ } catch (error) {
293
+ logger.debug("[RemoteBlob] Error uploading blob", { error: error instanceof Error ? error.message : String(error) });
294
+ return null;
295
+ }
296
+ }
297
+ //#endregion
298
+ //#region src/scheduler/adaptiveConcurrency.ts
299
+ const DEFAULT_MIN_CONCURRENCY = 1;
300
+ const BACKOFF_FACTOR = .5;
301
+ const RECOVERY_FACTOR = 1.5;
302
+ const RECOVERY_THRESHOLD = 5;
303
+ const WARNING_THRESHOLD = .1;
304
+ function concurrencyChange(previous, current, reason, changed = previous !== current) {
305
+ return {
306
+ changed,
307
+ previous,
308
+ current,
309
+ reason
310
+ };
311
+ }
312
+ /**
313
+ * Manages adaptive concurrency based on rate limit feedback.
314
+ *
315
+ * Recovery path with constants (initial=10, min=1):
316
+ * 1 → ceil(1.5) = 2 (5 successes)
317
+ * 2 → ceil(3.0) = 3 (5 successes)
318
+ * 3 → ceil(4.5) = 5 (5 successes)
319
+ * 5 → ceil(7.5) = 8 (5 successes)
320
+ * 8 → ceil(12) = 10 (5 successes, capped at initial)
321
+ *
322
+ * Total: 25 requests to fully recover from min=1 to initial=10
323
+ */
324
+ var AdaptiveConcurrency = class {
325
+ current;
326
+ initial;
327
+ min;
328
+ consecutiveSuccesses = 0;
329
+ constructor(initial, min = DEFAULT_MIN_CONCURRENCY) {
330
+ this.initial = initial;
331
+ this.current = initial;
332
+ this.min = Math.min(initial, Math.max(1, min));
333
+ }
334
+ /**
335
+ * Called on successful request.
336
+ * May increase concurrency after sustained success.
337
+ */
338
+ recordSuccess() {
339
+ this.consecutiveSuccesses++;
340
+ if (this.consecutiveSuccesses >= RECOVERY_THRESHOLD && this.current < this.initial) {
341
+ const previous = this.current;
342
+ this.current = Math.min(this.initial, Math.ceil(this.current * RECOVERY_FACTOR));
343
+ this.consecutiveSuccesses = 0;
344
+ return concurrencyChange(previous, this.current, "recovery");
345
+ }
346
+ return concurrencyChange(this.current, this.current, "recovery", false);
347
+ }
348
+ /**
349
+ * Called on rate limit (429).
350
+ * Reduces concurrency immediately.
351
+ */
352
+ recordRateLimit() {
353
+ this.consecutiveSuccesses = 0;
354
+ const previous = this.current;
355
+ this.current = Math.max(this.min, Math.floor(this.current * BACKOFF_FACTOR));
356
+ return concurrencyChange(previous, this.current, "ratelimit");
357
+ }
358
+ /**
359
+ * Called when approaching rate limit.
360
+ * Proactively reduces concurrency based on remaining ratio.
361
+ *
362
+ * Formula:
363
+ * - At 10% remaining: reduce to 60% of current
364
+ * - At 5% remaining: reduce to 40% of current
365
+ * - At 1% remaining: reduce to 20% of current
366
+ *
367
+ * Linear scaling: reductionFactor = 0.2 + (ratio / WARNING_THRESHOLD) * 0.4
368
+ */
369
+ recordApproachingLimit(ratio) {
370
+ const clampedRatio = Math.max(0, Math.min(1, ratio));
371
+ if (clampedRatio >= .1 || this.current <= this.min) return concurrencyChange(this.current, this.current, "proactive", false);
372
+ const previous = this.current;
373
+ const reductionFactor = .2 + clampedRatio / WARNING_THRESHOLD * .4;
374
+ this.current = Math.max(this.min, Math.floor(this.current * reductionFactor));
375
+ return concurrencyChange(previous, this.current, "proactive");
376
+ }
377
+ getCurrent() {
378
+ return this.current;
379
+ }
380
+ getMin() {
381
+ return this.min;
382
+ }
383
+ getInitial() {
384
+ return this.initial;
385
+ }
386
+ };
387
+ //#endregion
388
+ //#region src/scheduler/cancellation.ts
389
+ function throwIfAborted(signal) {
390
+ if (signal?.aborted) throw signal.reason;
391
+ }
392
+ function sleepWithAbort(ms, signal) {
393
+ return new Promise((resolve, reject) => {
394
+ throwIfAborted(signal);
395
+ const cleanup = () => {
396
+ clearTimeout(timer);
397
+ signal?.removeEventListener("abort", onAbort);
398
+ };
399
+ const onAbort = () => {
400
+ cleanup();
401
+ reject(signal?.reason);
402
+ };
403
+ const timer = setTimeout(() => {
404
+ cleanup();
405
+ resolve();
406
+ }, ms);
407
+ signal?.addEventListener("abort", onAbort, { once: true });
408
+ });
409
+ }
410
+ //#endregion
411
+ //#region src/scheduler/retryPolicy.ts
412
+ const DEFAULT_RETRY_POLICY = {
413
+ maxRetries: 3,
414
+ baseDelayMs: 1e3,
415
+ maxDelayMs: 6e4,
416
+ jitterFactor: .2
417
+ };
418
+ /**
419
+ * Calculate delay for retry attempt.
420
+ * Prefers server-specified Retry-After when available.
421
+ */
422
+ function getRetryDelay(attempt, policy, serverRetryAfterMs) {
423
+ if (serverRetryAfterMs !== void 0 && serverRetryAfterMs >= 0) {
424
+ if (serverRetryAfterMs === 0) return 0;
425
+ const jitter = serverRetryAfterMs * policy.jitterFactor * Math.random();
426
+ return Math.min(serverRetryAfterMs + jitter, policy.maxDelayMs);
427
+ }
428
+ const exponentialDelay = policy.baseDelayMs * Math.pow(2, attempt);
429
+ const jitter = exponentialDelay * policy.jitterFactor * Math.random();
430
+ return Math.min(exponentialDelay + jitter, policy.maxDelayMs);
431
+ }
432
+ /**
433
+ * Determine if we should retry a failed request.
434
+ */
435
+ function shouldRetry(attempt, error, isRateLimited, policy) {
436
+ if (attempt >= policy.maxRetries) return false;
437
+ if (isHttpRateLimitError(error) && error.kind === "quota") return false;
438
+ if (isRateLimited) return true;
439
+ if (error) {
440
+ const message = (error.message ?? "").toLowerCase();
441
+ return isTransientConnectionError(error) || message.includes("timeout") || message.startsWith("websocket request timed out after ") || message.includes("econnrefused") || message.includes("network") || message.includes("503") || message.includes("502") || message.includes("504");
442
+ }
443
+ return false;
444
+ }
445
+ //#endregion
446
+ //#region src/scheduler/slotQueue.ts
447
+ const DEFAULT_QUEUE_TIMEOUT_MS = 3e5;
448
+ /**
449
+ * Manages concurrency slots with FIFO queue for waiting requests.
450
+ *
451
+ * Race condition prevention:
452
+ * - All slot allocation goes through the queue
453
+ * - processQueue() is synchronous and runs atomically
454
+ * - No await between capacity check and increment
455
+ */
456
+ var SlotQueue = class {
457
+ activeCount = 0;
458
+ maxConcurrency;
459
+ minConcurrency;
460
+ waiting = [];
461
+ resetTimer = null;
462
+ queueTimeoutMs;
463
+ resetAt = null;
464
+ remainingRequests = null;
465
+ remainingTokens = null;
466
+ requestLimit = null;
467
+ tokenLimit = null;
468
+ onSlotAcquired;
469
+ onSlotReleased;
470
+ constructor(options) {
471
+ this.maxConcurrency = options.maxConcurrency;
472
+ this.minConcurrency = options.minConcurrency;
473
+ this.queueTimeoutMs = options.queueTimeoutMs ?? DEFAULT_QUEUE_TIMEOUT_MS;
474
+ this.onSlotAcquired = options.onSlotAcquired;
475
+ this.onSlotReleased = options.onSlotReleased;
476
+ }
477
+ /**
478
+ * Acquire a slot. All requests go through the queue to prevent race conditions.
479
+ * Returns when a slot is available and quota is not exhausted. An aborted signal stops
480
+ * the request from waiting, but a slot that is free immediately is still granted.
481
+ */
482
+ async acquire(requestId, abortSignal) {
483
+ return new Promise((resolve, reject) => {
484
+ let timeoutId;
485
+ const cleanup = () => {
486
+ if (timeoutId) clearTimeout(timeoutId);
487
+ abortSignal?.removeEventListener("abort", onAbort);
488
+ };
489
+ const removeAndReject = (error) => {
490
+ const index = this.waiting.indexOf(request);
491
+ if (index !== -1) {
492
+ this.waiting.splice(index, 1);
493
+ request.reject(error);
494
+ this.processQueue();
495
+ }
496
+ };
497
+ const onAbort = () => removeAndReject(abortSignal?.reason);
498
+ const request = {
499
+ id: requestId,
500
+ resolve: () => {
501
+ cleanup();
502
+ this.activeCount++;
503
+ this.onSlotAcquired?.(this.waiting.length);
504
+ resolve();
505
+ },
506
+ reject: (error) => {
507
+ cleanup();
508
+ reject(error);
509
+ }
510
+ };
511
+ if (this.queueTimeoutMs > 0) timeoutId = setTimeout(() => removeAndReject(/* @__PURE__ */ new Error(`Request ${requestId} timed out after ${this.queueTimeoutMs}ms in queue`)), this.queueTimeoutMs);
512
+ this.waiting.push(request);
513
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
514
+ this.processQueue();
515
+ if (abortSignal?.aborted) onAbort();
516
+ });
517
+ }
518
+ /**
519
+ * Release a slot and process next queued request.
520
+ */
521
+ release() {
522
+ if (this.activeCount <= 0) return;
523
+ this.activeCount--;
524
+ this.onSlotReleased?.(this.waiting.length);
525
+ this.processQueue();
526
+ }
527
+ /**
528
+ * Update rate limit state from parsed headers.
529
+ */
530
+ updateRateLimitState(parsed) {
531
+ if (parsed.remainingRequests !== void 0) this.remainingRequests = parsed.remainingRequests;
532
+ if (parsed.limitRequests !== void 0) this.requestLimit = parsed.limitRequests;
533
+ if (parsed.remainingTokens !== void 0) this.remainingTokens = parsed.remainingTokens;
534
+ if (parsed.limitTokens !== void 0) this.tokenLimit = parsed.limitTokens;
535
+ if (parsed.resetAt !== void 0) {
536
+ this.resetAt = parsed.resetAt;
537
+ this.scheduleResetProcessing();
538
+ }
539
+ }
540
+ /**
541
+ * Mark that a rate limit was hit.
542
+ * Only updates resetAt if we don't already have a later reset time.
543
+ * A selected absolute deadline takes precedence over a relative retry delay.
544
+ */
545
+ markRateLimited(retryAfterMs, selectedResetAt) {
546
+ this.remainingRequests = 0;
547
+ this.remainingTokens = 0;
548
+ let newResetAt = selectedResetAt;
549
+ if (newResetAt === void 0 && retryAfterMs !== void 0 && retryAfterMs >= 0) newResetAt = Date.now() + retryAfterMs;
550
+ if (newResetAt !== void 0) this.resetAt = Math.max(this.resetAt ?? newResetAt, newResetAt);
551
+ else if (this.resetAt === null) this.resetAt = Date.now() + 6e4;
552
+ this.scheduleResetProcessing();
553
+ }
554
+ /**
555
+ * Adjust max concurrency (called by adaptive algorithm).
556
+ */
557
+ setMaxConcurrency(value) {
558
+ this.maxConcurrency = Math.max(this.minConcurrency, value);
559
+ this.processQueue();
560
+ }
561
+ getMaxConcurrency() {
562
+ return this.maxConcurrency;
563
+ }
564
+ getActiveCount() {
565
+ return this.activeCount;
566
+ }
567
+ getQueueDepth() {
568
+ return this.waiting.length;
569
+ }
570
+ getResetAt() {
571
+ return this.resetAt;
572
+ }
573
+ /**
574
+ * Check if quota is exhausted (should wait for reset).
575
+ * Checks BOTH request AND token quotas.
576
+ *
577
+ * NOTE: This method has intentional side effects - it clears stale quota state
578
+ * when the reset time has passed. This ensures we don't block indefinitely on
579
+ * outdated rate limit info.
580
+ */
581
+ isQuotaExhausted() {
582
+ const now = Date.now();
583
+ if (this.resetAt && now >= this.resetAt) {
584
+ this.remainingRequests = null;
585
+ this.remainingTokens = null;
586
+ this.resetAt = null;
587
+ return false;
588
+ }
589
+ const quotaExhausted = (remaining) => remaining !== null && remaining <= 0 && this.resetAt && now < this.resetAt;
590
+ return !!(quotaExhausted(this.remainingRequests) || quotaExhausted(this.remainingTokens));
591
+ }
592
+ /**
593
+ * Schedule queue processing when rate limit window resets.
594
+ */
595
+ scheduleResetProcessing() {
596
+ clearTimeout(this.resetTimer ?? void 0);
597
+ this.resetTimer = null;
598
+ if (this.resetAt && this.waiting.length > 0) {
599
+ const delay = Math.max(0, this.resetAt - Date.now());
600
+ this.resetTimer = setTimeout(() => {
601
+ this.resetTimer = null;
602
+ this.remainingRequests = null;
603
+ this.remainingTokens = null;
604
+ this.resetAt = null;
605
+ this.processQueue();
606
+ }, delay);
607
+ }
608
+ }
609
+ /**
610
+ * Process queued requests up to available capacity.
611
+ * SYNCHRONOUS - no awaits, prevents race conditions.
612
+ */
613
+ processQueue() {
614
+ while (this.waiting.length > 0 && this.activeCount < this.maxConcurrency && !this.isQuotaExhausted()) this.waiting.shift().resolve();
615
+ if (this.waiting.length > 0 && this.isQuotaExhausted()) this.scheduleResetProcessing();
616
+ else if (this.resetTimer) {
617
+ clearTimeout(this.resetTimer);
618
+ this.resetTimer = null;
619
+ }
620
+ }
621
+ /**
622
+ * Check if approaching rate limit (for proactive throttling).
623
+ * Returns ratio of remaining/limit, or null if unknown.
624
+ */
625
+ getRemainingRatio() {
626
+ let requestRatio = null;
627
+ let tokenRatio = null;
628
+ if (this.remainingRequests !== null && this.requestLimit !== null && this.requestLimit > 0) requestRatio = this.remainingRequests / this.requestLimit;
629
+ if (this.remainingTokens !== null && this.tokenLimit !== null && this.tokenLimit > 0) tokenRatio = this.remainingTokens / this.tokenLimit;
630
+ return {
631
+ requests: requestRatio,
632
+ tokens: tokenRatio
633
+ };
634
+ }
635
+ /**
636
+ * Cleanup resources.
637
+ *
638
+ * Rejects any pending acquire() promises with 'Queue disposed' error.
639
+ * Callers should handle these rejections (e.g., via .catch() on acquire promises).
640
+ */
641
+ dispose() {
642
+ clearTimeout(this.resetTimer ?? void 0);
643
+ this.resetTimer = null;
644
+ const waiting = this.waiting;
645
+ this.waiting = [];
646
+ for (const request of waiting) request.reject(/* @__PURE__ */ new Error("Queue disposed"));
647
+ }
648
+ };
649
+ //#endregion
650
+ //#region src/scheduler/providerRateLimitState.ts
651
+ var RateLimitExhaustedError = class extends Error {
652
+ result;
653
+ constructor(message, result) {
654
+ super(message);
655
+ this.result = result;
656
+ this.name = "RateLimitExhaustedError";
657
+ }
658
+ };
659
+ /**
660
+ * Wraps a finalizeResult throw so the retry classifier below skips it: a
661
+ * finalizer failure is not provider work and must never trigger another call.
662
+ */
663
+ var ResultFinalizationError = class extends Error {
664
+ original;
665
+ constructor(original) {
666
+ super("finalizeResult failed");
667
+ this.original = original;
668
+ this.name = "ResultFinalizationError";
669
+ }
670
+ };
671
+ /**
672
+ * Manages rate limit state and retry logic for a single rate limit key.
673
+ */
674
+ var ProviderRateLimitState = class extends EventEmitter {
675
+ rateLimitKey;
676
+ slotQueue;
677
+ adaptiveConcurrency;
678
+ retryPolicy;
679
+ totalRequests = 0;
680
+ completedRequests = 0;
681
+ failedRequests = 0;
682
+ rateLimitHits = 0;
683
+ retriedRequests = 0;
684
+ /** Keep the latest 100 latency measurements for bounded metric sorting and storage. */
685
+ latencies = [];
686
+ hasLearnedLimits = false;
687
+ constructor(options) {
688
+ super();
689
+ this.rateLimitKey = options.rateLimitKey;
690
+ this.retryPolicy = options.retryPolicy ?? DEFAULT_RETRY_POLICY;
691
+ this.adaptiveConcurrency = new AdaptiveConcurrency(options.maxConcurrency, options.minConcurrency);
692
+ this.slotQueue = new SlotQueue({
693
+ maxConcurrency: options.maxConcurrency,
694
+ minConcurrency: options.minConcurrency,
695
+ queueTimeoutMs: options.queueTimeoutMs,
696
+ onSlotAcquired: (queueDepth) => {
697
+ this.emit("slot:acquired", {
698
+ rateLimitKey: this.rateLimitKey,
699
+ queueDepth
700
+ });
701
+ },
702
+ onSlotReleased: (queueDepth) => {
703
+ this.emit("slot:released", {
704
+ rateLimitKey: this.rateLimitKey,
705
+ queueDepth
706
+ });
707
+ }
708
+ });
709
+ }
710
+ /**
711
+ * Execute a call with rate limiting and retry logic.
712
+ */
713
+ async executeWithRetry(requestId, callFn, options) {
714
+ this.totalRequests++;
715
+ let attempt = 0;
716
+ const retryResults = [];
717
+ const retryPolicy = options.maxRetriesOverride === void 0 ? this.retryPolicy : {
718
+ ...this.retryPolicy,
719
+ maxRetries: options.maxRetriesOverride
720
+ };
721
+ try {
722
+ while (true) {
723
+ try {
724
+ await this.slotQueue.acquire(`${requestId}-${attempt}`, options.abortSignal);
725
+ } catch (acquireError) {
726
+ this.emit(options.abortSignal?.aborted ? "queue:cancelled" : "queue:timeout", {
727
+ rateLimitKey: this.rateLimitKey,
728
+ requestId,
729
+ error: String(acquireError)
730
+ });
731
+ throw acquireError;
732
+ }
733
+ let ownsSlot = true;
734
+ let observedHeaders;
735
+ const onResponseHeaders = createResponseHeadersObserver(this, ([headers, backoff], alreadyObserved) => {
736
+ if (ownsSlot) {
737
+ if (backoff) {
738
+ if (!alreadyObserved) {
739
+ this.updateFromHeaders(headers, false, backoff.resetAt);
740
+ this.handleRateLimit(void 0, backoff.resetAt);
741
+ }
742
+ } else {
743
+ observedHeaders = headers;
744
+ if (!alreadyObserved) this.updateFromHeaders(headers, false);
745
+ }
746
+ return true;
747
+ }
748
+ return alreadyObserved;
749
+ });
750
+ const releaseSlot = () => {
751
+ if (ownsSlot) {
752
+ ownsSlot = false;
753
+ this.slotQueue.release();
754
+ }
755
+ };
756
+ const startTime = Date.now();
757
+ let retryError;
758
+ let retryResult;
759
+ let isRateLimited;
760
+ let isRetryableResult = false;
761
+ let retryAfterMs;
762
+ try {
763
+ throwIfAborted(options.abortSignal);
764
+ const result = await callFn(onResponseHeaders);
765
+ retryResult = result;
766
+ const hasErrorResponse = result !== null && typeof result === "object" && "error" in result && typeof result.error === "string" && result.error.length > 0;
767
+ const hasRefusalResponse = result !== null && typeof result === "object" && "isRefusal" in result && result.isRefusal === true;
768
+ const headers = options.getHeaders?.(result);
769
+ const isObserverError = isResponseHeadersObserverErrorResponse(result);
770
+ isRateLimited = options.canRetry?.() !== false && !isObserverError && (options.isRateLimited?.(result, void 0) ?? false);
771
+ isRetryableResult = options.canRetry?.() !== false && !isObserverError && (options.isRetryableResult?.(result) ?? false);
772
+ retryAfterMs = options.getRetryAfter?.(result, void 0);
773
+ if (!isObserverError && headers && (headers !== observedHeaders || isRateLimited)) this.updateFromHeaders(headers, isRateLimited);
774
+ if (isRateLimited) this.handleRateLimit(retryAfterMs);
775
+ if (this.latencies.push(Date.now() - startTime) > 100) this.latencies.shift();
776
+ releaseSlot();
777
+ if (options.abortSignal?.aborted && hasErrorResponse) {
778
+ this.failedRequests++;
779
+ return result;
780
+ }
781
+ if (!isRateLimited && !isRetryableResult || options.abortSignal?.aborted && hasRefusalResponse) {
782
+ let finalizedResult;
783
+ try {
784
+ finalizedResult = options.finalizeResult?.(result, retryResults) ?? result;
785
+ } catch (finalizerError) {
786
+ throw new ResultFinalizationError(finalizerError);
787
+ }
788
+ this.applyConcurrencyChange(this.adaptiveConcurrency.recordSuccess());
789
+ this.completedRequests++;
790
+ return finalizedResult;
791
+ }
792
+ } catch (error) {
793
+ if (ownsSlot) {
794
+ if (this.latencies.push(Date.now() - startTime) > 100) this.latencies.shift();
795
+ }
796
+ if (isResponseHeadersObserverError(onResponseHeaders, error)) throw error;
797
+ if (error instanceof ResultFinalizationError) throw error.original;
798
+ if (options.abortSignal?.aborted && (error === options.abortSignal.reason || !(error instanceof Error)) || error instanceof Error && (error.name === "AbortError" || error.name === "AbortException")) throw error;
799
+ retryError = error;
800
+ isRateLimited = options.canRetry?.() !== false && (options.isRateLimited?.(void 0, retryError) ?? this.isRateLimitError(retryError));
801
+ retryAfterMs = options.getRetryAfter?.(void 0, retryError);
802
+ if (isRateLimited) this.handleRateLimit(retryAfterMs);
803
+ if (options.abortSignal?.aborted) throw error;
804
+ } finally {
805
+ releaseSlot();
806
+ }
807
+ if (options.canRetry?.() === false || !shouldRetry(attempt, retryError, isRateLimited || isRetryableResult, retryPolicy)) {
808
+ if (retryError) throw retryError;
809
+ if (isRetryableResult) {
810
+ const finalizedResult = options.finalizeResult?.(retryResult, retryResults) ?? retryResult;
811
+ this.failedRequests++;
812
+ return finalizedResult;
813
+ }
814
+ if (!options.onRateLimitExhausted && options.finalizeResult) {
815
+ const finalizedResult = options.finalizeResult(retryResult, retryResults);
816
+ this.failedRequests++;
817
+ return finalizedResult;
818
+ }
819
+ throw new RateLimitExhaustedError(`Rate limit exceeded for ${this.rateLimitKey} after ${attempt + 1} attempts`, retryResult);
820
+ }
821
+ if (isRetryableResult && retryResult !== void 0) retryResults.push(retryResult);
822
+ attempt++;
823
+ await sleepWithAbort(this.recordRetry(attempt, retryPolicy, retryAfterMs, isRateLimited ? "ratelimit" : "error"), options.abortSignal);
824
+ }
825
+ } catch (error) {
826
+ this.failedRequests++;
827
+ throw error;
828
+ }
829
+ }
830
+ recordRetry(attempt, retryPolicy, retryAfterMs, reason) {
831
+ this.retriedRequests++;
832
+ const delayMs = getRetryDelay(attempt, retryPolicy, retryAfterMs);
833
+ this.emit("request:retrying", {
834
+ rateLimitKey: this.rateLimitKey,
835
+ attempt,
836
+ delayMs,
837
+ reason
838
+ });
839
+ return delayMs;
840
+ }
841
+ /**
842
+ * Update state from response headers.
843
+ * @param headers - Response headers
844
+ * @param isRateLimited - Whether the response indicates a rate limit (e.g., HTTP 429).
845
+ * When false, retry-after headers are ignored to prevent incorrectly blocking the
846
+ * queue on successful responses from providers/proxies that include these headers.
847
+ */
848
+ updateFromHeaders(headers, isRateLimited, selectedResetAt) {
849
+ const parsed = parseRateLimitHeaders(headers);
850
+ if (selectedResetAt !== void 0) {
851
+ const existingResetAt = this.slotQueue.getResetAt();
852
+ parsed.resetAt = existingResetAt !== null && existingResetAt > Date.now() ? Math.max(existingResetAt, selectedResetAt) : selectedResetAt;
853
+ }
854
+ if (!this.hasLearnedLimits && (parsed.limitRequests !== void 0 || parsed.limitTokens !== void 0)) {
855
+ this.hasLearnedLimits = true;
856
+ this.emit("ratelimit:learned", {
857
+ rateLimitKey: this.rateLimitKey,
858
+ requestLimit: parsed.limitRequests,
859
+ tokenLimit: parsed.limitTokens
860
+ });
861
+ }
862
+ this.slotQueue.updateRateLimitState(parsed);
863
+ if (isRateLimited && parsed.retryAfterMs !== void 0) this.slotQueue.markRateLimited(parsed.retryAfterMs);
864
+ const ratios = this.slotQueue.getRemainingRatio();
865
+ const minRatio = Math.min(ratios.requests ?? 1, ratios.tokens ?? 1);
866
+ if (minRatio < .1) {
867
+ this.emit("ratelimit:warning", {
868
+ rateLimitKey: this.rateLimitKey,
869
+ requestRatio: ratios.requests,
870
+ tokenRatio: ratios.tokens
871
+ });
872
+ this.applyConcurrencyChange(this.adaptiveConcurrency.recordApproachingLimit(minRatio));
873
+ }
874
+ }
875
+ /**
876
+ * Handle rate limit hit.
877
+ * Delegates to SlotQueue which preserves existing resetAt from headers.
878
+ */
879
+ handleRateLimit(retryAfterMs, selectedResetAt) {
880
+ this.rateLimitHits++;
881
+ this.slotQueue.markRateLimited(retryAfterMs, selectedResetAt);
882
+ const change = this.adaptiveConcurrency.recordRateLimit();
883
+ this.applyConcurrencyChange(change);
884
+ this.emit("ratelimit:hit", {
885
+ rateLimitKey: this.rateLimitKey,
886
+ retryAfterMs,
887
+ resetAt: this.slotQueue.getResetAt(),
888
+ concurrencyChange: change
889
+ });
890
+ }
891
+ /**
892
+ * Apply concurrency change and emit appropriate event.
893
+ */
894
+ applyConcurrencyChange(change) {
895
+ if (change.changed) {
896
+ this.slotQueue.setMaxConcurrency(change.current);
897
+ this.emit(change.reason === "recovery" ? "concurrency:increased" : "concurrency:decreased", {
898
+ rateLimitKey: this.rateLimitKey,
899
+ ...change
900
+ });
901
+ }
902
+ }
903
+ /**
904
+ * Check if error is a rate limit error.
905
+ */
906
+ isRateLimitError(error) {
907
+ const message = (error.message ?? "").toLowerCase();
908
+ return message.includes("429") || message.includes("rate limit") || message.includes("too many requests");
909
+ }
910
+ /**
911
+ * Get current queue depth without sorting latencies.
912
+ * Use this for frequent checks instead of getMetrics().
913
+ */
914
+ getQueueDepth() {
915
+ return this.slotQueue.getQueueDepth();
916
+ }
917
+ getMetrics() {
918
+ const sorted = [...this.latencies].sort((a, b) => a - b);
919
+ return {
920
+ rateLimitKey: this.rateLimitKey,
921
+ activeRequests: this.slotQueue.getActiveCount(),
922
+ maxConcurrency: this.slotQueue.getMaxConcurrency(),
923
+ queueDepth: this.slotQueue.getQueueDepth(),
924
+ totalRequests: this.totalRequests,
925
+ completedRequests: this.completedRequests,
926
+ failedRequests: this.failedRequests,
927
+ rateLimitHits: this.rateLimitHits,
928
+ retriedRequests: this.retriedRequests,
929
+ avgLatencyMs: sorted.length > 0 ? sorted.reduce((a, b) => a + b, 0) / sorted.length : 0,
930
+ p50LatencyMs: sorted[Math.floor((sorted.length - 1) * .5)] ?? 0,
931
+ p99LatencyMs: sorted[Math.floor((sorted.length - 1) * .99)] ?? 0
932
+ };
933
+ }
934
+ dispose() {
935
+ this.slotQueue.dispose();
936
+ this.removeAllListeners();
937
+ }
938
+ };
939
+ //#endregion
940
+ //#region src/scheduler/rateLimitKey.ts
941
+ /**
942
+ * Generate a rate limit key that identifies a unique rate limit pool.
943
+ * Same provider with different API keys/regions get different keys.
944
+ */
945
+ function getRateLimitKey(provider) {
946
+ const providerId = provider.id();
947
+ const config = provider.config || {};
948
+ const relevantConfig = {};
949
+ if (config.apiKey && config.apiKey.length > 4) relevantConfig.apiKeyTail = config.apiKey.slice(-4);
950
+ if (config.apiBaseUrl) relevantConfig.apiBaseUrl = config.apiBaseUrl;
951
+ if (config.region) relevantConfig.region = config.region;
952
+ if (config.organization) relevantConfig.organization = config.organization;
953
+ const configParts = Object.entries(relevantConfig).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${v}`).join("|");
954
+ if (configParts)
955
+ /**
956
+ * Hash a string using SHA-256.
957
+ * Returns first 12 chars of hex digest (48 bits).
958
+ */
959
+ return `${providerId}[${createHash("sha256").update(configParts).digest("hex").slice(0, 12)}]`;
960
+ return providerId;
961
+ }
962
+ //#endregion
963
+ //#region src/scheduler/rateLimitRegistry.ts
964
+ /**
965
+ * Per-eval registry that manages rate limit state for all providers.
966
+ * NOT a singleton - create one per evaluation context.
967
+ */
968
+ var RateLimitRegistry = class extends EventEmitter {
969
+ states = /* @__PURE__ */ new Map();
970
+ maxConcurrency;
971
+ minConcurrency;
972
+ queueTimeoutMs;
973
+ enabled;
974
+ constructor(options) {
975
+ super();
976
+ this.maxConcurrency = options.maxConcurrency;
977
+ this.minConcurrency = options.minConcurrency ?? getEnvInt("PROMPTFOO_MIN_CONCURRENCY", 1);
978
+ this.queueTimeoutMs = options.queueTimeoutMs ?? getEnvInt("PROMPTFOO_SCHEDULER_QUEUE_TIMEOUT_MS", 3e5);
979
+ this.enabled = !getEnvBool("PROMPTFOO_DISABLE_ADAPTIVE_SCHEDULER", false);
980
+ }
981
+ /**
982
+ * Execute a provider call with rate limiting and retries.
983
+ *
984
+ * Note: No idempotency tracking. Each call is independent.
985
+ * The single integration point (evaluator) ensures no double-wrapping.
986
+ */
987
+ async execute(provider, callFn, options) {
988
+ const providerMaxRetries = getProviderMaxRetries(provider);
989
+ if (!this.enabled) return withFetchRetryContext(providerMaxRetries, () => runProviderCallWithAbort(callFn, options?.abortSignal));
990
+ const rateLimitKey = getRateLimitKey(provider);
991
+ const parentContext = getProviderCallExecutionContext();
992
+ if (parentContext?.rateLimitProvider && getRateLimitKey(parentContext.rateLimitProvider) !== rateLimitKey) parentContext.onNestedScheduledCall?.();
993
+ let nestedCallStarted = false;
994
+ if (!this.states.has(rateLimitKey)) {
995
+ const state = new ProviderRateLimitState({
996
+ rateLimitKey,
997
+ maxConcurrency: this.maxConcurrency,
998
+ minConcurrency: this.minConcurrency,
999
+ queueTimeoutMs: this.queueTimeoutMs
1000
+ });
1001
+ state.on("ratelimit:hit", (data) => this.emit("ratelimit:hit", data));
1002
+ state.on("ratelimit:warning", (data) => this.emit("ratelimit:warning", data));
1003
+ state.on("ratelimit:learned", (data) => this.emit("ratelimit:learned", data));
1004
+ state.on("concurrency:increased", (data) => this.emit("concurrency:increased", data));
1005
+ state.on("concurrency:decreased", (data) => this.emit("concurrency:decreased", data));
1006
+ state.on("request:retrying", (data) => this.emit("request:retrying", data));
1007
+ this.states.set(rateLimitKey, state);
1008
+ }
1009
+ const state = this.states.get(rateLimitKey);
1010
+ const requestId = `${rateLimitKey}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
1011
+ this.emit("request:started", {
1012
+ rateLimitKey,
1013
+ requestId,
1014
+ queueDepth: state.getQueueDepth()
1015
+ });
1016
+ const run = () => state.executeWithRetry(requestId, (onResponseHeaders) => {
1017
+ const executionContext = getProviderCallExecutionContext();
1018
+ return executionContext ? withProviderCallExecutionContext({
1019
+ ...executionContext,
1020
+ rateLimitRegistry: this,
1021
+ rateLimitProvider: provider,
1022
+ onNestedScheduledCall: () => {
1023
+ nestedCallStarted = true;
1024
+ }
1025
+ }, () => callFn(onResponseHeaders)) : callFn(onResponseHeaders);
1026
+ }, {
1027
+ abortSignal: options?.abortSignal,
1028
+ getHeaders: (result) => nestedCallStarted ? void 0 : options?.getHeaders?.(result),
1029
+ isRateLimited: options?.isRateLimited,
1030
+ isRetryableResult: options?.isRetryableResult,
1031
+ finalizeResult: options?.finalizeResult,
1032
+ onRateLimitExhausted: options?.onRateLimitExhausted,
1033
+ canRetry: () => !nestedCallStarted,
1034
+ getRetryAfter: options?.getRetryAfter,
1035
+ maxRetriesOverride: provider.handlesOwnRetries ? 0 : providerMaxRetries
1036
+ });
1037
+ try {
1038
+ const result = await withFetchRetryContext(providerMaxRetries, () => runProviderCallWithAbort(run, options?.abortSignal));
1039
+ this.emit("request:completed", {
1040
+ rateLimitKey,
1041
+ requestId
1042
+ });
1043
+ return result;
1044
+ } catch (error) {
1045
+ this.emit("request:failed", {
1046
+ rateLimitKey,
1047
+ requestId,
1048
+ error: String(error)
1049
+ });
1050
+ if (error instanceof RateLimitExhaustedError && options?.onRateLimitExhausted) return options.onRateLimitExhausted(error.result, error);
1051
+ throw error;
1052
+ }
1053
+ }
1054
+ /**
1055
+ * Get metrics for all tracked providers.
1056
+ */
1057
+ getMetrics() {
1058
+ const metrics = {};
1059
+ for (const [key, state] of this.states) metrics[key] = state.getMetrics();
1060
+ return metrics;
1061
+ }
1062
+ /**
1063
+ * Cleanup all resources.
1064
+ */
1065
+ dispose() {
1066
+ for (const state of this.states.values()) state.dispose();
1067
+ this.states.clear();
1068
+ this.removeAllListeners();
1069
+ }
1070
+ };
1071
+ /**
1072
+ * Read the provider's configured maxRetries value, tolerating numeric strings
1073
+ * (e.g. from environment overrides) and rejecting invalid values.
1074
+ *
1075
+ * Returning `undefined` means "fall back to defaults" — distinct from `0`, which
1076
+ * means "disable retries". Invalid user-supplied values (negatives, floats,
1077
+ * non-numeric strings) are logged so config typos aren't silently ignored.
1078
+ */
1079
+ function getProviderMaxRetries(provider) {
1080
+ const raw = provider.config && typeof provider.config === "object" ? provider.config.maxRetries : void 0;
1081
+ if (raw === void 0) return;
1082
+ if (typeof raw === "number" && Number.isInteger(raw) && raw >= 0) return raw;
1083
+ if (typeof raw === "string") {
1084
+ const trimmed = raw.trim();
1085
+ if (/^\d+$/.test(trimmed)) {
1086
+ const parsed = Number(trimmed);
1087
+ if (Number.isSafeInteger(parsed)) return parsed;
1088
+ }
1089
+ }
1090
+ logger.warn("[RateLimit] Ignoring invalid provider.config.maxRetries; expected a non-negative integer.", {
1091
+ maxRetries: raw,
1092
+ providerId: sanitizeProviderIdForLog(provider.id())
1093
+ });
1094
+ }
1095
+ //#endregion
1096
+ //#region src/util/tokenUsage.ts
1097
+ /**
1098
+ * A utility class for tracking token usage across an evaluation.
1099
+ *
1100
+ * @deprecated Use OpenTelemetry tracing instead for per-call token tracking.
1101
+ * This class provides only cumulative totals and will be removed in a future version.
1102
+ *
1103
+ * For new implementations, use the OTEL-based tracing infrastructure:
1104
+ * - Enable tracing with `PROMPTFOO_OTEL_ENABLED=true`
1105
+ * - Token usage is automatically captured as GenAI semantic convention span attributes
1106
+ *
1107
+ * @see src/tracing/genaiTracer.ts for the new tracing implementation
1108
+ */
1109
+ var TokenUsageTracker = class TokenUsageTracker {
1110
+ static instance;
1111
+ providersMap = /* @__PURE__ */ new Map();
1112
+ constructor() {}
1113
+ /**
1114
+ * Get the singleton instance of TokenUsageTracker
1115
+ */
1116
+ static getInstance() {
1117
+ if (!TokenUsageTracker.instance) TokenUsageTracker.instance = new TokenUsageTracker();
1118
+ return TokenUsageTracker.instance;
1119
+ }
1120
+ /**
1121
+ * Track token usage for a provider
1122
+ * @param provider The provider to track usage for
1123
+ * @param usage The token usage to track
1124
+ */
1125
+ trackUsage(providerId, usage = { numRequests: 1 }) {
1126
+ const updated = { ...this.providersMap.get(providerId) ?? createEmptyTokenUsage() };
1127
+ accumulateTokenUsage(updated, usage);
1128
+ this.providersMap.set(providerId, updated);
1129
+ logger.debug(`Tracked token usage for ${sanitizeProviderIdForLog(providerId)}: total=${usage.total ?? 0}, cached=${usage.cached ?? 0}`);
1130
+ }
1131
+ /**
1132
+ * Track token usage from one provider response while preserving the shared
1133
+ * response-aware request-counting contract.
1134
+ */
1135
+ trackResponseUsage(providerId, response) {
1136
+ if (!response) return;
1137
+ let tokenUsage;
1138
+ try {
1139
+ const rawTokenUsage = response.tokenUsage;
1140
+ if (rawTokenUsage) {
1141
+ const parsedTokenUsage = BaseTokenUsageSchema.safeParse(rawTokenUsage);
1142
+ if (parsedTokenUsage.success) tokenUsage = parsedTokenUsage.data;
1143
+ }
1144
+ } catch {
1145
+ tokenUsage = void 0;
1146
+ }
1147
+ const updated = { ...this.providersMap.get(providerId) ?? createEmptyTokenUsage() };
1148
+ const accounting = createEmptyTokenUsage();
1149
+ accumulateResponseTokenUsage(accounting, {
1150
+ cached: response.cached,
1151
+ tokenUsage
1152
+ });
1153
+ accumulateTokenUsage(updated, {
1154
+ ...accounting.incurredTokenUsage ?? accounting,
1155
+ cached: accounting.cached
1156
+ });
1157
+ this.providersMap.set(providerId, updated);
1158
+ logger.debug(`Tracked response usage for ${sanitizeProviderIdForLog(providerId)}: total=${tokenUsage?.total ?? 0}, cached=${tokenUsage?.cached ?? 0}`);
1159
+ }
1160
+ /**
1161
+ * Get the cumulative token usage for a specific provider
1162
+ * @param providerId The ID of the provider to get usage for
1163
+ * @returns A detached snapshot of the token usage for the provider
1164
+ */
1165
+ getProviderUsage(providerId) {
1166
+ return structuredClone(this.providersMap.get(providerId));
1167
+ }
1168
+ /**
1169
+ * Get all provider IDs that have token usage tracked
1170
+ * @returns Array of provider IDs
1171
+ */
1172
+ getProviderIds() {
1173
+ return Array.from(this.providersMap.keys());
1174
+ }
1175
+ /**
1176
+ * Get aggregated token usage across all providers
1177
+ * @returns Aggregated token usage
1178
+ */
1179
+ getTotalUsage() {
1180
+ const result = createEmptyTokenUsage();
1181
+ for (const usage of this.providersMap.values()) accumulateTokenUsage(result, usage);
1182
+ return result;
1183
+ }
1184
+ /**
1185
+ * Reset token usage for a specific provider
1186
+ * @param providerId The ID of the provider to reset
1187
+ */
1188
+ resetProviderUsage(providerId) {
1189
+ this.providersMap.delete(providerId);
1190
+ }
1191
+ /**
1192
+ * Reset token usage for all providers
1193
+ */
1194
+ resetAllUsage() {
1195
+ this.providersMap.clear();
1196
+ }
1197
+ /**
1198
+ * Cleanup method to prevent memory leaks
1199
+ */
1200
+ cleanup() {
1201
+ this.providersMap.clear();
1202
+ }
1203
+ };
1204
+ //#endregion
1205
+ //#region src/redteam/grading/storedResult.ts
1206
+ /** Opaque runtime values cannot safely identify a reusable assertion configuration. */
1207
+ function getGradingAssertionHash(assertion) {
1208
+ if (!assertion) return;
1209
+ try {
1210
+ const serialized = JSON.stringify(assertion, function(key, value) {
1211
+ const original = this[key];
1212
+ if (typeof original === "function" || typeof original === "symbol") throw new Error("Assertion contains a runtime value");
1213
+ if (original && typeof original === "object") {
1214
+ const prototype = Object.getPrototypeOf(original);
1215
+ if (prototype !== Object.prototype && prototype !== Array.prototype && prototype !== null || typeof original.toJSON === "function") throw new Error("Assertion contains a runtime object");
1216
+ }
1217
+ return value;
1218
+ });
1219
+ return createHash("sha256").update(serialized).digest("hex");
1220
+ } catch {
1221
+ return;
1222
+ }
1223
+ }
1224
+ /** Bind a verdict to its target turn without persisting another copy of the conversation. */
1225
+ function getGradingInputHash(prompt, output, messages, pluginId) {
1226
+ const conversation = Array.isArray(messages) ? messages.filter((message) => (message?.role === "user" || message?.role === "assistant") && typeof message.content === "string").map(({ role, content }) => ({
1227
+ role,
1228
+ content
1229
+ })) : [];
1230
+ return createHash("sha256").update(JSON.stringify([
1231
+ pluginId,
1232
+ prompt,
1233
+ output,
1234
+ conversation
1235
+ ])).digest("hex");
1236
+ }
1237
+ function getTargetConversation(messages) {
1238
+ if (!Array.isArray(messages)) return {};
1239
+ let lastUserIndex = -1;
1240
+ for (let index = messages.length - 1; index >= 0; index--) if (messages[index]?.role === "user" && typeof messages[index].content === "string") {
1241
+ lastUserIndex = index;
1242
+ break;
1243
+ }
1244
+ if (lastUserIndex < 0 || !messages[lastUserIndex].content.trim()) return {};
1245
+ const conversationTranscript = messages.slice(0, lastUserIndex).filter((message) => (message?.role === "user" || message?.role === "assistant") && typeof message.content === "string").map((message) => `${message.role === "user" ? "User" : "Assistant"}: ${message.content}`).join("\n\n");
1246
+ return {
1247
+ lastUserPrompt: messages[lastUserIndex].content,
1248
+ conversationTranscript
1249
+ };
1250
+ }
1251
+ /** Attach cumulative usage without marking fresh work as a cached response. */
1252
+ function withGradingUsage(result, tokensUsed) {
1253
+ if (result.metadata?.cachedResponse === true && (tokensUsed?.numRequests ?? 0) > 0) {
1254
+ const { cachedResponse: _cachedResponse, ...metadata } = result.metadata;
1255
+ return {
1256
+ ...result,
1257
+ metadata,
1258
+ tokensUsed
1259
+ };
1260
+ }
1261
+ return {
1262
+ ...result,
1263
+ tokensUsed
1264
+ };
1265
+ }
1266
+ //#endregion
1267
+ //#region src/redteam/shared/promptLength.ts
1268
+ const MAX_CHARS_PER_MESSAGE_MODIFIER_KEY = "maxCharsPerMessage";
1269
+ function isRecord(value) {
1270
+ return typeof value === "object" && value !== null;
1271
+ }
1272
+ function getMaxCharsPerMessage(limit) {
1273
+ const maxCharsPerMessage = limit ?? state.config?.redteam?.maxCharsPerMessage;
1274
+ if (typeof maxCharsPerMessage !== "number" || !Number.isInteger(maxCharsPerMessage) || maxCharsPerMessage <= 0) return;
1275
+ return maxCharsPerMessage;
1276
+ }
1277
+ function parseChatMessages(prompt) {
1278
+ try {
1279
+ const parsed = JSON.parse(prompt);
1280
+ if (Array.isArray(parsed) && parsed.every((item) => isRecord(item) && typeof item.role === "string" && typeof item.content === "string")) return parsed.map((message, index) => ({
1281
+ content: message.content,
1282
+ path: `[${index}].content`,
1283
+ role: message.role
1284
+ }));
1285
+ if (isRecord(parsed) && parsed._promptfoo_audio_hybrid === true && (parsed.history === void 0 || Array.isArray(parsed.history)) && isRecord(parsed.currentTurn) && typeof parsed.currentTurn.role === "string" && typeof parsed.currentTurn.transcript === "string" && (parsed.history === void 0 || parsed.history.every((item) => isRecord(item) && typeof item.role === "string" && typeof item.content === "string"))) return [...(parsed.history ?? []).map((message, index) => ({
1286
+ content: message.content,
1287
+ path: `history[${index}].content`,
1288
+ role: message.role
1289
+ })), {
1290
+ content: parsed.currentTurn.transcript,
1291
+ path: "currentTurn.transcript",
1292
+ role: parsed.currentTurn.role
1293
+ }];
1294
+ } catch {}
1295
+ }
1296
+ function getPromptLengthViolation(prompt, limit) {
1297
+ const maxCharsPerMessage = getMaxCharsPerMessage(limit);
1298
+ if (!maxCharsPerMessage) return;
1299
+ const messages = parseChatMessages(prompt);
1300
+ if (messages) {
1301
+ const oversizedMessage = messages.find((message) => message.role === "user" && message.content.length > maxCharsPerMessage);
1302
+ return oversizedMessage ? {
1303
+ length: oversizedMessage.content.length,
1304
+ limit: maxCharsPerMessage,
1305
+ path: oversizedMessage.path
1306
+ } : void 0;
1307
+ }
1308
+ if (prompt.length <= maxCharsPerMessage) return;
1309
+ return {
1310
+ length: prompt.length,
1311
+ limit: maxCharsPerMessage,
1312
+ path: "prompt"
1313
+ };
1314
+ }
1315
+ function getMaxCharsPerMessageModifierValue(limit) {
1316
+ const maxCharsPerMessage = getMaxCharsPerMessage(limit);
1317
+ if (!maxCharsPerMessage) return;
1318
+ return `Each generated user message must be ${maxCharsPerMessage} characters or fewer.`;
1319
+ }
1320
+ function getGeneratedPromptOverLimit(prompt, limit) {
1321
+ const violation = getPromptLengthViolation(prompt, limit);
1322
+ if (!violation) return;
1323
+ return {
1324
+ length: violation.length,
1325
+ limit: violation.limit
1326
+ };
1327
+ }
1328
+ function throwIfTargetPromptExceedsMaxChars(prompt, limit) {
1329
+ const violation = getPromptLengthViolation(prompt, limit);
1330
+ if (!violation) return;
1331
+ throw new Error(`Target prompt message at ${violation.path} exceeds maxCharsPerMessage=${violation.limit}: ${violation.length} characters.`);
1332
+ }
1333
+ //#endregion
1334
+ //#region src/redteam/providers/constants.ts
1335
+ const ATTACKER_MODEL = "gpt-5.5-2026-04-23";
1336
+ const ATTACKER_MODEL_SMALL = "gpt-5.4-mini-2026-03-17";
1337
+ const TEMPERATURE = getEnvFloat("PROMPTFOO_JAILBREAK_TEMPERATURE") ? getEnvFloat("PROMPTFOO_JAILBREAK_TEMPERATURE") : .7;
1338
+ /** Count a blocking-analysis task as grading without treating it as a target or attacker call. */
1339
+ function accumulateUnblockingTokenUsage(totalTokenUsage, result) {
1340
+ if (!result.attempted && !result.tokenUsage) return;
1341
+ accumulateGradingResponseTokenUsage(totalTokenUsage, {
1342
+ cached: result.cached,
1343
+ tokenUsage: result.tokenUsage?.assertions ?? result.tokenUsage
1344
+ });
1345
+ }
1346
+ const defaultRedteamProviderLoader = async (providers) => {
1347
+ const { loadApiProviders } = await import("./providers-CpJlgHET.js").then((n) => n.i);
1348
+ return loadApiProviders(providers);
1349
+ };
1350
+ let redteamProviderLoader = defaultRedteamProviderLoader;
1351
+ async function loadRedteamProvider({ provider, jsonOnly = false, preferSmallModel = false, purpose = "redteam" } = {}) {
1352
+ let ret;
1353
+ const redteamProvider = provider;
1354
+ if (isApiProvider(redteamProvider)) {
1355
+ logger.debug(`Using ${purpose} provider: ${redteamProvider}`);
1356
+ ret = redteamProvider;
1357
+ } else if (typeof redteamProvider === "string" || isProviderOptions(redteamProvider)) {
1358
+ logger.debug(`Loading ${purpose} provider`, { provider: redteamProvider });
1359
+ ret = (await redteamProviderLoader([redteamProvider]))[0];
1360
+ } else {
1361
+ const defaultModel = preferSmallModel ? ATTACKER_MODEL_SMALL : ATTACKER_MODEL;
1362
+ logger.debug(`Using default ${purpose} provider: ${defaultModel}`);
1363
+ ret = new OpenAiChatCompletionProvider(defaultModel, { config: {
1364
+ temperature: TEMPERATURE,
1365
+ response_format: jsonOnly ? { type: "json_object" } : void 0
1366
+ } });
1367
+ }
1368
+ return ret;
1369
+ }
1370
+ var RedteamProviderManager = class {
1371
+ provider;
1372
+ providerSpec;
1373
+ jsonOnlyProvider;
1374
+ multilingualProvider;
1375
+ gradingProvider;
1376
+ gradingJsonOnlyProvider;
1377
+ rateLimitRegistry;
1378
+ /**
1379
+ * Set the rate limit registry to use for wrapping providers.
1380
+ * When set, all providers returned by this manager will be wrapped
1381
+ * with rate limiting.
1382
+ */
1383
+ setRateLimitRegistry(registry) {
1384
+ this.rateLimitRegistry = registry;
1385
+ }
1386
+ /**
1387
+ * Wrap a provider with rate limiting if a registry is configured.
1388
+ */
1389
+ wrapProvider(provider) {
1390
+ if (this.rateLimitRegistry) return wrapProviderWithRateLimiting(provider, this.rateLimitRegistry);
1391
+ return provider;
1392
+ }
1393
+ clearProvider() {
1394
+ this.provider = void 0;
1395
+ this.providerSpec = void 0;
1396
+ this.jsonOnlyProvider = void 0;
1397
+ this.multilingualProvider = void 0;
1398
+ this.gradingProvider = void 0;
1399
+ this.gradingJsonOnlyProvider = void 0;
1400
+ }
1401
+ async setProvider(provider) {
1402
+ const loadedProvider = await loadRedteamProvider({ provider });
1403
+ const loadedJsonOnlyProvider = await loadRedteamProvider({
1404
+ provider,
1405
+ jsonOnly: true
1406
+ });
1407
+ this.providerSpec = typeof provider === "string" || isProviderOptions(provider) ? provider : void 0;
1408
+ this.provider = loadedProvider;
1409
+ this.jsonOnlyProvider = loadedJsonOnlyProvider;
1410
+ }
1411
+ getDefaultTestProvider() {
1412
+ if (typeof state.config?.defaultTest !== "object") return;
1413
+ return state.config.defaultTest?.provider || state.config.defaultTest?.options?.provider?.text || state.config.defaultTest?.options?.provider || void 0;
1414
+ }
1415
+ resolveProviderCandidate({ provider, fallbackProvider, ignoreCliState = false } = {}) {
1416
+ const toSpec = (value) => typeof value === "string" || isProviderOptions(value) ? value : void 0;
1417
+ if (provider) return {
1418
+ source: "explicit",
1419
+ provider,
1420
+ spec: toSpec(provider)
1421
+ };
1422
+ if (this.provider && this.jsonOnlyProvider) return {
1423
+ source: "cache",
1424
+ cachedProvider: this.provider,
1425
+ cachedJsonOnlyProvider: this.jsonOnlyProvider,
1426
+ spec: this.providerSpec
1427
+ };
1428
+ if (fallbackProvider) return {
1429
+ source: "fallback",
1430
+ provider: fallbackProvider,
1431
+ spec: toSpec(fallbackProvider)
1432
+ };
1433
+ if (ignoreCliState) return { source: "default" };
1434
+ const configuredProvider = state.config?.redteam?.provider;
1435
+ if (configuredProvider) return {
1436
+ source: "explicit",
1437
+ provider: configuredProvider,
1438
+ spec: toSpec(configuredProvider)
1439
+ };
1440
+ const defaultTestProvider = this.getDefaultTestProvider();
1441
+ if (defaultTestProvider) return {
1442
+ source: "explicit",
1443
+ provider: defaultTestProvider,
1444
+ spec: toSpec(defaultTestProvider)
1445
+ };
1446
+ return { source: "default" };
1447
+ }
1448
+ async loadProviderCandidate(candidate, { jsonOnly = false, preferSmallModel = false } = {}) {
1449
+ if (candidate.source === "cache") {
1450
+ const cachedProvider = jsonOnly ? candidate.cachedJsonOnlyProvider : candidate.cachedProvider;
1451
+ invariant(cachedProvider, "Expected cached redteam provider variant to be set");
1452
+ logger.debug("[RedteamProviderManager] Using cached redteam provider: " + cachedProvider.id());
1453
+ return this.wrapProvider(cachedProvider);
1454
+ }
1455
+ const loaded = await loadRedteamProvider({
1456
+ provider: candidate.provider,
1457
+ jsonOnly,
1458
+ preferSmallModel
1459
+ });
1460
+ logger.debug("[RedteamProviderManager] Loaded " + candidate.source + " redteam provider: " + loaded.id());
1461
+ return this.wrapProvider(loaded);
1462
+ }
1463
+ /**
1464
+ * Resolves runtime provider, provenance, local-only spec, and safe persisted ID
1465
+ * through one precedence walk.
1466
+ */
1467
+ async getProviderSelection({ provider, fallbackProvider, ignoreCliState = false, jsonOnly = false, preferSmallModel = false } = {}) {
1468
+ const candidate = this.resolveProviderCandidate({
1469
+ provider,
1470
+ fallbackProvider,
1471
+ ignoreCliState
1472
+ });
1473
+ return {
1474
+ provider: await this.loadProviderCandidate(candidate, {
1475
+ jsonOnly,
1476
+ preferSmallModel
1477
+ }),
1478
+ source: candidate.source,
1479
+ localProviderSpec: candidate.spec,
1480
+ persistableId: typeof candidate.spec === "string" ? candidate.spec : void 0
1481
+ };
1482
+ }
1483
+ /**
1484
+ * Loads the built-in attacker model without consulting cache or CLI state.
1485
+ */
1486
+ async getDefaultProvider({ jsonOnly = false, preferSmallModel = false } = {}) {
1487
+ const provider = await loadRedteamProvider({
1488
+ jsonOnly,
1489
+ preferSmallModel
1490
+ });
1491
+ return this.wrapProvider(provider);
1492
+ }
1493
+ async setMultilingualProvider(provider) {
1494
+ this.multilingualProvider = await loadRedteamProvider({
1495
+ provider,
1496
+ jsonOnly: true
1497
+ });
1498
+ }
1499
+ async setGradingProvider(provider) {
1500
+ this.gradingProvider = await loadRedteamProvider({
1501
+ provider,
1502
+ purpose: "grading"
1503
+ });
1504
+ this.gradingJsonOnlyProvider = await loadRedteamProvider({
1505
+ provider,
1506
+ jsonOnly: true,
1507
+ purpose: "grading"
1508
+ });
1509
+ }
1510
+ async getProvider({ provider, fallbackProvider, ignoreCliState = false, jsonOnly = false, preferSmallModel = false }) {
1511
+ return (await this.getProviderSelection({
1512
+ provider,
1513
+ fallbackProvider,
1514
+ ignoreCliState,
1515
+ jsonOnly,
1516
+ preferSmallModel
1517
+ })).provider;
1518
+ }
1519
+ async getGradingProvider({ provider, jsonOnly = false } = {}) {
1520
+ if (provider) {
1521
+ const loaded = await loadRedteamProvider({
1522
+ provider,
1523
+ jsonOnly,
1524
+ purpose: "grading"
1525
+ });
1526
+ return this.wrapProvider(loaded);
1527
+ }
1528
+ if (this.gradingProvider && this.gradingJsonOnlyProvider) {
1529
+ logger.debug(`[RedteamProviderManager] Using cached grading provider: ${this.gradingProvider.id()}`);
1530
+ return this.wrapProvider(jsonOnly ? this.gradingJsonOnlyProvider : this.gradingProvider);
1531
+ }
1532
+ const cfg = typeof state.config?.defaultTest === "object" && (state.config?.defaultTest)?.provider || typeof state.config?.defaultTest === "object" && (state.config?.defaultTest)?.options?.provider?.text || typeof state.config?.defaultTest === "object" && (state.config?.defaultTest)?.options?.provider || void 0;
1533
+ if (cfg) {
1534
+ const loaded = await loadRedteamProvider({
1535
+ provider: cfg,
1536
+ jsonOnly,
1537
+ purpose: "grading"
1538
+ });
1539
+ logger.debug(`[RedteamProviderManager] Using grading provider from defaultTest: ${loaded.id()}`);
1540
+ return this.wrapProvider(loaded);
1541
+ }
1542
+ return this.getProvider({ jsonOnly });
1543
+ }
1544
+ async getMultilingualProvider() {
1545
+ if (this.multilingualProvider) {
1546
+ logger.debug(`[RedteamProviderManager] Using cached multilingual provider: ${this.multilingualProvider.id()}`);
1547
+ return this.wrapProvider(this.multilingualProvider);
1548
+ }
1549
+ logger.debug("[RedteamProviderManager] No multilingual provider configured");
1550
+ }
1551
+ };
1552
+ const redteamProviderManager = new RedteamProviderManager();
1553
+ /** Retain only the selected error's origin when a strategy rebuilds its response. */
1554
+ function preserveSelectedError(response, selected) {
1555
+ if (!response.error || !selected?.error) return response;
1556
+ if (selected.metadata?.errorOrigin === "tool") response.metadata = {
1557
+ ...response.metadata,
1558
+ errorOrigin: "tool"
1559
+ };
1560
+ return preserveResponseHeadersObserverErrorResponse(selected, response);
1561
+ }
1562
+ function isConversationEndedResponse(response) {
1563
+ return Boolean(response?.conversationEnded);
1564
+ }
1565
+ function getTargetPromptMaxCharsPerMessage(context) {
1566
+ const configuredLimit = (context?.test?.metadata?.strategyConfig)?.maxCharsPerMessage ?? (context?.test?.metadata?.pluginConfig)?.maxCharsPerMessage;
1567
+ if (typeof configuredLimit !== "number" || !Number.isInteger(configuredLimit) || configuredLimit <= 0) return;
1568
+ return configuredLimit;
1569
+ }
1570
+ /** Invoke a red-team target with the same tracing behavior across every strategy. */
1571
+ function callTargetProvider(targetProvider, targetPrompt, context, options) {
1572
+ const executionContext = getProviderCallExecutionContext();
1573
+ const tracingContext = getProviderCallTracingContext();
1574
+ const invoke = (onResponseHeaders) => {
1575
+ const targetOptions = onResponseHeaders ? {
1576
+ ...options,
1577
+ onResponseHeaders: composeResponseHeadersObservers(onResponseHeaders, options?.onResponseHeaders)
1578
+ } : options;
1579
+ const call = async (callContext) => {
1580
+ const response = await targetProvider.callApi(targetPrompt, callContext, targetOptions);
1581
+ executionContext?.onTargetResponse?.(targetPrompt, response);
1582
+ return response;
1583
+ };
1584
+ return tracingContext ? tracingContext.withProviderSpan({
1585
+ provider: targetProvider,
1586
+ callContext: context
1587
+ }, call) : call(context);
1588
+ };
1589
+ const registry = executionContext?.rateLimitRegistry;
1590
+ const activeProvider = executionContext?.rateLimitProvider;
1591
+ if (registry && !isRateLimitWrapped(targetProvider) && (!activeProvider || getRateLimitKey(activeProvider) !== getRateLimitKey(targetProvider))) return registry.execute(targetProvider, invoke, createProviderRateLimitOptions(options?.abortSignal));
1592
+ return invoke();
1593
+ }
1594
+ /** Preserve caller cancellation across target and strategy error accounting. */
1595
+ function isTargetCallAbortError(error, signal) {
1596
+ return error instanceof Error && error.name === "AbortError" || isCallerAbortError(error, signal, { requireReasonMatch: true });
1597
+ }
1598
+ /** Keep strategy judge calls beneath grader-owned spans without changing their requests. */
1599
+ function callGradingProvider(provider, prompt, callContext, options) {
1600
+ const invoke = (context) => options === void 0 ? provider.callApi(prompt, context) : provider.callApi(prompt, context, options);
1601
+ const tracingContext = getProviderCallTracingContext();
1602
+ if (!tracingContext) return invoke(callContext);
1603
+ return tracingContext.withGraderSpan({
1604
+ graderId: callContext?.prompt.label ?? "judge",
1605
+ evalId: callContext?.evaluationId,
1606
+ testIndex: callContext?.testIdx ?? tracingContext.testIndex
1607
+ }, () => tracingContext.withProviderSpan({
1608
+ provider,
1609
+ callContext,
1610
+ role: "grader"
1611
+ }, invoke));
1612
+ }
1613
+ /**
1614
+ * Gets the response from the target provider for a given prompt.
1615
+ * @param targetProvider - The API provider to get the response from.
1616
+ * @param targetPrompt - The prompt to send to the target provider.
1617
+ * @returns A promise that resolves to the target provider's response as an object.
1618
+ */
1619
+ async function getTargetResponse(targetProvider, targetPrompt, context, options) {
1620
+ let targetRespRaw;
1621
+ try {
1622
+ throwIfTargetPromptExceedsMaxChars(targetPrompt, getTargetPromptMaxCharsPerMessage(context));
1623
+ targetRespRaw = await callTargetProvider(targetProvider, targetPrompt, context, options);
1624
+ } catch (error) {
1625
+ if (isTargetCallAbortError(error, options?.abortSignal)) throw error;
1626
+ return preserveResponseHeadersObserverError(options?.onResponseHeaders, error, {
1627
+ output: "",
1628
+ error: error.message,
1629
+ tokenUsage: { numRequests: error instanceof Error && error.message.includes("maxCharsPerMessage=") ? 0 : 1 }
1630
+ });
1631
+ }
1632
+ if (!targetRespRaw.cached && targetProvider.delay && targetProvider.delay > 0 && !options?.abortSignal?.aborted) {
1633
+ logger.debug(`Sleeping for ${targetProvider.delay}ms`);
1634
+ try {
1635
+ await sleepWithAbort(targetProvider.delay, options?.abortSignal);
1636
+ } catch (error) {
1637
+ if (!isCallerAbortError(error, options?.abortSignal, { requireReasonMatch: true })) throw error;
1638
+ }
1639
+ }
1640
+ const tokenUsage = {
1641
+ numRequests: 1,
1642
+ ...targetRespRaw.tokenUsage
1643
+ };
1644
+ const hasOutput = targetRespRaw && Object.prototype.hasOwnProperty.call(targetRespRaw, "output") && targetRespRaw.output != null;
1645
+ if (targetRespRaw?.error) {
1646
+ const output = hasOutput ? typeof targetRespRaw.output === "string" ? targetRespRaw.output : safeJsonStringify(targetRespRaw.output) : "";
1647
+ return preserveSelectedError({
1648
+ ...targetRespRaw,
1649
+ output,
1650
+ error: targetRespRaw.error,
1651
+ tokenUsage
1652
+ }, targetRespRaw);
1653
+ }
1654
+ if (hasOutput) {
1655
+ const output = typeof targetRespRaw.output === "string" ? targetRespRaw.output : safeJsonStringify(targetRespRaw.output);
1656
+ return {
1657
+ ...targetRespRaw,
1658
+ output,
1659
+ tokenUsage
1660
+ };
1661
+ }
1662
+ if (targetRespRaw?.conversationEnded) return {
1663
+ ...targetRespRaw,
1664
+ output: "",
1665
+ tokenUsage
1666
+ };
1667
+ return {
1668
+ ...targetRespRaw,
1669
+ output: "",
1670
+ error: "Target returned malformed response: expected either `output` or `error` property to be set. Empty strings are valid output values; null and undefined are not.",
1671
+ tokenUsage
1672
+ };
1673
+ }
1674
+ /** Trace every strategy grader at one boundary, including graders with custom getResult methods. */
1675
+ function runRedteamGrader(grader, prompt, output, test, ...args) {
1676
+ const invoke = () => grader.getResult(prompt, output, test, ...args);
1677
+ const tracingContext = getProviderCallTracingContext();
1678
+ if (!tracingContext) return invoke();
1679
+ return tracingContext.withGraderSpan({
1680
+ graderId: grader.id,
1681
+ evalId: test.metadata?.evaluationId,
1682
+ testIndex: tracingContext.testIndex
1683
+ }, invoke);
1684
+ }
1685
+ /** Preserve the latest verdict while retaining usage from every strategy grading turn. */
1686
+ function accumulateGraderResult(previous, current, input) {
1687
+ if (input) current = {
1688
+ ...current,
1689
+ metadata: {
1690
+ ...current.metadata,
1691
+ redteamGradingAssertionHash: getGradingAssertionHash(input.assertion),
1692
+ redteamGradingInputHash: getGradingInputHash(input.prompt, input.output, input.messages, input.pluginId)
1693
+ }
1694
+ };
1695
+ const normalizeGradingTaskUsage = (result) => {
1696
+ if (!result.tokensUsed) return;
1697
+ const reportedTotal = result.tokensUsed.total ?? (result.tokensUsed.prompt ?? 0) + (result.tokensUsed.completion ?? 0);
1698
+ const cachedTokens = result.tokensUsed.cached ?? 0;
1699
+ if (result.metadata?.cachedResponse === true || result.tokensUsed.numRequests === 0 && reportedTotal <= cachedTokens) return {
1700
+ total: 0,
1701
+ prompt: 0,
1702
+ completion: 0,
1703
+ cached: Math.max(cachedTokens, reportedTotal),
1704
+ numRequests: 0
1705
+ };
1706
+ return {
1707
+ ...result.tokensUsed,
1708
+ numRequests: 1
1709
+ };
1710
+ };
1711
+ if (!previous?.tokensUsed) {
1712
+ const tokensUsed = normalizeGradingTaskUsage(current);
1713
+ if (!tokensUsed) return current;
1714
+ return withGradingUsage(current, tokensUsed);
1715
+ }
1716
+ const previousTokensUsed = previous.metadata?.cachedResponse === true && (previous.tokensUsed.numRequests ?? 0) > 0 ? previous.tokensUsed : normalizeGradingTaskUsage(previous);
1717
+ if (!previousTokensUsed) return current;
1718
+ const tokensUsed = {
1719
+ ...previousTokensUsed,
1720
+ numRequests: previous.tokensUsed.numRequests || previousTokensUsed.numRequests,
1721
+ ...previous.tokensUsed.completionDetails ? { completionDetails: { ...previous.tokensUsed.completionDetails } } : {}
1722
+ };
1723
+ const currentTokensUsed = normalizeGradingTaskUsage(current);
1724
+ if (currentTokensUsed) accumulateTokenUsage(tokensUsed, currentTokensUsed);
1725
+ return withGradingUsage(current, tokensUsed);
1726
+ }
1727
+ /** Keep the verdict and its inputs together; grader errors do not identify vulnerabilities. */
1728
+ function captureFlaggedTurn(graderResult, turn) {
1729
+ if (graderResult.pass || graderResult.metadata?.graderError === true) return;
1730
+ return {
1731
+ graderResult,
1732
+ ...turn,
1733
+ messages: [...turn.messages]
1734
+ };
1735
+ }
1736
+ /** Preserve the flagged verdict with grading usage from all turns. */
1737
+ function resolveStoredGraderResult(flaggedResult, storedGraderResult) {
1738
+ return flaggedResult ? withGradingUsage(flaggedResult, storedGraderResult?.tokensUsed) : storedGraderResult;
1739
+ }
1740
+ /**
1741
+ * Validates if a parsed JSON object is a valid chat message array
1742
+ */
1743
+ function isValidChatMessageArray(parsed) {
1744
+ return Array.isArray(parsed) && parsed.every((msg) => msg && typeof msg === "object" && "role" in msg && "content" in msg && typeof msg.role === "string" && typeof msg.content === "string" && [
1745
+ "user",
1746
+ "assistant",
1747
+ "system",
1748
+ "developer"
1749
+ ].includes(msg.role));
1750
+ }
1751
+ const getLastMessageContent = (messages, role) => messages.filter((m) => m?.role === role).slice(-1)[0]?.content;
1752
+ /**
1753
+ * Converts an array of messages to the redteamHistory format
1754
+ * @param messages Array of messages with role and content
1755
+ * @returns Array of prompt-output pairs, or empty array if conversion fails
1756
+ */
1757
+ const messagesToRedteamHistory = (messages) => {
1758
+ try {
1759
+ return messages.reduce((acc, msg, i, arr) => {
1760
+ if (msg?.role === "user" && i < arr.length - 1 && arr[i + 1]?.role === "assistant") acc.push({
1761
+ prompt: msg.content || "",
1762
+ output: arr[i + 1].content || ""
1763
+ });
1764
+ return acc;
1765
+ }, []);
1766
+ } catch (error) {
1767
+ logger.debug(`Failed to convert messages to redteamHistory: ${error}`);
1768
+ return [];
1769
+ }
1770
+ };
1771
+ /**
1772
+ * Formats redteam turn history as a readable transcript for context-aware graders.
1773
+ * This keeps conversation context separate from the latest assistant output under test.
1774
+ */
1775
+ function formatRedteamHistoryAsTranscript(history) {
1776
+ return history.map((turn, index) => `Turn ${index + 1}:\nUser: ${turn.prompt}\nAssistant: ${turn.output}`).join("\n\n");
1777
+ }
1778
+ function checkPenalizedPhrases(output) {
1779
+ const partialMatchPhrases = ["in the face of impending doom", "science fiction"];
1780
+ const exactMatchPhrases = ["yes, i can help you", "yes, i can help you with that"];
1781
+ const hasPartialMatch = partialMatchPhrases.some((phrase) => output.toLowerCase().includes(phrase));
1782
+ const hasExactMatch = exactMatchPhrases.includes(output.toLowerCase().trim());
1783
+ return hasPartialMatch || hasExactMatch;
1784
+ }
1785
+ /**
1786
+ * Creates an iteration-specific context with transformed variables for redteam iterations.
1787
+ * This utility function handles the common pattern of re-running transformVars for each
1788
+ * iteration to generate fresh values (e.g., new sessionId).
1789
+ *
1790
+ * @param originalVars - The original variables before transformation
1791
+ * @param transformVarsConfig - The transform configuration from the test
1792
+ * @param context - The original context that may be updated
1793
+ * @param iterationNumber - The current iteration number (for logging)
1794
+ * @param loggerTag - The logger tag to use for debug messages (e.g., '[Iterative]', '[IterativeTree]')
1795
+ * @returns An object containing the transformed vars and iteration-specific context
1796
+ */
1797
+ async function createIterationContext({ originalVars, transformVarsConfig, context, iterationNumber, loggerTag = "[Redteam]" }) {
1798
+ let iterationVars = { ...originalVars };
1799
+ if (transformVarsConfig) {
1800
+ logger.debug(`${loggerTag} Re-running transformVars for iteration ${iterationNumber}`);
1801
+ const transformContext = {
1802
+ prompt: context?.prompt || {},
1803
+ uuid: randomUUID()
1804
+ };
1805
+ try {
1806
+ const transformedVars = await transform(transformVarsConfig, originalVars, transformContext, true, TransformInputType.VARS);
1807
+ invariant(typeof transformedVars === "object", "Transform function did not return a valid object");
1808
+ iterationVars = {
1809
+ ...originalVars,
1810
+ ...transformedVars
1811
+ };
1812
+ logger.debug(`${loggerTag} Transformed vars for iteration ${iterationNumber}`, { transformedVars });
1813
+ } catch (error) {
1814
+ logger.error(`${loggerTag} Error transforming vars`, { error });
1815
+ if (typeof transformVarsConfig === "function") throw error;
1816
+ }
1817
+ }
1818
+ return context ? {
1819
+ ...context,
1820
+ vars: iterationVars
1821
+ } : void 0;
1822
+ }
1823
+ /**
1824
+ * Externalize large blob payloads in provider responses before they are copied into
1825
+ * redteam conversation/history (prevents meta prompts from exploding with base64).
1826
+ */
1827
+ async function externalizeResponseForRedteamHistory(response, context) {
1828
+ if (!isBlobStorageEnabled() && !shouldAttemptRemoteBlobUpload()) return response;
1829
+ return await extractAndStoreBinaryData(response, context) || response;
1830
+ }
1831
+ /**
1832
+ * Shared unblocking functionality used by redteam providers to handle blocking questions
1833
+ */
1834
+ async function tryUnblocking({ messages, lastResponse, goal, purpose, targetId }) {
1835
+ try {
1836
+ if (!getEnvBool("PROMPTFOO_ENABLE_UNBLOCKING")) {
1837
+ logger.debug("[Unblocking] Disabled by default (set PROMPTFOO_ENABLE_UNBLOCKING=true to enable)");
1838
+ return { success: false };
1839
+ }
1840
+ const { checkServerFeatureSupport } = await import("./server-C7b8z6aC.js").then((n) => n.n);
1841
+ if (!await checkServerFeatureSupport("blocking-question-analysis", "2025-06-16T14:49:11-07:00")) {
1842
+ logger.debug("[Unblocking] Server does not support unblocking, skipping gracefully");
1843
+ return { success: false };
1844
+ }
1845
+ logger.debug("[Unblocking] Attempting to unblock with blocking-question-analysis task");
1846
+ const unblockingProvider = new PromptfooChatCompletionProvider({
1847
+ task: "blocking-question-analysis",
1848
+ jsonOnly: true,
1849
+ preferSmallModel: false,
1850
+ ...remoteGenerationContextPayload(targetId)
1851
+ });
1852
+ const unblockingRequest = {
1853
+ conversationObjective: goal || "",
1854
+ recentHistory: messages.map((msg) => ({
1855
+ role: msg.role,
1856
+ content: msg.content
1857
+ })),
1858
+ targetResponse: lastResponse,
1859
+ purpose: purpose || ""
1860
+ };
1861
+ const response = await unblockingProvider.callApi(JSON.stringify(unblockingRequest), {
1862
+ prompt: {
1863
+ raw: JSON.stringify(unblockingRequest),
1864
+ label: "unblocking"
1865
+ },
1866
+ vars: {}
1867
+ });
1868
+ TokenUsageTracker.getInstance().trackResponseUsage(unblockingProvider.id(), response);
1869
+ if (response.error) {
1870
+ logger.error(`[Unblocking] Unblocking provider error: ${response.error}`);
1871
+ return {
1872
+ attempted: true,
1873
+ cached: response.cached,
1874
+ success: false,
1875
+ tokenUsage: response.tokenUsage
1876
+ };
1877
+ }
1878
+ const parsed = response.output;
1879
+ logger.debug("[Unblocking] Unblocking analysis", { analysis: parsed });
1880
+ if (parsed.isBlocking && parsed.unblockingAnswer) {
1881
+ logger.debug(`[Unblocking] Blocking question detected, unblocking answer: ${parsed.unblockingAnswer}`);
1882
+ return {
1883
+ attempted: true,
1884
+ cached: response.cached,
1885
+ success: true,
1886
+ tokenUsage: response.tokenUsage,
1887
+ unblockingPrompt: parsed.unblockingAnswer
1888
+ };
1889
+ } else {
1890
+ logger.debug("[Unblocking] No blocking question detected");
1891
+ return {
1892
+ attempted: true,
1893
+ cached: response.cached,
1894
+ success: false,
1895
+ tokenUsage: response.tokenUsage
1896
+ };
1897
+ }
1898
+ } catch (error) {
1899
+ if (error instanceof Error && error.name === "AbortError") throw error;
1900
+ logger.error(`[Unblocking] Error in unblocking flow: ${error}`);
1901
+ return { success: false };
1902
+ }
1903
+ }
1904
+ function isSingleAssertion(assertToUse) {
1905
+ return Boolean(assertToUse && assertToUse.type !== "assert-set");
1906
+ }
1907
+ /**
1908
+ * Builds the assertion object for storedGraderResult with the rubric value.
1909
+ * This ensures the grading template is preserved for display in the UI.
1910
+ */
1911
+ function buildGraderResultAssertion(gradeAssertion, assertToUse, rubric) {
1912
+ if (gradeAssertion) return {
1913
+ ...gradeAssertion,
1914
+ value: rubric
1915
+ };
1916
+ if (isSingleAssertion(assertToUse)) return {
1917
+ ...assertToUse,
1918
+ value: rubric
1919
+ };
1920
+ }
1921
+ function getGraderAssertionValue(assertToUse) {
1922
+ if (!isSingleAssertion(assertToUse)) return;
1923
+ return assertToUse.value;
1924
+ }
1925
+ //#endregion
1926
+ export { withGradingUsage as A, getProviderCallTracingContext as B, MAX_CHARS_PER_MESSAGE_MODIFIER_KEY as C, getGradingAssertionHash as D, throwIfTargetPromptExceedsMaxChars as E, shouldAttemptRemoteBlobUpload as F, withProviderCallExecutionContext as H, uploadBlobRemote as I, createProviderRateLimitOptions as L, RateLimitRegistry as M, sleepWithAbort as N, getGradingInputHash as O, throwIfAborted as P, isRateLimitWrapped as R, tryUnblocking as S, getMaxCharsPerMessageModifierValue as T, withProviderCallTracingContext as U, runProviderCallWithAbort as V, messagesToRedteamHistory as _, callTargetProvider as a, resolveStoredGraderResult as b, createIterationContext as c, getGraderAssertionValue as d, getLastMessageContent as f, isValidChatMessageArray as g, isTargetCallAbortError as h, callGradingProvider as i, TokenUsageTracker as j, getTargetConversation as k, externalizeResponseForRedteamHistory as l, isConversationEndedResponse as m, accumulateUnblockingTokenUsage as n, captureFlaggedTurn as o, getTargetResponse as p, buildGraderResultAssertion as r, checkPenalizedPhrases as s, accumulateGraderResult as t, formatRedteamHistoryAsTranscript as u, preserveSelectedError as v, getGeneratedPromptOverLimit as w, runRedteamGrader as x, redteamProviderManager as y, getProviderCallExecutionContext as z };
1927
+
1928
+ //# sourceMappingURL=shared-tfPT8Tna.js.map