promptfoo 0.120.27 → 0.121.2
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/README.md +1 -1
- package/dist/src/{ListApp-8WOe2nT6.js → ListApp-Du7YVwj5.js} +2 -4
- package/dist/src/accounts-B0pgC1oV.js +206 -0
- package/dist/src/{accounts-DVINui-2.js → accounts-Bm2D8Db9.js} +39 -34
- package/dist/src/{accounts-CPDRAMND.js → accounts-CiBLOnA7.js} +38 -33
- package/dist/src/{accounts-Fl2J3_Fu.cjs → accounts-gtkH-5KX.cjs} +77 -78
- package/dist/src/{agentic-utils-D922n6mm.js → agentic-utils-DS1g3GLF.js} +9 -10
- package/dist/src/{agents-BcsN_BgB.js → agents-9qiOy0ho.js} +16 -12
- package/dist/src/{agents-BXLmVsxR.js → agents-CBr9A01V.js} +37 -37
- package/dist/src/{agents-pMfppv9Z.js → agents-CmvBq8LV.js} +16 -18
- package/dist/src/{agents-hqgSV-3o.js → agents-D__IdAlg.js} +39 -40
- package/dist/src/{agents-BO2n8Z0d.cjs → agents-DbRtpYxR.cjs} +37 -40
- package/dist/src/{agents-BdUTAwi-.js → agents-DgF2zDag.js} +37 -42
- package/dist/src/{agents-DgJf2-ez.cjs → agents-Di9DKPzn.cjs} +16 -17
- package/dist/src/{agents-DNvSH78i.js → agents-cLXA8a_8.js} +17 -19
- package/dist/src/{aimlapi-DtgPI0nE.js → aimlapi-B4rcnZgv.js} +15 -17
- package/dist/src/{aimlapi-BE_Tg9Fl.cjs → aimlapi-BvlNH0gr.cjs} +15 -16
- package/dist/src/{aimlapi-DOib86oE.js → aimlapi-CnkC2HqE.js} +16 -18
- package/dist/src/{aimlapi-DTPACCB1.js → aimlapi-DHJU_kcV.js} +15 -4
- package/dist/src/app/assets/index-4LKxG2CG.js +439 -0
- package/dist/src/app/assets/{index-NCn4eVBv.css → index-C3zcsZFQ.css} +1 -1
- package/dist/src/app/assets/vendor-charts-BnDWwBlI.js +36 -0
- package/dist/src/app/index.html +3 -3
- package/dist/src/app/tsconfig.app.tsbuildinfo +1 -1
- package/dist/src/{audio-BnRUGAm_.js → audio-Bkv46et0.js} +6 -5
- package/dist/src/{audio-Cwo68yZS.cjs → audio-CGMyULza.cjs} +6 -7
- package/dist/src/{audio-MSRki4JU.js → audio-ClI_AFre.js} +6 -8
- package/dist/src/{audio-BRYU0BFo.js → audio-Dz3z7s3J.js} +7 -9
- package/dist/src/{base-pGVmXNl4.cjs → base-CGrhspbK.cjs} +36 -38
- package/dist/src/{base-h961VXYk.js → base-CpjcHe4e.js} +11 -13
- package/dist/src/base-DLKtKMFh.js +193 -0
- package/dist/src/{base-XB2tDJrB.js → base-Dy1V8--Z.js} +11 -13
- package/dist/src/blobs-BDbfYdrJ.js +236 -0
- package/dist/src/{blobs-CR5C4Ihh.js → blobs-CBO20krR.js} +9 -12
- package/dist/src/{blobs-BM_e6hCa.js → blobs-CMHN0Qcz.js} +9 -12
- package/dist/src/{blobs-B-KQAFhX.cjs → blobs-D23XLin-.cjs} +34 -37
- package/dist/src/{cache-jsiwsAJv.js → cache-BVeDlD87.js} +132 -117
- package/dist/src/{cache-CIpsoBZR.js → cache-C4Nxf52C.js} +132 -118
- package/dist/src/cache-CeUpFm3M.cjs +5 -0
- package/dist/src/{cache-BTVYfbka.cjs → cache-Dh5WtQps.cjs} +182 -168
- package/dist/src/cache-i1P6crbO.js +756 -0
- package/dist/src/cache-n-RCJ-hL.js +6 -0
- package/dist/src/{chat-BcPjZXIp.js → chat-BiKyneZl.js} +45 -46
- package/dist/src/{chat-D31K7C4u.cjs → chat-C1Qst7jL.cjs} +20 -21
- package/dist/src/{chat-B84t99NW.js → chat-C2jrdPMx.js} +20 -9
- package/dist/src/{chat-BE44YOc6.cjs → chat-CgF-J-Jj.cjs} +65 -66
- package/dist/src/{chat-DwWifjxi.js → chat-CzkrVDfz.js} +20 -22
- package/dist/src/chat-DJIw17u0.js +766 -0
- package/dist/src/{chat-CcUCysjU.js → chat-DqxYYtWA.js} +45 -46
- package/dist/src/{chat-DZM2GUHO.js → chat-qmatte1u.js} +21 -23
- package/dist/src/{chatkit-D67HS_0b.js → chatkit-65VXf5SR.js} +58 -58
- package/dist/src/{chatkit-DAB_qfzI.js → chatkit-Be-Q-a9F.js} +58 -60
- package/dist/src/{chatkit-Biqb_wsD.js → chatkit-BxFvW8KY.js} +58 -60
- package/dist/src/{chatkit-PGG4ZYIn.cjs → chatkit-DKyPi1Gs.cjs} +58 -60
- package/dist/src/chunk-DEq-mXcV.js +15 -0
- package/dist/src/chunk-DRamLcfz.js +16 -0
- package/dist/src/{claude-agent-sdk-SVM6AdBu.js → claude-agent-sdk-Apiy0iaz.js} +31 -31
- package/dist/src/{claude-agent-sdk-C-IOTPfo.js → claude-agent-sdk-D2bJee9S.js} +31 -29
- package/dist/src/{claude-agent-sdk-C9SiaQub.cjs → claude-agent-sdk-D9Z5Pr9X.cjs} +31 -28
- package/dist/src/{claude-agent-sdk-CiluSyW1.js → claude-agent-sdk-DfCoW0E6.js} +33 -20
- package/dist/src/cloud-BBh91EUK.js +4 -0
- package/dist/src/{cloud-CZ-q9Ier.js → cloud-C0dlstV_.js} +7 -9
- package/dist/src/{cloudflare-ai-BahKHyhh.js → cloudflare-ai-8TDxHR0x.js} +16 -18
- package/dist/src/{cloudflare-ai-v_qZD6_q.js → cloudflare-ai-BxAGvfju.js} +17 -19
- package/dist/src/{cloudflare-ai-Dfahv5SY.cjs → cloudflare-ai-CknbZ5LJ.cjs} +16 -17
- package/dist/src/{cloudflare-ai-Dxyt50Nl.js → cloudflare-ai-g7PB6VHR.js} +16 -4
- package/dist/src/{cloudflare-gateway-Bi_FpOFy.js → cloudflare-gateway-B9HWA5wf.js} +23 -23
- package/dist/src/{cloudflare-gateway-BPWoZIzJ.cjs → cloudflare-gateway-BSnDmHYo.cjs} +21 -22
- package/dist/src/{cloudflare-gateway-C0guUNwk.js → cloudflare-gateway-CKDb4dJ8.js} +26 -14
- package/dist/src/{cloudflare-gateway-btS7h1OZ.js → cloudflare-gateway-CP9QEWYS.js} +21 -25
- package/dist/src/{codex-sdk-DSxAnbfT.js → codex-sdk-C6UMlxwV.js} +28 -29
- package/dist/src/{codex-sdk-IYVi9fuM.js → codex-sdk-DUwKWezN.js} +28 -27
- package/dist/src/{codex-sdk-DulY0ZRq.js → codex-sdk-GGAw0qbD.js} +28 -29
- package/dist/src/{codex-sdk-DFKMtAyf.cjs → codex-sdk-fAO0c3yA.cjs} +28 -29
- package/dist/src/{cometapi-DzrR3SR_.js → cometapi-BL9yvj_f.js} +16 -4
- package/dist/src/{cometapi-DIO64tf4.cjs → cometapi-C4xSqeID.cjs} +21 -22
- package/dist/src/{cometapi-C9EEpJzT.js → cometapi-CUQq3H_a.js} +21 -24
- package/dist/src/{cometapi-DkNBMk0G.js → cometapi-DFNiKmSz.js} +17 -19
- package/dist/src/{completion-CG29bfKX.js → completion-5MzrpJxT.js} +11 -13
- package/dist/src/{completion-CCRT4kX1.cjs → completion-CM6oK8PS.cjs} +21 -23
- package/dist/src/{completion-Bgf1VJoq.js → completion-DZ083F31.js} +11 -13
- package/dist/src/completion-qRoZAYRB.js +120 -0
- package/dist/src/{createHash-Dw_iLu31.js → createHash-CTQmL3G2.js} +2 -3
- package/dist/src/{createHash-CYQy4YeL.cjs → createHash-CfZSc0b4.cjs} +13 -14
- package/dist/src/{createHash-CJcfskIZ.js → createHash-Da8fMwqB.js} +2 -3
- package/dist/src/createHash-DmPQkvBh.js +15 -0
- package/dist/src/{docker-D-ayp2FW.js → docker-Bb5dcxr8.js} +18 -20
- package/dist/src/{docker-B81N0t4e.js → docker-BvfL2BrW.js} +19 -21
- package/dist/src/{docker-DNcLR4Ig.cjs → docker-DcF2pRrj.cjs} +18 -19
- package/dist/src/{docker-egERKxCF.js → docker-ExVyLp0S.js} +18 -7
- package/dist/src/entrypoint.js +2 -3
- package/dist/src/{errors-DnGCbnx8.js → errors-P6ll7XSJ.js} +2 -2
- package/dist/src/{esm-B9dPm_BF.js → esm-C03C-mv3.js} +17 -20
- package/dist/src/{esm-D2pZ87fL.js → esm-CaIwzWR5.js} +18 -21
- package/dist/src/esm-Cd1AjG1D.js +379 -0
- package/dist/src/{esm-Ct-Joyue.cjs → esm-CnNt7sI4.cjs} +47 -49
- package/dist/src/eval-B3r2CVXr.js +15 -0
- package/dist/src/{eval-C-Nr6wX_.js → eval-Dg2nG4v2.js} +47 -54
- package/dist/src/evalResult-5xwYnECe.js +12 -0
- package/dist/src/evalResult-71lY93Kj.cjs +10 -0
- package/dist/src/{evalResult-DXMWJ3sx.js → evalResult-BBRNtX4I.js} +10 -11
- package/dist/src/{evalResult-4BzI2tmj.js → evalResult-BDMqrapS.js} +16 -12
- package/dist/src/evalResult-Dx5P5cIv.js +10 -0
- package/dist/src/{evalResult-CX8wQecI.cjs → evalResult-fuaI8HkH.cjs} +20 -21
- package/dist/src/{evaluator-8aGyV12L.js → evaluator-BhoWwp5b.js} +211 -235
- package/dist/src/evaluator-Jx6bRZV6.js +36 -0
- package/dist/src/{extractor-V5x_m1i0.js → extractor-C0EVHewb.js} +22 -24
- package/dist/src/extractor-D25qpmGX.js +374 -0
- package/dist/src/{extractor-CD5yKL-G.js → extractor-DReVID0K.js} +22 -24
- package/dist/src/{extractor-C031XmTA.cjs → extractor-pYLLi3wS.cjs} +37 -39
- package/dist/src/{fetch-BmbD-v1L.cjs → fetch-BPkYtG8K.cjs} +244 -277
- package/dist/src/fetch-BxNb_Lp3.js +5 -0
- package/dist/src/{fetch-D3OHf-lV.js → fetch-Cwxnd8zz.js} +36 -44
- package/dist/src/{fetch-CXZI9RRr.js → fetch-Dxpd4_sr.js} +23 -35
- package/dist/src/fetch-HaqdX7U1.js +780 -0
- package/dist/src/{fileExtensions-ePDqouxn.js → fileExtensions-DnqA1y9x.js} +2 -2
- package/dist/src/{fileExtensions-BpuMmaFL.js → fileExtensions-Ds-foDzt.js} +2 -2
- package/dist/src/fileExtensions-LcDYkU4v.js +85 -0
- package/dist/src/{fileExtensions-DkJYkWUy.cjs → fileExtensions-bYh77CN8.cjs} +27 -28
- package/dist/src/{formatDuration-CdevI3An.js → formatDuration-DgBVMN65.js} +2 -2
- package/dist/src/{genaiTracer-Ce19n68P.js → genaiTracer-70Z8BIuV.js} +2 -3
- package/dist/src/{genaiTracer-CqNnnXrE.js → genaiTracer-C1rxGO8Q.js} +2 -3
- package/dist/src/genaiTracer-D3fD9dNV.js +256 -0
- package/dist/src/{genaiTracer-Dres3qrN.cjs → genaiTracer-DN4dQywX.cjs} +13 -14
- package/dist/src/{graders--1y2u9HO.js → graders-BTeBGqjJ.js} +349 -397
- package/dist/src/graders-B_pgMLS2.js +34 -0
- package/dist/src/{graders-DTeBrzWp.js → graders-Bj_Odv7c.js} +349 -397
- package/dist/src/graders-DErokPDO.cjs +32 -0
- package/dist/src/graders-DP7KFFo-.js +13466 -0
- package/dist/src/graders-DR_uNe54.js +32 -0
- package/dist/src/{graders-DohM2dir.cjs → graders-DU49_J8Y.cjs} +684 -732
- package/dist/src/graders-w3176Wz-.js +32 -0
- package/dist/src/{image-B0U4Hqll.js → image-B02ogr_b.js} +7 -9
- package/dist/src/{image-DmE-niFE.js → image-B0h9VEMc.js} +6 -5
- package/dist/src/{image-CuKHuccK.cjs → image-BLmROtN3.cjs} +29 -30
- package/dist/src/{image-DNEIf_aI.js → image-Bb4vWQLM.js} +6 -8
- package/dist/src/{image-DpKl2F15.cjs → image-C1madmKh.cjs} +6 -7
- package/dist/src/{image-C3wHC9_h.js → image-CHfWvljl.js} +9 -10
- package/dist/src/{image-O1u4bCFg.js → image-DS-o-0ph.js} +9 -10
- package/dist/src/image-Dpxa1Jt6.js +257 -0
- package/dist/src/index.cjs +615 -695
- package/dist/src/index.d.cts +271 -7
- package/dist/src/index.d.ts +271 -3
- package/dist/src/index.js +580 -664
- package/dist/src/{interactiveCheck-Bxj1Swex.js → interactiveCheck-BgLZUIt3.js} +7 -8
- package/dist/src/{invariant-DT20jrBd.js → invariant-BtWWVVhl.js} +2 -2
- package/dist/src/{invariant-1pAf2CD1.js → invariant-Ddh24eXh.js} +2 -2
- package/dist/src/{invariant-CKcJAQ6M.cjs → invariant-kfQ8Bu82.cjs} +7 -8
- package/dist/src/invariant-vgHWClmd.js +25 -0
- package/dist/src/{knowledgeBase-CEzQobWX.js → knowledgeBase-B3OoKIej.js} +14 -9
- package/dist/src/{knowledgeBase-Be_zyW4L.js → knowledgeBase-CYTLHOt1.js} +16 -16
- package/dist/src/{knowledgeBase-BZ41IFwq.js → knowledgeBase-D33Ty2l6.js} +14 -18
- package/dist/src/{knowledgeBase-D-5BMXlr.cjs → knowledgeBase-DOO_BM9b.cjs} +14 -15
- package/dist/src/{litellm-DnbRJ2if.js → litellm-AaeZcZQF.js} +18 -19
- package/dist/src/{litellm-hUSNM_M2.cjs → litellm-I_hbp_dc.cjs} +17 -17
- package/dist/src/{litellm-CRDqPhNI.js → litellm-NbjknEh6.js} +17 -18
- package/dist/src/{litellm-9vR8zpfU.js → litellm-TrljxD9G.js} +17 -5
- package/dist/src/{logger-CG1uZPbQ.js → logger-CT3IKMKA.js} +10 -29
- package/dist/src/{logger-B7sBeGa0.cjs → logger-Cp1GPUjj.cjs} +152 -180
- package/dist/src/logger-DLcq4dWf.js +713 -0
- package/dist/src/{logger-LSBxlt7a.js → logger-KkObSCzq.js} +13 -31
- package/dist/src/{luma-ray-4blv9iZ2.js → luma-ray-BS2_tY8L.js} +22 -21
- package/dist/src/{luma-ray-drvgdpP9.js → luma-ray-DDsjcgZZ.js} +20 -13
- package/dist/src/{luma-ray-Hm3d6VJE.cjs → luma-ray-Due0n7di.cjs} +20 -21
- package/dist/src/{luma-ray-B2__8lYH.js → luma-ray-f6I2fft-.js} +20 -23
- package/dist/src/main.js +1170 -1321
- package/dist/src/{messages-Uee41Mj5.js → messages-BS17jdMx.js} +22 -24
- package/dist/src/{messages-XhiwCbi4.cjs → messages-Bs1kC7P4.cjs} +32 -34
- package/dist/src/{messages-CGPPidQr.js → messages-D0lx5qK7.js} +22 -24
- package/dist/src/messages-ZJk778GH.js +240 -0
- package/dist/src/{meteor-BYykdXrV.js → meteor-44VjEACX.js} +3 -4
- package/dist/src/{meteor-CsopaHrH.js → meteor-D-SotUw9.js} +3 -4
- package/dist/src/{meteor-e-E-2vVl.cjs → meteor-DLZZ3osF.cjs} +3 -4
- package/dist/src/{meteor-C8lGP6P4.js → meteor-DUiCJRC-.js} +3 -4
- package/dist/src/{modelslab-yKz-ZNB4.js → modelslab-Bmni6skY.js} +17 -10
- package/dist/src/{modelslab-E9gO-bYd.js → modelslab-Bx9IrZfS.js} +18 -20
- package/dist/src/{modelslab-lUVW0cmB.cjs → modelslab-CoUX6Jc_.cjs} +17 -18
- package/dist/src/{modelslab-ClBkr8_9.js → modelslab-DRb74SP4.js} +17 -19
- package/dist/src/{nova-reel-Dk8jNpId.js → nova-reel-BfPq-0Yk.js} +20 -13
- package/dist/src/{nova-reel-D8CuO6QH.cjs → nova-reel-C_QM18Xn.cjs} +20 -21
- package/dist/src/{nova-reel-u2eF2Cxm.js → nova-reel-D_W1tjMH.js} +22 -21
- package/dist/src/{nova-reel-P9bwvtYX.js → nova-reel-bgjxilYW.js} +20 -23
- package/dist/src/{nova-sonic-CK2rAiKi.js → nova-sonic-CFb5GYhg.js} +30 -26
- package/dist/src/{nova-sonic-BaqWlkds.js → nova-sonic-DIGQNR07.js} +30 -31
- package/dist/src/{nova-sonic-yZapPLv7.js → nova-sonic-De1HW5fD.js} +31 -32
- package/dist/src/{nova-sonic-Ds1C-dpm.cjs → nova-sonic-zfcljeRp.cjs} +30 -31
- package/dist/src/{openai-DUFopMrH.cjs → openai-Cuif0GEt.cjs} +8 -9
- package/dist/src/{openai-PblZ3jUE.js → openai-DElQ-fPX.js} +3 -4
- package/dist/src/{openai-CcN1B8Sb.js → openai-DhbB7eWK.js} +3 -4
- package/dist/src/openai-j-sE2O7r.js +44 -0
- package/dist/src/{openclaw-B6qqDr_u.cjs → openclaw-CSugPYAr.cjs} +188 -130
- package/dist/src/{openclaw-A-3_loM7.js → openclaw-DiSz3I5L.js} +180 -109
- package/dist/src/{openclaw-a3lylB-V.js → openclaw-DuvJKEW5.js} +178 -124
- package/dist/src/{openclaw-COn6QzDi.js → openclaw-tiVYRtr-.js} +178 -122
- package/dist/src/opencode-sdk-0j6rTWNb.js +562 -0
- package/dist/src/opencode-sdk-B3CWY9h_.js +560 -0
- package/dist/src/opencode-sdk-BL764Jdi.cjs +564 -0
- package/dist/src/opencode-sdk-C2y6UkP2.js +560 -0
- package/dist/src/{otlpReceiver-oyf5wLGC.js → otlpReceiver-C99PPb48.js} +53 -51
- package/dist/src/{otlpReceiver-lXsYVbpj.cjs → otlpReceiver-CGq6LspY.cjs} +53 -55
- package/dist/src/{otlpReceiver-94URx7UW.js → otlpReceiver-CdNBdbsk.js} +53 -55
- package/dist/src/{otlpReceiver-BmmTiMjA.js → otlpReceiver-D89fR-rC.js} +53 -55
- package/dist/src/{providerRegistry-Cq_JK_CJ.js → providerRegistry-B0RUOLI_.js} +7 -8
- package/dist/src/{providerRegistry-DSSHjMKf.js → providerRegistry-CD8MEar9.js} +7 -8
- package/dist/src/{providerRegistry-CvHEVJad.cjs → providerRegistry-Civky8Ar.cjs} +12 -13
- package/dist/src/providerRegistry-DM8rZYol.js +45 -0
- package/dist/src/providers-B7V0njNs.js +32 -0
- package/dist/src/providers-BEwbhv0X.js +30 -0
- package/dist/src/{providers-Iil64vk9.js → providers-BlqUifFg.js} +1543 -1676
- package/dist/src/providers-CH3C7zf7.js +30 -0
- package/dist/src/{providers-DHbjzW2e.cjs → providers-CgKOSgTR.cjs} +1896 -2029
- package/dist/src/providers-D8lF1sqW.js +33246 -0
- package/dist/src/{providers-BnFpbY_s.js → providers-Dk_6ocUX.js} +1536 -1669
- package/dist/src/providers-zyB6k_38.cjs +31 -0
- package/dist/src/{pythonUtils-CcT5LH1M.js → pythonUtils-C3py6GC1.js} +18 -19
- package/dist/src/{pythonUtils-DBbuI3QJ.cjs → pythonUtils-CTU3Y3lw.cjs} +42 -43
- package/dist/src/{pythonUtils-hZ8LeQLv.js → pythonUtils-D5nxkQ0P.js} +18 -19
- package/dist/src/pythonUtils-D6fwaDSg.js +249 -0
- package/dist/src/{quiverai-BuI0tE39.js → quiverai-BbOUOn2L.js} +8 -7
- package/dist/src/{quiverai-DCGSZt4U.js → quiverai-CIaELU_m.js} +8 -10
- package/dist/src/{quiverai-DiMVJQDz.cjs → quiverai-PdShCPox.cjs} +8 -9
- package/dist/src/{quiverai-fQNkExW4.js → quiverai-uH-dcTIr.js} +9 -11
- package/dist/src/{render-Dj1smHEb.js → render-Drod8m7K.js} +4 -5
- package/dist/src/responses-CB2jwoAr.js +660 -0
- package/dist/src/{responses-ghR3IOfy.cjs → responses-D8SBTL64.cjs} +39 -42
- package/dist/src/{responses-DOAFFENS.js → responses-DIR9Ud3j.js} +24 -27
- package/dist/src/{responses-CxzoQoBe.js → responses-WNGNYe3K.js} +24 -27
- package/dist/src/rubyUtils-BUHu6PhO.js +5 -0
- package/dist/src/{rubyUtils-CwbGmgYN.js → rubyUtils-BUVePouc.js} +27 -20
- package/dist/src/rubyUtils-BcuGX77l.js +222 -0
- package/dist/src/{rubyUtils-DudlFZed.js → rubyUtils-Boc4HZzX.js} +18 -19
- package/dist/src/rubyUtils-CP42kMvq.cjs +4 -0
- package/dist/src/{rubyUtils-C8MhKGHb.cjs → rubyUtils-DhCAlxZr.cjs} +48 -50
- package/dist/src/{sagemaker-gmskuyre.js → sagemaker-CNBxx5CJ.js} +75 -70
- package/dist/src/{sagemaker-CcxhlOAR.js → sagemaker-CemTFp2h.js} +75 -79
- package/dist/src/{sagemaker-77zbJ2Q2.cjs → sagemaker-Cl28mZU2.cjs} +75 -76
- package/dist/src/{sagemaker-DuM71dVU.js → sagemaker-YSyBXQQh.js} +77 -77
- package/dist/src/{scanner-DJYiSXQj.js → scanner-BsBlNXNn.js} +100 -121
- package/dist/src/server/index.js +5520 -67427
- package/dist/src/{server-B5v33lvE.cjs → server-C_7Ax-hA.cjs} +57 -67
- package/dist/src/{server-BJ4m4f1D.js → server-CqzrVGpF.js} +26 -29
- package/dist/src/server-CuxBbeSY.js +229 -0
- package/dist/src/server-DA4Cyrrq.js +7 -0
- package/dist/src/server-Dulb-4-K.cjs +5 -0
- package/dist/src/{server-RV_i_YX5.js → server-VWgWb00X.js} +19 -24
- package/dist/src/{signal-BW33JuId.js → signal-4U3mfRvL.js} +9 -11
- package/dist/src/{slack-DEURelTy.cjs → slack-BmVAVGaK.cjs} +7 -8
- package/dist/src/{slack-BQYeW9L3.js → slack-DCUPTzS2.js} +8 -8
- package/dist/src/{slack-BB6yuZzp.js → slack-DOdy_kyv.js} +7 -8
- package/dist/src/{slack-2pRrhhgJ.js → slack-DXMKtA-f.js} +7 -9
- package/dist/src/store-CXGFv4aR.js +228 -0
- package/dist/src/store-CXS-Q_91.js +6 -0
- package/dist/src/{store-D7CgQzAR.cjs → store-DLlFCC4h.cjs} +44 -45
- package/dist/src/{store-DJNsD1iC.js → store-DXilxTl-.js} +40 -36
- package/dist/src/{store-s3SftUwF.js → store-Dim__MDd.js} +34 -35
- package/dist/src/store-eYkaKMwq.cjs +5 -0
- package/dist/src/{tables-DfTsNN7X.js → tables-6YKwjN9-.js} +19 -21
- package/dist/src/tables-DLJPUdUE.js +288 -0
- package/dist/src/{tables-BKTmd6u7.cjs → tables-DPi7wKeM.cjs} +89 -91
- package/dist/src/{tables-DMegD0Xf.js → tables-gftXzE9I.js} +21 -23
- package/dist/src/telemetry-BpMfhthR.cjs +5 -0
- package/dist/src/{telemetry--WAdAfVi.js → telemetry-CMrFgtPB.js} +11 -13
- package/dist/src/telemetry-Cps3mIU-.js +171 -0
- package/dist/src/{telemetry-DQgVBCAb.cjs → telemetry-DaX14Chu.cjs} +21 -24
- package/dist/src/{telemetry-BedSm-bZ.js → telemetry-Dthj_BbD.js} +17 -14
- package/dist/src/telemetry-Dw38hanS.js +7 -0
- package/dist/src/{text-oiSbwSOI.js → text-B_UCRPp2.js} +2 -2
- package/dist/src/{text-oKzCBnK6.cjs → text-CW1cyrwj.cjs} +12 -13
- package/dist/src/{text-B_IrO4GZ.js → text-Db-Wt2u2.js} +2 -2
- package/dist/src/text-TIv0QYnd.js +22 -0
- package/dist/src/{tokenUsageUtils-FZd5O_4A.js → tokenUsageUtils-BDGe-iyI.js} +2 -2
- package/dist/src/{tokenUsageUtils-DmZSD2eU.js → tokenUsageUtils-DflFMjS0.js} +2 -2
- package/dist/src/tokenUsageUtils-NYT-WKS6.js +138 -0
- package/dist/src/{tokenUsageUtils-CXhxVj72.cjs → tokenUsageUtils-bVa1ga6f.cjs} +32 -33
- package/dist/src/{transcription-mYS9vd5v.js → transcription-BNYURcXg.js} +14 -7
- package/dist/src/{transcription-X2-B4vkX.js → transcription-B_OdaHp7.js} +14 -16
- package/dist/src/{transcription-BO1AHegO.cjs → transcription-NLVG9MT1.cjs} +14 -15
- package/dist/src/{transcription-lzBLiTFJ.js → transcription-s6A-bNrZ.js} +15 -17
- package/dist/src/{transform-B1Hi5lWS.cjs → transform-CzK1Q0zl.cjs} +24 -26
- package/dist/src/{transform-DeGlxb0D.js → transform-D5HsjduX.js} +39 -47
- package/dist/src/{transform-CYDILYDe.js → transform-DECvGmzp.js} +15 -13
- package/dist/src/transform-DTGDnAzW.js +6 -0
- package/dist/src/{transform-BEgStbHK.js → transform-DilY9wbS.js} +10 -12
- package/dist/src/{transform-D5PjiWiZ.cjs → transform-DuHvhZpj.cjs} +179 -187
- package/dist/src/transform-aa6tmVpZ.js +216 -0
- package/dist/src/transform-m3qNw4KP.cjs +5 -0
- package/dist/src/transform-uAytVuyX.js +1506 -0
- package/dist/src/{transform-Dfl89yi4.js → transform-vNucnNr0.js} +39 -47
- package/dist/src/{transformersAvailability-SZnTS3pJ.js → transformersAvailability-CEVM2GNQ.js} +2 -2
- package/dist/src/{transformersAvailability-D-glmEy7.cjs → transformersAvailability-CwayUSlh.cjs} +2 -3
- package/dist/src/{transformersAvailability-CjeFXhuJ.js → transformersAvailability-D6c6ROpT.js} +2 -2
- package/dist/src/{types-DWNf48sT.cjs → types-C_7nyzr1.cjs} +538 -574
- package/dist/src/{types-CXQduE9o.js → types-Cbd8uOMq.js} +68 -100
- package/dist/src/types-CzW2QFyi.js +3288 -0
- package/dist/src/{types-C5hEkb-x.js → types-DmyIJ-sR.js} +63 -99
- package/dist/src/{util-CoQjmE3u.js → util-B3xGByQh.js} +4 -5
- package/dist/src/{util-aLhtl3fe.cjs → util-B9vlHIIh.cjs} +208 -223
- package/dist/src/{util-Du96oyYS.js → util-BHGHw5G1.js} +4 -5
- package/dist/src/{util-DQ984syk.js → util-BRYkYPTd.js} +36 -51
- package/dist/src/{util-D9eLdGfa.js → util-BV4XUC0n.js} +5 -6
- package/dist/src/util-Bv6uGDfH.js +293 -0
- package/dist/src/{util-1wWM599Z.cjs → util-BzMcevZc.cjs} +50 -51
- package/dist/src/{util-_h4pVqrz.js → util-C1CeHl-P.js} +36 -51
- package/dist/src/{util-Bm_-UMD_.js → util-CMy69ZgQ.js} +5 -6
- package/dist/src/{util-CyUdMzV0.cjs → util-DGNOS1db.cjs} +34 -35
- package/dist/src/util-Dnmk2mBQ.js +599 -0
- package/dist/src/util-ZzmqNPlg.js +1426 -0
- package/dist/src/{utils-BjLy-Q72.cjs → utils-Cz9qXqII.cjs} +29 -32
- package/dist/src/{utils-CFMn2yHW.js → utils-XiOAgly5.js} +4 -7
- package/dist/src/utils-dLokC-eR.js +94 -0
- package/dist/src/{utils-DvWMzuMx.js → utils-f2-Moju7.js} +4 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +38 -38
- package/dist/src/app/assets/index-B2D0bCSI.js +0 -439
- package/dist/src/app/assets/vendor-charts-CCl15Imd.js +0 -36
- package/dist/src/cache-ChPcurj7.js +0 -6
- package/dist/src/cache-VVu_W-yg.js +0 -8
- package/dist/src/cache-YLNCFEM2.cjs +0 -6
- package/dist/src/chunk-DHDDz29n.js +0 -22
- package/dist/src/chunk-FhC4c-0y.js +0 -21
- package/dist/src/cloud-BndfXy4H.js +0 -5
- package/dist/src/eval-BhHvMY82.js +0 -17
- package/dist/src/evalResult-Dq2gFNQY.js +0 -12
- package/dist/src/evalResult-nmcP5VKH.cjs +0 -12
- package/dist/src/evalResult-trqZjVYh.js +0 -14
- package/dist/src/evaluator-CnfPstzT.js +0 -39
- package/dist/src/fetch-IDPDue6F.cjs +0 -4
- package/dist/src/fetch-hKJ-It8q.js +0 -6
- package/dist/src/fetch-ouKnrWK-.js +0 -4
- package/dist/src/graders-CQn7WUsd.cjs +0 -34
- package/dist/src/graders-DC6QAbpW.js +0 -35
- package/dist/src/graders-DUWz3Y7j.js +0 -37
- package/dist/src/opencode-sdk-4bL9n-Gk.js +0 -382
- package/dist/src/opencode-sdk-BfC2zWcR.js +0 -376
- package/dist/src/opencode-sdk-DMJyuwMg.js +0 -380
- package/dist/src/opencode-sdk-Da-9adza.cjs +0 -383
- package/dist/src/providers-CsXB2Ix-.js +0 -35
- package/dist/src/providers-DO8ltjLC.js +0 -33
- package/dist/src/providers-Dtq-xnXd.cjs +0 -33
- package/dist/src/rubyUtils-BUbcND2f.js +0 -6
- package/dist/src/rubyUtils-Cr55X_KE.js +0 -5
- package/dist/src/rubyUtils-DlIiqoYo.cjs +0 -5
- package/dist/src/server-C2eQH4Gu.js +0 -6
- package/dist/src/server-CXWycu7H.cjs +0 -6
- package/dist/src/server-Q6OGlxxT.js +0 -8
- package/dist/src/store-B3EDO9Q3.js +0 -7
- package/dist/src/store-Dl9F8aw5.js +0 -6
- package/dist/src/store-SnrGrlt9.cjs +0 -6
- package/dist/src/telemetry-BGhiPZtl.js +0 -8
- package/dist/src/telemetry-CFfiYan6.cjs +0 -6
- package/dist/src/telemetry-DHzEduxX.js +0 -6
- package/dist/src/transform-C1x1ZlMQ.cjs +0 -6
- package/dist/src/transform-DYHjFmQu.js +0 -8
- package/dist/src/transform-rmwJT5JQ.js +0 -7
- package/dist/src/transformersAvailability-eJooj0gX.js +0 -35
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./logger-KkObSCzq.js";
|
|
3
|
+
import "./fetch-Dxpd4_sr.js";
|
|
4
|
+
import "./accounts-Bm2D8Db9.js";
|
|
5
|
+
import "./cloud-C0dlstV_.js";
|
|
6
|
+
import "./telemetry-CMrFgtPB.js";
|
|
7
|
+
import "./types-Cbd8uOMq.js";
|
|
8
|
+
import "./server-CqzrVGpF.js";
|
|
9
|
+
import "./providers-BlqUifFg.js";
|
|
10
|
+
import "./cache-BVeDlD87.js";
|
|
11
|
+
import "./util-C1CeHl-P.js";
|
|
12
|
+
import "./esm-C03C-mv3.js";
|
|
13
|
+
import "./pythonUtils-C3py6GC1.js";
|
|
14
|
+
import "./transform-DilY9wbS.js";
|
|
15
|
+
import "./graders-Bj_Odv7c.js";
|
|
16
|
+
import "./utils-f2-Moju7.js";
|
|
17
|
+
import "./genaiTracer-C1rxGO8Q.js";
|
|
18
|
+
import "./chat-BiKyneZl.js";
|
|
19
|
+
import "./transform-D5HsjduX.js";
|
|
20
|
+
import "./messages-D0lx5qK7.js";
|
|
21
|
+
import "./util-B3xGByQh.js";
|
|
22
|
+
import "./responses-WNGNYe3K.js";
|
|
23
|
+
import "./openai-DhbB7eWK.js";
|
|
24
|
+
import "./util-CMy69ZgQ.js";
|
|
25
|
+
import "./completion-DZ083F31.js";
|
|
26
|
+
import "./blobs-CMHN0Qcz.js";
|
|
27
|
+
import "./tables-gftXzE9I.js";
|
|
28
|
+
import "./extractor-DReVID0K.js";
|
|
29
|
+
import "./store-Dim__MDd.js";
|
|
30
|
+
import "./base-Dy1V8--Z.js";
|
|
31
|
+
import "./image-DS-o-0ph.js";
|
|
32
|
+
import "./providerRegistry-B0RUOLI_.js";
|
|
33
|
+
import "./rubyUtils-Boc4HZzX.js";
|
|
34
|
+
import { t as evaluate } from "./evaluator-BhoWwp5b.js";
|
|
35
|
+
import "./signal-4U3mfRvL.js";
|
|
36
|
+
export { evaluate };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { _ as getEnvBool, i as
|
|
2
|
-
import {
|
|
3
|
-
import { o as isLoggedIntoCloud } from "./accounts-
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { _ as getEnvBool, i as logger } from "./logger-CT3IKMKA.js";
|
|
2
|
+
import { o as cloudConfig } from "./fetch-Cwxnd8zz.js";
|
|
3
|
+
import { o as isLoggedIntoCloud } from "./accounts-CiBLOnA7.js";
|
|
4
|
+
import { n as recordBlobReference, r as storeBlob } from "./blobs-CBO20krR.js";
|
|
6
5
|
//#region src/blobs/remoteUpload.ts
|
|
7
6
|
function buildRemoteUrl() {
|
|
8
7
|
const baseUrl = cloudConfig.getApiHost();
|
|
@@ -11,7 +10,7 @@ function buildRemoteUrl() {
|
|
|
11
10
|
try {
|
|
12
11
|
return new URL("/api/blobs", baseUrl).toString();
|
|
13
12
|
} catch (error) {
|
|
14
|
-
|
|
13
|
+
logger.debug("[RemoteBlob] Invalid remote blob URL", {
|
|
15
14
|
error: error instanceof Error ? error.message : String(error),
|
|
16
15
|
baseUrl
|
|
17
16
|
});
|
|
@@ -26,7 +25,7 @@ async function uploadBlobRemote(buffer, mimeType, context) {
|
|
|
26
25
|
const apiKey = cloudConfig.getApiKey();
|
|
27
26
|
if (!url || !apiKey) return null;
|
|
28
27
|
try {
|
|
29
|
-
const { fetchWithProxy } = await import("./fetch-
|
|
28
|
+
const { fetchWithProxy } = await import("./fetch-Cwxnd8zz.js").then((n) => n.i);
|
|
30
29
|
const response = await fetchWithProxy(url, {
|
|
31
30
|
method: "POST",
|
|
32
31
|
headers: {
|
|
@@ -40,12 +39,12 @@ async function uploadBlobRemote(buffer, mimeType, context) {
|
|
|
40
39
|
})
|
|
41
40
|
});
|
|
42
41
|
if (response.status === 404 || response.status === 400) {
|
|
43
|
-
|
|
42
|
+
logger.debug("[RemoteBlob] Remote blob upload unavailable", { status: response.status });
|
|
44
43
|
return null;
|
|
45
44
|
}
|
|
46
45
|
if (!response.ok) {
|
|
47
46
|
const text = await response.text();
|
|
48
|
-
|
|
47
|
+
logger.debug("[RemoteBlob] Failed to upload blob", {
|
|
49
48
|
status: response.status,
|
|
50
49
|
statusText: response.statusText,
|
|
51
50
|
body: text
|
|
@@ -54,16 +53,15 @@ async function uploadBlobRemote(buffer, mimeType, context) {
|
|
|
54
53
|
}
|
|
55
54
|
const data = await response.json();
|
|
56
55
|
if (!data?.ref?.hash) {
|
|
57
|
-
|
|
56
|
+
logger.debug("[RemoteBlob] Remote upload returned malformed response");
|
|
58
57
|
return null;
|
|
59
58
|
}
|
|
60
59
|
return data;
|
|
61
60
|
} catch (error) {
|
|
62
|
-
|
|
61
|
+
logger.debug("[RemoteBlob] Error uploading blob", { error: error instanceof Error ? error.message : String(error) });
|
|
63
62
|
return null;
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
|
-
|
|
67
65
|
//#endregion
|
|
68
66
|
//#region src/blobs/extractor.ts
|
|
69
67
|
const BLOB_URI_REGEX = /^promptfoo:\/\/blob\/([a-f0-9]{64})$/i;
|
|
@@ -81,13 +79,13 @@ function extractBase64(value) {
|
|
|
81
79
|
mimeType
|
|
82
80
|
};
|
|
83
81
|
} catch (error) {
|
|
84
|
-
|
|
82
|
+
logger.warn("[BlobExtractor] Failed to parse base64 data URL", { error });
|
|
85
83
|
return null;
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
function shouldExternalize(buffer) {
|
|
89
87
|
const size = buffer.length;
|
|
90
|
-
return size >=
|
|
88
|
+
return size >= 1024 && size <= 52428800;
|
|
91
89
|
}
|
|
92
90
|
function getKindFromMimeType(mimeType) {
|
|
93
91
|
return mimeType.startsWith("audio/") ? "audio" : "image";
|
|
@@ -113,7 +111,7 @@ function normalizeAudioMimeType(format) {
|
|
|
113
111
|
};
|
|
114
112
|
if (mimeMap[formatLower]) return mimeMap[formatLower];
|
|
115
113
|
if (!/^[a-z0-9_-]+$/i.test(formatLower)) {
|
|
116
|
-
|
|
114
|
+
logger.warn("[BlobExtractor] Invalid audio format, using default", { format });
|
|
117
115
|
return "audio/wav";
|
|
118
116
|
}
|
|
119
117
|
return `audio/${formatLower}`;
|
|
@@ -130,7 +128,7 @@ function parseBinary(base64OrDataUrl, defaultMimeType) {
|
|
|
130
128
|
mimeType: defaultMimeType
|
|
131
129
|
};
|
|
132
130
|
} catch (error) {
|
|
133
|
-
|
|
131
|
+
logger.warn("[BlobExtractor] Failed to parse base64 data", { error });
|
|
134
132
|
return null;
|
|
135
133
|
}
|
|
136
134
|
}
|
|
@@ -151,7 +149,7 @@ async function maybeStore(base64OrDataUrl, defaultMimeType, context, location, k
|
|
|
151
149
|
location,
|
|
152
150
|
kind
|
|
153
151
|
}).catch((error) => {
|
|
154
|
-
|
|
152
|
+
logger.debug("[BlobExtractor] Cloud upload failed (non-fatal)", {
|
|
155
153
|
error: error instanceof Error ? error.message : String(error),
|
|
156
154
|
hash: ref.hash
|
|
157
155
|
});
|
|
@@ -235,7 +233,7 @@ async function extractAndStoreBinaryData(response, context) {
|
|
|
235
233
|
blobRef: stored
|
|
236
234
|
};
|
|
237
235
|
mutated = true;
|
|
238
|
-
|
|
236
|
+
logger.debug("[BlobExtractor] Stored audio blob", {
|
|
239
237
|
...context,
|
|
240
238
|
hash: stored.hash
|
|
241
239
|
});
|
|
@@ -246,7 +244,7 @@ async function extractAndStoreBinaryData(response, context) {
|
|
|
246
244
|
const stored = await maybeStore(img.data, img.mimeType || "image/png", blobContext, `response.images[${idx}].data`, "image");
|
|
247
245
|
if (stored) {
|
|
248
246
|
mutated = true;
|
|
249
|
-
|
|
247
|
+
logger.debug("[BlobExtractor] Stored image blob", {
|
|
250
248
|
...context,
|
|
251
249
|
hash: stored.hash
|
|
252
250
|
});
|
|
@@ -283,7 +281,7 @@ async function extractAndStoreBinaryData(response, context) {
|
|
|
283
281
|
if (stored) {
|
|
284
282
|
next.output = stored.uri;
|
|
285
283
|
mutated = true;
|
|
286
|
-
|
|
284
|
+
logger.debug("[BlobExtractor] Stored output blob", {
|
|
287
285
|
...context,
|
|
288
286
|
hash: stored.hash
|
|
289
287
|
});
|
|
@@ -302,7 +300,7 @@ async function extractAndStoreBinaryData(response, context) {
|
|
|
302
300
|
storedUris.push(stored.uri);
|
|
303
301
|
jsonMutated = true;
|
|
304
302
|
mutated = true;
|
|
305
|
-
|
|
303
|
+
logger.debug("[BlobExtractor] Stored image blob from b64_json", {
|
|
306
304
|
...context,
|
|
307
305
|
hash: stored.hash
|
|
308
306
|
});
|
|
@@ -320,7 +318,7 @@ async function extractAndStoreBinaryData(response, context) {
|
|
|
320
318
|
}
|
|
321
319
|
}
|
|
322
320
|
} catch (err) {
|
|
323
|
-
|
|
321
|
+
logger.debug("[BlobExtractor] Failed to parse base64 JSON output", {
|
|
324
322
|
error: err instanceof Error ? err.message : String(err),
|
|
325
323
|
location: "response.output"
|
|
326
324
|
});
|
|
@@ -370,7 +368,7 @@ async function recordExistingBlobReferences(value, context, location) {
|
|
|
370
368
|
}
|
|
371
369
|
if (value && typeof value === "object") for (const [key, child] of Object.entries(value)) await recordExistingBlobReferences(child, context, location ? `${location}.${key}` : key);
|
|
372
370
|
}
|
|
373
|
-
|
|
374
371
|
//#endregion
|
|
375
372
|
export { isBlobStorageEnabled as n, shouldAttemptRemoteBlobUpload as r, extractAndStoreBinaryData as t };
|
|
376
|
-
|
|
373
|
+
|
|
374
|
+
//# sourceMappingURL=extractor-C0EVHewb.js.map
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { _ as getEnvBool, i as logger } from "./logger-DLcq4dWf.js";
|
|
2
|
+
import { o as cloudConfig } from "./fetch-HaqdX7U1.js";
|
|
3
|
+
import { c as isLoggedIntoCloud } from "./accounts-B0pgC1oV.js";
|
|
4
|
+
import { i as storeBlob, r as recordBlobReference } from "./blobs-BDbfYdrJ.js";
|
|
5
|
+
//#region src/blobs/remoteUpload.ts
|
|
6
|
+
function buildRemoteUrl() {
|
|
7
|
+
const baseUrl = cloudConfig.getApiHost();
|
|
8
|
+
const apiKey = cloudConfig.getApiKey();
|
|
9
|
+
if (!baseUrl || !apiKey || !isLoggedIntoCloud()) return null;
|
|
10
|
+
try {
|
|
11
|
+
return new URL("/api/blobs", baseUrl).toString();
|
|
12
|
+
} catch (error) {
|
|
13
|
+
logger.debug("[RemoteBlob] Invalid remote blob URL", {
|
|
14
|
+
error: error instanceof Error ? error.message : String(error),
|
|
15
|
+
baseUrl
|
|
16
|
+
});
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function shouldAttemptRemoteBlobUpload() {
|
|
21
|
+
return buildRemoteUrl() !== null;
|
|
22
|
+
}
|
|
23
|
+
async function uploadBlobRemote(buffer, mimeType, context) {
|
|
24
|
+
const url = buildRemoteUrl();
|
|
25
|
+
const apiKey = cloudConfig.getApiKey();
|
|
26
|
+
if (!url || !apiKey) return null;
|
|
27
|
+
try {
|
|
28
|
+
const { fetchWithProxy } = await import("./fetch-HaqdX7U1.js").then((n) => n.i);
|
|
29
|
+
const response = await fetchWithProxy(url, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
Authorization: `Bearer ${apiKey}`
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
data: buffer.toString("base64"),
|
|
37
|
+
mimeType,
|
|
38
|
+
context
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
if (response.status === 404 || response.status === 400) {
|
|
42
|
+
logger.debug("[RemoteBlob] Remote blob upload unavailable", { status: response.status });
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
const text = await response.text();
|
|
47
|
+
logger.debug("[RemoteBlob] Failed to upload blob", {
|
|
48
|
+
status: response.status,
|
|
49
|
+
statusText: response.statusText,
|
|
50
|
+
body: text
|
|
51
|
+
});
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const data = await response.json();
|
|
55
|
+
if (!data?.ref?.hash) {
|
|
56
|
+
logger.debug("[RemoteBlob] Remote upload returned malformed response");
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return data;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.debug("[RemoteBlob] Error uploading blob", { error: error instanceof Error ? error.message : String(error) });
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/blobs/extractor.ts
|
|
67
|
+
const BLOB_URI_REGEX = /^promptfoo:\/\/blob\/([a-f0-9]{64})$/i;
|
|
68
|
+
const BLOB_HASH_REGEX = /^[a-f0-9]{64}$/i;
|
|
69
|
+
function isDataUrl(value) {
|
|
70
|
+
return /^data:(audio|image)\/[^;]+;base64,/.test(value);
|
|
71
|
+
}
|
|
72
|
+
function extractBase64(value) {
|
|
73
|
+
const match = value.match(/^data:([^;]+);base64,(.+)$/);
|
|
74
|
+
if (!match) return null;
|
|
75
|
+
const mimeType = match[1];
|
|
76
|
+
try {
|
|
77
|
+
return {
|
|
78
|
+
buffer: Buffer.from(match[2], "base64"),
|
|
79
|
+
mimeType
|
|
80
|
+
};
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logger.warn("[BlobExtractor] Failed to parse base64 data URL", { error });
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function shouldExternalize(buffer) {
|
|
87
|
+
const size = buffer.length;
|
|
88
|
+
return size >= 1024 && size <= 52428800;
|
|
89
|
+
}
|
|
90
|
+
function getKindFromMimeType(mimeType) {
|
|
91
|
+
return mimeType.startsWith("audio/") ? "audio" : "image";
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Normalize audio format to proper MIME type.
|
|
95
|
+
* Some providers return just 'wav' instead of 'audio/wav'.
|
|
96
|
+
* @internal Exported for testing
|
|
97
|
+
*/
|
|
98
|
+
function normalizeAudioMimeType(format) {
|
|
99
|
+
if (!format) return "audio/wav";
|
|
100
|
+
const trimmedFormat = format.trim();
|
|
101
|
+
if (/^audio\/[a-z0-9_+-]+$/i.test(trimmedFormat)) return trimmedFormat;
|
|
102
|
+
const formatLower = trimmedFormat.toLowerCase();
|
|
103
|
+
const mimeMap = {
|
|
104
|
+
wav: "audio/wav",
|
|
105
|
+
mp3: "audio/mpeg",
|
|
106
|
+
ogg: "audio/ogg",
|
|
107
|
+
flac: "audio/flac",
|
|
108
|
+
aac: "audio/aac",
|
|
109
|
+
m4a: "audio/mp4",
|
|
110
|
+
webm: "audio/webm"
|
|
111
|
+
};
|
|
112
|
+
if (mimeMap[formatLower]) return mimeMap[formatLower];
|
|
113
|
+
if (!/^[a-z0-9_-]+$/i.test(formatLower)) {
|
|
114
|
+
logger.warn("[BlobExtractor] Invalid audio format, using default", { format });
|
|
115
|
+
return "audio/wav";
|
|
116
|
+
}
|
|
117
|
+
return `audio/${formatLower}`;
|
|
118
|
+
}
|
|
119
|
+
function parseBinary(base64OrDataUrl, defaultMimeType) {
|
|
120
|
+
if (isDataUrl(base64OrDataUrl)) {
|
|
121
|
+
const parsed = extractBase64(base64OrDataUrl);
|
|
122
|
+
if (!parsed) return null;
|
|
123
|
+
return parsed;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
return {
|
|
127
|
+
buffer: Buffer.from(base64OrDataUrl, "base64"),
|
|
128
|
+
mimeType: defaultMimeType
|
|
129
|
+
};
|
|
130
|
+
} catch (error) {
|
|
131
|
+
logger.warn("[BlobExtractor] Failed to parse base64 data", { error });
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function maybeStore(base64OrDataUrl, defaultMimeType, context, location, kind) {
|
|
136
|
+
const parsed = parseBinary(base64OrDataUrl, defaultMimeType);
|
|
137
|
+
if (!parsed || !shouldExternalize(parsed.buffer)) return null;
|
|
138
|
+
if (!isBlobStorageEnabled()) return null;
|
|
139
|
+
const mimeType = parsed.mimeType || "application/octet-stream";
|
|
140
|
+
const { ref } = await storeBlob(parsed.buffer, mimeType, {
|
|
141
|
+
...context,
|
|
142
|
+
location,
|
|
143
|
+
kind
|
|
144
|
+
});
|
|
145
|
+
if (shouldAttemptRemoteBlobUpload()) uploadBlobRemote(parsed.buffer, mimeType, {
|
|
146
|
+
evalId: context.evalId,
|
|
147
|
+
testIdx: context.testIdx,
|
|
148
|
+
promptIdx: context.promptIdx,
|
|
149
|
+
location,
|
|
150
|
+
kind
|
|
151
|
+
}).catch((error) => {
|
|
152
|
+
logger.debug("[BlobExtractor] Cloud upload failed (non-fatal)", {
|
|
153
|
+
error: error instanceof Error ? error.message : String(error),
|
|
154
|
+
hash: ref.hash
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
return ref;
|
|
158
|
+
}
|
|
159
|
+
async function externalizeDataUrls(value, context, location) {
|
|
160
|
+
if (typeof value === "string") {
|
|
161
|
+
if (!isDataUrl(value)) return {
|
|
162
|
+
value,
|
|
163
|
+
mutated: false
|
|
164
|
+
};
|
|
165
|
+
const parsed = extractBase64(value);
|
|
166
|
+
if (!parsed || !shouldExternalize(parsed.buffer)) return {
|
|
167
|
+
value,
|
|
168
|
+
mutated: false
|
|
169
|
+
};
|
|
170
|
+
const storedRef = await maybeStore(parsed.buffer.toString("base64"), parsed.mimeType, context, location, getKindFromMimeType(parsed.mimeType)) || null;
|
|
171
|
+
if (!storedRef) return {
|
|
172
|
+
value,
|
|
173
|
+
mutated: false
|
|
174
|
+
};
|
|
175
|
+
return {
|
|
176
|
+
value: storedRef.uri,
|
|
177
|
+
mutated: true
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (Array.isArray(value)) {
|
|
181
|
+
let mutated = false;
|
|
182
|
+
const nextValues = await Promise.all(value.map(async (item, idx) => {
|
|
183
|
+
const { value: nextValue, mutated: childMutated } = await externalizeDataUrls(item, context, `${location}[${idx}]`);
|
|
184
|
+
mutated ||= childMutated;
|
|
185
|
+
return nextValue;
|
|
186
|
+
}));
|
|
187
|
+
return mutated ? {
|
|
188
|
+
value: nextValues,
|
|
189
|
+
mutated
|
|
190
|
+
} : {
|
|
191
|
+
value,
|
|
192
|
+
mutated: false
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (value && typeof value === "object") {
|
|
196
|
+
let mutated = false;
|
|
197
|
+
const nextObject = { ...value };
|
|
198
|
+
for (const [key, child] of Object.entries(value)) {
|
|
199
|
+
const { value: nextValue, mutated: childMutated } = await externalizeDataUrls(child, context, location ? `${location}.${key}` : key);
|
|
200
|
+
if (childMutated) {
|
|
201
|
+
nextObject[key] = nextValue;
|
|
202
|
+
mutated = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return mutated ? {
|
|
206
|
+
value: nextObject,
|
|
207
|
+
mutated: true
|
|
208
|
+
} : {
|
|
209
|
+
value,
|
|
210
|
+
mutated: false
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
value,
|
|
215
|
+
mutated: false
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Best-effort extraction of binary data from provider responses.
|
|
220
|
+
* Currently focuses on audio.data fields and data URL outputs.
|
|
221
|
+
*/
|
|
222
|
+
async function extractAndStoreBinaryData(response, context) {
|
|
223
|
+
if (!response) return response;
|
|
224
|
+
let mutated = false;
|
|
225
|
+
const next = { ...response };
|
|
226
|
+
const blobContext = context || {};
|
|
227
|
+
if (response.audio?.data && typeof response.audio.data === "string") {
|
|
228
|
+
const stored = await maybeStore(response.audio.data, normalizeAudioMimeType(response.audio.format), blobContext, "response.audio.data", "audio");
|
|
229
|
+
if (stored) {
|
|
230
|
+
next.audio = {
|
|
231
|
+
...response.audio,
|
|
232
|
+
data: void 0,
|
|
233
|
+
blobRef: stored
|
|
234
|
+
};
|
|
235
|
+
mutated = true;
|
|
236
|
+
logger.debug("[BlobExtractor] Stored audio blob", {
|
|
237
|
+
...context,
|
|
238
|
+
hash: stored.hash
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (response.images?.length) next.images = await Promise.all(response.images.map(async (img, idx) => {
|
|
243
|
+
if (!img.data || typeof img.data !== "string" || !isDataUrl(img.data)) return img;
|
|
244
|
+
const stored = await maybeStore(img.data, img.mimeType || "image/png", blobContext, `response.images[${idx}].data`, "image");
|
|
245
|
+
if (stored) {
|
|
246
|
+
mutated = true;
|
|
247
|
+
logger.debug("[BlobExtractor] Stored image blob", {
|
|
248
|
+
...context,
|
|
249
|
+
hash: stored.hash
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
...img,
|
|
253
|
+
data: void 0,
|
|
254
|
+
blobRef: stored
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return img;
|
|
258
|
+
}));
|
|
259
|
+
const turns = response.turns;
|
|
260
|
+
if (Array.isArray(turns)) next.turns = await Promise.all(turns.map(async (turn, idx) => {
|
|
261
|
+
if (turn?.audio?.data && typeof turn.audio.data === "string") {
|
|
262
|
+
const stored = await maybeStore(turn.audio.data, normalizeAudioMimeType(turn.audio.format), blobContext, `response.turns[${idx}].audio.data`, "audio");
|
|
263
|
+
if (stored) {
|
|
264
|
+
mutated = true;
|
|
265
|
+
return {
|
|
266
|
+
...turn,
|
|
267
|
+
audio: {
|
|
268
|
+
...turn.audio,
|
|
269
|
+
data: void 0,
|
|
270
|
+
blobRef: stored
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return turn;
|
|
276
|
+
}));
|
|
277
|
+
if (typeof response.output === "string" && isDataUrl(response.output)) {
|
|
278
|
+
const parsed = extractBase64(response.output);
|
|
279
|
+
if (parsed && shouldExternalize(parsed.buffer)) {
|
|
280
|
+
const stored = await maybeStore(parsed.buffer.toString("base64"), parsed.mimeType, blobContext, "response.output", getKindFromMimeType(parsed.mimeType));
|
|
281
|
+
if (stored) {
|
|
282
|
+
next.output = stored.uri;
|
|
283
|
+
mutated = true;
|
|
284
|
+
logger.debug("[BlobExtractor] Stored output blob", {
|
|
285
|
+
...context,
|
|
286
|
+
hash: stored.hash
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (typeof response.output === "string" && response.output.trim().startsWith("{") && (response.isBase64 && response.format === "json" || response.output.includes("\"b64_json\"") || response.output.includes("b64_json"))) try {
|
|
292
|
+
const parsed = JSON.parse(response.output);
|
|
293
|
+
if (Array.isArray(parsed.data)) {
|
|
294
|
+
let jsonMutated = false;
|
|
295
|
+
const storedUris = [];
|
|
296
|
+
for (const item of parsed.data) if (item?.b64_json && typeof item.b64_json === "string") {
|
|
297
|
+
const stored = await maybeStore(item.b64_json, "image/png", blobContext, "response.output.data[].b64_json", "image");
|
|
298
|
+
if (stored) {
|
|
299
|
+
item.b64_json = stored.uri;
|
|
300
|
+
storedUris.push(stored.uri);
|
|
301
|
+
jsonMutated = true;
|
|
302
|
+
mutated = true;
|
|
303
|
+
logger.debug("[BlobExtractor] Stored image blob from b64_json", {
|
|
304
|
+
...context,
|
|
305
|
+
hash: stored.hash
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (jsonMutated) {
|
|
310
|
+
if (storedUris.length === 1) next.output = storedUris[0];
|
|
311
|
+
else if (storedUris.length > 1) next.output = JSON.stringify(storedUris);
|
|
312
|
+
else next.output = JSON.stringify(parsed);
|
|
313
|
+
next.metadata = {
|
|
314
|
+
...response.metadata || {},
|
|
315
|
+
blobUris: storedUris,
|
|
316
|
+
originalFormat: response.format
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
} catch (err) {
|
|
321
|
+
logger.debug("[BlobExtractor] Failed to parse base64 JSON output", {
|
|
322
|
+
error: err instanceof Error ? err.message : String(err),
|
|
323
|
+
location: "response.output"
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (response.metadata) {
|
|
327
|
+
const { value, mutated: metadataMutated } = await externalizeDataUrls(response.metadata, blobContext, "response.metadata");
|
|
328
|
+
if (metadataMutated) {
|
|
329
|
+
next.metadata = value;
|
|
330
|
+
mutated = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const finalResponse = mutated ? next : response;
|
|
334
|
+
if (blobContext.evalId) await recordExistingBlobReferences(finalResponse, blobContext, "response");
|
|
335
|
+
return finalResponse;
|
|
336
|
+
}
|
|
337
|
+
function isBlobStorageEnabled() {
|
|
338
|
+
return !getEnvBool("PROMPTFOO_INLINE_MEDIA", false);
|
|
339
|
+
}
|
|
340
|
+
function parseBlobHashFromValue(value) {
|
|
341
|
+
if (!value) return null;
|
|
342
|
+
if (typeof value === "string") {
|
|
343
|
+
const match = value.match(BLOB_URI_REGEX);
|
|
344
|
+
return match ? match[1] : null;
|
|
345
|
+
}
|
|
346
|
+
if (typeof value === "object") {
|
|
347
|
+
const candidate = value;
|
|
348
|
+
if (candidate.hash && BLOB_HASH_REGEX.test(candidate.hash)) return candidate.hash;
|
|
349
|
+
if (candidate.uri && typeof candidate.uri === "string") {
|
|
350
|
+
const match = candidate.uri.match(BLOB_URI_REGEX);
|
|
351
|
+
if (match) return match[1];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
async function recordExistingBlobReferences(value, context, location) {
|
|
357
|
+
const hash = parseBlobHashFromValue(value);
|
|
358
|
+
if (hash) {
|
|
359
|
+
await recordBlobReference(hash, {
|
|
360
|
+
...context,
|
|
361
|
+
location
|
|
362
|
+
});
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (Array.isArray(value)) {
|
|
366
|
+
await Promise.all(value.map((child, idx) => recordExistingBlobReferences(child, context, `${location}[${idx}]`)));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (value && typeof value === "object") for (const [key, child] of Object.entries(value)) await recordExistingBlobReferences(child, context, location ? `${location}.${key}` : key);
|
|
370
|
+
}
|
|
371
|
+
//#endregion
|
|
372
|
+
export { isBlobStorageEnabled as n, shouldAttemptRemoteBlobUpload as r, extractAndStoreBinaryData as t };
|
|
373
|
+
|
|
374
|
+
//# sourceMappingURL=extractor-D25qpmGX.js.map
|