promptfoo 0.121.4 → 0.121.7
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.
- package/dist/src/{ListApp-DQkFNqE9.js → ListApp-DLmM02JS.js} +1 -1
- package/dist/src/{accounts-DhMYUUbu.js → accounts-Ca7WIoPY.js} +12 -7
- package/dist/src/{accounts-F9d_5sMC.js → accounts-CjFnOPmb.js} +14 -9
- package/dist/src/{accounts-Dy17bs4D.cjs → accounts-CmWzeD2d.cjs} +16 -10
- package/dist/src/{accounts-DdJ2pHMI.js → accounts-DanM1wq_.js} +13 -8
- package/dist/src/{agentic-utils-qFlm6zes.js → agentic-utils-CJ0j3fBi.js} +3 -3
- package/dist/src/{agentic-utils-w68v6_Dz.js → agentic-utils-DDEGRV9v.js} +3 -3
- package/dist/src/{agentic-utils-BpX5b23w.cjs → agentic-utils-DvPWSUpb.cjs} +8 -7
- package/dist/src/{agentic-utils-P172hM8B.js → agentic-utils-TxUEMPYS.js} +2 -2
- package/dist/src/{agents-BahDpe5G.cjs → agents-B4sRuXg3.cjs} +7 -6
- package/dist/src/{agents-pQeBEXMm.js → agents-B8q7h_ek.js} +5 -5
- package/dist/src/{agents-CgaMXvLM.js → agents-CBgJvRkB.js} +21 -10
- package/dist/src/{agents-C-R_jfzI.js → agents-CYn2n3QP.js} +4 -4
- package/dist/src/{agents-8FDnTriG.js → agents-D-vDNFx4.js} +21 -10
- package/dist/src/{agents-aYPQLf8W.js → agents-LrHuQqr1.js} +20 -9
- package/dist/src/{agents-DJ35I3Nt.js → agents-QGg76OF-.js} +5 -5
- package/dist/src/{agents-D7-HGxUj.cjs → agents-eHZ9nlgA.cjs} +21 -10
- package/dist/src/{aimlapi-sgYnkE54.js → aimlapi-CJEbQ0o6.js} +7 -7
- package/dist/src/{aimlapi-BD6J9oKt.js → aimlapi-D5HXzZ0s.js} +6 -6
- package/dist/src/{aimlapi-qcK4OT55.cjs → aimlapi-T6HGNxNe.cjs} +7 -7
- package/dist/src/{aimlapi-BCq3MHeL.js → aimlapi-eYv3a_DK.js} +7 -7
- package/dist/src/app/app/tsconfig.app.tsbuildinfo +1 -1
- package/dist/src/app/assets/Report-BNHJKN35.js +1 -0
- package/dist/src/app/assets/index-BnT6P6sF.js +388 -0
- package/dist/src/app/assets/index-yhM8y1PP.css +1 -0
- package/dist/src/app/assets/{scroll-timeline-D9IT_e8Z.js → scroll-timeline-RpeTwOvs.js} +1 -1
- package/dist/src/app/assets/sync-5gq6fmG4.js +4 -0
- package/dist/src/app/assets/vendor-charts-BL9OMNU7.js +36 -0
- package/dist/src/app/assets/{vendor-markdown-Ch00wnNI.js → vendor-markdown-BYsQqn7Z.js} +10 -10
- package/dist/src/app/assets/{vendor-react-CVvmk1UB.js → vendor-react-CqWgVW6T.js} +2 -2
- package/dist/src/app/assets/{vendor-utils-BnEYbx2Q.js → vendor-utils-BHPO71pu.js} +1 -1
- package/dist/src/app/index.html +31 -6
- package/dist/src/{audio-COrn8rM6.js → audio-BqnRvcWG.js} +3 -3
- package/dist/src/{audio-DcVKoInv.js → audio-CPMtV1yR.js} +4 -4
- package/dist/src/{audio-B7izf48x.js → audio-DyiebVB3.js} +4 -4
- package/dist/src/{audio-BQtNuYBj.cjs → audio-FnxbEnSE.cjs} +4 -4
- package/dist/src/authoritativeMarkupInjection-BZIywVjG.js +74 -0
- package/dist/src/authoritativeMarkupInjection-DyAXAsSr.js +75 -0
- package/dist/src/authoritativeMarkupInjection-F2gBw0lN.cjs +74 -0
- package/dist/src/authoritativeMarkupInjection-QEQmFS83.js +74 -0
- package/dist/src/{base-PYJvBE1i.js → base-CKLo890h.js} +4 -3
- package/dist/src/{base-fZ9wgg50.js → base-Co80MMCi.js} +5 -4
- package/dist/src/{base-D-670DX8.cjs → base-DGJW48uz.cjs} +5 -4
- package/dist/src/{base-yrI1Yal4.js → base-E9I8zXjz.js} +5 -4
- package/dist/src/bestOfN-B3wNzjSB.js +137 -0
- package/dist/src/bestOfN-BBsO41z4.js +136 -0
- package/dist/src/bestOfN-CAwmg5UL.cjs +140 -0
- package/dist/src/bestOfN-_kTi8Bxe.js +136 -0
- package/dist/src/{blobs-D2FAd1Q5.cjs → blobs-B0977K1O.cjs} +7 -6
- package/dist/src/{blobs-BCZavS8s.js → blobs-CeFdPn_T.js} +3 -3
- package/dist/src/{blobs-BQWqnnvL.js → blobs-DODuTK-a.js} +3 -3
- package/dist/src/{blobs-C-F78Kfn.js → blobs-Dwef1Ao1.js} +2 -2
- package/dist/src/{cache-BIyPcp5v.cjs → cache-CPGUA4Yl.cjs} +135 -25
- package/dist/src/cache-Cf7b4pWE.js +3 -0
- package/dist/src/{cache-D5NZmMiT.js → cache-DIXbtkNO.js} +125 -10
- package/dist/src/{cache-mb7c8hbp.js → cache-DpPWrkTE.js} +128 -12
- package/dist/src/{cache-C4Xb-hNb.js → cache-roFAE0cI.js} +126 -11
- package/dist/src/{chat-I9izLm49.js → chat-CUCorGiL.js} +12 -12
- package/dist/src/{chat-BPXSW8Bv.cjs → chat-DG1wG4w0.cjs} +6 -6
- package/dist/src/{chat-BfPaS15_.js → chat-Dabu84Br.js} +12 -12
- package/dist/src/{chat-Dr3DUQ0D.js → chat-DqUFcWI0.js} +12 -12
- package/dist/src/{chat-CclRbxGf.cjs → chat-DxTDQ83C.cjs} +14 -13
- package/dist/src/{chat-MKxMnZJZ.js → chat-GmlolEwo.js} +4 -4
- package/dist/src/{chat-0bwXjVP0.js → chat-TP8Qifkh.js} +6 -6
- package/dist/src/{chat-mW0ORo8G.js → chat-iwaM5UTQ.js} +6 -6
- package/dist/src/{chatkit-zUIVoDos.js → chatkit-B6DWi70Q.js} +4 -4
- package/dist/src/{chatkit-BoWoSgXl.cjs → chatkit-BYveR48_.cjs} +6 -5
- package/dist/src/{chatkit-Cv6AhukM.js → chatkit-fARZwEfV.js} +3 -3
- package/dist/src/{chatkit-CJnHRRMM.js → chatkit-lb6FK02w.js} +4 -4
- package/dist/src/{claude-agent-sdk-Dtq_L-Sc.js → claude-agent-sdk-BQNp_y-F.js} +212 -67
- package/dist/src/{claude-agent-sdk-BQNuLaAK.js → claude-agent-sdk-D5Jl0SDh.js} +212 -67
- package/dist/src/{claude-agent-sdk-CPJo3dBQ.cjs → claude-agent-sdk-DH416NBD.cjs} +218 -72
- package/dist/src/{claude-agent-sdk-nfAIcxNf.js → claude-agent-sdk-x1XJ1-pU.js} +212 -67
- package/dist/src/{cloud-DQZ5sVjW.js → cloud-D3DiFqH6.js} +3 -3
- package/dist/src/cloud-p96PA4MH.js +3 -0
- package/dist/src/{cloudflare-ai-BIB567w6.js → cloudflare-ai-B6NVI3ax.js} +4 -4
- package/dist/src/{cloudflare-ai-Dl3N9OVD.cjs → cloudflare-ai-CEAW-xQa.cjs} +6 -6
- package/dist/src/{cloudflare-ai-DlKr0rY7.js → cloudflare-ai-RFSojyXG.js} +6 -6
- package/dist/src/{cloudflare-ai-DGLte7Py.js → cloudflare-ai-r4tbYmWU.js} +6 -6
- package/dist/src/{cloudflare-gateway-CiIZHU0Q.js → cloudflare-gateway-BCkLouto.js} +5 -5
- package/dist/src/{cloudflare-gateway-DI1HNP5F.js → cloudflare-gateway-BaZ4insB.js} +3 -3
- package/dist/src/{cloudflare-gateway-BDZrYydE.js → cloudflare-gateway-CF-Vb-2Z.js} +5 -5
- package/dist/src/{cloudflare-gateway-BYDp495F.cjs → cloudflare-gateway-TJMLBj6I.cjs} +5 -5
- package/dist/src/codex-app-server-B8KHEiF4.js +1915 -0
- package/dist/src/codex-app-server-CnrLBCeA.cjs +1921 -0
- package/dist/src/codex-app-server-DIXZ230V.js +1915 -0
- package/dist/src/codex-app-server-Dd22dC_N.js +1916 -0
- package/dist/src/{codex-sdk-CpqiOqDO.js → codex-sdk-B6Wah8Pa.js} +6 -6
- package/dist/src/codex-sdk-BGjVAk23.js +3 -0
- package/dist/src/{codex-sdk-C2_M2pl_.cjs → codex-sdk-CFF6gUyi.cjs} +18 -10
- package/dist/src/{codex-sdk-Rtky3M4I.js → codex-sdk-CmQABzV3.js} +6 -6
- package/dist/src/{codex-sdk-CErXn7qh.js → codex-sdk-D2d54RL8.js} +5 -5
- package/dist/src/{cometapi-CtJ-mS8R.js → cometapi-Bu9B8NUY.js} +8 -8
- package/dist/src/{cometapi-DT-jlVCB.js → cometapi-CtzNCHKu.js} +7 -7
- package/dist/src/{cometapi-UVOryo4W.cjs → cometapi-DHCDlQUI.cjs} +8 -8
- package/dist/src/{cometapi-BUlt_ELa.js → cometapi-OBILPLlu.js} +8 -8
- package/dist/src/{completion-HUe8wDhZ.js → completion-CO2e1_62.js} +6 -6
- package/dist/src/{completion-BozdoXba.cjs → completion-CSYfl2cd.cjs} +6 -6
- package/dist/src/{completion-x0a_c2y1.js → completion-DZNxcyfG.js} +6 -6
- package/dist/src/{completion-Dnxn7E-j.js → completion-sNvCLTAP.js} +5 -5
- package/dist/src/constants-BjJV0cRr.js +6 -0
- package/dist/src/constants-DH5XYLKZ.js +7 -0
- package/dist/src/constants-DZGEFLsu.js +6 -0
- package/dist/src/constants-a2kYssQk.cjs +11 -0
- package/dist/src/{createHash-4gFQpDDv.js → createHash-BtbSX3mj.js} +1 -1
- package/dist/src/{createHash-CwDVU5xr.js → createHash-CGVzWdjj.js} +1 -1
- package/dist/src/{createHash-B7KvgoOD.cjs → createHash-CSiqnK5P.cjs} +2 -2
- package/dist/src/{createHash-ChI45QR1.js → createHash-CgRvs4Fn.js} +1 -1
- package/dist/src/crescendo-BXEJK_bi.cjs +704 -0
- package/dist/src/crescendo-CU_Y2i-m.js +702 -0
- package/dist/src/crescendo-J1Xx4_zb.js +703 -0
- package/dist/src/crescendo-QiaSLW0d.js +701 -0
- package/dist/src/custom-BJfP00Bh.js +619 -0
- package/dist/src/custom-CZVn-1-r.js +620 -0
- package/dist/src/custom-Cqia7M0D.cjs +621 -0
- package/dist/src/custom-notggYVl.js +618 -0
- package/dist/src/{docker-DCgsveLD.js → docker-4D1eL6Gq.js} +6 -6
- package/dist/src/{docker-ClnmCf1Z.js → docker-BBv1WUDu.js} +5 -5
- package/dist/src/{docker-DS4_Osau.cjs → docker-D06JUoe2.cjs} +6 -6
- package/dist/src/{docker-CQmlA2NU.js → docker-DdJQBxK9.js} +6 -6
- package/dist/src/{embedding-D3xTseo7.js → embedding--UZVe4_7.js} +6 -6
- package/dist/src/{embedding-I45KG3o7.cjs → embedding-BbrwopfX.cjs} +6 -6
- package/dist/src/{embedding-nFbumxcv.js → embedding-Bi3rxrZF.js} +5 -5
- package/dist/src/{embedding-DD9wa3ae.js → embedding-C251p1-8.js} +6 -6
- package/dist/src/{errors-Cw810C93.js → errors-9PcUL8BC.js} +1 -1
- package/dist/src/{esm-Dh4dOLlt.js → esm-B6whoAcf.js} +2 -2
- package/dist/src/{esm-CtEPLdAj.cjs → esm-BIKakvNa.cjs} +8 -7
- package/dist/src/{esm-C7PnfdF8.js → esm-BTK1W7lG.js} +1 -1
- package/dist/src/{esm-tVgYPY-f.js → esm-Bexx2PFc.js} +2 -2
- package/dist/src/{eval-u4UVafl6.js → eval-0VRANImH.js} +21 -21
- package/dist/src/{eval-CzJFfFO9.js → eval-DscR5iOM.js} +1 -1
- package/dist/src/{evalResult-Bgm9ZH31.js → evalResult-2RRJvFyB.js} +41 -16
- package/dist/src/{evalResult-KZqXl4XP.cjs → evalResult-CvtS8h8u.cjs} +51 -15
- package/dist/src/evalResult-DqzsS6_W.js +3 -0
- package/dist/src/{evalResult-D3hVYFis.js → evalResult-eUkJv9Ko.js} +40 -15
- package/dist/src/evaluator-DNdJF1Gv.js +3 -0
- package/dist/src/{evaluator-IvuDYSvQ.js → evaluator-DRoiYB2q.js} +1060 -187
- package/dist/src/evaluatorHelpers-BsYP_muT.js +511 -0
- package/dist/src/evaluatorHelpers-CRqTvSux.cjs +537 -0
- package/dist/src/evaluatorHelpers-DuqFFfq7.js +510 -0
- package/dist/src/{extractor-CAfTSraf.js → extractor-BR7XAzAL.js} +6 -6
- package/dist/src/{extractor-WVPOrH43.cjs → extractor-BdxEtt3J.cjs} +6 -6
- package/dist/src/{extractor-DNSeBVOJ.js → extractor-CIW3iN-b.js} +6 -6
- package/dist/src/{extractor-Dk6bRWkv.js → extractor-CxRtnaHl.js} +5 -5
- package/dist/src/{fetch-B0Z3Oe4k.js → fetch-BufrQtvR.js} +93 -40
- package/dist/src/{fetch-BEWnXrrG.js → fetch-DXUnXkVU.js} +89 -40
- package/dist/src/{fetch-CJU5ELPa.cjs → fetch-Dw4XZHjj.cjs} +330 -270
- package/dist/src/{fetch-Di00EQrc.js → fetch-It34O8Ur.js} +305 -252
- package/dist/src/fetch-_YgGd2qv.js +3 -0
- package/dist/src/{fileExtensions-bYh77CN8.cjs → fileExtensions-BhdwzYaD.cjs} +24 -1
- package/dist/src/{fileExtensions-DnqA1y9x.js → fileExtensions-CXRfY3Ss.js} +12 -2
- package/dist/src/{fileExtensions-AWa2ZML4.js → fileExtensions-D4GCJ67J.js} +12 -2
- package/dist/src/{formatDuration-DZzPsexs.js → formatDuration-CMVNrYvE.js} +1 -1
- package/dist/src/{genaiTracer-yRuxj9-L.cjs → genaiTracer-14nugQQx.cjs} +14 -2
- package/dist/src/{genaiTracer-DWdZ28hY.js → genaiTracer-BPVvltoW.js} +2 -2
- package/dist/src/{genaiTracer-XnrcgDCe.js → genaiTracer-D18lYzhB.js} +2 -2
- package/dist/src/{genaiTracer-COYDi-tC.js → genaiTracer-jJKYsnjc.js} +2 -2
- package/dist/src/goat-Ckd3q3AY.js +467 -0
- package/dist/src/goat-Qgurm-NP.js +466 -0
- package/dist/src/goat-ghadEDdy.js +465 -0
- package/dist/src/goat-una6pZGP.cjs +469 -0
- package/dist/src/graders-BDT7dif6.js +3 -0
- package/dist/src/{graders-eIHhRqoC.js → graders-BGP99PdK.js} +2416 -2224
- package/dist/src/{graders-Zy3x0zqX.js → graders-BX0f2tvS.js} +2423 -2226
- package/dist/src/{graders-pvbReLLn.js → graders-C0nXU_ZP.js} +1806 -1609
- package/dist/src/{graders--zknU_uk.cjs → graders-ClrU2fnd.cjs} +2219 -1949
- package/dist/src/hydra-BSNZZm2M.js +543 -0
- package/dist/src/hydra-BxdG4nkg.js +541 -0
- package/dist/src/hydra-DE4xWwyc.js +542 -0
- package/dist/src/hydra-DrJttnvw.cjs +542 -0
- package/dist/src/image-B4oBtu6J.js +443 -0
- package/dist/src/{image-dnoUgPrC.js → image-BN-hjLL9.js} +4 -4
- package/dist/src/{image-9302QVqR.js → image-B_fPIwdg.js} +3 -3
- package/dist/src/image-BvUAW344.js +442 -0
- package/dist/src/image-Cvjwx1uY.js +442 -0
- package/dist/src/{image-De2FBmYV.cjs → image-DfVCGPbI.cjs} +4 -4
- package/dist/src/{image-u7-rKnYU.js → image-QzmydkiG.js} +4 -4
- package/dist/src/image-X0oY4350.cjs +465 -0
- package/dist/src/index.cjs +1689 -558
- package/dist/src/index.d.cts +3270 -1624
- package/dist/src/index.d.ts +3270 -1624
- package/dist/src/index.js +1553 -438
- package/dist/src/indirectWebPwn-02ZIghCS.js +259 -0
- package/dist/src/indirectWebPwn-BJ22AbQa.cjs +397 -0
- package/dist/src/indirectWebPwn-CbjUG0rh.js +385 -0
- package/dist/src/indirectWebPwn-CfQJt3gk.cjs +260 -0
- package/dist/src/indirectWebPwn-DBQhOjoD.js +260 -0
- package/dist/src/indirectWebPwn-OsXnKejv.js +259 -0
- package/dist/src/indirectWebPwn-tNx9OZ35.js +385 -0
- package/dist/src/indirectWebPwn-uyWdHx04.js +386 -0
- package/dist/src/inputVariables-B0qUChbV.js +467 -0
- package/dist/src/inputVariables-DUGMb9Ka.js +464 -0
- package/dist/src/inputVariables-DXFdi7AI.js +468 -0
- package/dist/src/inputVariables-Dq9W-Z3a.cjs +475 -0
- package/dist/src/{interactiveCheck-CLERUB0c.js → interactiveCheck-C4QlIuoR.js} +2 -2
- package/dist/src/{invariant-BtWWVVhl.js → invariant-B2Rf6avk.js} +1 -1
- package/dist/src/{invariant-vgHWClmd.js → invariant-DIYf9sP1.js} +1 -1
- package/dist/src/{invariant-kfQ8Bu82.cjs → invariant-QtnLD03y.cjs} +1 -1
- package/dist/src/iterative-CpU6i2As.js +490 -0
- package/dist/src/iterative-DJQEQpG3.js +491 -0
- package/dist/src/iterative-DQBuWM-j.cjs +493 -0
- package/dist/src/iterative-FTS4Bz67.js +492 -0
- package/dist/src/iterativeImage-BUABMVOA.js +413 -0
- package/dist/src/iterativeImage-ByFWkxax.cjs +415 -0
- package/dist/src/iterativeImage-BzUapOUi.js +414 -0
- package/dist/src/iterativeImage-Doz8mgxF.js +413 -0
- package/dist/src/iterativeMeta-B3YiAOc8.js +386 -0
- package/dist/src/iterativeMeta-C7APE_P1.js +385 -0
- package/dist/src/iterativeMeta-CSS8M6Ds.cjs +385 -0
- package/dist/src/iterativeMeta-DgoQ7bLh.js +384 -0
- package/dist/src/iterativeTree-B5zxBBSW.js +769 -0
- package/dist/src/iterativeTree-CNyIk0Yn.js +768 -0
- package/dist/src/iterativeTree-CPMF10ve.cjs +771 -0
- package/dist/src/iterativeTree-DvZ7GBwt.js +770 -0
- package/dist/src/{knowledgeBase-Dgc7CBWF.js → knowledgeBase-BadkINlJ.js} +24 -10
- package/dist/src/{knowledgeBase-RhFPGWDc.js → knowledgeBase-Bi_8sV-H.js} +25 -11
- package/dist/src/{knowledgeBase-lm9RXSAm.js → knowledgeBase-CkMljjdg.js} +25 -11
- package/dist/src/{knowledgeBase-Bpoe_nLu.cjs → knowledgeBase-DUh34xba.cjs} +25 -11
- package/dist/src/{litellm-DRjpcSa7.js → litellm-BKBo0jpC.js} +5 -5
- package/dist/src/{litellm-C2kqjxqp.js → litellm-BXyn5kZK.js} +5 -5
- package/dist/src/{litellm-p37R1dzQ.js → litellm-CNcfbCfa.js} +4 -4
- package/dist/src/{litellm-CoyI4IAl.cjs → litellm-CtAr7bKG.cjs} +5 -5
- package/dist/src/{logger-DksKw1Qc.js → logger-BbY6ypFL.js} +2 -2
- package/dist/src/{logger-B88EkIn6.js → logger-KD8JjCRJ.js} +2 -2
- package/dist/src/{logger-COuQb2xB.cjs → logger-cfNpzI4o.cjs} +13 -55
- package/dist/src/{luma-ray-KgTCXrZC.js → luma-ray-BMX1iEB6.js} +5 -5
- package/dist/src/{luma-ray-B863CmuZ.js → luma-ray-CR5TSpp4.js} +5 -5
- package/dist/src/{luma-ray-BxVKaW2a.cjs → luma-ray-D3FUc2K3.cjs} +9 -8
- package/dist/src/{luma-ray-BTTLtqQ8.js → luma-ray-OEMmS1RB.js} +6 -6
- package/dist/src/main.js +909 -369
- package/dist/src/memoryPoisoning-CM83NWYl.js +107 -0
- package/dist/src/memoryPoisoning-D8h9gXJF.js +106 -0
- package/dist/src/memoryPoisoning-Dp-btinn.cjs +106 -0
- package/dist/src/memoryPoisoning-cLuCoTuJ.js +106 -0
- package/dist/src/{messages-BTQz42fn.js → messages-BabO-cX8.js} +273 -17
- package/dist/src/{messages-811uVVW5.cjs → messages-DBPir0TQ.cjs} +278 -18
- package/dist/src/{messages-zWbkLLHz.js → messages-DGUlSNU7.js} +273 -17
- package/dist/src/{messages-MYTQ2TWp.js → messages-vsE_-Lv0.js} +273 -17
- package/dist/src/{meteor-DHdzY1Ss.js → meteor--TZYICTI.js} +2 -2
- package/dist/src/{meteor-Co1VQ1u5.cjs → meteor-CR226f7Z.cjs} +2 -2
- package/dist/src/{meteor-CU5UAE-H.js → meteor-Cl_yd7rJ.js} +2 -2
- package/dist/src/{meteor-DuAFv6gF.js → meteor-Dce-_zGQ.js} +1 -1
- package/dist/src/mischievousUser-0l8GD7Dp.js +46 -0
- package/dist/src/mischievousUser-BUOP9W5r.js +46 -0
- package/dist/src/mischievousUser-frFYKxu6.js +47 -0
- package/dist/src/mischievousUser-olGgHIVR.cjs +46 -0
- package/dist/src/{modelslab-Dk1JAtVo.cjs → modelslab-CNV5bMSk.cjs} +7 -7
- package/dist/src/{modelslab-D0erNWKe.js → modelslab-Cogmu4mG.js} +6 -6
- package/dist/src/{modelslab-DIq-6y7x.js → modelslab-Dzst7VTU.js} +6 -6
- package/dist/src/{modelslab-wu9yi5GE.js → modelslab-EyDczZ5A.js} +7 -7
- package/dist/src/{nova-reel-CCFRfeRb.js → nova-reel-BGPNBOMS.js} +6 -6
- package/dist/src/{nova-reel-DQrm74ng.js → nova-reel-B_5NKFu1.js} +5 -5
- package/dist/src/{nova-reel-gr11WG7f.js → nova-reel-C4eUJGse.js} +5 -5
- package/dist/src/{nova-reel-CrLXVKQf.cjs → nova-reel-CjJRxI1X.cjs} +9 -8
- package/dist/src/{nova-sonic-BYdp-QLs.js → nova-sonic-BNGmgfFz.js} +4 -4
- package/dist/src/{nova-sonic-TDgrlTk7.js → nova-sonic-ChPlh5na.js} +4 -4
- package/dist/src/{nova-sonic-B_ZXcUJB.js → nova-sonic-CrV0iaY_.js} +3 -3
- package/dist/src/{nova-sonic-i5tUvXKn.cjs → nova-sonic-DuOG9Aun.cjs} +5 -4
- package/dist/src/{openai-DhVEmgeZ.js → openai-BMHD2Huo.js} +2 -2
- package/dist/src/{openai-URNyItar.cjs → openai-C3uXv8wS.cjs} +2 -2
- package/dist/src/{openai-Qsvz25mV.js → openai-CJrsh9n4.js} +2 -2
- package/dist/src/{openai-iYtrXzOX.js → openai-zgwBb4Ff.js} +1 -1
- package/dist/src/{openclaw-CnQ363Wi.js → openclaw-BIHlu_36.js} +10 -8
- package/dist/src/{openclaw-CwzlQSQX.js → openclaw-CF7fMido.js} +9 -7
- package/dist/src/{openclaw-wX9rtfke.cjs → openclaw-Dphc01BY.cjs} +18 -15
- package/dist/src/{openclaw-CLWrW03k.js → openclaw-zIJAsz3P.js} +10 -8
- package/dist/src/{opencode-sdk-BUu5Nevv.js → opencode-sdk-B3vlPLsp.js} +40 -5
- package/dist/src/{opencode-sdk-BxD8vXp_.js → opencode-sdk-D05JSgMQ.js} +40 -5
- package/dist/src/{opencode-sdk-BZ2idgYA.cjs → opencode-sdk-DoY6GbWw.cjs} +46 -10
- package/dist/src/{opencode-sdk-GI2KaAXq.js → opencode-sdk-sRKYHGoI.js} +39 -4
- package/dist/src/{otlpReceiver-BntK801g.js → otlpReceiver--gTpSagc.js} +120 -4
- package/dist/src/{otlpReceiver-DmVulbhC.js → otlpReceiver-B2eaKC8C.js} +120 -4
- package/dist/src/{otlpReceiver-B2z58l4e.js → otlpReceiver-BXjcRqAM.js} +119 -3
- package/dist/src/{otlpReceiver-BfcVq2Nq.cjs → otlpReceiver-CvJdBGSc.cjs} +125 -7
- package/dist/src/packageParser--MWTSrPW.js +36 -0
- package/dist/src/packageParser-CgE-ziRo.js +35 -0
- package/dist/src/packageParser-QoCS1FMl.cjs +54 -0
- package/dist/src/packageParser-hwwSGnAZ.js +35 -0
- package/dist/src/processShim-BBxt7LKO.js +95 -0
- package/dist/src/processShim-BcGzU8fY.js +94 -0
- package/dist/src/processShim-C_z3aRvF.js +94 -0
- package/dist/src/processShim-DSY9BV2T.cjs +98 -0
- package/dist/src/promptLength-0qIHyhA5.js +71 -0
- package/dist/src/promptLength-4X-Wd8PG.js +72 -0
- package/dist/src/promptLength-B9nZEfO6.js +71 -0
- package/dist/src/promptLength-BbBbDHNj.cjs +94 -0
- package/dist/src/promptfoo-BDrfT30-.js +180 -0
- package/dist/src/promptfoo-Cm4hiy1Y.js +180 -0
- package/dist/src/promptfoo-Rjp-MeBb.js +181 -0
- package/dist/src/promptfoo-b-baRMj-.cjs +205 -0
- package/dist/src/prompts-BYMtqPCw.js +259 -0
- package/dist/src/prompts-C-bqE1Yp.js +260 -0
- package/dist/src/prompts-Cp_Qx5Ml.js +270 -0
- package/dist/src/prompts-DHhQsANy.js +259 -0
- package/dist/src/prompts-D_QpZ2Dm.js +271 -0
- package/dist/src/prompts-hNvWBD3z.cjs +284 -0
- package/dist/src/prompts-huDVH2CI.js +270 -0
- package/dist/src/prompts-p78Hul5i.cjs +289 -0
- package/dist/src/{providerRegistry-CPQ_CmVO.js → providerRegistry-1gB5vtzQ.js} +2 -2
- package/dist/src/{providerRegistry-CQMdTmHP.cjs → providerRegistry-CZO_w7ue.cjs} +2 -2
- package/dist/src/{providerRegistry-Bvh8mv85.js → providerRegistry-DHcFiVWX.js} +1 -1
- package/dist/src/{providerRegistry-CWoPjKFZ.js → providerRegistry-ReCd0sFa.js} +2 -2
- package/dist/src/{providers-BV_KMZje.js → providers-B9KzWxAX.js} +10558 -21587
- package/dist/src/{providers-DruaQfwu.js → providers-BCCz6_IX.js} +1228 -12196
- package/dist/src/{providers-1eKkXBKp.cjs → providers-BDVVIQM6.cjs} +10649 -21843
- package/dist/src/{providers-iUt5fbAN.js → providers-BYAn82cf.js} +1 -1
- package/dist/src/{providers-Domz_llv.js → providers-DVYRZP4E.js} +10589 -21570
- package/dist/src/{pythonUtils-Cldx7huE.js → pythonUtils-CLCgQ9tt.js} +3 -3
- package/dist/src/{pythonUtils-CnndUbW-.js → pythonUtils-CgYxeSmO.js} +3 -3
- package/dist/src/{pythonUtils-tAJvvpS-.cjs → pythonUtils-Cokhluq3.cjs} +8 -7
- package/dist/src/{pythonUtils-C2UQ30Rz.js → pythonUtils-D0BYebvX.js} +3 -3
- package/dist/src/{quiverai-DFotyafY.cjs → quiverai-BAp6iTZD.cjs} +4 -4
- package/dist/src/{quiverai-aPPvXOgn.js → quiverai-BvIhI_0l.js} +4 -4
- package/dist/src/{quiverai-DR0SnIQV.js → quiverai-CdTWPe-A.js} +3 -3
- package/dist/src/{quiverai-CtWi6x_g.js → quiverai-Cv7rJKDz.js} +4 -4
- package/dist/src/registry-BUJrgjwv.js +124 -0
- package/dist/src/registry-DXm1t_x0.js +125 -0
- package/dist/src/registry-Dp5EqoXc.js +124 -0
- package/dist/src/registry-KCVF1CFC.cjs +124 -0
- package/dist/src/{server-D6Il2Sob.js → remoteGeneration-B1_XsKXU.js} +16 -108
- package/dist/src/{server-BSB45Nt9.js → remoteGeneration-COpWcmWd.js} +15 -146
- package/dist/src/{server-Dx2TyCH2.cjs → remoteGeneration-DS9N3pgB.cjs} +30 -119
- package/dist/src/remoteGeneration-DsaSwmG2.js +217 -0
- package/dist/src/render-BNTrbmBw.cjs +384 -0
- package/dist/src/render-CSP99NLm.js +348 -0
- package/dist/src/render-DFfDeYUK.js +347 -0
- package/dist/src/{render-CgVDrJmM.js → render-DznWrxGO.js} +2 -2
- package/dist/src/render-_6ur1fhE.js +347 -0
- package/dist/src/resourceAttributes-D1jP3kL5.js +17 -0
- package/dist/src/resourceAttributes-DQbBB--2.js +16 -0
- package/dist/src/resourceAttributes-ephgOvdR.cjs +27 -0
- package/dist/src/resourceAttributes-v6-I67fn.js +16 -0
- package/dist/src/{responses-Bi9vBuW_.cjs → responses-1UFFF9N_.cjs} +51 -16
- package/dist/src/{responses-DL9m8CyY.js → responses-B3W2JvOQ.js} +49 -15
- package/dist/src/{responses--OsX2aYW.js → responses-B6ktc3Ra.js} +49 -15
- package/dist/src/{responses-C-flexAY.js → responses-URRzV8qE.js} +49 -15
- package/dist/src/rolldown-runtime-D_mwlA32.cjs +43 -0
- package/dist/src/rubyUtils-BYVlQ94c.js +3 -0
- package/dist/src/{rubyUtils-DsGrTx8R.js → rubyUtils-CXlFM2rR.js} +3 -3
- package/dist/src/{rubyUtils-DVLeA2jg.js → rubyUtils-CnlW8AYb.js} +3 -3
- package/dist/src/{rubyUtils-B6eljPuh.cjs → rubyUtils-CqUWBZAt.cjs} +18 -27
- package/dist/src/{rubyUtils-CYSQEG4a.js → rubyUtils-DdGojpfv.js} +3 -3
- package/dist/src/runtimeTransform-BJOpL9Yc.js +142 -0
- package/dist/src/runtimeTransform-Dgh_D7DU.js +143 -0
- package/dist/src/runtimeTransform-DigbjU1r.js +142 -0
- package/dist/src/runtimeTransform-ON3YYILw.cjs +147 -0
- package/dist/src/{sagemaker-BVkaG2-l.js → sagemaker-CujrzP1a.js} +62 -51
- package/dist/src/{sagemaker-XnfhheQv.cjs → sagemaker-DzffAqo_.cjs} +65 -53
- package/dist/src/{sagemaker-D67yzMzs.js → sagemaker-vhtSV7JI.js} +62 -51
- package/dist/src/{sagemaker-BveBvuxm.js → sagemaker-yr1QKeBs.js} +61 -50
- package/dist/src/{scanner-1DqWi1Ej.js → scanner-DS0109SS.js} +7 -7
- package/dist/src/server/index.js +5105 -605
- package/dist/src/server-B8rqV126.cjs +126 -0
- package/dist/src/server-BaLytskk.js +3 -0
- package/dist/src/server-CMJD10J4.js +107 -0
- package/dist/src/server-Ddp8GNMp.js +146 -0
- package/dist/src/server-DhMHosWj.js +182 -0
- package/dist/src/shared-7pmVZLNO.js +1334 -0
- package/dist/src/shared-9WHQ1oNE.js +1335 -0
- package/dist/src/{fileExtensions-BArZuxsI.js → shared-BoG7qLMv.js} +12 -2
- package/dist/src/shared-D6IjElRI.js +1334 -0
- package/dist/src/shared-WkgnDkcg.cjs +1436 -0
- package/dist/src/{signal-CE5G3a7x.js → signal-CSurUUyV.js} +3 -3
- package/dist/src/simulatedUser-C9aQObBI.js +222 -0
- package/dist/src/simulatedUser-Cu601Dd4.cjs +227 -0
- package/dist/src/simulatedUser-U_qAHnuB.js +222 -0
- package/dist/src/simulatedUser-p3tACcmw.js +223 -0
- package/dist/src/{slack-DDUe-5MC.js → slack-Bapo-7_8.js} +2 -2
- package/dist/src/{slack-1Rhq0EoV.cjs → slack-DMC1QVEg.cjs} +3 -2
- package/dist/src/{slack-D5Wpy8LM.js → slack-DTEFhrMn.js} +2 -2
- package/dist/src/{slack-acRb0IqQ.js → slack-k-_CP84Q.js} +1 -1
- package/dist/src/storage-BU4qcnOb.js +875 -0
- package/dist/src/storage-CA-v9V2v.cjs +911 -0
- package/dist/src/storage-CD-GWAdx.js +822 -0
- package/dist/src/storage-QdU-SmvD.js +834 -0
- package/dist/src/{store-DAAyxcy6.cjs → store-B2NDDooM.cjs} +60 -24
- package/dist/src/{store-CYEy5J2D.js → store-DKd5592Q.js} +51 -20
- package/dist/src/{store-M0b1WfYb.js → store-HpopRVzl.js} +50 -19
- package/dist/src/store-IbiRIF3k.js +3 -0
- package/dist/src/strategies-7CS3Alao.cjs +2360 -0
- package/dist/src/strategies-CiSeroPH.js +2331 -0
- package/dist/src/strategies-DRJjGTIY.js +2333 -0
- package/dist/src/{tables-DQ4WU5tX.js → tables-CRSXQ2Ke.js} +2 -2
- package/dist/src/{tables-CsWou1Bx.js → tables-CxjU7bBd.js} +3 -3
- package/dist/src/{tables-DUfh1F7Z.cjs → tables-DBIJU0WE.cjs} +6 -5
- package/dist/src/{tables-C4CH3zRr.js → tables-DafUHOeh.js} +3 -3
- package/dist/src/{telemetry-CQPez_Jp.js → telemetry-00ezXr_t.js} +5 -4
- package/dist/src/telemetry-ByPqDcKC.js +3 -0
- package/dist/src/{telemetry-Dsw_faFj.cjs → telemetry-CJ7FnCsc.cjs} +18 -11
- package/dist/src/{telemetry-dbaJ0E98.js → telemetry-DmXYcJNV.js} +5 -4
- package/dist/src/{telemetry-Dvqxv3YC.js → telemetry-DwX9XUN5.js} +4 -3
- package/dist/src/{text-KvuD2Iko.js → text-Db-Wt2u2.js} +1 -1
- package/dist/src/{text-DHxdyQqT.js → text-DwYK5EBn.js} +1 -1
- package/dist/src/{text-BVi-cLPJ.cjs → text-nywWsRBM.cjs} +1 -1
- package/dist/src/{tokenUsageUtils-C-bmyHoE.js → tokenUsageUtils-BjVkdk18.js} +1 -1
- package/dist/src/{tokenUsageUtils-CXrvO-wA.js → tokenUsageUtils-CDet74yk.js} +1 -1
- package/dist/src/tokenUsageUtils-CmnQ0G2m.js +142 -0
- package/dist/src/{tokenUsageUtils-Bb7DkZPz.cjs → tokenUsageUtils-_B-P8IAi.cjs} +1 -1
- package/dist/src/toolAttributes-BAjwcBf0.cjs +103 -0
- package/dist/src/toolAttributes-COVgDrBG.js +87 -0
- package/dist/src/toolAttributes-DJ9ZEKXD.js +86 -0
- package/dist/src/tracingOptions-BnwKCkSB.js +221 -0
- package/dist/src/tracingOptions-Chi74lOD.js +219 -0
- package/dist/src/tracingOptions-DrbSFaKy.cjs +249 -0
- package/dist/src/tracingOptions-ji2OuXbT.js +220 -0
- package/dist/src/{transcription-DuWDupG7.js → transcription-B8uIgCYX.js} +5 -5
- package/dist/src/{transcription-CJspiD2c.js → transcription-CfU5loSq.js} +6 -6
- package/dist/src/{transcription-V2HaAmy2.js → transcription-Dkd22_4K.js} +6 -6
- package/dist/src/{transcription-BvjmiYB1.cjs → transcription-mzuf18Mq.cjs} +9 -8
- package/dist/src/{transform-lQrDE1BQ.js → transform-BIMynQsA.js} +9 -9
- package/dist/src/transform-BnSTnFlp.js +187 -0
- package/dist/src/transform-BnSXWmU_2.cjs +221 -0
- package/dist/src/transform-CGt7Kt3y2.js +186 -0
- package/dist/src/transform-CrPGTsij.js +186 -0
- package/dist/src/{transform-CTeuTR3S.cjs → transform-DhNkAUs8.cjs} +13 -12
- package/dist/src/{transform-CG0ehZNG.js → transform-DmvYBRll.js} +9 -9
- package/dist/src/{transform-zDhMmzwX.js → transform-EtD4jAWi.js} +9 -9
- package/dist/src/{transformersAvailability-CcHusyhw.js → transformersAvailability-0ThtPved.js} +1 -1
- package/dist/src/transformersAvailability-BYydDE5U.js +35 -0
- package/dist/src/{transformersAvailability-DLlROWhg.js → transformersAvailability-BvyU9vDD.js} +1 -1
- package/dist/src/{transformersAvailability-Cju9mHgR.cjs → transformersAvailability-BytPvKUW.cjs} +1 -1
- package/dist/src/{types-Dm9JM6Vb.js → types-BFevViUY.js} +115 -19
- package/dist/src/{types-Bgh5SOn6.js → types-BJQBBPTP.js} +115 -19
- package/dist/src/{types-CeaeaZdP.cjs → types-CxJvaY2S.cjs} +357 -172
- package/dist/src/{types-BGQDAP8i.js → types-D6glLbdF.js} +271 -170
- package/dist/src/{util-BYvQUPp7.js → util--WMgw7wM.js} +28 -8
- package/dist/src/{util-C9J8ahRn.js → util-5WnCSb0h.js} +72 -48
- package/dist/src/{util-CN3SrLT4.cjs → util-BSIuSLVK.cjs} +74 -49
- package/dist/src/{util-C8e5uydV.js → util-Bx677_k2.js} +154 -147
- package/dist/src/util-CN8om2rz.cjs +386 -0
- package/dist/src/{util-DDs-7g6-.js → util-CoQWM76y.js} +28 -8
- package/dist/src/util-DNl96nNs.js +327 -0
- package/dist/src/{util-DxWpWjhc.js → util-DURocbYR.js} +667 -507
- package/dist/src/util-Df8YMvS1.js +327 -0
- package/dist/src/{util-DvU2Pw8c.js → util-DiQ3QvBB.js} +28 -8
- package/dist/src/{util-oGMLA7vc.js → util-I-Rf-KaD.js} +862 -577
- package/dist/src/{util-olYL5C6N.cjs → util-IYzs5Y04.cjs} +33 -7
- package/dist/src/{util-D9TisOyk.js → util-LKTmNsMQ.js} +71 -47
- package/dist/src/{util-Bxn8emtE.cjs → util-SPsvFONY.cjs} +738 -582
- package/dist/src/{util-D3q0WQ-0.js → util-efByNxcr.js} +72 -48
- package/dist/src/util-kDURhgJW.js +328 -0
- package/dist/src/{utils-DJfvjyMj.js → utils-B0lzitHZ.js} +3 -3
- package/dist/src/{utils-BLJKfv0y.js → utils-BFOh20Gb.js} +3 -3
- package/dist/src/{utils-hXtCYanr.js → utils-BGY69tk_.js} +2 -2
- package/dist/src/{utils-B05gLxER.cjs → utils-Ve6kuJsa.cjs} +3 -3
- package/dist/src/version-BK20a4sw.js +16 -0
- package/dist/src/version-BWCSaByA.cjs +27 -0
- package/dist/src/version-eRkNuGv8.js +17 -0
- package/dist/src/version-lpHV_53E.js +16 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +56 -28
- package/dist/src/app/assets/Report-CQYFezYu.js +0 -1
- package/dist/src/app/assets/index-BXGkeMwh.css +0 -1
- package/dist/src/app/assets/index-BzJt18Jz.js +0 -385
- package/dist/src/app/assets/sync-IjzpWrOE.js +0 -4
- package/dist/src/app/assets/vendor-charts-BNdH8TCw.js +0 -36
- package/dist/src/cache-Cr9oLMUa.js +0 -3
- package/dist/src/cache-DbLsVWB2.cjs +0 -3
- package/dist/src/cloud-Hphvo8kr.js +0 -3
- package/dist/src/codex-sdk-BAmYE7qy.js +0 -3
- package/dist/src/codex-sdk-CWEnH70W.cjs +0 -2
- package/dist/src/evalResult-D8MT9p0s.js +0 -3
- package/dist/src/evalResult-DElBuddX.js +0 -2
- package/dist/src/evalResult-Dvc-iucu.cjs +0 -2
- package/dist/src/evaluator-CVessDWe.js +0 -3
- package/dist/src/fetch-C7bGKDlQ.js +0 -3
- package/dist/src/graders-BOAzQEUe.cjs +0 -2
- package/dist/src/graders-D4BTsZdG2.js +0 -3
- package/dist/src/graders-DOJK1XpV.js +0 -2
- package/dist/src/graders-NAv9LcBn.js +0 -2
- package/dist/src/image-B5Mv-Z3h.js +0 -257
- package/dist/src/image-DVz2RiMF.js +0 -258
- package/dist/src/image-qUpPvmNZ.js +0 -257
- package/dist/src/image-x6KqLQl4.cjs +0 -280
- package/dist/src/providers-Bp4S-FvO.js +0 -2
- package/dist/src/providers-DV3ax9e_.cjs +0 -3
- package/dist/src/providers-u9Enmfok.js +0 -2
- package/dist/src/render-CH-62LbA.js +0 -135
- package/dist/src/render-CMEpfLaO.js +0 -136
- package/dist/src/render-DHIZ6_k8.js +0 -135
- package/dist/src/render-DfQSFxGE.cjs +0 -165
- package/dist/src/rubyUtils-D1L2d3jb.js +0 -3
- package/dist/src/rubyUtils-DUbq4tff.cjs +0 -2
- package/dist/src/server-BNYztJkh.js +0 -385
- package/dist/src/server-DCtHUqlp.js +0 -3
- package/dist/src/server-DaA2eR26.cjs +0 -2
- package/dist/src/store-CWOSz6D_.cjs +0 -2
- package/dist/src/store-DCDBhv7B.js +0 -3
- package/dist/src/store-Dn9HUkdW.js +0 -240
- package/dist/src/telemetry-C1IqxcdW.js +0 -3
- package/dist/src/telemetry-C4ZEa_es.cjs +0 -2
- package/dist/src/transform-Bbg6A8Jk.js +0 -216
- package/dist/src/transform-CUnzlsbn.cjs +0 -228
- package/dist/src/transform-DYX1_Xnh.js +0 -216
- package/dist/src/transform-DgKlRr73.cjs +0 -2
- package/dist/src/transform-M6ITAESf.js +0 -3
- package/dist/src/transform-UN5UGu8U.js +0 -213
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { N as state, T as getEnvBool, m as sanitizeObject, s as logger } from "./logger-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { o as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { N as state, T as getEnvBool, m as sanitizeObject, s as logger } from "./logger-BbY6ypFL.js";
|
|
3
|
+
import { M as TERMINAL_MAX_WIDTH, n as fetchWithProxy } from "./fetch-DXUnXkVU.js";
|
|
4
|
+
import { n as VERSION } from "./version-eRkNuGv8.js";
|
|
5
|
+
import { t as invariant } from "./invariant-B2Rf6avk.js";
|
|
6
|
+
import { m as isProviderOptions, o as OutputFileExtension, p as isApiProvider, s as ResultFailureReason } from "./types-BFevViUY.js";
|
|
7
|
+
import { i as isJavascriptFile, t as JAVASCRIPT_EXTENSIONS } from "./fileExtensions-D4GCJ67J.js";
|
|
8
|
+
import { o as safeResolve, r as importModule, t as getDirectory } from "./esm-Bexx2PFc.js";
|
|
9
|
+
import { n as renderVarsInObject, o as getNunjucksEngine } from "./render-CSP99NLm.js";
|
|
10
|
+
import { r as runPython } from "./pythonUtils-CgYxeSmO.js";
|
|
10
11
|
import dotenv from "dotenv";
|
|
11
12
|
import * as fs$2 from "fs";
|
|
13
|
+
import fs from "fs";
|
|
12
14
|
import * as path$1 from "path";
|
|
13
15
|
import path from "path";
|
|
14
16
|
import * as os$1 from "os";
|
|
@@ -21,309 +23,6 @@ import { parse as parse$1 } from "csv-parse/sync";
|
|
|
21
23
|
import { globSync, hasMagic } from "glob";
|
|
22
24
|
import { XMLBuilder } from "fast-xml-parser";
|
|
23
25
|
import { stringify } from "csv-stringify/sync";
|
|
24
|
-
//#region src/util/provider.ts
|
|
25
|
-
function canonicalizeProviderId(id) {
|
|
26
|
-
if (id.startsWith("file://")) {
|
|
27
|
-
const filePath = id.slice(7);
|
|
28
|
-
return path$1.isAbsolute(filePath) ? id : `file://${path$1.resolve(filePath)}`;
|
|
29
|
-
}
|
|
30
|
-
for (const prefix of [
|
|
31
|
-
"exec:",
|
|
32
|
-
"python:",
|
|
33
|
-
"golang:"
|
|
34
|
-
]) if (id.startsWith(prefix)) {
|
|
35
|
-
const filePath = id.slice(prefix.length);
|
|
36
|
-
if (filePath.includes("/") || filePath.includes("\\")) return `${prefix}${path$1.resolve(filePath)}`;
|
|
37
|
-
return id;
|
|
38
|
-
}
|
|
39
|
-
if ((id.endsWith(".js") || id.endsWith(".ts") || id.endsWith(".mjs")) && (id.includes("/") || id.includes("\\"))) return `file://${path$1.resolve(id)}`;
|
|
40
|
-
return id;
|
|
41
|
-
}
|
|
42
|
-
function getProviderLabel(provider) {
|
|
43
|
-
return provider?.label && typeof provider.label === "string" ? provider.label : void 0;
|
|
44
|
-
}
|
|
45
|
-
function providerToIdentifier(provider) {
|
|
46
|
-
if (!provider) return;
|
|
47
|
-
if (typeof provider === "string") return canonicalizeProviderId(provider);
|
|
48
|
-
const label = getProviderLabel(provider);
|
|
49
|
-
if (label) return label;
|
|
50
|
-
if (isApiProvider(provider)) return canonicalizeProviderId(provider.id());
|
|
51
|
-
if (isProviderOptions(provider)) {
|
|
52
|
-
if (provider.id) return canonicalizeProviderId(provider.id);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (typeof provider === "object" && "id" in provider && typeof provider.id === "string") return canonicalizeProviderId(provider.id);
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Gets a descriptive identifier string for a provider, showing both label and ID when both exist.
|
|
59
|
-
* Useful for error messages to help users debug provider reference issues.
|
|
60
|
-
*/
|
|
61
|
-
function getProviderDescription(provider) {
|
|
62
|
-
const label = provider.label;
|
|
63
|
-
const id = provider.id();
|
|
64
|
-
if (label && label !== id) return `${label} (${id})`;
|
|
65
|
-
return id;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Checks if a provider reference matches a given provider.
|
|
69
|
-
* Supports exact matching and wildcard patterns.
|
|
70
|
-
*/
|
|
71
|
-
function doesProviderRefMatch(ref, provider) {
|
|
72
|
-
const label = provider.label;
|
|
73
|
-
const id = provider.id();
|
|
74
|
-
const canonicalRef = canonicalizeProviderId(ref);
|
|
75
|
-
const canonicalId = canonicalizeProviderId(id);
|
|
76
|
-
if (label && label === ref) return true;
|
|
77
|
-
if (id === ref || canonicalId === canonicalRef) return true;
|
|
78
|
-
if (ref.endsWith("*")) {
|
|
79
|
-
const prefix = ref.slice(0, -1);
|
|
80
|
-
if (label?.startsWith(prefix) || id.startsWith(prefix) || canonicalId.startsWith(prefix)) return true;
|
|
81
|
-
}
|
|
82
|
-
if (label?.startsWith(`${ref}:`) || id.startsWith(`${ref}:`) || canonicalId.startsWith(`${ref}:`)) return true;
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Checks if a provider is allowed based on a list of allowed references.
|
|
87
|
-
*/
|
|
88
|
-
function isProviderAllowed(provider, allowedProviders) {
|
|
89
|
-
if (!Array.isArray(allowedProviders)) return true;
|
|
90
|
-
if (allowedProviders.length === 0) return false;
|
|
91
|
-
return allowedProviders.some((ref) => doesProviderRefMatch(ref, provider));
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Detects if a provider uses OpenAI models.
|
|
95
|
-
* This includes direct OpenAI providers and Azure OpenAI.
|
|
96
|
-
*/
|
|
97
|
-
function isOpenAiProvider(providerId) {
|
|
98
|
-
const lowerProviderId = providerId.toLowerCase();
|
|
99
|
-
if (lowerProviderId.startsWith("openai:")) return true;
|
|
100
|
-
if (lowerProviderId.startsWith("azureopenai:")) return true;
|
|
101
|
-
if (lowerProviderId.startsWith("azure:")) {
|
|
102
|
-
if ([
|
|
103
|
-
"gpt",
|
|
104
|
-
"openai",
|
|
105
|
-
"davinci",
|
|
106
|
-
"curie",
|
|
107
|
-
"babbage",
|
|
108
|
-
"ada",
|
|
109
|
-
"text-embedding",
|
|
110
|
-
"whisper",
|
|
111
|
-
"dall-e",
|
|
112
|
-
"tts"
|
|
113
|
-
].some((indicator) => lowerProviderId.includes(indicator))) return true;
|
|
114
|
-
}
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Detects if a provider uses Anthropic/Claude models.
|
|
119
|
-
* This includes direct Anthropic providers, Bedrock with Claude, and Vertex with Claude.
|
|
120
|
-
*/
|
|
121
|
-
function isAnthropicProvider(providerId) {
|
|
122
|
-
const lowerProviderId = providerId.toLowerCase();
|
|
123
|
-
if (lowerProviderId.startsWith("anthropic:")) return true;
|
|
124
|
-
if (lowerProviderId.startsWith("bedrock:")) {
|
|
125
|
-
if (lowerProviderId.includes("claude") || lowerProviderId.includes("anthropic")) return true;
|
|
126
|
-
}
|
|
127
|
-
if (lowerProviderId.startsWith("vertex:")) {
|
|
128
|
-
if (lowerProviderId.includes("claude")) return true;
|
|
129
|
-
}
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
const KNOWN_ENV_VARS = {
|
|
133
|
-
openai: "OPENAI_API_KEY",
|
|
134
|
-
anthropic: "ANTHROPIC_API_KEY",
|
|
135
|
-
google: "GOOGLE_API_KEY",
|
|
136
|
-
mistral: "MISTRAL_API_KEY",
|
|
137
|
-
cohere: "COHERE_API_KEY",
|
|
138
|
-
replicate: "REPLICATE_API_TOKEN",
|
|
139
|
-
voyage: "VOYAGE_API_KEY",
|
|
140
|
-
ai21: "AI21_API_KEY",
|
|
141
|
-
xai: "XAI_API_KEY",
|
|
142
|
-
groq: "GROQ_API_KEY",
|
|
143
|
-
deepseek: "DEEPSEEK_API_KEY",
|
|
144
|
-
perplexity: "PERPLEXITY_API_KEY",
|
|
145
|
-
hyperbolic: "HYPERBOLIC_API_KEY",
|
|
146
|
-
cerebras: "CEREBRAS_API_KEY",
|
|
147
|
-
togetherai: "TOGETHER_API_KEY",
|
|
148
|
-
fal: "FAL_KEY",
|
|
149
|
-
huggingface: "HF_TOKEN",
|
|
150
|
-
"cloudflare-ai": "CLOUDFLARE_API_KEY"
|
|
151
|
-
};
|
|
152
|
-
function getDefaultEnvVar(providerId) {
|
|
153
|
-
const prefix = providerId.split(":")[0];
|
|
154
|
-
return KNOWN_ENV_VARS[prefix] || `${prefix.toUpperCase()}_API_KEY`;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Pre-checks providers for missing API keys before evaluation starts.
|
|
158
|
-
* Assumes getApiKey() is side-effect free (no network calls or token refresh).
|
|
159
|
-
*/
|
|
160
|
-
function checkProviderApiKeys(providers) {
|
|
161
|
-
const missingApiKeys = /* @__PURE__ */ new Map();
|
|
162
|
-
for (const provider of providers) {
|
|
163
|
-
const p = provider;
|
|
164
|
-
if (typeof p.getApiKey !== "function") continue;
|
|
165
|
-
if (provider.id().startsWith("azure:")) continue;
|
|
166
|
-
const requiresKey = typeof p.requiresApiKey === "function" ? p.requiresApiKey() : p.config?.apiKeyRequired !== false;
|
|
167
|
-
let apiKey;
|
|
168
|
-
try {
|
|
169
|
-
apiKey = p.getApiKey();
|
|
170
|
-
} catch {
|
|
171
|
-
apiKey = void 0;
|
|
172
|
-
}
|
|
173
|
-
if (requiresKey && !apiKey) {
|
|
174
|
-
const envVar = p.config?.apiKeyEnvar || getDefaultEnvVar(provider.id());
|
|
175
|
-
if (!missingApiKeys.has(envVar)) missingApiKeys.set(envVar, []);
|
|
176
|
-
missingApiKeys.get(envVar).push(provider.id());
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return missingApiKeys;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Detects if a provider uses Google models.
|
|
183
|
-
* This includes direct Google/Vertex providers with Gemini and other Google models.
|
|
184
|
-
* Note: Vertex with Claude models is NOT counted as Google (it's Anthropic).
|
|
185
|
-
*/
|
|
186
|
-
function isGoogleProvider(providerId) {
|
|
187
|
-
const lowerProviderId = providerId.toLowerCase();
|
|
188
|
-
if (lowerProviderId.startsWith("google:")) return true;
|
|
189
|
-
if (lowerProviderId.startsWith("vertex:")) {
|
|
190
|
-
if (!lowerProviderId.includes("claude")) return true;
|
|
191
|
-
}
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
//#endregion
|
|
195
|
-
//#region src/util/comparison.ts
|
|
196
|
-
/**
|
|
197
|
-
* Explicit runtime variable names that don't follow the underscore convention.
|
|
198
|
-
* These are added during evaluation but aren't part of the original test definition.
|
|
199
|
-
*
|
|
200
|
-
* - sessionId: Added by multi-turn strategy providers (GOAT, Crescendo)
|
|
201
|
-
*
|
|
202
|
-
* Note: Variables starting with underscore (e.g., _conversation) are automatically
|
|
203
|
-
* treated as runtime variables and filtered out.
|
|
204
|
-
*/
|
|
205
|
-
const EXPLICIT_RUNTIME_VAR_KEYS = ["sessionId"];
|
|
206
|
-
/**
|
|
207
|
-
* Checks if a variable key is a runtime-only variable that should be filtered
|
|
208
|
-
* when comparing test cases.
|
|
209
|
-
*
|
|
210
|
-
* Runtime variables are identified by:
|
|
211
|
-
* 1. Starting with underscore (_) - convention for internal/runtime vars
|
|
212
|
-
* 2. Being in the explicit runtime var list (for legacy vars like sessionId)
|
|
213
|
-
*/
|
|
214
|
-
function isRuntimeVar(key) {
|
|
215
|
-
return key.startsWith("_") || EXPLICIT_RUNTIME_VAR_KEYS.includes(key);
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Filters out runtime-only variables that are added during evaluation
|
|
219
|
-
* but aren't part of the original test definition.
|
|
220
|
-
*
|
|
221
|
-
* This is used when comparing test cases to determine if a result
|
|
222
|
-
* corresponds to a particular test, regardless of runtime state.
|
|
223
|
-
*
|
|
224
|
-
* Runtime variables are identified by:
|
|
225
|
-
* - Starting with underscore (e.g., _conversation, _metadata)
|
|
226
|
-
* - Being in the explicit list (e.g., sessionId for backward compatibility)
|
|
227
|
-
*/
|
|
228
|
-
function filterRuntimeVars(vars) {
|
|
229
|
-
if (!vars || typeof vars !== "object" || Array.isArray(vars)) return vars;
|
|
230
|
-
const filtered = {};
|
|
231
|
-
for (const [key, value] of Object.entries(vars)) if (!isRuntimeVar(key)) filtered[key] = value;
|
|
232
|
-
return filtered;
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Extracts only runtime variables from a vars object.
|
|
236
|
-
* This is the inverse of filterRuntimeVars.
|
|
237
|
-
*
|
|
238
|
-
* Used to restore runtime state when re-running filtered tests.
|
|
239
|
-
*/
|
|
240
|
-
function extractRuntimeVars(vars) {
|
|
241
|
-
if (!vars || typeof vars !== "object" || Array.isArray(vars)) return;
|
|
242
|
-
const extracted = {};
|
|
243
|
-
for (const [key, value] of Object.entries(vars)) if (isRuntimeVar(key)) extracted[key] = value;
|
|
244
|
-
return Object.keys(extracted).length > 0 ? extracted : void 0;
|
|
245
|
-
}
|
|
246
|
-
function varsMatch(vars1, vars2) {
|
|
247
|
-
return deepEqual(vars1, vars2);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Generate a unique key for a test case for deduplication purposes.
|
|
251
|
-
* Excludes runtime variables and includes strategyId to distinguish tests
|
|
252
|
-
* with the same prompt but different strategies.
|
|
253
|
-
*
|
|
254
|
-
* @param testCase - The test case to generate a key for
|
|
255
|
-
* @returns A JSON string that uniquely identifies the test case
|
|
256
|
-
*/
|
|
257
|
-
function getTestCaseDeduplicationKey(testCase) {
|
|
258
|
-
const filteredVars = filterRuntimeVars(testCase.vars);
|
|
259
|
-
const strategyId = testCase.metadata?.strategyId || "none";
|
|
260
|
-
return JSON.stringify({
|
|
261
|
-
vars: filteredVars,
|
|
262
|
-
strategyId
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Deduplicates an array of test cases based on their vars and strategyId.
|
|
267
|
-
* Tests with the same vars but different strategies are considered different.
|
|
268
|
-
* Runtime variables (like _conversation, sessionId) are filtered out before comparison.
|
|
269
|
-
*
|
|
270
|
-
* @param tests - Array of test cases to deduplicate
|
|
271
|
-
* @returns Deduplicated array of test cases
|
|
272
|
-
*/
|
|
273
|
-
function deduplicateTestCases(tests) {
|
|
274
|
-
const seen = /* @__PURE__ */ new Set();
|
|
275
|
-
return tests.filter((test) => {
|
|
276
|
-
const key = getTestCaseDeduplicationKey(test);
|
|
277
|
-
if (seen.has(key)) return false;
|
|
278
|
-
seen.add(key);
|
|
279
|
-
return true;
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
function resultIsForTestCase(result, testCase) {
|
|
283
|
-
const testProviderId = testCase.provider ? providerToIdentifier(testCase.provider) : void 0;
|
|
284
|
-
const resultProviderId = providerToIdentifier(result.provider);
|
|
285
|
-
const providersMatch = !testProviderId || !resultProviderId || testProviderId === resultProviderId;
|
|
286
|
-
const resultVars = filterRuntimeVars(result.vars);
|
|
287
|
-
const testVars = filterRuntimeVars(testCase.vars);
|
|
288
|
-
const doVarsMatch = varsMatch(testVars, resultVars);
|
|
289
|
-
const isMatch = doVarsMatch && providersMatch;
|
|
290
|
-
if (!isMatch) {
|
|
291
|
-
const varKeys = testVars ? Object.keys(testVars).join(", ") : "none";
|
|
292
|
-
logger.debug(`[resultIsForTestCase] No match: vars=${doVarsMatch}, providers=${providersMatch}`, {
|
|
293
|
-
testProvider: testProviderId || "none",
|
|
294
|
-
resultProvider: resultProviderId || "none",
|
|
295
|
-
testVarKeys: varKeys
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
return isMatch;
|
|
299
|
-
}
|
|
300
|
-
//#endregion
|
|
301
|
-
//#region src/util/env.ts
|
|
302
|
-
/**
|
|
303
|
-
* Load environment variables from .env file(s).
|
|
304
|
-
* @param envPath - Single path, array of paths, or undefined for default .env loading.
|
|
305
|
-
* When paths are explicitly specified, all files must exist or an error is thrown.
|
|
306
|
-
* When multiple files are provided, later files override values from earlier files.
|
|
307
|
-
*/
|
|
308
|
-
function setupEnv(envPath) {
|
|
309
|
-
if (envPath) {
|
|
310
|
-
const paths = (Array.isArray(envPath) ? envPath : [envPath]).flatMap((p) => p.includes(",") ? p.split(",").map((s) => s.trim()) : p.trim()).filter((p) => p.length > 0);
|
|
311
|
-
if (paths.length === 0) {
|
|
312
|
-
dotenv.config({ quiet: true });
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
for (const p of paths) if (!fs$2.existsSync(p)) throw new Error(`Environment file not found: ${p}`);
|
|
316
|
-
if (paths.length === 1) logger.info(`Loading environment variables from ${paths[0]}`);
|
|
317
|
-
else logger.info(`Loading environment variables from: ${paths.join(", ")}`);
|
|
318
|
-
const pathArg = paths.length === 1 ? paths[0] : paths;
|
|
319
|
-
dotenv.config({
|
|
320
|
-
path: pathArg,
|
|
321
|
-
override: true,
|
|
322
|
-
quiet: true
|
|
323
|
-
});
|
|
324
|
-
} else dotenv.config({ quiet: true });
|
|
325
|
-
}
|
|
326
|
-
//#endregion
|
|
327
26
|
//#region src/util/functions/loadFunction.ts
|
|
328
27
|
const functionCache = {};
|
|
329
28
|
/**
|
|
@@ -448,243 +147,676 @@ function maybeLoadFromExternalFile(filePath, context) {
|
|
|
448
147
|
else allContents.push(...records);
|
|
449
148
|
} else allContents.push(contents);
|
|
450
149
|
}
|
|
451
|
-
return allContents;
|
|
150
|
+
return allContents;
|
|
151
|
+
}
|
|
152
|
+
const finalPath = resolvedPath;
|
|
153
|
+
let contents;
|
|
154
|
+
try {
|
|
155
|
+
contents = fs$2.readFileSync(finalPath, "utf8");
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error.code === "ENOENT") throw new Error(`File does not exist: ${finalPath}`);
|
|
158
|
+
throw new Error(`Failed to read file ${finalPath}: ${error}`);
|
|
159
|
+
}
|
|
160
|
+
if (finalPath.endsWith(".json")) try {
|
|
161
|
+
return JSON.parse(contents);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
throw new Error(`Failed to parse JSON file ${finalPath}: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
if (finalPath.endsWith(".yaml") || finalPath.endsWith(".yml")) try {
|
|
166
|
+
return yaml.load(contents);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
throw new Error(`Failed to parse YAML file ${finalPath}: ${error}`);
|
|
169
|
+
}
|
|
170
|
+
if (finalPath.endsWith(".csv")) {
|
|
171
|
+
const records = parse$1(contents, { columns: true });
|
|
172
|
+
if (records.length > 0 && Object.keys(records[0]).length === 1) return records.map((record) => Object.values(record)[0]);
|
|
173
|
+
return records;
|
|
174
|
+
}
|
|
175
|
+
return contents;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Resolves a relative file path with respect to a base path, handling cloud configuration appropriately.
|
|
179
|
+
* When using a cloud configuration, the current working directory is always used instead of the context's base path.
|
|
180
|
+
*
|
|
181
|
+
* @param filePath - The relative or absolute file path to resolve.
|
|
182
|
+
* @param isCloudConfig - Whether this is a cloud configuration.
|
|
183
|
+
* @returns The resolved absolute file path.
|
|
184
|
+
*/
|
|
185
|
+
function getResolvedRelativePath(filePath, isCloudConfig) {
|
|
186
|
+
if (path$1.isAbsolute(filePath) || !isCloudConfig) return filePath;
|
|
187
|
+
return path$1.join(process.cwd(), filePath);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Recursively loads external file references from a configuration object.
|
|
191
|
+
*
|
|
192
|
+
* @param config - The configuration object to process
|
|
193
|
+
* @param context - Optional context to control file loading behavior
|
|
194
|
+
* @returns The configuration with external file references resolved
|
|
195
|
+
*/
|
|
196
|
+
function maybeLoadConfigFromExternalFile(config, context) {
|
|
197
|
+
if (Array.isArray(config)) return config.map((item) => maybeLoadConfigFromExternalFile(item, context));
|
|
198
|
+
if (typeof config === "object" && config !== null) {
|
|
199
|
+
const result = {};
|
|
200
|
+
for (const key of Object.keys(config)) {
|
|
201
|
+
const childContext = key === "value" && "type" in config && typeof config.type === "string" && (config.type === "python" || config.type === "javascript") ? "assertion" : key === "vars" ? "vars" : context;
|
|
202
|
+
const value = maybeLoadConfigFromExternalFile(config[key], childContext);
|
|
203
|
+
if (key === "__proto__") Object.defineProperty(result, key, {
|
|
204
|
+
value,
|
|
205
|
+
enumerable: true,
|
|
206
|
+
configurable: true,
|
|
207
|
+
writable: true
|
|
208
|
+
});
|
|
209
|
+
else result[key] = value;
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
return maybeLoadFromExternalFile(config, context);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Parses a file path or glob pattern to extract function names and file extensions.
|
|
217
|
+
* Function names can be specified in the filename like this:
|
|
218
|
+
* prompt.py:myFunction or prompts.js:myFunction.
|
|
219
|
+
* @param basePath - The base path for file resolution.
|
|
220
|
+
* @param promptPath - The path or glob pattern.
|
|
221
|
+
* @returns Parsed details including function name, file extension, and directory status.
|
|
222
|
+
*/
|
|
223
|
+
function parsePathOrGlob(basePath, promptPath) {
|
|
224
|
+
if (promptPath.startsWith("file://")) promptPath = promptPath.slice(7);
|
|
225
|
+
const filePath = path$1.resolve(basePath, promptPath);
|
|
226
|
+
let filename = path$1.relative(basePath, filePath);
|
|
227
|
+
let functionName;
|
|
228
|
+
if (filename.includes(":")) {
|
|
229
|
+
const lastColonIndex = filename.lastIndexOf(":");
|
|
230
|
+
if (lastColonIndex > 1) {
|
|
231
|
+
const pathWithoutFunction = filename.slice(0, lastColonIndex);
|
|
232
|
+
if (isJavascriptFile(pathWithoutFunction) || pathWithoutFunction.endsWith(".py") || pathWithoutFunction.endsWith(".go") || pathWithoutFunction.endsWith(".rb")) {
|
|
233
|
+
functionName = filename.slice(lastColonIndex + 1);
|
|
234
|
+
filename = pathWithoutFunction;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
let stats;
|
|
239
|
+
try {
|
|
240
|
+
stats = fs$2.statSync(path$1.join(basePath, filename));
|
|
241
|
+
} catch (err) {
|
|
242
|
+
if (getEnvBool("PROMPTFOO_STRICT_FILES")) throw err;
|
|
243
|
+
}
|
|
244
|
+
const normalizedFilePath = filePath.replace(/\\/g, "/");
|
|
245
|
+
const isPathPattern = stats?.isDirectory() || hasMagic(promptPath) || hasMagic(normalizedFilePath);
|
|
246
|
+
const safeFilename = path$1.relative(basePath, safeResolve(basePath, filename));
|
|
247
|
+
return {
|
|
248
|
+
extension: isPathPattern ? void 0 : path$1.parse(safeFilename).ext,
|
|
249
|
+
filePath: path$1.join(basePath, safeFilename),
|
|
250
|
+
functionName,
|
|
251
|
+
isPathPattern
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function readOutput(outputPath) {
|
|
255
|
+
const ext = path$1.parse(outputPath).ext.slice(1);
|
|
256
|
+
switch (ext) {
|
|
257
|
+
case "json": return JSON.parse(fs$2.readFileSync(outputPath, "utf-8"));
|
|
258
|
+
default: throw new Error(`Unsupported output file format: ${ext} currently only supports json`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Load custom Nunjucks filters from external files.
|
|
263
|
+
* Note: If a glob pattern matches multiple files, only the last file's export is used.
|
|
264
|
+
* Each filter name should typically resolve to a single file.
|
|
265
|
+
*/
|
|
266
|
+
async function readFilters(filters, basePath = "") {
|
|
267
|
+
const ret = {};
|
|
268
|
+
for (const [name, filterPath] of Object.entries(filters)) {
|
|
269
|
+
const filePaths = globSync(path$1.join(basePath, filterPath), { windowsPathsNoEscape: true });
|
|
270
|
+
for (const filePath of filePaths) ret[name] = await importModule(path$1.resolve(filePath));
|
|
271
|
+
}
|
|
272
|
+
return ret;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Loads configuration from an external file with variable rendering.
|
|
276
|
+
* This is a convenience wrapper that combines renderVarsInObject and maybeLoadFromExternalFile.
|
|
277
|
+
*
|
|
278
|
+
* Use this for simple config fields that:
|
|
279
|
+
* - Need variable rendering ({{ vars.x }}, {{ env.X }})
|
|
280
|
+
* - May reference external files (file://path.json)
|
|
281
|
+
* - Don't have nested file references that need loading
|
|
282
|
+
*
|
|
283
|
+
* For fields with nested file references (like response_format.schema),
|
|
284
|
+
* use maybeLoadResponseFormatFromExternalFile instead.
|
|
285
|
+
*
|
|
286
|
+
* @param config - The configuration to process
|
|
287
|
+
* @param vars - Variables for template rendering
|
|
288
|
+
* @returns The processed configuration with variables rendered and files loaded
|
|
289
|
+
*/
|
|
290
|
+
function maybeLoadFromExternalFileWithVars(config, vars) {
|
|
291
|
+
return maybeLoadFromExternalFile(renderVarsInObject(config, vars));
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Loads response_format configuration from an external file with variable rendering.
|
|
295
|
+
*
|
|
296
|
+
* This function handles the special case where response_format may contain:
|
|
297
|
+
* 1. A top-level file reference (file://format.json)
|
|
298
|
+
* 2. A nested schema reference for json_schema type (schema: file://schema.json)
|
|
299
|
+
*
|
|
300
|
+
* Both levels need variable rendering and file loading.
|
|
301
|
+
*
|
|
302
|
+
* @param responseFormat - The response_format configuration
|
|
303
|
+
* @param vars - Variables for template rendering
|
|
304
|
+
* @returns The processed response_format with all files loaded
|
|
305
|
+
*/
|
|
306
|
+
function maybeLoadResponseFormatFromExternalFile(responseFormat, vars) {
|
|
307
|
+
if (responseFormat === void 0 || responseFormat === null) return responseFormat;
|
|
308
|
+
const loaded = maybeLoadFromExternalFile(renderVarsInObject(responseFormat, vars));
|
|
309
|
+
if (!loaded || typeof loaded !== "object") return loaded;
|
|
310
|
+
if (loaded.type === "json_schema") {
|
|
311
|
+
const nestedSchema = loaded.schema || loaded.json_schema?.schema;
|
|
312
|
+
if (nestedSchema) {
|
|
313
|
+
const loadedSchema = maybeLoadFromExternalFile(renderVarsInObject(nestedSchema, vars));
|
|
314
|
+
if (loaded.schema !== void 0) return {
|
|
315
|
+
...loaded,
|
|
316
|
+
schema: loadedSchema
|
|
317
|
+
};
|
|
318
|
+
else if (loaded.json_schema?.schema !== void 0) return {
|
|
319
|
+
...loaded,
|
|
320
|
+
json_schema: {
|
|
321
|
+
...loaded.json_schema,
|
|
322
|
+
schema: loadedSchema
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return loaded;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Renders variables in a tools object and loads from external file if applicable.
|
|
331
|
+
* This function combines renderVarsInObject and maybeLoadFromExternalFile into a single step
|
|
332
|
+
* specifically for handling tools configurations.
|
|
333
|
+
*
|
|
334
|
+
* Supports loading from JSON, YAML, Python, and JavaScript files.
|
|
335
|
+
*
|
|
336
|
+
* @param tools - The tools configuration object or array to process.
|
|
337
|
+
* @param vars - Variables to use for rendering.
|
|
338
|
+
* @returns The processed tools configuration with variables rendered and content loaded from files if needed.
|
|
339
|
+
* @throws {Error} If the loaded tools are in an invalid format
|
|
340
|
+
*/
|
|
341
|
+
async function maybeLoadToolsFromExternalFile(tools, vars) {
|
|
342
|
+
const rendered = renderVarsInObject(tools, vars);
|
|
343
|
+
if (typeof rendered === "string" && rendered.startsWith("file://")) {
|
|
344
|
+
const { filePath, functionName } = parseFileUrl(rendered);
|
|
345
|
+
if (functionName && (filePath.endsWith(".py") || isJavascriptFile(filePath))) {
|
|
346
|
+
const fileType = filePath.endsWith(".py") ? "Python" : "JavaScript";
|
|
347
|
+
logger.debug(`[maybeLoadToolsFromExternalFile] Loading tools from ${fileType} file: ${filePath}:${functionName}`);
|
|
348
|
+
try {
|
|
349
|
+
let toolDefinitions;
|
|
350
|
+
if (filePath.endsWith(".py")) {
|
|
351
|
+
const absPath = safeResolve(state.basePath || process.cwd(), filePath);
|
|
352
|
+
logger.debug(`[maybeLoadToolsFromExternalFile] Resolved Python path: ${absPath}`);
|
|
353
|
+
toolDefinitions = await runPython(absPath, functionName, []);
|
|
354
|
+
} else {
|
|
355
|
+
const absPath = safeResolve(state.basePath || process.cwd(), filePath);
|
|
356
|
+
logger.debug(`[maybeLoadToolsFromExternalFile] Resolved JavaScript path: ${absPath}`);
|
|
357
|
+
const module = await importModule(absPath);
|
|
358
|
+
const fn = module[functionName] || module.default?.[functionName];
|
|
359
|
+
if (typeof fn !== "function") {
|
|
360
|
+
const availableExports = Object.keys(module).filter((k) => k !== "default");
|
|
361
|
+
const basePath = state.basePath || process.cwd();
|
|
362
|
+
throw new Error(`Function "${functionName}" not found in ${filePath}. Available exports: ${availableExports.length > 0 ? availableExports.join(", ") : "(none)"}\nResolved from: ${basePath}`);
|
|
363
|
+
}
|
|
364
|
+
toolDefinitions = await Promise.resolve(fn());
|
|
365
|
+
}
|
|
366
|
+
if (!toolDefinitions || typeof toolDefinitions === "string" || typeof toolDefinitions === "number" || typeof toolDefinitions === "boolean") throw new Error(`Function "${functionName}" must return an array or object of tool definitions, but returned: ${toolDefinitions === null ? "null" : typeof toolDefinitions}`);
|
|
367
|
+
logger.debug(`[maybeLoadToolsFromExternalFile] Successfully loaded ${Array.isArray(toolDefinitions) ? toolDefinitions.length : "object"} tools`);
|
|
368
|
+
return toolDefinitions;
|
|
369
|
+
} catch (err) {
|
|
370
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
371
|
+
const basePath = state.basePath || process.cwd();
|
|
372
|
+
throw new Error(`Failed to load tools from ${rendered}:\n${errorMessage}\n\nMake sure the function "${functionName}" exists and returns a valid tool definition array.\nResolved from: ${basePath}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (filePath.endsWith(".py") || isJavascriptFile(filePath)) {
|
|
376
|
+
const ext = filePath.endsWith(".py") ? "Python" : "JavaScript";
|
|
377
|
+
const basePath = state.basePath || process.cwd();
|
|
378
|
+
throw new Error(`Cannot load tools from ${rendered}\n${ext} files require a function name. Use this format:\n tools: file://${filePath}:get_tools\n\nYour ${ext} file should export a function that returns tool definitions:\n` + (filePath.endsWith(".py") ? ` def get_tools():\n return [{"type": "function", "function": {...}}]` : ` module.exports.get_tools = () => [{ type: "function", function: {...} }];`) + `\n\nResolved from: ${basePath}`);
|
|
379
|
+
}
|
|
452
380
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
} catch (error) {
|
|
458
|
-
if (error.code === "ENOENT") throw new Error(`File does not exist: ${finalPath}`);
|
|
459
|
-
throw new Error(`Failed to read file ${finalPath}: ${error}`);
|
|
381
|
+
if (Array.isArray(rendered)) {
|
|
382
|
+
const results = await Promise.all(rendered.map((item) => maybeLoadToolsFromExternalFile(item, vars)));
|
|
383
|
+
if (results.every((r) => Array.isArray(r))) return results.flat();
|
|
384
|
+
return results;
|
|
460
385
|
}
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
throw new Error(`Failed to
|
|
386
|
+
if (typeof rendered !== "string") return rendered;
|
|
387
|
+
const loaded = maybeLoadFromExternalFile(rendered);
|
|
388
|
+
if (loaded !== void 0 && loaded !== null && typeof loaded === "string") {
|
|
389
|
+
if (loaded.startsWith("file://")) throw new Error(`Failed to load tools from ${loaded}\nEnsure the file exists and contains valid JSON or YAML tool definitions.`);
|
|
390
|
+
if (loaded.includes("def ") || loaded.includes("import ")) throw new Error("Invalid tools configuration: file appears to contain Python code.\nPython files require a function name. Use this format:\n tools: file://tools.py:get_tools");
|
|
391
|
+
throw new Error("Invalid tools configuration: expected an array or object, but got a string.\nIf using file://, ensure the file contains valid JSON or YAML tool definitions.");
|
|
465
392
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
393
|
+
return loaded;
|
|
394
|
+
}
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/util/providerRef.ts
|
|
397
|
+
const PROVIDER_OPTION_KEYS = new Set([
|
|
398
|
+
"id",
|
|
399
|
+
"label",
|
|
400
|
+
"config",
|
|
401
|
+
"prompts",
|
|
402
|
+
"transform",
|
|
403
|
+
"delay",
|
|
404
|
+
"env",
|
|
405
|
+
"inputs"
|
|
406
|
+
]);
|
|
407
|
+
/** Returns true if the value is a non-empty string suitable as a provider identifier. */
|
|
408
|
+
function isValidProviderId(id) {
|
|
409
|
+
return typeof id === "string" && id !== "";
|
|
410
|
+
}
|
|
411
|
+
function getProviderLabel(provider) {
|
|
412
|
+
if ((typeof provider === "object" || typeof provider === "function") && provider !== null && "label" in provider && typeof provider.label === "string") return provider.label;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Resolves relative file paths in provider IDs to absolute paths for consistent matching.
|
|
416
|
+
* Handles file://, exec:, python:, golang: prefixes and bare .js/.ts/.mjs paths.
|
|
417
|
+
*/
|
|
418
|
+
function canonicalizeProviderId(id) {
|
|
419
|
+
if (id.startsWith("file://")) {
|
|
420
|
+
const filePath = id.slice(7);
|
|
421
|
+
return path.isAbsolute(filePath) ? id : `file://${path.resolve(filePath)}`;
|
|
470
422
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
423
|
+
for (const prefix of [
|
|
424
|
+
"exec:",
|
|
425
|
+
"python:",
|
|
426
|
+
"golang:"
|
|
427
|
+
]) if (id.startsWith(prefix)) {
|
|
428
|
+
const filePath = id.slice(prefix.length);
|
|
429
|
+
if (filePath.includes("/") || filePath.includes("\\")) return `${prefix}${path.resolve(filePath)}`;
|
|
430
|
+
return id;
|
|
475
431
|
}
|
|
476
|
-
return
|
|
432
|
+
if ((id.endsWith(".js") || id.endsWith(".ts") || id.endsWith(".mjs")) && (id.includes("/") || id.includes("\\"))) return `file://${path.resolve(id)}`;
|
|
433
|
+
return id;
|
|
477
434
|
}
|
|
478
435
|
/**
|
|
479
|
-
*
|
|
480
|
-
* When using a cloud configuration, the current working directory is always used instead of the context's base path.
|
|
481
|
-
*
|
|
482
|
-
* @param filePath - The relative or absolute file path to resolve.
|
|
483
|
-
* @param isCloudConfig - Whether this is a cloud configuration.
|
|
484
|
-
* @returns The resolved absolute file path.
|
|
436
|
+
* Returns true for provider refs that should be expanded from YAML/JSON config files.
|
|
485
437
|
*/
|
|
486
|
-
function
|
|
487
|
-
|
|
488
|
-
return path$1.join(process.cwd(), filePath);
|
|
438
|
+
function isProviderConfigFileReference(providerPath) {
|
|
439
|
+
return providerPath.startsWith("file://") && (providerPath.endsWith(".yaml") || providerPath.endsWith(".yml") || providerPath.endsWith(".json"));
|
|
489
440
|
}
|
|
490
441
|
/**
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
* @param context - Optional context to control file loading behavior
|
|
495
|
-
* @returns The configuration with external file references resolved
|
|
442
|
+
* Reads a provider config file and normalizes single-provider and multi-provider files.
|
|
443
|
+
* Returns a `wasArray` flag so callers can detect multi-provider files that require
|
|
444
|
+
* `loadApiProviders` instead of `loadApiProvider`.
|
|
496
445
|
*/
|
|
497
|
-
function
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
return result;
|
|
446
|
+
function readProviderConfigFile(providerPath, basePath) {
|
|
447
|
+
const relativePath = providerPath.slice(7);
|
|
448
|
+
const resolvedPath = path.isAbsolute(relativePath) ? relativePath : path.join(basePath || process.cwd(), relativePath);
|
|
449
|
+
let rawContent;
|
|
450
|
+
try {
|
|
451
|
+
rawContent = yaml.load(fs.readFileSync(resolvedPath, "utf8"));
|
|
452
|
+
} catch (err) {
|
|
453
|
+
throw new Error(`Failed to load provider config ${relativePath}: ${err instanceof Error ? err.message : err}`);
|
|
506
454
|
}
|
|
507
|
-
|
|
455
|
+
const fileContent = maybeLoadConfigFromExternalFile(rawContent);
|
|
456
|
+
invariant(fileContent, `Provider config ${relativePath} is undefined`);
|
|
457
|
+
return {
|
|
458
|
+
configs: [fileContent].flat(),
|
|
459
|
+
relativePath,
|
|
460
|
+
wasArray: Array.isArray(fileContent)
|
|
461
|
+
};
|
|
508
462
|
}
|
|
509
463
|
/**
|
|
510
|
-
*
|
|
511
|
-
* Function names can be specified in the filename like this:
|
|
512
|
-
* prompt.py:myFunction or prompts.js:myFunction.
|
|
513
|
-
* @param basePath - The base path for file resolution.
|
|
514
|
-
* @param promptPath - The path or glob pattern.
|
|
515
|
-
* @returns Parsed details including function name, file extension, and directory status.
|
|
464
|
+
* Loads provider config objects from a file-backed provider reference.
|
|
516
465
|
*/
|
|
517
|
-
function
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
466
|
+
function loadProviderConfigsFromFile(providerPath, basePath) {
|
|
467
|
+
return readProviderConfigFile(providerPath, basePath).configs;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Pure, synchronous classifier that converts every supported provider reference shape
|
|
471
|
+
* into a discriminated descriptor. Does not read files or instantiate providers.
|
|
472
|
+
*/
|
|
473
|
+
function normalizeProviderRef(provider, options = {}) {
|
|
474
|
+
const { index } = options;
|
|
475
|
+
if (typeof provider === "string") {
|
|
476
|
+
if (!isValidProviderId(provider)) return {
|
|
477
|
+
kind: "unknown",
|
|
478
|
+
id: index === void 0 ? "unknown" : `unknown-${index}`
|
|
479
|
+
};
|
|
480
|
+
if (isProviderConfigFileReference(provider)) return {
|
|
481
|
+
kind: "file",
|
|
482
|
+
id: provider,
|
|
483
|
+
loadProviderPath: provider
|
|
484
|
+
};
|
|
485
|
+
return {
|
|
486
|
+
kind: "named",
|
|
487
|
+
id: provider,
|
|
488
|
+
loadProviderPath: provider
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
if (typeof provider === "function") {
|
|
492
|
+
const label = getProviderLabel(provider);
|
|
493
|
+
return {
|
|
494
|
+
kind: "function",
|
|
495
|
+
id: label ?? (index === void 0 ? "custom-function" : `custom-function-${index}`),
|
|
496
|
+
label
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
if (typeof provider === "object" && provider !== null && !Array.isArray(provider)) {
|
|
500
|
+
const providerId = provider.id;
|
|
501
|
+
const label = getProviderLabel(provider);
|
|
502
|
+
if (isValidProviderId(providerId)) return {
|
|
503
|
+
kind: "options",
|
|
504
|
+
id: providerId,
|
|
505
|
+
label,
|
|
506
|
+
loadOptions: provider,
|
|
507
|
+
loadProviderPath: providerId
|
|
508
|
+
};
|
|
509
|
+
const keys = Object.keys(provider);
|
|
510
|
+
if (keys.length === 1 && !PROVIDER_OPTION_KEYS.has(keys[0])) {
|
|
511
|
+
const originalId = keys[0];
|
|
512
|
+
const providerObject = provider[originalId];
|
|
513
|
+
if (typeof providerObject === "object" && providerObject !== null && !Array.isArray(providerObject) && isValidProviderId(originalId)) {
|
|
514
|
+
const id = isValidProviderId(providerObject.id) ? providerObject.id : originalId;
|
|
515
|
+
return {
|
|
516
|
+
kind: "map",
|
|
517
|
+
id,
|
|
518
|
+
label: getProviderLabel(providerObject),
|
|
519
|
+
loadOptions: {
|
|
520
|
+
...providerObject,
|
|
521
|
+
id
|
|
522
|
+
},
|
|
523
|
+
loadProviderPath: originalId
|
|
524
|
+
};
|
|
529
525
|
}
|
|
530
526
|
}
|
|
527
|
+
if (isValidProviderId(label)) return {
|
|
528
|
+
kind: "unknown",
|
|
529
|
+
id: label,
|
|
530
|
+
label
|
|
531
|
+
};
|
|
531
532
|
}
|
|
532
|
-
let stats;
|
|
533
|
-
try {
|
|
534
|
-
stats = fs$2.statSync(path$1.join(basePath, filename));
|
|
535
|
-
} catch (err) {
|
|
536
|
-
if (getEnvBool("PROMPTFOO_STRICT_FILES")) throw err;
|
|
537
|
-
}
|
|
538
|
-
const normalizedFilePath = filePath.replace(/\\/g, "/");
|
|
539
|
-
const isPathPattern = stats?.isDirectory() || hasMagic(promptPath) || hasMagic(normalizedFilePath);
|
|
540
|
-
const safeFilename = path$1.relative(basePath, safeResolve(basePath, filename));
|
|
541
533
|
return {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
functionName,
|
|
545
|
-
isPathPattern
|
|
534
|
+
kind: "unknown",
|
|
535
|
+
id: index === void 0 ? "unknown" : `unknown-${index}`
|
|
546
536
|
};
|
|
547
537
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
538
|
+
//#endregion
|
|
539
|
+
//#region src/util/provider.ts
|
|
540
|
+
function providerToIdentifier(provider) {
|
|
541
|
+
if (!provider) return;
|
|
542
|
+
if (typeof provider === "string") return canonicalizeProviderId(provider);
|
|
543
|
+
const { label } = normalizeProviderRef(provider);
|
|
544
|
+
if (label) return label;
|
|
545
|
+
if (isApiProvider(provider)) return canonicalizeProviderId(provider.id());
|
|
546
|
+
if (isProviderOptions(provider)) {
|
|
547
|
+
if (provider.id) return canonicalizeProviderId(provider.id);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (typeof provider === "object" && "id" in provider && typeof provider.id === "string") return canonicalizeProviderId(provider.id);
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Gets a descriptive identifier string for a provider, showing both label and ID when both exist.
|
|
554
|
+
* Useful for error messages to help users debug provider reference issues.
|
|
555
|
+
*/
|
|
556
|
+
function getProviderDescription(provider) {
|
|
557
|
+
const label = provider.label;
|
|
558
|
+
const id = provider.id();
|
|
559
|
+
if (label && label !== id) return `${label} (${id})`;
|
|
560
|
+
return id;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Checks if a provider reference matches a given provider.
|
|
564
|
+
* Supports exact matching and wildcard patterns.
|
|
565
|
+
*/
|
|
566
|
+
function doesProviderRefMatch(ref, provider) {
|
|
567
|
+
const label = provider.label;
|
|
568
|
+
const id = provider.id();
|
|
569
|
+
const canonicalRef = canonicalizeProviderId(ref);
|
|
570
|
+
const canonicalId = canonicalizeProviderId(id);
|
|
571
|
+
if (label && label === ref) return true;
|
|
572
|
+
if (id === ref || canonicalId === canonicalRef) return true;
|
|
573
|
+
if (ref.endsWith("*")) {
|
|
574
|
+
const prefix = ref.slice(0, -1);
|
|
575
|
+
if (label?.startsWith(prefix) || id.startsWith(prefix) || canonicalId.startsWith(prefix)) return true;
|
|
576
|
+
}
|
|
577
|
+
if (label?.startsWith(`${ref}:`) || id.startsWith(`${ref}:`) || canonicalId.startsWith(`${ref}:`)) return true;
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Checks if a provider is allowed based on a list of allowed references.
|
|
582
|
+
*/
|
|
583
|
+
function isProviderAllowed(provider, allowedProviders) {
|
|
584
|
+
if (!Array.isArray(allowedProviders)) return true;
|
|
585
|
+
if (allowedProviders.length === 0) return false;
|
|
586
|
+
return allowedProviders.some((ref) => doesProviderRefMatch(ref, provider));
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Detects if a provider uses OpenAI models.
|
|
590
|
+
* This includes direct OpenAI providers and Azure OpenAI.
|
|
591
|
+
*/
|
|
592
|
+
function isOpenAiProvider(providerId) {
|
|
593
|
+
const lowerProviderId = providerId.toLowerCase();
|
|
594
|
+
if (lowerProviderId.startsWith("openai:")) return true;
|
|
595
|
+
if (lowerProviderId.startsWith("azureopenai:")) return true;
|
|
596
|
+
if (lowerProviderId.startsWith("azure:")) {
|
|
597
|
+
if ([
|
|
598
|
+
"gpt",
|
|
599
|
+
"openai",
|
|
600
|
+
"davinci",
|
|
601
|
+
"curie",
|
|
602
|
+
"babbage",
|
|
603
|
+
"ada",
|
|
604
|
+
"text-embedding",
|
|
605
|
+
"whisper",
|
|
606
|
+
"dall-e",
|
|
607
|
+
"tts"
|
|
608
|
+
].some((indicator) => lowerProviderId.includes(indicator))) return true;
|
|
609
|
+
}
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Detects if a provider uses Anthropic/Claude models.
|
|
614
|
+
* This includes direct Anthropic providers, Bedrock with Claude, and Vertex with Claude.
|
|
615
|
+
*/
|
|
616
|
+
function isAnthropicProvider(providerId) {
|
|
617
|
+
const lowerProviderId = providerId.toLowerCase();
|
|
618
|
+
if (lowerProviderId.startsWith("anthropic:")) return true;
|
|
619
|
+
if (lowerProviderId.startsWith("bedrock:")) {
|
|
620
|
+
if (lowerProviderId.includes("claude") || lowerProviderId.includes("anthropic")) return true;
|
|
621
|
+
}
|
|
622
|
+
if (lowerProviderId.startsWith("vertex:")) {
|
|
623
|
+
if (lowerProviderId.includes("claude")) return true;
|
|
624
|
+
}
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
const KNOWN_ENV_VARS = {
|
|
628
|
+
openai: "OPENAI_API_KEY",
|
|
629
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
630
|
+
google: "GOOGLE_API_KEY",
|
|
631
|
+
mistral: "MISTRAL_API_KEY",
|
|
632
|
+
cohere: "COHERE_API_KEY",
|
|
633
|
+
replicate: "REPLICATE_API_TOKEN",
|
|
634
|
+
voyage: "VOYAGE_API_KEY",
|
|
635
|
+
ai21: "AI21_API_KEY",
|
|
636
|
+
xai: "XAI_API_KEY",
|
|
637
|
+
groq: "GROQ_API_KEY",
|
|
638
|
+
deepseek: "DEEPSEEK_API_KEY",
|
|
639
|
+
perplexity: "PERPLEXITY_API_KEY",
|
|
640
|
+
hyperbolic: "HYPERBOLIC_API_KEY",
|
|
641
|
+
cerebras: "CEREBRAS_API_KEY",
|
|
642
|
+
togetherai: "TOGETHER_API_KEY",
|
|
643
|
+
fal: "FAL_KEY",
|
|
644
|
+
huggingface: "HF_TOKEN",
|
|
645
|
+
"cloudflare-ai": "CLOUDFLARE_API_KEY"
|
|
646
|
+
};
|
|
647
|
+
function getDefaultEnvVar(providerId) {
|
|
648
|
+
const prefix = providerId.split(":")[0];
|
|
649
|
+
return KNOWN_ENV_VARS[prefix] || `${prefix.toUpperCase()}_API_KEY`;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Pre-checks providers for missing API keys before evaluation starts.
|
|
653
|
+
* Assumes getApiKey() is side-effect free (no network calls or token refresh).
|
|
654
|
+
*/
|
|
655
|
+
function checkProviderApiKeys(providers) {
|
|
656
|
+
const missingApiKeys = /* @__PURE__ */ new Map();
|
|
657
|
+
for (const provider of providers) {
|
|
658
|
+
const p = provider;
|
|
659
|
+
if (typeof p.getApiKey !== "function") continue;
|
|
660
|
+
if (provider.id().startsWith("azure:")) continue;
|
|
661
|
+
const requiresKey = typeof p.requiresApiKey === "function" ? p.requiresApiKey() : p.config?.apiKeyRequired !== false;
|
|
662
|
+
let apiKey;
|
|
663
|
+
try {
|
|
664
|
+
apiKey = p.getApiKey();
|
|
665
|
+
} catch {
|
|
666
|
+
apiKey = void 0;
|
|
667
|
+
}
|
|
668
|
+
if (requiresKey && !apiKey) {
|
|
669
|
+
const envVar = p.config?.apiKeyEnvar || getDefaultEnvVar(provider.id());
|
|
670
|
+
if (!missingApiKeys.has(envVar)) missingApiKeys.set(envVar, []);
|
|
671
|
+
missingApiKeys.get(envVar).push(provider.id());
|
|
672
|
+
}
|
|
553
673
|
}
|
|
674
|
+
return missingApiKeys;
|
|
554
675
|
}
|
|
555
676
|
/**
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
677
|
+
* Detects if a provider uses Google models.
|
|
678
|
+
* This includes direct Google/Vertex providers with Gemini and other Google models.
|
|
679
|
+
* Note: Vertex with Claude models is NOT counted as Google (it's Anthropic).
|
|
559
680
|
*/
|
|
560
|
-
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
681
|
+
function isGoogleProvider(providerId) {
|
|
682
|
+
const lowerProviderId = providerId.toLowerCase();
|
|
683
|
+
if (lowerProviderId.startsWith("google:")) return true;
|
|
684
|
+
if (lowerProviderId.startsWith("vertex:")) {
|
|
685
|
+
if (!lowerProviderId.includes("claude")) return true;
|
|
565
686
|
}
|
|
566
|
-
return
|
|
687
|
+
return false;
|
|
567
688
|
}
|
|
689
|
+
//#endregion
|
|
690
|
+
//#region src/util/comparison.ts
|
|
568
691
|
/**
|
|
569
|
-
*
|
|
570
|
-
*
|
|
692
|
+
* Explicit runtime variable names that don't follow the underscore convention.
|
|
693
|
+
* These are added during evaluation but aren't part of the original test definition.
|
|
571
694
|
*
|
|
572
|
-
*
|
|
573
|
-
* - Need variable rendering ({{ vars.x }}, {{ env.X }})
|
|
574
|
-
* - May reference external files (file://path.json)
|
|
575
|
-
* - Don't have nested file references that need loading
|
|
695
|
+
* - sessionId: Added by multi-turn strategy providers (GOAT, Crescendo)
|
|
576
696
|
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
697
|
+
* Note: Variables starting with underscore (e.g., _conversation) are automatically
|
|
698
|
+
* treated as runtime variables and filtered out.
|
|
699
|
+
*/
|
|
700
|
+
const EXPLICIT_RUNTIME_VAR_KEYS = ["sessionId"];
|
|
701
|
+
/**
|
|
702
|
+
* Checks if a variable key is a runtime-only variable that should be filtered
|
|
703
|
+
* when comparing test cases.
|
|
579
704
|
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
705
|
+
* Runtime variables are identified by:
|
|
706
|
+
* 1. Starting with underscore (_) - convention for internal/runtime vars
|
|
707
|
+
* 2. Being in the explicit runtime var list (for legacy vars like sessionId)
|
|
583
708
|
*/
|
|
584
|
-
function
|
|
585
|
-
return
|
|
709
|
+
function isRuntimeVar(key) {
|
|
710
|
+
return key.startsWith("_") || EXPLICIT_RUNTIME_VAR_KEYS.includes(key);
|
|
586
711
|
}
|
|
587
712
|
/**
|
|
588
|
-
*
|
|
713
|
+
* Filters out runtime-only variables that are added during evaluation
|
|
714
|
+
* but aren't part of the original test definition.
|
|
589
715
|
*
|
|
590
|
-
* This
|
|
591
|
-
*
|
|
592
|
-
* 2. A nested schema reference for json_schema type (schema: file://schema.json)
|
|
716
|
+
* This is used when comparing test cases to determine if a result
|
|
717
|
+
* corresponds to a particular test, regardless of runtime state.
|
|
593
718
|
*
|
|
594
|
-
*
|
|
719
|
+
* Runtime variables are identified by:
|
|
720
|
+
* - Starting with underscore (e.g., _conversation, _metadata)
|
|
721
|
+
* - Being in the explicit list (e.g., sessionId for backward compatibility)
|
|
722
|
+
*/
|
|
723
|
+
function filterRuntimeVars(vars) {
|
|
724
|
+
if (!vars || typeof vars !== "object" || Array.isArray(vars)) return vars;
|
|
725
|
+
const filtered = {};
|
|
726
|
+
for (const [key, value] of Object.entries(vars)) if (!isRuntimeVar(key)) filtered[key] = value;
|
|
727
|
+
return filtered;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Extracts only runtime variables from a vars object.
|
|
731
|
+
* This is the inverse of filterRuntimeVars.
|
|
595
732
|
*
|
|
596
|
-
*
|
|
597
|
-
* @param vars - Variables for template rendering
|
|
598
|
-
* @returns The processed response_format with all files loaded
|
|
733
|
+
* Used to restore runtime state when re-running filtered tests.
|
|
599
734
|
*/
|
|
600
|
-
function
|
|
601
|
-
if (
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
if (loaded.schema !== void 0) return {
|
|
609
|
-
...loaded,
|
|
610
|
-
schema: loadedSchema
|
|
611
|
-
};
|
|
612
|
-
else if (loaded.json_schema?.schema !== void 0) return {
|
|
613
|
-
...loaded,
|
|
614
|
-
json_schema: {
|
|
615
|
-
...loaded.json_schema,
|
|
616
|
-
schema: loadedSchema
|
|
617
|
-
}
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
return loaded;
|
|
735
|
+
function extractRuntimeVars(vars) {
|
|
736
|
+
if (!vars || typeof vars !== "object" || Array.isArray(vars)) return;
|
|
737
|
+
const extracted = {};
|
|
738
|
+
for (const [key, value] of Object.entries(vars)) if (isRuntimeVar(key)) extracted[key] = value;
|
|
739
|
+
return Object.keys(extracted).length > 0 ? extracted : void 0;
|
|
740
|
+
}
|
|
741
|
+
function varsMatch(vars1, vars2) {
|
|
742
|
+
return deepEqual(vars1, vars2);
|
|
622
743
|
}
|
|
623
744
|
/**
|
|
624
|
-
*
|
|
625
|
-
*
|
|
626
|
-
*
|
|
745
|
+
* Generate a unique key for a test case for deduplication purposes.
|
|
746
|
+
* Excludes runtime variables and includes strategyId to distinguish tests
|
|
747
|
+
* with the same prompt but different strategies.
|
|
627
748
|
*
|
|
628
|
-
*
|
|
749
|
+
* @param testCase - The test case to generate a key for
|
|
750
|
+
* @returns A JSON string that uniquely identifies the test case
|
|
751
|
+
*/
|
|
752
|
+
function getTestCaseDeduplicationKey(testCase) {
|
|
753
|
+
const filteredVars = filterRuntimeVars(testCase.vars);
|
|
754
|
+
const strategyId = testCase.metadata?.strategyId || "none";
|
|
755
|
+
return JSON.stringify({
|
|
756
|
+
vars: filteredVars,
|
|
757
|
+
strategyId
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Deduplicates an array of test cases based on their vars and strategyId.
|
|
762
|
+
* Tests with the same vars but different strategies are considered different.
|
|
763
|
+
* Runtime variables (like _conversation, sessionId) are filtered out before comparison.
|
|
629
764
|
*
|
|
630
|
-
* @param
|
|
631
|
-
* @
|
|
632
|
-
* @returns The processed tools configuration with variables rendered and content loaded from files if needed.
|
|
633
|
-
* @throws {Error} If the loaded tools are in an invalid format
|
|
765
|
+
* @param tests - Array of test cases to deduplicate
|
|
766
|
+
* @returns Deduplicated array of test cases
|
|
634
767
|
*/
|
|
635
|
-
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
const
|
|
639
|
-
if (
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
}
|
|
660
|
-
if (!toolDefinitions || typeof toolDefinitions === "string" || typeof toolDefinitions === "number" || typeof toolDefinitions === "boolean") throw new Error(`Function "${functionName}" must return an array or object of tool definitions, but returned: ${toolDefinitions === null ? "null" : typeof toolDefinitions}`);
|
|
661
|
-
logger.debug(`[maybeLoadToolsFromExternalFile] Successfully loaded ${Array.isArray(toolDefinitions) ? toolDefinitions.length : "object"} tools`);
|
|
662
|
-
return toolDefinitions;
|
|
663
|
-
} catch (err) {
|
|
664
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
665
|
-
const basePath = state.basePath || process.cwd();
|
|
666
|
-
throw new Error(`Failed to load tools from ${rendered}:\n${errorMessage}\n\nMake sure the function "${functionName}" exists and returns a valid tool definition array.\nResolved from: ${basePath}`);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
if (filePath.endsWith(".py") || isJavascriptFile(filePath)) {
|
|
670
|
-
const ext = filePath.endsWith(".py") ? "Python" : "JavaScript";
|
|
671
|
-
const basePath = state.basePath || process.cwd();
|
|
672
|
-
throw new Error(`Cannot load tools from ${rendered}\n${ext} files require a function name. Use this format:\n tools: file://${filePath}:get_tools\n\nYour ${ext} file should export a function that returns tool definitions:\n` + (filePath.endsWith(".py") ? ` def get_tools():\n return [{"type": "function", "function": {...}}]` : ` module.exports.get_tools = () => [{ type: "function", function: {...} }];`) + `\n\nResolved from: ${basePath}`);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
if (Array.isArray(rendered)) {
|
|
676
|
-
const results = await Promise.all(rendered.map((item) => maybeLoadToolsFromExternalFile(item, vars)));
|
|
677
|
-
if (results.every((r) => Array.isArray(r))) return results.flat();
|
|
678
|
-
return results;
|
|
679
|
-
}
|
|
680
|
-
if (typeof rendered !== "string") return rendered;
|
|
681
|
-
const loaded = maybeLoadFromExternalFile(rendered);
|
|
682
|
-
if (loaded !== void 0 && loaded !== null && typeof loaded === "string") {
|
|
683
|
-
if (loaded.startsWith("file://")) throw new Error(`Failed to load tools from ${loaded}\nEnsure the file exists and contains valid JSON or YAML tool definitions.`);
|
|
684
|
-
if (loaded.includes("def ") || loaded.includes("import ")) throw new Error("Invalid tools configuration: file appears to contain Python code.\nPython files require a function name. Use this format:\n tools: file://tools.py:get_tools");
|
|
685
|
-
throw new Error("Invalid tools configuration: expected an array or object, but got a string.\nIf using file://, ensure the file contains valid JSON or YAML tool definitions.");
|
|
768
|
+
function deduplicateTestCases(tests) {
|
|
769
|
+
const seen = /* @__PURE__ */ new Set();
|
|
770
|
+
return tests.filter((test) => {
|
|
771
|
+
const key = getTestCaseDeduplicationKey(test);
|
|
772
|
+
if (seen.has(key)) return false;
|
|
773
|
+
seen.add(key);
|
|
774
|
+
return true;
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
function resultIsForTestCase(result, testCase) {
|
|
778
|
+
const testProviderId = testCase.provider ? providerToIdentifier(testCase.provider) : void 0;
|
|
779
|
+
const resultProviderId = providerToIdentifier(result.provider);
|
|
780
|
+
const providersMatch = !testProviderId || !resultProviderId || testProviderId === resultProviderId;
|
|
781
|
+
const resultVars = filterRuntimeVars(result.vars);
|
|
782
|
+
const testVars = filterRuntimeVars(testCase.vars);
|
|
783
|
+
const doVarsMatch = varsMatch(testVars, resultVars);
|
|
784
|
+
const isMatch = doVarsMatch && providersMatch;
|
|
785
|
+
if (!isMatch) {
|
|
786
|
+
const varKeys = testVars ? Object.keys(testVars).join(", ") : "none";
|
|
787
|
+
logger.debug(`[resultIsForTestCase] No match: vars=${doVarsMatch}, providers=${providersMatch}`, {
|
|
788
|
+
testProvider: testProviderId || "none",
|
|
789
|
+
resultProvider: resultProviderId || "none",
|
|
790
|
+
testVarKeys: varKeys
|
|
791
|
+
});
|
|
686
792
|
}
|
|
687
|
-
return
|
|
793
|
+
return isMatch;
|
|
794
|
+
}
|
|
795
|
+
//#endregion
|
|
796
|
+
//#region src/util/env.ts
|
|
797
|
+
/**
|
|
798
|
+
* Load environment variables from .env file(s).
|
|
799
|
+
* @param envPath - Single path, array of paths, or undefined for default .env loading.
|
|
800
|
+
* When paths are explicitly specified, all files must exist or an error is thrown.
|
|
801
|
+
* When multiple files are provided, later files override values from earlier files.
|
|
802
|
+
*/
|
|
803
|
+
function setupEnv(envPath) {
|
|
804
|
+
if (envPath) {
|
|
805
|
+
const paths = (Array.isArray(envPath) ? envPath : [envPath]).flatMap((p) => p.includes(",") ? p.split(",").map((s) => s.trim()) : p.trim()).filter((p) => p.length > 0);
|
|
806
|
+
if (paths.length === 0) {
|
|
807
|
+
dotenv.config({ quiet: true });
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
for (const p of paths) if (!fs$2.existsSync(p)) throw new Error(`Environment file not found: ${p}`);
|
|
811
|
+
if (paths.length === 1) logger.info(`Loading environment variables from ${paths[0]}`);
|
|
812
|
+
else logger.info(`Loading environment variables from: ${paths.join(", ")}`);
|
|
813
|
+
const pathArg = paths.length === 1 ? paths[0] : paths;
|
|
814
|
+
dotenv.config({
|
|
815
|
+
path: pathArg,
|
|
816
|
+
override: true,
|
|
817
|
+
quiet: true
|
|
818
|
+
});
|
|
819
|
+
} else dotenv.config({ quiet: true });
|
|
688
820
|
}
|
|
689
821
|
//#endregion
|
|
690
822
|
//#region src/googleSheets.ts
|
|
@@ -965,6 +1097,34 @@ function evalTableToCsv(table, options = { isRedteam: false }) {
|
|
|
965
1097
|
function evalTableToJson(table) {
|
|
966
1098
|
return table;
|
|
967
1099
|
}
|
|
1100
|
+
function getEvalTableOutputPromptLocationsBySize(payload) {
|
|
1101
|
+
return payload.table.body.flatMap((row, rowIndex) => row.outputs.flatMap((output, outputIndex) => output?.prompt ? [{
|
|
1102
|
+
rowIndex,
|
|
1103
|
+
outputIndex,
|
|
1104
|
+
length: output.prompt.length
|
|
1105
|
+
}] : [])).sort((a, b) => b.length - a.length);
|
|
1106
|
+
}
|
|
1107
|
+
function stripEvalTableOutputPrompts(payload, locationsToStrip) {
|
|
1108
|
+
return {
|
|
1109
|
+
...payload,
|
|
1110
|
+
table: {
|
|
1111
|
+
...payload.table,
|
|
1112
|
+
body: payload.table.body.map((row, rowIndex) => ({
|
|
1113
|
+
...row,
|
|
1114
|
+
outputs: row.outputs.map((output, outputIndex) => {
|
|
1115
|
+
if (!output || !locationsToStrip.has(`${rowIndex}:${outputIndex}`)) return output;
|
|
1116
|
+
return {
|
|
1117
|
+
...output,
|
|
1118
|
+
prompt: ""
|
|
1119
|
+
};
|
|
1120
|
+
})
|
|
1121
|
+
}))
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
function getEvalTablePromptStrippedPayload(payload, promptLocations, promptCountToStrip) {
|
|
1126
|
+
return stripEvalTableOutputPrompts(payload, new Set(promptLocations.slice(0, promptCountToStrip).map(({ rowIndex, outputIndex }) => `${rowIndex}:${outputIndex}`)));
|
|
1127
|
+
}
|
|
968
1128
|
/**
|
|
969
1129
|
* Merges comparison tables with the main table for side-by-side CSV export.
|
|
970
1130
|
*
|
|
@@ -1164,7 +1324,7 @@ function createOutputMetadata(evalRecord) {
|
|
|
1164
1324
|
arch: os$1.arch(),
|
|
1165
1325
|
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1166
1326
|
evaluationCreatedAt,
|
|
1167
|
-
author: evalRecord.author
|
|
1327
|
+
author: evalRecord.author ?? void 0
|
|
1168
1328
|
};
|
|
1169
1329
|
}
|
|
1170
1330
|
/**
|
|
@@ -1299,6 +1459,6 @@ function printBorder() {
|
|
|
1299
1459
|
logger.info(border);
|
|
1300
1460
|
}
|
|
1301
1461
|
//#endregion
|
|
1302
|
-
export {
|
|
1462
|
+
export { getResolvedRelativePath as A, parseFileUrl as B, isOpenAiProvider as C, normalizeProviderRef as D, loadProviderConfigsFromFile as E, maybeLoadToolsFromExternalFile as F, parsePathOrGlob as I, readFilters as L, maybeLoadFromExternalFile as M, maybeLoadFromExternalFileWithVars as N, readProviderConfigFile as O, maybeLoadResponseFormatFromExternalFile as P, readOutput as R, isGoogleProvider as S, isProviderConfigFileReference as T, resultIsForTestCase as _, ComparisonEvalNotFoundError as a, getProviderDescription as b, getEvalTableOutputPromptLocationsBySize as c, fetchCsvFromGoogleSheet as d, setupEnv as f, getTestCaseDeduplicationKey as g, filterRuntimeVars as h, writeOutput as i, maybeLoadConfigFromExternalFile as j, getNunjucksEngineForFilePath as k, getEvalTablePromptStrippedPayload as l, extractRuntimeVars as m, createOutputMetadata as n, evalTableToJson as o, deduplicateTestCases as p, writeMultipleOutputs as r, generateEvalCsv as s, printBorder as t, mergeComparisonTables as u, checkProviderApiKeys as v, isProviderAllowed as w, isAnthropicProvider as x, doesProviderRefMatch as y, loadFunction as z };
|
|
1303
1463
|
|
|
1304
|
-
//# sourceMappingURL=util-
|
|
1464
|
+
//# sourceMappingURL=util-DURocbYR.js.map
|