reeval 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -40
- package/THIRD_PARTY_NOTICES.md +218 -11
- package/assets/package.json +1 -1
- package/assets/pnpm-lock.yaml +30 -30
- package/dist/adapter-DWlpOtRn.js +279 -0
- package/dist/adapter-DWlpOtRn.js.map +1 -0
- package/dist/{agent-B72lZ6w5.js → agent-CURAwx_q.js} +6 -6
- package/dist/{agent-B72lZ6w5.js.map → agent-CURAwx_q.js.map} +1 -1
- package/dist/{agent-Cfj1wD4D.js → agent-CaS_2Sce.js} +92 -26
- package/dist/agent-CaS_2Sce.js.map +1 -0
- package/dist/{analysis-BTNnKh1w.js → analysis-Bxub9LMT.js} +4 -4
- package/dist/{analysis-BTNnKh1w.js.map → analysis-Bxub9LMT.js.map} +1 -1
- package/dist/{assemble-BbFVjHeS.js → assemble-B9Alds-z.js} +290 -30
- package/dist/assemble-B9Alds-z.js.map +1 -0
- package/dist/assemble-J5MukZFY.js +1 -0
- package/dist/{client-CwzU9CiW.js → assert-EUIoRdIt.js} +38 -112
- package/dist/assert-EUIoRdIt.js.map +1 -0
- package/dist/bridge/index.mjs +248 -55
- package/dist/{capture-BXhBfmsM.js → capture-CNb9SuU5.js} +204 -39
- package/dist/capture-CNb9SuU5.js.map +1 -0
- package/dist/capture-jquXZBKK.js +1 -0
- package/dist/{cli-BMjTKY-D.js → cli-D303Vj5N.js} +257 -146
- package/dist/cli-D303Vj5N.js.map +1 -0
- package/dist/{cli-spec-DSvKsOK4.js → cli-spec-BPZbQG2p.js} +38 -19
- package/dist/cli-spec-BPZbQG2p.js.map +1 -0
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/client-fcwgwOAD.js +106 -0
- package/dist/client-fcwgwOAD.js.map +1 -0
- package/dist/{command-JPGNzFsA.js → command-BLfT7vnQ.js} +19 -18
- package/dist/command-BLfT7vnQ.js.map +1 -0
- package/dist/{command-BK4kOgkH.js → command-BT9a37ZR.js} +381 -78
- package/dist/command-BT9a37ZR.js.map +1 -0
- package/dist/{command-BqJtFiPy.js → command-Bge8F7Ko.js} +384 -101
- package/dist/command-Bge8F7Ko.js.map +1 -0
- package/dist/command-BkFjijN2.js +1 -0
- package/dist/{command-BdstSEHu.js → command-CMJtHKRa.js} +14 -14
- package/dist/{command-BdstSEHu.js.map → command-CMJtHKRa.js.map} +1 -1
- package/dist/commands-1p-bIWhN.js +1 -0
- package/dist/{commands-B618jg3C.js → commands-BFx16WB8.js} +8 -8
- package/dist/commands-BFx16WB8.js.map +1 -0
- package/dist/config-DEgnUiU-.js +756 -0
- package/dist/config-DEgnUiU-.js.map +1 -0
- package/dist/{context-CvUv7DUb.js → context-C1mxXh80.js} +11 -7
- package/dist/context-C1mxXh80.js.map +1 -0
- package/dist/{db-DFbtGIYy.js → db-CdHizc4_.js} +582 -53
- package/dist/db-CdHizc4_.js.map +1 -0
- package/dist/db-Dm1cRJJP.js +2 -0
- package/dist/debug-D7bEv_UV.js +1 -0
- package/dist/{dist-CTzThfu_.js → dist-B8hJImYt.js} +17 -4
- package/dist/dist-B8hJImYt.js.map +1 -0
- package/dist/{docker-2qns7hJ2.js → docker-7b_2SaH7.js} +35 -22
- package/dist/docker-7b_2SaH7.js.map +1 -0
- package/dist/{docker-IFRW8K5f.js → docker-sZrNrr82.js} +3 -3
- package/dist/docker-sZrNrr82.js.map +1 -0
- package/dist/docker-yauK-9X8.js +1 -0
- package/dist/{doctor-B6oYTPoR.js → doctor-BYNok4UO.js} +263 -84
- package/dist/doctor-BYNok4UO.js.map +1 -0
- package/dist/{duration-JsJrIWXq.js → duration-CEOQww97.js} +2 -2
- package/dist/{duration-JsJrIWXq.js.map → duration-CEOQww97.js.map} +1 -1
- package/dist/{egress-IUKdeayc.js → egress-C4PZTSSe.js} +147 -14
- package/dist/egress-C4PZTSSe.js.map +1 -0
- package/dist/environment-DNjRk0nU.js +1133 -0
- package/dist/environment-DNjRk0nU.js.map +1 -0
- package/dist/{errors-yDAEwmZo.js → errors-B6BSMs03.js} +2 -2
- package/dist/errors-B6BSMs03.js.map +1 -0
- package/dist/{errors-C9w_ud7g.js → errors-r025B0Zb.js} +4 -4
- package/dist/errors-r025B0Zb.js.map +1 -0
- package/dist/evaluate-C1UVL21l.d.ts +92 -0
- package/dist/evaluate-D4zeRGBF.js +2351 -0
- package/dist/evaluate-D4zeRGBF.js.map +1 -0
- package/dist/family-D2b7WD10.js +67 -0
- package/dist/family-D2b7WD10.js.map +1 -0
- package/dist/files-BAt0i00X.js +1 -0
- package/dist/{files-CMSUXAEg.js → files-BXUdY8tr.js} +10 -9
- package/dist/{files-CMSUXAEg.js.map → files-BXUdY8tr.js.map} +1 -1
- package/dist/files-BhyltlDB.js +1 -0
- package/dist/files-Bk1mC3AN.js +43 -0
- package/dist/files-Bk1mC3AN.js.map +1 -0
- package/dist/{files-B6aVVGrk.js → files-DQmHE7pb.js} +5 -5
- package/dist/{files-B6aVVGrk.js.map → files-DQmHE7pb.js.map} +1 -1
- package/dist/files-ZZPqfAo6.js +1 -0
- package/dist/{git-EmdFJ4DY.js → git-DfG-YJ1u.js} +2 -2
- package/dist/{git-EmdFJ4DY.js.map → git-DfG-YJ1u.js.map} +1 -1
- package/dist/harness-B8QC9u0O.js +323 -0
- package/dist/harness-B8QC9u0O.js.map +1 -0
- package/dist/harness.d.ts +19 -31
- package/dist/harness.js +1 -2
- package/dist/{header-_F0EWob3.js → header-hK-Z_Po9.js} +10 -3
- package/dist/{header-_F0EWob3.js.map → header-hK-Z_Po9.js.map} +1 -1
- package/dist/{images-CscddrJU.js → images-0On0cztu.js} +114 -45
- package/dist/images-0On0cztu.js.map +1 -0
- package/dist/index.d.ts +10 -26
- package/dist/index.js +6 -2108
- package/dist/{init-NQfIvi-0.js → init-B77Rpcqc.js} +26 -8
- package/dist/init-B77Rpcqc.js.map +1 -0
- package/dist/init-BrOWin3W.js +1 -0
- package/dist/{invocations-nPvrlZPj.js → invocations-DbGfBAA_.js} +4 -4
- package/dist/{invocations-nPvrlZPj.js.map → invocations-DbGfBAA_.js.map} +1 -1
- package/dist/{judge-CeYPN8P_.js → judge-DW_GDOmB.js} +11 -19
- package/dist/{judge-CeYPN8P_.js.map → judge-DW_GDOmB.js.map} +1 -1
- package/dist/judge.d.ts +2 -2
- package/dist/judge.js +1 -1
- package/dist/{live-S0qODb6o.js → live-jlfszAbb.js} +9 -20
- package/dist/live-jlfszAbb.js.map +1 -0
- package/dist/matchers-Ddmc2z7H.js +118 -0
- package/dist/matchers-Ddmc2z7H.js.map +1 -0
- package/dist/{model-DEQo3FkZ.js → model-DaVCY3rb.js} +2 -2
- package/dist/{model-DEQo3FkZ.js.map → model-DaVCY3rb.js.map} +1 -1
- package/dist/model-NM3ID0uR.js +1 -0
- package/dist/{model-Cl507trk.js → model-h_cDtcRr.js} +19 -18
- package/dist/model-h_cDtcRr.js.map +1 -0
- package/dist/model-nwWJvaUR.js +1 -0
- package/dist/{model-BndnmcLm.js → model-oqcDplJG.js} +271 -34
- package/dist/model-oqcDplJG.js.map +1 -0
- package/dist/{node-Co7EXge0.js → node-B3ydHo6t.js} +10 -47
- package/dist/node-B3ydHo6t.js.map +1 -0
- package/dist/object-CLf2-tNq.js +9 -0
- package/dist/object-CLf2-tNq.js.map +1 -0
- package/dist/{opencode-providers-ByD85Q0l.js → opencode-providers-J9colP0-.js} +96 -21
- package/dist/opencode-providers-J9colP0-.js.map +1 -0
- package/dist/options-Bh2W63dK.js +1119 -0
- package/dist/options-Bh2W63dK.js.map +1 -0
- package/dist/{pairs-DDsjgm5F.js → pairs-CnInRu-G.js} +76 -2
- package/dist/{pairs-DDsjgm5F.js.map → pairs-CnInRu-G.js.map} +1 -1
- package/dist/{patch-CGCVipPu.js → patch-Zac5aIRM.js} +6 -6
- package/dist/{patch-CGCVipPu.js.map → patch-Zac5aIRM.js.map} +1 -1
- package/dist/{plan-PPc4-6xd.js → plan-C9Cy27Ay.js} +75 -32
- package/dist/plan-C9Cy27Ay.js.map +1 -0
- package/dist/preflight-CPWpQeBI.js +1 -0
- package/dist/{preflight-CddycK92.js → preflight-D7iFPKeK.js} +8 -7
- package/dist/preflight-D7iFPKeK.js.map +1 -0
- package/dist/prepare-BGjePFQl.js +2 -0
- package/dist/{prepare-CsP-057p.js → prepare-doGxaAGR.js} +38 -30
- package/dist/prepare-doGxaAGR.js.map +1 -0
- package/dist/process-CSVO_jsc.js +119 -0
- package/dist/process-CSVO_jsc.js.map +1 -0
- package/dist/{provenance-CsX6PHDR.js → provenance-DmE9uPVt.js} +4 -4
- package/dist/{provenance-CsX6PHDR.js.map → provenance-DmE9uPVt.js.map} +1 -1
- package/dist/provider-DehR4CMN.js +1 -0
- package/dist/providers-gDMko8fl.js +1 -0
- package/dist/providers-tAOD1NQN.js +165 -0
- package/dist/providers-tAOD1NQN.js.map +1 -0
- package/dist/{query-BUcwCYsI.js → query-Bes9Kh6Y.js} +3 -3
- package/dist/{query-BUcwCYsI.js.map → query-Bes9Kh6Y.js.map} +1 -1
- package/dist/query-C_G_svLU.js +1 -0
- package/dist/questions-DjAwMxZ3.js +524 -0
- package/dist/questions-DjAwMxZ3.js.map +1 -0
- package/dist/{record-BRP9vZrj.js → record-BKmMvZ6O.js} +9 -1
- package/dist/{record-BRP9vZrj.js.map → record-BKmMvZ6O.js.map} +1 -1
- package/dist/remote-HDRt16ew.js +378 -0
- package/dist/remote-HDRt16ew.js.map +1 -0
- package/dist/{results-BcSHWbgB.js → results-DuauQI3Z.js} +4 -4
- package/dist/{results-BcSHWbgB.js.map → results-DuauQI3Z.js.map} +1 -1
- package/dist/{resume-DZ9AmfPv.js → resume-BRfa8E_s.js} +10 -10
- package/dist/{resume-DZ9AmfPv.js.map → resume-BRfa8E_s.js.map} +1 -1
- package/dist/{root-CvdRlRZX.js → root-DICDHCtp.js} +4 -4
- package/dist/{root-CvdRlRZX.js.map → root-DICDHCtp.js.map} +1 -1
- package/dist/{runtime-Dfb2r-cS.js → runtime-PX_oXiCS.js} +105 -11
- package/dist/runtime-PX_oXiCS.js.map +1 -0
- package/dist/sandbox-D3A8oUb7.js +70 -0
- package/dist/sandbox-D3A8oUb7.js.map +1 -0
- package/dist/sandbox.d.ts +22 -8
- package/dist/sandbox.js +1 -2
- package/dist/server-C7sg1ndo.js +1 -0
- package/dist/{server-Da60oe4b.js → server-XDleKaF_.js} +11 -11
- package/dist/server-XDleKaF_.js.map +1 -0
- package/dist/shared-DYpIb1BI.js +166 -0
- package/dist/shared-DYpIb1BI.js.map +1 -0
- package/dist/{source-BVOnL3sn.js → source-C8xumIWj.js} +2 -2
- package/dist/{source-BVOnL3sn.js.map → source-C8xumIWj.js.map} +1 -1
- package/dist/source-fGd0SaKP.js +1 -0
- package/dist/{src-TdJuDYqB.js → src-B7treWa8.js} +1597 -292
- package/dist/src-B7treWa8.js.map +1 -0
- package/dist/{src-C1E9HDWO.js → src-C7_1SqDP.js} +3 -3
- package/dist/{src-C1E9HDWO.js.map → src-C7_1SqDP.js.map} +1 -1
- package/dist/{src-DDNXsD9H.js → src-CF17Ug08.js} +5 -4
- package/dist/src-CF17Ug08.js.map +1 -0
- package/dist/{src-D_cXqmnI.js → src-CFp86GtV.js} +60 -60
- package/dist/src-CFp86GtV.js.map +1 -0
- package/dist/src-C_lPtowT.js +2 -0
- package/dist/src-DIL0jST0.js +368 -0
- package/dist/src-DIL0jST0.js.map +1 -0
- package/dist/src-DNnG4e4R.js +2 -0
- package/dist/src-DTbrY1hi.js +2 -0
- package/dist/src-DdyJEh2v.js +2 -0
- package/dist/src-Dj9PAroc.js +2 -0
- package/dist/src-Du8H85Qq.js +2 -0
- package/dist/src-DvCg0NBs.js +324 -0
- package/dist/src-DvCg0NBs.js.map +1 -0
- package/dist/{src-CxTC5kNI.js → src-DvK0EIZx.js} +8 -10
- package/dist/{src-CxTC5kNI.js.map → src-DvK0EIZx.js.map} +1 -1
- package/dist/{src-DVy58-zZ.js → src-FGXhkEkH.js} +5 -5
- package/dist/{src-DVy58-zZ.js.map → src-FGXhkEkH.js.map} +1 -1
- package/dist/src-jzagbuqH.js +2 -0
- package/dist/src-ofUaYbuY.js +3 -0
- package/dist/src-pJZOrYR9.js +1 -0
- package/dist/{src-D95O-Smv.js → src-u8_ixn_F.js} +15 -11
- package/dist/src-u8_ixn_F.js.map +1 -0
- package/dist/{state-B72h_jEw.js → state-C__9swoG.js} +36 -24
- package/dist/state-C__9swoG.js.map +1 -0
- package/dist/state-CeR6oz0k.js +66 -0
- package/dist/state-CeR6oz0k.js.map +1 -0
- package/dist/state-CgjQo29K.js +1 -0
- package/dist/studio-app/assets/index-CwQN3f_h.css +2 -0
- package/dist/studio-app/assets/{index-Bgr-efZm.js → index-DrQc2Yxd.js} +12 -12
- package/dist/studio-app/index.html +2 -2
- package/dist/{summary-k3mhWWXv.js → summary-BLAVLySU.js} +202 -17
- package/dist/summary-BLAVLySU.js.map +1 -0
- package/dist/{summary-CJdxaRdM.js → summary-DgyjUh_l.js} +7 -7
- package/dist/{summary-CJdxaRdM.js.map → summary-DgyjUh_l.js.map} +1 -1
- package/dist/testing.d.ts +3 -2
- package/dist/testing.js +3 -2
- package/dist/{tool-target-BU1JnSE9.js → tool-target-D2mcYlSQ.js} +14 -7
- package/dist/tool-target-D2mcYlSQ.js.map +1 -0
- package/dist/{tools-D0gF2QoV.js → tools-GCyNYSc1.js} +7 -7
- package/dist/tools-GCyNYSc1.js.map +1 -0
- package/dist/transcript-BNNANU8A.js +64 -0
- package/dist/transcript-BNNANU8A.js.map +1 -0
- package/dist/types-C5vI3g1C.js.map +1 -1
- package/dist/{types-_LOFdPUf.d.ts → types-g17bRAzt.d.ts} +578 -49
- package/dist/{usage-DDF_6tkV.js → usage-CleNKkly.js} +4 -2
- package/dist/{usage-DDF_6tkV.js.map → usage-CleNKkly.js.map} +1 -1
- package/dist/view/index.d.ts +83 -17
- package/dist/view/index.js +7 -6
- package/dist/views-BW6oCDUQ.js +2 -0
- package/dist/{views-DZ1YDqey.js → views-BmQF4UCI.js} +13 -8
- package/dist/views-BmQF4UCI.js.map +1 -0
- package/dist/{worker-entry-DXeyWY-m.js → worker-entry-yOchGYYv.js} +16 -225
- package/dist/worker-entry-yOchGYYv.js.map +1 -0
- package/dist/{workspace-DpXdrslo.js → workspace-CgyHEM0l.js} +7 -7
- package/dist/{workspace-DpXdrslo.js.map → workspace-CgyHEM0l.js.map} +1 -1
- package/dist/workspace-D8sSgpiy.js +1 -0
- package/docker/Dockerfile +7 -5
- package/package.json +12 -12
- package/dist/agent-Cfj1wD4D.js.map +0 -1
- package/dist/assemble-BbFVjHeS.js.map +0 -1
- package/dist/assemble-CXiTVyHD.js +0 -2
- package/dist/capture-BXhBfmsM.js.map +0 -1
- package/dist/capture-N7r3yeak.js +0 -2
- package/dist/cli-BMjTKY-D.js.map +0 -1
- package/dist/cli-spec-DSvKsOK4.js.map +0 -1
- package/dist/client-CwzU9CiW.js.map +0 -1
- package/dist/command-BK4kOgkH.js.map +0 -1
- package/dist/command-BqJtFiPy.js.map +0 -1
- package/dist/command-CTVGuH8y.js +0 -2
- package/dist/command-JPGNzFsA.js.map +0 -1
- package/dist/commands-B618jg3C.js.map +0 -1
- package/dist/commands-Duo2ur3r.js +0 -2
- package/dist/config-B-E0xRkf.js +0 -447
- package/dist/config-B-E0xRkf.js.map +0 -1
- package/dist/context-CvUv7DUb.js.map +0 -1
- package/dist/db-CnoUy-FZ.js +0 -3
- package/dist/db-DFbtGIYy.js.map +0 -1
- package/dist/debug-SEmW4w8f.js +0 -2
- package/dist/dist-CTzThfu_.js.map +0 -1
- package/dist/docker-2qns7hJ2.js.map +0 -1
- package/dist/docker-D6t23fZl.js +0 -2
- package/dist/docker-IFRW8K5f.js.map +0 -1
- package/dist/doctor-B6oYTPoR.js.map +0 -1
- package/dist/egress-IUKdeayc.js.map +0 -1
- package/dist/environment-DiCljXMD.js +0 -657
- package/dist/environment-DiCljXMD.js.map +0 -1
- package/dist/errors-C9w_ud7g.js.map +0 -1
- package/dist/errors-yDAEwmZo.js.map +0 -1
- package/dist/fake-instructions-CUI33I_F.js +0 -32
- package/dist/fake-instructions-CUI33I_F.js.map +0 -1
- package/dist/files-BM78_nnF.js +0 -2
- package/dist/files-BpYgF2z0.js +0 -2
- package/dist/files-YCCVaTQC.js +0 -2
- package/dist/harness-iqWeJQMM.js +0 -154
- package/dist/harness-iqWeJQMM.js.map +0 -1
- package/dist/images-CscddrJU.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init-DBHyi92L.js +0 -2
- package/dist/init-NQfIvi-0.js.map +0 -1
- package/dist/jiti-BcJHCtrb.js +0 -46
- package/dist/jiti-BcJHCtrb.js.map +0 -1
- package/dist/live-S0qODb6o.js.map +0 -1
- package/dist/model-BbLGRtOs.js +0 -2
- package/dist/model-BndnmcLm.js.map +0 -1
- package/dist/model-Cl507trk.js.map +0 -1
- package/dist/model-DMOraCcm.js +0 -2
- package/dist/node-Co7EXge0.js.map +0 -1
- package/dist/opencode-providers-ByD85Q0l.js.map +0 -1
- package/dist/options-DPUlm4FI.js +0 -735
- package/dist/options-DPUlm4FI.js.map +0 -1
- package/dist/plan-PPc4-6xd.js.map +0 -1
- package/dist/preflight-CddycK92.js.map +0 -1
- package/dist/preflight-Zumy0adT.js +0 -2
- package/dist/prepare-CKdMoC7e.js +0 -3
- package/dist/prepare-CsP-057p.js.map +0 -1
- package/dist/provider-BDbNOQhQ.js +0 -2
- package/dist/providers-DkwiLKDS.js +0 -107
- package/dist/providers-DkwiLKDS.js.map +0 -1
- package/dist/providers-yXZZcPfx.js +0 -2
- package/dist/query-noGbekGF.js +0 -2
- package/dist/questions-BEPj98fZ.js +0 -234
- package/dist/questions-BEPj98fZ.js.map +0 -1
- package/dist/runtime-Dfb2r-cS.js.map +0 -1
- package/dist/sandbox--ZXuscAZ.js +0 -134
- package/dist/sandbox--ZXuscAZ.js.map +0 -1
- package/dist/server-Da60oe4b.js.map +0 -1
- package/dist/server-DiGR4JxK.js +0 -2
- package/dist/source-Dqu0jKwx.js +0 -2
- package/dist/src-BHNiP-5A.js +0 -4
- package/dist/src-BT4dB5CO.js +0 -2
- package/dist/src-BT5pwco0.js +0 -3
- package/dist/src-BrMbt1B2.js +0 -3
- package/dist/src-D13vpMh0.js +0 -3
- package/dist/src-D95O-Smv.js.map +0 -1
- package/dist/src-DDNXsD9H.js.map +0 -1
- package/dist/src-D_cXqmnI.js.map +0 -1
- package/dist/src-DdRlaiRc.js +0 -3
- package/dist/src-TdJuDYqB.js.map +0 -1
- package/dist/src-xczuQbE6.js +0 -3
- package/dist/state-B72h_jEw.js.map +0 -1
- package/dist/state-Bf_Vq_pV.js +0 -2
- package/dist/studio-app/assets/index-CUx6GoL5.css +0 -2
- package/dist/summary-k3mhWWXv.js.map +0 -1
- package/dist/tool-target-BU1JnSE9.js.map +0 -1
- package/dist/tools-D0gF2QoV.js.map +0 -1
- package/dist/views-DZ1YDqey.js.map +0 -1
- package/dist/views-Ds0GXWtX.js +0 -3
- package/dist/worker-entry-DXeyWY-m.js.map +0 -1
- package/dist/workspace-DzNL-3iO.js +0 -2
|
@@ -1,13 +1,224 @@
|
|
|
1
|
-
import { n as toolTarget } from "./tool-target-
|
|
2
|
-
import { n as UsageError } from "./errors-
|
|
3
|
-
import { d as ownRequire, t as BUILD_ID } from "./root-CvdRlRZX.js";
|
|
1
|
+
import { n as toolTarget, t as SKILL_LOAD_TOOLS } from "./tool-target-D2mcYlSQ.js";
|
|
2
|
+
import { n as UsageError } from "./errors-B6BSMs03.js";
|
|
4
3
|
import { t as RUN_ID } from "./paths-BmR-7tx3.js";
|
|
5
4
|
import { c as relativeFile, l as sha256 } from "./ids-Bp6ut7ZD.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { d as ownRequire, t as BUILD_ID } from "./root-DICDHCtp.js";
|
|
6
|
+
import { n as isRuntimeState } from "./context-C1mxXh80.js";
|
|
7
|
+
import { Q as contrastEffort, _t as wilson, ht as round3, nt as effortOf, pt as median, ut as liftInterval } from "./model-oqcDplJG.js";
|
|
8
|
+
import { r as pairTallies } from "./pairs-CnInRu-G.js";
|
|
9
|
+
import { m as warnUnreadable, p as scratchDir, s as readRecord, u as recordNames } from "./files-BXUdY8tr.js";
|
|
10
|
+
import { h as contrastPairs, m as checkVerdict } from "./summary-BLAVLySU.js";
|
|
9
11
|
import { dirname, join } from "node:path";
|
|
10
12
|
import { mkdir, readFile, stat } from "node:fs/promises";
|
|
13
|
+
//#region src/history/rows.ts
|
|
14
|
+
/** A statement's rows as `Row`, the columns its SQL selects: SQLite checks none of them. */
|
|
15
|
+
const rowsOf = (statement, ...params) => statement.all(...params);
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/history/tool-class.ts
|
|
18
|
+
const TOOL_CLASSES = [
|
|
19
|
+
"context",
|
|
20
|
+
"dependency",
|
|
21
|
+
"web",
|
|
22
|
+
"verify",
|
|
23
|
+
"workspace"
|
|
24
|
+
];
|
|
25
|
+
const SHELL_TOOL = /shell|bash|terminal|command|exec/i;
|
|
26
|
+
const WEB_TOOL = /web|fetch|browse|url/i;
|
|
27
|
+
const DEPENDENCY = /(^|\/)(node_modules|site-packages|dist-packages|vendor|\.venv|\.cargo\/registry|go\/pkg\/mod)(\/|$)/;
|
|
28
|
+
const VERIFY = /\b(?:(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|build|lint|typecheck|check)|npx\s+(?:tsc|vitest|jest|eslint|biome)|tsc|vitest|jest|pytest|eslint|cargo\s+(?:test|build|check)|go\s+(?:test|build|vet))\b/;
|
|
29
|
+
/** Words of a shell command, quotes removed; `;`, `|` and `&&` split words. */
|
|
30
|
+
function shellWords(command) {
|
|
31
|
+
const words = [];
|
|
32
|
+
let word = "";
|
|
33
|
+
let quote = null;
|
|
34
|
+
let started = false;
|
|
35
|
+
const flush = () => {
|
|
36
|
+
if (started) words.push(word);
|
|
37
|
+
word = "";
|
|
38
|
+
started = false;
|
|
39
|
+
};
|
|
40
|
+
for (const ch of command) {
|
|
41
|
+
if (quote) {
|
|
42
|
+
if (ch === quote) quote = null;
|
|
43
|
+
else word += ch;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (ch === "\"" || ch === "'") {
|
|
47
|
+
quote = ch;
|
|
48
|
+
started = true;
|
|
49
|
+
} else if (/\s/.test(ch)) flush();
|
|
50
|
+
else if (ch === ";" || ch === "|" || ch === "&") {
|
|
51
|
+
flush();
|
|
52
|
+
words.push(ch);
|
|
53
|
+
} else {
|
|
54
|
+
word += ch;
|
|
55
|
+
started = true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
flush();
|
|
59
|
+
return words;
|
|
60
|
+
}
|
|
61
|
+
/** A command's words, with a `bash -c '…'` (or `-lc`) script split into its own words. */
|
|
62
|
+
function commandWords(command) {
|
|
63
|
+
const words = shellWords(command);
|
|
64
|
+
return words.flatMap((w, i) => i > 0 && /^-[a-z]*c$/.test(words[i - 1]) && /\s/.test(w) ? commandWords(w) : [w]);
|
|
65
|
+
}
|
|
66
|
+
const EXCLUDING_FLAG = /^--(?:exclude|exclude-dir|ignore|ignore-dir)(?:=|$)/;
|
|
67
|
+
/** The words of a command that name something it reads, without the ones it excludes. */
|
|
68
|
+
function readWords(words) {
|
|
69
|
+
const out = [];
|
|
70
|
+
let test = false;
|
|
71
|
+
for (let i = 0; i < words.length; i++) {
|
|
72
|
+
const w = words[i];
|
|
73
|
+
const prev = words[i - 1];
|
|
74
|
+
if (w === "[" || w === "[[" || w === "test") test = true;
|
|
75
|
+
else if (w === "]" || w === "]]" || w === ";" || w === "|" || w === "&") test = false;
|
|
76
|
+
if (test && /^-[defsrwx]$/.test(w)) {
|
|
77
|
+
i++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (EXCLUDING_FLAG.test(w)) {
|
|
81
|
+
if (!w.includes("=")) i++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if ((w === "-path" || w === "-name" || w === "-ipath" || w === "-wholename") && i + 1 < words.length) {
|
|
85
|
+
const pruned = words[i + 2] === "-prune";
|
|
86
|
+
if (prev === "-not" || prev === "!" || pruned) {
|
|
87
|
+
i++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if ((w === "-g" || w === "--glob" || w === "--iglob") && words[i + 1]?.startsWith("!")) {
|
|
92
|
+
i++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (/^--i?glob=!/.test(w)) continue;
|
|
96
|
+
if (w === "-v" && i > 0) {
|
|
97
|
+
i++;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
out.push(w);
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** `/home/<user>/x` and `/root/x` as `~/x`; `./x` as `x`. */
|
|
105
|
+
const normalise = (p) => p.replace(/^\/home\/[^/]+\//, "~/").replace(/^\/root\//, "~/").replace(/^\$HOME\//, "~/").replace(/^\.\//, "");
|
|
106
|
+
const GLOB = /[*?[{]/;
|
|
107
|
+
/** `*`, `**` and `?` as wildcards; every other character, `[` included, literally. */
|
|
108
|
+
function wildcards(glob) {
|
|
109
|
+
let re = "";
|
|
110
|
+
for (let i = 0; i < glob.length; i++) {
|
|
111
|
+
const ch = glob[i];
|
|
112
|
+
if (ch === "*") {
|
|
113
|
+
if (glob[i + 1] === "*") {
|
|
114
|
+
re += ".*";
|
|
115
|
+
i++;
|
|
116
|
+
} else re += "[^/]*";
|
|
117
|
+
} else if (ch === "?") re += "[^/]";
|
|
118
|
+
else re += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
119
|
+
}
|
|
120
|
+
return re;
|
|
121
|
+
}
|
|
122
|
+
/** A glob as a regex, with `{a,b}` alternatives. Words come from transcripts, so it never throws. */
|
|
123
|
+
function globRegex(glob) {
|
|
124
|
+
let re = "";
|
|
125
|
+
let from = 0;
|
|
126
|
+
for (let i = 0; i < glob.length; i++) {
|
|
127
|
+
if (glob[i] !== "{") continue;
|
|
128
|
+
const end = glob.indexOf("}", i);
|
|
129
|
+
if (end < 0) break;
|
|
130
|
+
re += wildcards(glob.slice(from, i));
|
|
131
|
+
re += `(?:${glob.slice(i + 1, end).split(",").map(wildcards).join("|")})`;
|
|
132
|
+
from = end + 1;
|
|
133
|
+
i = end;
|
|
134
|
+
}
|
|
135
|
+
return new RegExp(`^${re}${wildcards(glob.slice(from))}$`);
|
|
136
|
+
}
|
|
137
|
+
/** The declared files one word names: the file itself, one of a glob's matches, or a directory's. */
|
|
138
|
+
function filesOf(word, files) {
|
|
139
|
+
const w = normalise(word).replace(/\/+$/, "");
|
|
140
|
+
if (!w) return {
|
|
141
|
+
files: [],
|
|
142
|
+
dir: false
|
|
143
|
+
};
|
|
144
|
+
const forms = (f) => f.startsWith("~/") ? [f, f.slice(2)] : [f];
|
|
145
|
+
const matches = (f, test) => forms(f).some((form) => test(form) || !w.startsWith("~/") && test(`~/${form}`));
|
|
146
|
+
if (GLOB.test(w)) {
|
|
147
|
+
const re = globRegex(w);
|
|
148
|
+
const fromWorkspace = /^[*?[{]/.test(w);
|
|
149
|
+
return {
|
|
150
|
+
files: files.filter((f) => fromWorkspace ? !f.startsWith("~/") && re.test(f) : matches(f, (form) => re.test(form))),
|
|
151
|
+
dir: false
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const exact = files.filter((f) => matches(f, (form) => form === w || form.endsWith(`/${w}`)));
|
|
155
|
+
if (exact.length) return {
|
|
156
|
+
files: exact,
|
|
157
|
+
dir: false
|
|
158
|
+
};
|
|
159
|
+
return {
|
|
160
|
+
files: [],
|
|
161
|
+
dir: files.filter((f) => matches(f, (form) => form.startsWith(`${w}/`))).length > 0
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/** A tool call's class, and the declared files it read (for `skill_files`). */
|
|
165
|
+
function classifyCall(tool, target, ctx) {
|
|
166
|
+
if (SKILL_LOAD_TOOLS.has(tool)) {
|
|
167
|
+
if (!ctx.skills.includes(target)) return {
|
|
168
|
+
class: "workspace",
|
|
169
|
+
files: []
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
class: "context",
|
|
173
|
+
files: ctx.files.filter((f) => f.endsWith(`skills/${target}/SKILL.md`))
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (ctx.mcp.some((s) => tool.startsWith(`mcp__${s}__`) || tool.startsWith(`${s}__`))) return {
|
|
177
|
+
class: "context",
|
|
178
|
+
files: []
|
|
179
|
+
};
|
|
180
|
+
const shell = SHELL_TOOL.test(tool);
|
|
181
|
+
const words = shell ? readWords(commandWords(target)) : [target];
|
|
182
|
+
const files = /* @__PURE__ */ new Set();
|
|
183
|
+
let context = false;
|
|
184
|
+
for (const w of words) {
|
|
185
|
+
const hit = filesOf(w, ctx.files);
|
|
186
|
+
for (const f of hit.files) files.add(f);
|
|
187
|
+
if (hit.files.length || hit.dir) context = true;
|
|
188
|
+
if (ctx.skills.some((s) => normalise(w).includes(`skills/${s}/`) || normalise(w).endsWith(`skills/${s}`))) context = true;
|
|
189
|
+
}
|
|
190
|
+
if (context) return {
|
|
191
|
+
class: "context",
|
|
192
|
+
files: [...files]
|
|
193
|
+
};
|
|
194
|
+
if (words.some((w) => DEPENDENCY.test(normalise(w))) || shell && words.includes("--help")) return {
|
|
195
|
+
class: "dependency",
|
|
196
|
+
files: []
|
|
197
|
+
};
|
|
198
|
+
if (!shell && WEB_TOOL.test(tool)) return {
|
|
199
|
+
class: "web",
|
|
200
|
+
files: []
|
|
201
|
+
};
|
|
202
|
+
if (shell && words.some((w) => w === "curl" || w === "wget") && /https?:\/\//.test(target)) return {
|
|
203
|
+
class: "web",
|
|
204
|
+
files: []
|
|
205
|
+
};
|
|
206
|
+
if (shell) {
|
|
207
|
+
const command = target.trim();
|
|
208
|
+
if (ctx.verify.some((v) => v.trim().length >= 4 && command.includes(v.trim()))) return {
|
|
209
|
+
class: "verify",
|
|
210
|
+
files: []
|
|
211
|
+
};
|
|
212
|
+
if (VERIFY.test(command)) return {
|
|
213
|
+
class: "verify",
|
|
214
|
+
files: []
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
class: "workspace",
|
|
219
|
+
files: []
|
|
220
|
+
};
|
|
221
|
+
}
|
|
11
222
|
/** A failing verdict this close to its threshold points at the judge, not the agent. */
|
|
12
223
|
const JUDGE_MARGIN = .1;
|
|
13
224
|
const DERIVED_TABLES = `
|
|
@@ -20,7 +231,19 @@ CREATE TABLE effort_m (
|
|
|
20
231
|
control_tokens_median REAL,
|
|
21
232
|
tools_ratio REAL, agent_s_ratio REAL, agent_s_delta REAL, tokens_ratio REAL,
|
|
22
233
|
tools_p REAL, agent_s_p REAL, tokens_p REAL,
|
|
23
|
-
separated INTEGER,
|
|
234
|
+
separated INTEGER, time_separated INTEGER, tokens_separated INTEGER,
|
|
235
|
+
verdict TEXT, time_verdict TEXT, tokens_verdict TEXT, tokens_note TEXT,
|
|
236
|
+
context_calls_median REAL, dependency_calls_median REAL, web_calls_median REAL,
|
|
237
|
+
verify_calls_median REAL, workspace_calls_median REAL
|
|
238
|
+
);
|
|
239
|
+
CREATE TABLE contrasts_m (
|
|
240
|
+
run_id TEXT, eval_key TEXT, harness TEXT, sandbox TEXT, a_key TEXT, b_key TEXT,
|
|
241
|
+
a_environment TEXT, b_environment TEXT, a_pass INTEGER, a_counted INTEGER, b_pass INTEGER,
|
|
242
|
+
b_counted INTEGER, points REAL, lo REAL, hi REAL, pass_verdict TEXT,
|
|
243
|
+
a_tools_median REAL, b_tools_median REAL, tools_ratio REAL, tools_p REAL, separated INTEGER,
|
|
244
|
+
verdict TEXT, agent_s_ratio REAL, time_separated INTEGER, time_verdict TEXT,
|
|
245
|
+
tokens_ratio REAL, tokens_separated INTEGER, tokens_verdict TEXT,
|
|
246
|
+
checks INTEGER, discriminating TEXT
|
|
24
247
|
);
|
|
25
248
|
CREATE TABLE factor_effects_m (
|
|
26
249
|
factor TEXT, level TEXT, baseline TEXT, context TEXT, tier TEXT, run_id TEXT, eval_key TEXT,
|
|
@@ -34,15 +257,35 @@ CREATE TABLE factor_effects_m (
|
|
|
34
257
|
CREATE TABLE flaky_m (
|
|
35
258
|
eval_key TEXT, cell_key TEXT, fingerprint TEXT, runs INTEGER, flaky_runs INTEGER,
|
|
36
259
|
first_seen TEXT, last_seen TEXT, pass INTEGER, counted INTEGER, infra_error INTEGER,
|
|
37
|
-
|
|
260
|
+
pass_at_1 REAL, lo REAL, hi REAL, verdict TEXT, cause TEXT, min_attempts INTEGER
|
|
38
261
|
);
|
|
39
262
|
CREATE TABLE drift_m (
|
|
40
263
|
run_id TEXT, prev_run_id TEXT, eval_key TEXT, cell_key TEXT, changed TEXT,
|
|
41
264
|
changed_paths TEXT, noise INTEGER, real_changed TEXT
|
|
42
265
|
);
|
|
43
266
|
`;
|
|
267
|
+
const FAMILY_COLUMNS = [
|
|
268
|
+
"run_id",
|
|
269
|
+
"family_id",
|
|
270
|
+
"harness",
|
|
271
|
+
"variant",
|
|
272
|
+
"pairs",
|
|
273
|
+
"points",
|
|
274
|
+
"lo",
|
|
275
|
+
"hi",
|
|
276
|
+
"within_noise",
|
|
277
|
+
"verdict",
|
|
278
|
+
"tools_ratio",
|
|
279
|
+
"tools_p",
|
|
280
|
+
"effort_verdict",
|
|
281
|
+
"agent_s_ratio",
|
|
282
|
+
"tokens_ratio",
|
|
283
|
+
"tokens_p",
|
|
284
|
+
"tokens_verdict"
|
|
285
|
+
];
|
|
44
286
|
const DERIVED = [
|
|
45
287
|
"effort_m",
|
|
288
|
+
"contrasts_m",
|
|
46
289
|
"factor_effects_m",
|
|
47
290
|
"flaky_m",
|
|
48
291
|
"drift_m"
|
|
@@ -158,18 +401,19 @@ const merge = (sides) => ({
|
|
|
158
401
|
});
|
|
159
402
|
function insertAll(db, table, rows) {
|
|
160
403
|
if (rows.length === 0) return;
|
|
161
|
-
const cols = db.prepare(`PRAGMA table_info("${table}")`)
|
|
404
|
+
const cols = rowsOf(db.prepare(`PRAGMA table_info("${table}")`)).map((c) => c.name);
|
|
162
405
|
const statement = db.prepare(`INSERT INTO ${table} (${cols.join(", ")}) VALUES (${cols.map(() => "?").join(", ")})`);
|
|
163
406
|
for (const row of rows) statement.run(...cols.map((c) => row[c] ?? null));
|
|
164
407
|
}
|
|
165
408
|
/** Recomputes every derived table from the projected rows; run inside the sync's transaction. */
|
|
166
409
|
function deriveFacts(db) {
|
|
167
410
|
for (const table of DERIVED) db.exec(`DELETE FROM ${table}`);
|
|
168
|
-
const cells = db.prepare("SELECT c.*, r.started_at FROM cells c JOIN runs r USING (run_id) ORDER BY c.run_id, c.rowid")
|
|
169
|
-
const attempts = db.prepare(`SELECT run_id, eval_key, cell_key, key, outcome, error_kind, tools, agent_ms, file_edits,
|
|
411
|
+
const cells = rowsOf(db.prepare("SELECT c.*, r.started_at FROM cells c JOIN runs r USING (run_id) ORDER BY c.run_id, c.rowid"));
|
|
412
|
+
const attempts = rowsOf(db.prepare(`SELECT run_id, eval_key, cell_key, key, outcome, error_kind, tools, agent_ms, file_edits,
|
|
170
413
|
input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, reasoning_tokens
|
|
171
|
-
FROM attempts ORDER BY run_id, rowid`)
|
|
172
|
-
const nearThreshold = new Set(db.prepare(`SELECT DISTINCT run_id, attempt_key FROM judgements WHERE verdict = 'fail' AND ABS(score - threshold) <= ${JUDGE_MARGIN}`)
|
|
414
|
+
FROM attempts ORDER BY run_id, rowid`));
|
|
415
|
+
const nearThreshold = new Set(rowsOf(db.prepare(`SELECT DISTINCT run_id, attempt_key FROM judgements WHERE verdict = 'fail' AND ABS(score - threshold) <= ${JUDGE_MARGIN}`)).map((r) => `${r.run_id}\0${r.attempt_key}`));
|
|
416
|
+
const diffs = new Map(rowsOf(db.prepare(`SELECT run_id, attempt_key, sha256 FROM artifacts WHERE kind = 'diff' AND bytes > 0`)).flatMap((r) => r.sha256 ? [[`${r.run_id}\0${r.attempt_key}`, r.sha256]] : []));
|
|
173
417
|
const samples = /* @__PURE__ */ new Map();
|
|
174
418
|
const byCell = /* @__PURE__ */ new Map();
|
|
175
419
|
for (const a of attempts) {
|
|
@@ -190,6 +434,20 @@ function deriveFacts(db) {
|
|
|
190
434
|
samples: samples.get(cellId(c.run_id, c.eval_key, c.key)) ?? []
|
|
191
435
|
});
|
|
192
436
|
const find = (run, evalKey, key) => cells.find((c) => c.run_id === run && c.eval_key === evalKey && c.key === key);
|
|
437
|
+
const classCounts = /* @__PURE__ */ new Map();
|
|
438
|
+
for (const r of rowsOf(db.prepare("SELECT run_id, attempt_key, class, COUNT(*) AS n FROM tool_calls GROUP BY run_id, attempt_key, class"))) {
|
|
439
|
+
const id = `${r.run_id}\0${r.attempt_key}`;
|
|
440
|
+
const m = classCounts.get(id) ?? /* @__PURE__ */ new Map();
|
|
441
|
+
m.set(r.class, r.n);
|
|
442
|
+
classCounts.set(id, m);
|
|
443
|
+
}
|
|
444
|
+
const classMedians = (c) => {
|
|
445
|
+
const known = (byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []).filter((a) => a.outcome === "pass" || a.outcome === "fail").flatMap((a) => {
|
|
446
|
+
const m = classCounts.get(`${a.run_id}\0${a.key}`);
|
|
447
|
+
return m ? [m] : [];
|
|
448
|
+
});
|
|
449
|
+
return Object.fromEntries(TOOL_CLASSES.map((k) => [`${k}_calls_median`, known.length ? median(known.map((m) => m.get(k) ?? 0)) ?? null : null]));
|
|
450
|
+
};
|
|
193
451
|
insertAll(db, "effort_m", cells.map((c) => {
|
|
194
452
|
const own = effortOf(side(c).samples);
|
|
195
453
|
const control = c.lift_vs ? find(c.run_id, c.eval_key, c.lift_vs) : void 0;
|
|
@@ -226,12 +484,83 @@ function deriveFacts(db) {
|
|
|
226
484
|
agent_s_p: r4(vs?.agentMsP ?? null),
|
|
227
485
|
tokens_p: r4(vs?.tokensP ?? null),
|
|
228
486
|
separated: vs ? vs.separated ? 1 : 0 : null,
|
|
487
|
+
time_separated: vs ? vs.timeSeparated ? 1 : 0 : null,
|
|
488
|
+
tokens_separated: vs?.tokensSeparated == null ? null : vs.tokensSeparated ? 1 : 0,
|
|
229
489
|
verdict: vs?.verdict ?? null,
|
|
230
490
|
time_verdict: vs?.timeVerdict ?? null,
|
|
231
491
|
tokens_verdict: vs?.tokensVerdict ?? null,
|
|
232
|
-
tokens_note: vs?.tokensNote ?? null
|
|
492
|
+
tokens_note: vs?.tokensNote ?? null,
|
|
493
|
+
...classMedians(c)
|
|
233
494
|
};
|
|
234
495
|
}));
|
|
496
|
+
const checkRows = rowsOf(db.prepare("SELECT run_id, eval_key, cell_key, label, pass, fail, error, not_run FROM cell_checks"));
|
|
497
|
+
const checksOf = /* @__PURE__ */ new Map();
|
|
498
|
+
for (const k of checkRows) {
|
|
499
|
+
const id = cellId(k.run_id, k.eval_key, k.cell_key);
|
|
500
|
+
const m = checksOf.get(id) ?? /* @__PURE__ */ new Map();
|
|
501
|
+
m.set(k.label, {
|
|
502
|
+
pass: k.pass,
|
|
503
|
+
fail: k.fail,
|
|
504
|
+
error: k.error,
|
|
505
|
+
notRun: k.not_run
|
|
506
|
+
});
|
|
507
|
+
checksOf.set(id, m);
|
|
508
|
+
}
|
|
509
|
+
const evalCells = /* @__PURE__ */ new Map();
|
|
510
|
+
for (const c of cells) {
|
|
511
|
+
const id = `${c.run_id}\0${c.eval_key}`;
|
|
512
|
+
evalCells.set(id, [...evalCells.get(id) ?? [], c]);
|
|
513
|
+
}
|
|
514
|
+
const contrastRows = [];
|
|
515
|
+
for (const group of evalCells.values()) for (const [a, b] of contrastPairs(group)) {
|
|
516
|
+
const x = side(a);
|
|
517
|
+
const y = side(b);
|
|
518
|
+
const e = contrastEffort(x.samples, y.samples);
|
|
519
|
+
const ka = checksOf.get(cellId(a.run_id, a.eval_key, a.key)) ?? /* @__PURE__ */ new Map();
|
|
520
|
+
const kb = checksOf.get(cellId(b.run_id, b.eval_key, b.key)) ?? /* @__PURE__ */ new Map();
|
|
521
|
+
const verdicts = [...ka].flatMap(([label, t]) => {
|
|
522
|
+
const other = kb.get(label);
|
|
523
|
+
const verdict = other && checkVerdict(t, other);
|
|
524
|
+
return verdict ? [{
|
|
525
|
+
label,
|
|
526
|
+
verdict
|
|
527
|
+
}] : [];
|
|
528
|
+
});
|
|
529
|
+
const pass = passCols(x, y);
|
|
530
|
+
contrastRows.push({
|
|
531
|
+
run_id: a.run_id,
|
|
532
|
+
eval_key: a.eval_key,
|
|
533
|
+
harness: a.harness,
|
|
534
|
+
sandbox: a.sandbox,
|
|
535
|
+
a_key: a.key,
|
|
536
|
+
b_key: b.key,
|
|
537
|
+
a_environment: a.environment,
|
|
538
|
+
b_environment: b.environment,
|
|
539
|
+
a_pass: x.pass,
|
|
540
|
+
a_counted: x.counted,
|
|
541
|
+
b_pass: y.pass,
|
|
542
|
+
b_counted: y.counted,
|
|
543
|
+
points: pass.points ?? null,
|
|
544
|
+
lo: pass.lo ?? null,
|
|
545
|
+
hi: pass.hi ?? null,
|
|
546
|
+
pass_verdict: pass.pass_verdict ?? null,
|
|
547
|
+
a_tools_median: e?.variant.tools.median ?? null,
|
|
548
|
+
b_tools_median: e?.control.tools.median ?? null,
|
|
549
|
+
tools_ratio: r4(e?.toolsRatio ?? null),
|
|
550
|
+
tools_p: r4(e?.toolsP ?? null),
|
|
551
|
+
separated: e ? e.separated ? 1 : 0 : null,
|
|
552
|
+
verdict: e?.verdict ?? null,
|
|
553
|
+
agent_s_ratio: r4(e?.agentMsRatio ?? null),
|
|
554
|
+
time_separated: e ? e.timeSeparated ? 1 : 0 : null,
|
|
555
|
+
time_verdict: e?.timeVerdict ?? null,
|
|
556
|
+
tokens_ratio: r4(e?.tokensRatio ?? null),
|
|
557
|
+
tokens_separated: e?.tokensSeparated == null ? null : e.tokensSeparated ? 1 : 0,
|
|
558
|
+
tokens_verdict: e?.tokensVerdict ?? null,
|
|
559
|
+
checks: verdicts.length,
|
|
560
|
+
discriminating: verdicts.filter((v) => v.verdict === "discriminates").map((v) => v.label).join(" · ") || null
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
insertAll(db, "contrasts_m", contrastRows);
|
|
235
564
|
const pairs = [];
|
|
236
565
|
const groups = /* @__PURE__ */ new Map();
|
|
237
566
|
for (const c of cells) {
|
|
@@ -358,9 +687,34 @@ function deriveFacts(db) {
|
|
|
358
687
|
runs: null,
|
|
359
688
|
...passCols(v, c),
|
|
360
689
|
...pooledEffort(comparable.map((s) => contrastEffort(s.v.samples, s.c.samples))),
|
|
361
|
-
note: "pass
|
|
690
|
+
note: "pass@1: summed counts; effort: an effect in at least 2/3 of strata"
|
|
362
691
|
});
|
|
363
692
|
}
|
|
693
|
+
const familyLifts = rowsOf(db.prepare(`SELECT ${FAMILY_COLUMNS.join(", ")} FROM family_lift_m`));
|
|
694
|
+
for (const f of familyLifts) factorRows.push({
|
|
695
|
+
factor: "environment",
|
|
696
|
+
level: f.variant,
|
|
697
|
+
baseline: "control",
|
|
698
|
+
context: f.harness,
|
|
699
|
+
tier: "paired",
|
|
700
|
+
run_id: f.run_id,
|
|
701
|
+
eval_key: f.family_id,
|
|
702
|
+
strata: f.pairs,
|
|
703
|
+
runs: 1,
|
|
704
|
+
points: f.points,
|
|
705
|
+
lo: f.lo,
|
|
706
|
+
hi: f.hi,
|
|
707
|
+
within_noise: f.within_noise,
|
|
708
|
+
pass_verdict: f.verdict === "insufficient" ? "insufficient" : f.within_noise ? "noise" : "effect",
|
|
709
|
+
tools_ratio: f.tools_ratio,
|
|
710
|
+
agent_s_ratio: f.agent_s_ratio,
|
|
711
|
+
tools_p: f.tools_p,
|
|
712
|
+
effort_verdict: f.effort_verdict,
|
|
713
|
+
tokens_ratio: f.tokens_ratio,
|
|
714
|
+
tokens_p: f.tokens_p,
|
|
715
|
+
tokens_verdict: f.tokens_verdict,
|
|
716
|
+
note: "paired by case over a pooled evaluate.each: strata is the paired cases"
|
|
717
|
+
});
|
|
364
718
|
const driftRows = [];
|
|
365
719
|
const series = /* @__PURE__ */ new Map();
|
|
366
720
|
for (const c of cells) {
|
|
@@ -370,7 +724,7 @@ function deriveFacts(db) {
|
|
|
370
724
|
const contextOf = db.prepare("SELECT path, sha256 FROM attempt_context WHERE run_id = ? AND attempt_key = ?");
|
|
371
725
|
const cellContext = (c) => {
|
|
372
726
|
const files = /* @__PURE__ */ new Map();
|
|
373
|
-
for (const a of byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []) for (const f of contextOf
|
|
727
|
+
for (const a of byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []) for (const f of rowsOf(contextOf, c.run_id, a.key)) files.set(f.path, f.sha256);
|
|
374
728
|
return files;
|
|
375
729
|
};
|
|
376
730
|
for (const list of series.values()) {
|
|
@@ -453,7 +807,12 @@ function deriveFacts(db) {
|
|
|
453
807
|
const infra = list.reduce((n, c) => n + c.infra_error, 0);
|
|
454
808
|
const failing = list.flatMap((c) => (byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []).filter((a) => a.outcome === "fail"));
|
|
455
809
|
const w = wilson(pass, pass + fail);
|
|
456
|
-
const
|
|
810
|
+
const passedDiffs = new Set(list.flatMap((c) => (byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []).flatMap((a) => {
|
|
811
|
+
const sha = a.outcome === "pass" && diffs.get(`${a.run_id}\0${a.key}`);
|
|
812
|
+
return sha ? [sha] : [];
|
|
813
|
+
})));
|
|
814
|
+
const sameWork = failing.length > 0 && failing.every((a) => a.error_kind === "assertion" && passedDiffs.has(diffs.get(`${a.run_id}\0${a.key}`) ?? ""));
|
|
815
|
+
const cause = infra > 0 || failing.some((a) => a.error_kind === "infra") ? "infra" : failing.some((a) => nearThreshold.has(`${a.run_id}\0${a.key}`)) ? "judge" : sameWork ? "check" : "agent";
|
|
457
816
|
const starts = list.map((c) => c.started_at).sort();
|
|
458
817
|
flakyRows.push({
|
|
459
818
|
eval_key: first.eval_key,
|
|
@@ -466,7 +825,7 @@ function deriveFacts(db) {
|
|
|
466
825
|
pass,
|
|
467
826
|
counted: pass + fail,
|
|
468
827
|
infra_error: infra,
|
|
469
|
-
|
|
828
|
+
pass_at_1: round3(pass / (pass + fail)),
|
|
470
829
|
lo: round3(w.low),
|
|
471
830
|
hi: round3(w.high),
|
|
472
831
|
verdict: pass + fail >= 6 ? "flaky" : "insufficient",
|
|
@@ -480,7 +839,7 @@ function deriveFacts(db) {
|
|
|
480
839
|
//#endregion
|
|
481
840
|
//#region src/history/db.ts
|
|
482
841
|
/** Bump when the tables or views change: a database from another version is rebuilt. */
|
|
483
|
-
const DB_VERSION =
|
|
842
|
+
const DB_VERSION = 10;
|
|
484
843
|
/** This build of reeval, like the header cache: another reeval re-derives every row. */
|
|
485
844
|
const BUILD = BUILD_ID;
|
|
486
845
|
const historyDbPath = (root) => join(root, ".reeval", "history.db");
|
|
@@ -512,22 +871,54 @@ CREATE TABLE files (run_id TEXT PRIMARY KEY, path TEXT NOT NULL, size INTEGER NO
|
|
|
512
871
|
CREATE TABLE runs (
|
|
513
872
|
run_id TEXT PRIMARY KEY, recorded INTEGER NOT NULL, status TEXT, started_at TEXT, ended_at TEXT,
|
|
514
873
|
duration_ms INTEGER, author TEXT, git_sha TEXT, branch TEXT, dirty INTEGER, runner TEXT,
|
|
515
|
-
ci_provider TEXT, ci_url TEXT, pr_number INTEGER, pr_base TEXT,
|
|
874
|
+
ci_provider TEXT, ci_url TEXT, pr_number INTEGER, pr_base TEXT, reeval TEXT, judge_model TEXT,
|
|
516
875
|
judge_version TEXT, profile TEXT, evals INTEGER, attempts INTEGER, pass INTEGER, fail INTEGER,
|
|
517
876
|
not_gated INTEGER, infra_error INTEGER, skipped INTEGER
|
|
518
877
|
);
|
|
519
878
|
CREATE TABLE evals (
|
|
520
879
|
run_id TEXT NOT NULL, key TEXT NOT NULL, id TEXT, slug TEXT, file TEXT, groups TEXT, name TEXT,
|
|
521
|
-
tags TEXT, fingerprint TEXT, outcome TEXT,
|
|
880
|
+
tags TEXT, fingerprint TEXT, outcome TEXT, pass_at_1 REAL, sources TEXT, family_id TEXT,
|
|
881
|
+
case_index INTEGER,
|
|
522
882
|
PRIMARY KEY (run_id, key)
|
|
523
883
|
);
|
|
884
|
+
-- Each pooled evaluate.each per run: its cases, and each cell's pass@1 over them (the mean of the
|
|
885
|
+
-- cases' pass@1).
|
|
886
|
+
CREATE TABLE families (
|
|
887
|
+
run_id TEXT NOT NULL, family_id TEXT NOT NULL, file TEXT, groups TEXT, name TEXT,
|
|
888
|
+
cases INTEGER, ran INTEGER, cell_key TEXT NOT NULL, cell_cases INTEGER, pass INTEGER,
|
|
889
|
+
counted INTEGER, pass_at_1 REAL, lo REAL, hi REAL, method TEXT, outcome TEXT,
|
|
890
|
+
PRIMARY KEY (run_id, family_id, cell_key)
|
|
891
|
+
);
|
|
892
|
+
-- Every compare-question vote: a pair of sides (arms within a harness, harnesses across an arm)
|
|
893
|
+
-- on one run, shown in one order (swapped = 1: b first), and the side picked or 'tie'.
|
|
894
|
+
CREATE TABLE votes (
|
|
895
|
+
run_id TEXT NOT NULL, eval_key TEXT NOT NULL, question TEXT NOT NULL, cut TEXT, held TEXT,
|
|
896
|
+
pair_run INTEGER, a TEXT, b TEXT, winner TEXT, swapped INTEGER, reason TEXT
|
|
897
|
+
);
|
|
898
|
+
-- Each pair of sides' head-to-head per question: a pair decides when both orders agree (or one
|
|
899
|
+
-- ties); a split is a pair whose orders picked opposite sides, split_first those that picked
|
|
900
|
+
-- the side shown first both times.
|
|
901
|
+
CREATE TABLE question_pairs_m (
|
|
902
|
+
run_id TEXT NOT NULL, eval_key TEXT NOT NULL, question TEXT NOT NULL, cut TEXT, held TEXT,
|
|
903
|
+
a TEXT, b TEXT, pairs INTEGER, a_wins INTEGER, b_wins INTEGER, ties INTEGER, splits INTEGER,
|
|
904
|
+
splits_first INTEGER
|
|
905
|
+
);
|
|
906
|
+
CREATE TABLE family_lift_m (
|
|
907
|
+
run_id TEXT NOT NULL, family_id TEXT NOT NULL, name TEXT, harness TEXT, variant TEXT,
|
|
908
|
+
cell_key TEXT, control TEXT,
|
|
909
|
+
pairs INTEGER, variant_pass_at_1 REAL, control_pass_at_1 REAL, discordant_vc INTEGER,
|
|
910
|
+
discordant_cv INTEGER, points REAL, lo REAL, hi REAL, method TEXT, p REAL,
|
|
911
|
+
within_noise INTEGER, verdict TEXT, min_lift REAL, outcome TEXT, tools_ratio REAL,
|
|
912
|
+
tools_p REAL, effort_verdict TEXT, agent_s_ratio REAL, agent_s_p REAL, time_verdict TEXT,
|
|
913
|
+
tokens_ratio REAL, tokens_p REAL, tokens_verdict TEXT
|
|
914
|
+
);
|
|
524
915
|
CREATE TABLE cells (
|
|
525
916
|
run_id TEXT NOT NULL, eval_key TEXT NOT NULL, key TEXT NOT NULL, role TEXT, variant TEXT,
|
|
526
|
-
harness TEXT, harness_kind TEXT, model TEXT,
|
|
527
|
-
sandbox TEXT, gate TEXT, gate_pass_rate REAL, fingerprint TEXT,
|
|
528
|
-
fp_harness TEXT, fp_environment TEXT, fp_image TEXT, fp_agent_cli TEXT,
|
|
529
|
-
fp_context TEXT, runs INTEGER, pass INTEGER, fail INTEGER, infra_error INTEGER,
|
|
530
|
-
skipped INTEGER,
|
|
917
|
+
harness TEXT, harness_kind TEXT, model TEXT, reasoning_effort TEXT, environment TEXT,
|
|
918
|
+
environment_digest TEXT, sandbox TEXT, gate TEXT, gate_pass_rate REAL, fingerprint TEXT,
|
|
919
|
+
fp_sources TEXT, fp_harness TEXT, fp_environment TEXT, fp_image TEXT, fp_agent_cli TEXT,
|
|
920
|
+
fp_judge TEXT, fp_context TEXT, runs INTEGER, pass INTEGER, fail INTEGER, infra_error INTEGER,
|
|
921
|
+
skipped INTEGER, pass_at_1 REAL, outcome TEXT, lift_vs TEXT, lift_points REAL, lift_lo REAL,
|
|
531
922
|
lift_hi REAL, within_noise INTEGER, min_lift REAL, comparable TEXT,
|
|
532
923
|
PRIMARY KEY (run_id, eval_key, key)
|
|
533
924
|
);
|
|
@@ -537,7 +928,8 @@ CREATE TABLE attempts (
|
|
|
537
928
|
error_message TEXT, duration_ms INTEGER, image_id TEXT, turns INTEGER, tools INTEGER,
|
|
538
929
|
file_edits INTEGER, setup_ms INTEGER, agent_ms INTEGER, checks_ms INTEGER, judge_ms INTEGER,
|
|
539
930
|
last_text TEXT, input_tokens INTEGER, output_tokens INTEGER, cache_read_tokens INTEGER,
|
|
540
|
-
cache_write_tokens INTEGER, reasoning_tokens INTEGER, served_model TEXT,
|
|
931
|
+
cache_write_tokens INTEGER, reasoning_tokens INTEGER, served_model TEXT, oom_kills INTEGER,
|
|
932
|
+
reasoning_effort TEXT, served_reasoning_effort TEXT,
|
|
541
933
|
PRIMARY KEY (run_id, key)
|
|
542
934
|
);
|
|
543
935
|
CREATE TABLE judgements (
|
|
@@ -557,34 +949,61 @@ CREATE TABLE artifacts (
|
|
|
557
949
|
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, kind TEXT NOT NULL, path TEXT NOT NULL,
|
|
558
950
|
sha256 TEXT, bytes INTEGER
|
|
559
951
|
);
|
|
560
|
-
-- What the agent could see, by content hash; runtime = 1 for an agent CLI's own session state
|
|
952
|
+
-- What the agent could see, by content hash; runtime = 1 for an agent CLI's own session state,
|
|
953
|
+
-- declared = 1 for a file the environment declared (its skills' files, rules and config).
|
|
561
954
|
CREATE TABLE attempt_context (
|
|
562
|
-
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, path TEXT NOT NULL, sha256 TEXT, runtime INTEGER
|
|
955
|
+
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, path TEXT NOT NULL, sha256 TEXT, runtime INTEGER,
|
|
956
|
+
declared INTEGER
|
|
563
957
|
);
|
|
564
|
-
-- Every tool call in each attempt's transcript: its line in transcript.jsonl (from 1) and
|
|
958
|
+
-- Every tool call in each attempt's transcript: its line in transcript.jsonl (from 1), target and
|
|
959
|
+
-- class (context, dependency, web, verify or workspace: a heuristic, see tool-class.ts).
|
|
565
960
|
CREATE TABLE tool_calls (
|
|
566
961
|
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, line INTEGER NOT NULL, turn INTEGER,
|
|
567
|
-
tool TEXT, target TEXT, ok INTEGER, duration_ms INTEGER
|
|
962
|
+
tool TEXT, target TEXT, ok INTEGER, duration_ms INTEGER, class TEXT
|
|
963
|
+
);
|
|
964
|
+
-- Each placed file a tool call named (directly or through a glob), by the call's line.
|
|
965
|
+
CREATE TABLE context_reads (
|
|
966
|
+
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, line INTEGER NOT NULL, path TEXT NOT NULL
|
|
967
|
+
);
|
|
968
|
+
-- Every expect / expect.soft matcher call each attempt made, in call order (seq from 1).
|
|
969
|
+
CREATE TABLE assertions (
|
|
970
|
+
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, eval_key TEXT NOT NULL, cell_key TEXT NOT NULL,
|
|
971
|
+
seq INTEGER NOT NULL, label TEXT NOT NULL, labelled INTEGER, matcher TEXT, status TEXT,
|
|
972
|
+
soft INTEGER, message TEXT, duration_ms INTEGER
|
|
973
|
+
);
|
|
974
|
+
-- Each check (assertion label) per cell over its counted attempts; on a variant, its control's too.
|
|
975
|
+
CREATE TABLE cell_checks (
|
|
976
|
+
run_id TEXT NOT NULL, eval_key TEXT NOT NULL, cell_key TEXT NOT NULL, label TEXT NOT NULL,
|
|
977
|
+
pass INTEGER, fail INTEGER, error INTEGER, not_run INTEGER, control_pass INTEGER,
|
|
978
|
+
control_fail INTEGER, control_error INTEGER, control_not_run INTEGER, verdict TEXT
|
|
568
979
|
);
|
|
569
980
|
${DERIVED_TABLES}
|
|
981
|
+
CREATE INDEX assertions_by_attempt ON assertions (run_id, attempt_key);
|
|
570
982
|
CREATE INDEX cells_by_eval ON cells (eval_key, key);
|
|
571
983
|
CREATE INDEX tool_calls_by_attempt ON tool_calls (run_id, attempt_key);
|
|
572
984
|
CREATE INDEX context_by_attempt ON attempt_context (run_id, attempt_key);
|
|
985
|
+
CREATE INDEX context_reads_by_attempt ON context_reads (run_id, attempt_key);
|
|
573
986
|
CREATE INDEX attempts_by_cell ON attempts (run_id, eval_key, cell_key);
|
|
574
987
|
CREATE INDEX env_skills_by_digest ON env_skills (run_id, digest);
|
|
575
988
|
`;
|
|
576
|
-
/**
|
|
989
|
+
/** Canned questions about the history, as views to filter. */
|
|
577
990
|
const VIEWS = `
|
|
578
991
|
-- Variant against control, per harness, per run.
|
|
579
992
|
CREATE VIEW lift AS
|
|
580
993
|
SELECT c.run_id, r.started_at, r.branch, c.eval_key, c.harness, c.model, c.variant,
|
|
581
994
|
c.lift_vs AS control, c.pass AS variant_pass, c.pass + c.fail AS variant_counted,
|
|
582
|
-
k.pass AS control_pass, k.pass + k.fail AS control_counted, c.
|
|
995
|
+
k.pass AS control_pass, k.pass + k.fail AS control_counted, c.pass_at_1 AS variant_pass_at_1,
|
|
996
|
+
k.pass_at_1 AS control_pass_at_1, c.lift_points AS points,
|
|
583
997
|
c.lift_lo AS lo, c.lift_hi AS hi, c.within_noise, c.min_lift, c.outcome, c.fingerprint
|
|
584
998
|
FROM cells c JOIN runs r USING (run_id)
|
|
585
999
|
JOIN cells k ON k.run_id = c.run_id AND k.eval_key = c.eval_key AND k.key = c.lift_vs
|
|
586
1000
|
WHERE c.role = 'variant';
|
|
587
1001
|
|
|
1002
|
+
-- Each variant against its control over a pooled evaluate.each's cases, paired by case, per run.
|
|
1003
|
+
CREATE VIEW family_lift AS
|
|
1004
|
+
SELECT f.*, r.started_at, r.branch
|
|
1005
|
+
FROM family_lift_m f JOIN runs r USING (run_id);
|
|
1006
|
+
|
|
588
1007
|
-- Cells with mixed outcomes, pooled over runs whose fingerprints match once agent runtime state is
|
|
589
1008
|
-- left out; 'flaky' needs FLAKY_MIN_ATTEMPTS counted attempts, else 'insufficient'.
|
|
590
1009
|
CREATE VIEW flaky_cells AS SELECT * FROM flaky_m;
|
|
@@ -596,6 +1015,15 @@ CREATE VIEW drift AS SELECT * FROM drift_m;
|
|
|
596
1015
|
-- Tool calls, agent time and tokens per cell, and a variant's against its control in the same run.
|
|
597
1016
|
CREATE VIEW effort AS SELECT * FROM effort_m;
|
|
598
1017
|
|
|
1018
|
+
-- Each pair of arms (cells a and b) on one harness and sandbox, when an eval has two variants or
|
|
1019
|
+
-- more: pass@1 lift of a over b, effort with its verdicts and separation, and the checks that
|
|
1020
|
+
-- tell them apart. A variant against its control is here too; gating stays variant vs control.
|
|
1021
|
+
CREATE VIEW contrasts AS SELECT * FROM contrasts_m;
|
|
1022
|
+
|
|
1023
|
+
-- Each compare question's pairs of sides, head to head: wins when both orders agree, and splits
|
|
1024
|
+
-- when the order decided. The pooled win rate counts a split as a win for each side.
|
|
1025
|
+
CREATE VIEW question_pairs AS SELECT * FROM question_pairs_m;
|
|
1026
|
+
|
|
599
1027
|
-- What a factor (environment, harness, model) did, by evidence tier: controlled (one run),
|
|
600
1028
|
-- pooled (comparable runs, and across evals), observed (over time), not_measured (one level).
|
|
601
1029
|
CREATE VIEW factor_effects AS SELECT * FROM factor_effects_m;
|
|
@@ -616,19 +1044,60 @@ CREATE VIEW skill_reads AS
|
|
|
616
1044
|
JOIN cells c ON c.run_id = a.run_id AND c.eval_key = a.eval_key AND c.key = a.cell_key
|
|
617
1045
|
JOIN env_skills s ON s.run_id = c.run_id AND s.digest = c.environment_digest;
|
|
618
1046
|
|
|
619
|
-
--
|
|
1047
|
+
-- Tool calls per attempt by class: context (a placed skill, rules file or other placed file, a
|
|
1048
|
+
-- skill load, an MCP tool of the environment), dependency (node_modules, site-packages, vendor,
|
|
1049
|
+
-- --help), web, verify (a command the eval's checks run, or test/build/lint/tsc) and workspace.
|
|
1050
|
+
-- A heuristic: shell commands are split into words and exclusions are not counted.
|
|
1051
|
+
CREATE VIEW context_use AS
|
|
1052
|
+
SELECT a.run_id, a.eval_key, a.cell_key, c.environment, a.key AS attempt_key, a.id AS attempt_id,
|
|
1053
|
+
t.class, COUNT(*) AS calls, MIN(t.line) AS first_line,
|
|
1054
|
+
(SELECT x.target FROM tool_calls x WHERE x.run_id = a.run_id AND x.attempt_key = a.key
|
|
1055
|
+
AND x.class = t.class ORDER BY x.line LIMIT 1) AS example
|
|
1056
|
+
FROM tool_calls t
|
|
1057
|
+
JOIN attempts a ON a.run_id = t.run_id AND a.key = t.attempt_key
|
|
1058
|
+
JOIN cells c ON c.run_id = a.run_id AND c.eval_key = a.eval_key AND c.key = a.cell_key
|
|
1059
|
+
GROUP BY a.run_id, a.key, t.class;
|
|
1060
|
+
|
|
1061
|
+
-- Each file the environment declared (its skills' files, rules), per attempt: how many tool calls
|
|
1062
|
+
-- named it, directly or through a glob, and the first one's transcript line (null: never read).
|
|
1063
|
+
CREATE VIEW skill_files AS
|
|
1064
|
+
SELECT a.run_id, a.eval_key, a.cell_key, c.environment, a.key AS attempt_key,
|
|
1065
|
+
a.id AS attempt_id, x.path,
|
|
1066
|
+
(SELECT COUNT(*) FROM context_reads r WHERE r.run_id = a.run_id AND r.attempt_key = a.key
|
|
1067
|
+
AND r.path = x.path) AS reads,
|
|
1068
|
+
(SELECT MIN(r.line) FROM context_reads r WHERE r.run_id = a.run_id AND r.attempt_key = a.key
|
|
1069
|
+
AND r.path = x.path) AS first_line
|
|
1070
|
+
FROM attempt_context x
|
|
1071
|
+
JOIN attempts a ON a.run_id = x.run_id AND a.key = x.attempt_key
|
|
1072
|
+
JOIN cells c ON c.run_id = a.run_id AND c.eval_key = a.eval_key AND c.key = a.cell_key
|
|
1073
|
+
WHERE x.declared = 1;
|
|
1074
|
+
|
|
1075
|
+
-- Failed attempts and infra errors (an OOM kill among them) with the cell's harness, model, each
|
|
1076
|
+
-- of its environment's skills and the label of the first check that failed.
|
|
620
1077
|
CREATE VIEW failing_attempts AS
|
|
621
1078
|
SELECT a.run_id, r.started_at, a.eval_key, a.key AS attempt_key, a.cell_key, c.harness,
|
|
622
|
-
c.model, c.environment, s.name AS skill, a.
|
|
1079
|
+
c.model, c.environment, s.name AS skill, a.outcome, a.error_kind, a.error_message,
|
|
1080
|
+
a.duration_ms, a.oom_kills,
|
|
1081
|
+
(SELECT x.label FROM assertions x WHERE x.run_id = a.run_id AND x.attempt_key = a.key
|
|
1082
|
+
AND x.status = 'fail' ORDER BY x.seq LIMIT 1) AS first_failed_check
|
|
623
1083
|
FROM attempts a JOIN runs r USING (run_id)
|
|
624
1084
|
JOIN cells c ON c.run_id = a.run_id AND c.eval_key = a.eval_key AND c.key = a.cell_key
|
|
625
1085
|
LEFT JOIN env_skills s ON s.run_id = c.run_id AND s.digest = c.environment_digest
|
|
626
|
-
WHERE a.outcome
|
|
1086
|
+
WHERE a.outcome IN ('fail', 'infra_error');
|
|
627
1087
|
|
|
628
|
-
--
|
|
1088
|
+
-- Each check of a variant cell beside its control's: whether it tells them apart.
|
|
1089
|
+
CREATE VIEW check_discrimination AS
|
|
1090
|
+
SELECT k.run_id, k.eval_key, c.harness, c.variant, c.key AS cell_key, k.label,
|
|
1091
|
+
k.pass AS variant_pass, k.fail AS variant_fail, k.not_run AS variant_not_run,
|
|
1092
|
+
k.control_pass, k.control_fail, k.control_not_run, k.verdict
|
|
1093
|
+
FROM cell_checks k
|
|
1094
|
+
JOIN cells c ON c.run_id = k.run_id AND c.eval_key = k.eval_key AND c.key = k.cell_key
|
|
1095
|
+
WHERE c.role = 'variant' AND k.verdict IS NOT NULL;
|
|
1096
|
+
|
|
1097
|
+
-- One eval per run: outcome and pass@1, with the branch and pull request.
|
|
629
1098
|
CREATE VIEW eval_trend AS
|
|
630
1099
|
SELECT e.eval_key, r.run_id, r.started_at, r.branch, r.pr_number, r.recorded, e.outcome,
|
|
631
|
-
e.
|
|
1100
|
+
e.pass_at_1, e.fingerprint
|
|
632
1101
|
FROM (SELECT key AS eval_key, * FROM evals) e JOIN runs r USING (run_id);
|
|
633
1102
|
|
|
634
1103
|
-- Each judge question's pass rate per cell per run, where it differs from that cell's last run.
|
|
@@ -648,16 +1117,30 @@ CREATE VIEW verdict_flips AS
|
|
|
648
1117
|
`;
|
|
649
1118
|
const VIEW_NAMES = [
|
|
650
1119
|
"lift",
|
|
1120
|
+
"family_lift",
|
|
651
1121
|
"effort",
|
|
1122
|
+
"contrasts",
|
|
1123
|
+
"question_pairs",
|
|
652
1124
|
"factor_effects",
|
|
653
1125
|
"skill_reads",
|
|
1126
|
+
"context_use",
|
|
1127
|
+
"skill_files",
|
|
654
1128
|
"flaky_cells",
|
|
655
1129
|
"drift",
|
|
656
1130
|
"failing_attempts",
|
|
657
1131
|
"eval_trend",
|
|
658
|
-
"verdict_flips"
|
|
1132
|
+
"verdict_flips",
|
|
1133
|
+
"check_discrimination"
|
|
659
1134
|
];
|
|
660
1135
|
const json = (value) => JSON.stringify(value);
|
|
1136
|
+
/** The agent CLI's home config, which its harness writes (MCP servers, settings), not the eval. */
|
|
1137
|
+
const HARNESS_CONFIG = /^~\/.*(^|\/)(config\.(toml|ya?ml|json)|settings(\.local)?\.json|mcp\.json)$/;
|
|
1138
|
+
/**
|
|
1139
|
+
* A placed file the environment declared: under one of its skills, or a rules file outside any
|
|
1140
|
+
* skills directory. Not an agent CLI's own state or home config, its bundled skills or the
|
|
1141
|
+
* adapter's skill index.
|
|
1142
|
+
*/
|
|
1143
|
+
const declaredContext = (path, skills) => !isRuntimeState(path) && !path.endsWith("/.ai-sdk-harness-skills.json") && !HARNESS_CONFIG.test(path) && (skills.some((s) => path.includes(`skills/${s}/`)) || !/(^|\/)skills(-[^/]+)?\//.test(path));
|
|
661
1144
|
/** `attempts.last_text` is the agent's final message, capped: most "why" questions start there. */
|
|
662
1145
|
const LAST_TEXT_LIMIT = 2048;
|
|
663
1146
|
/** The tool calls in a transcript.jsonl, numbered by line from 1; lines that aren't JSON are skipped. */
|
|
@@ -683,6 +1166,17 @@ function toolCalls(transcript) {
|
|
|
683
1166
|
});
|
|
684
1167
|
return calls;
|
|
685
1168
|
}
|
|
1169
|
+
/** `classifyCall`, but a call its heuristic can't read counts as workspace: one transcript line can't stop the sync. */
|
|
1170
|
+
function classifyOrWorkspace(tool, target, ctx) {
|
|
1171
|
+
try {
|
|
1172
|
+
return classifyCall(tool, target, ctx);
|
|
1173
|
+
} catch {
|
|
1174
|
+
return {
|
|
1175
|
+
class: "workspace",
|
|
1176
|
+
files: []
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
686
1180
|
/**
|
|
687
1181
|
* What a cell's results can be pooled on across runs: its fingerprint parts, with the context
|
|
688
1182
|
* part replaced by the context files that aren't an agent CLI's own runtime state.
|
|
@@ -702,22 +1196,42 @@ function comparableFingerprint(cell, attempts) {
|
|
|
702
1196
|
function insertRun(db, record, recorded, transcripts) {
|
|
703
1197
|
const run = (sql, ...values) => db.prepare(sql).run(...values);
|
|
704
1198
|
const { runner, summary, git } = record;
|
|
705
|
-
run(`INSERT INTO runs VALUES (${Array(26).fill("?").join(", ")})`, record.runId, recorded ? 1 : 0, record.status, record.startedAt, record.endedAt, record.durationMs, record.author, git?.sha ?? null, git?.branch ?? null, git ? git.dirty ? 1 : 0 : null, runner.kind, runner.kind === "ci" ? runner.provider : null, runner.kind === "ci" ? runner.runUrl : null, runner.kind === "ci" ? runner.pr?.number ?? null : null, runner.kind === "ci" ? runner.pr?.baseRef ?? null : null, record.stack.
|
|
1199
|
+
run(`INSERT INTO runs VALUES (${Array(26).fill("?").join(", ")})`, record.runId, recorded ? 1 : 0, record.status, record.startedAt, record.endedAt, record.durationMs, record.author, git?.sha ?? null, git?.branch ?? null, git ? git.dirty ? 1 : 0 : null, runner.kind, runner.kind === "ci" ? runner.provider : null, runner.kind === "ci" ? runner.runUrl : null, runner.kind === "ci" ? runner.pr?.number ?? null : null, runner.kind === "ci" ? runner.pr?.baseRef ?? null : null, record.stack.reeval, record.stack.judge.model, record.stack.judge.version, record.profile?.name ?? null, summary.evals, summary.attempts, summary.pass, summary.fail, summary.notGated, summary.infraError, summary.skipped);
|
|
706
1200
|
for (const env of record.environments) {
|
|
707
1201
|
run("INSERT OR IGNORE INTO environments VALUES (?, ?, ?, ?, ?)", record.runId, env.name, env.digest, env.parent, json(env.overrides));
|
|
708
1202
|
for (const s of env.skills) run("INSERT INTO env_skills VALUES (?, ?, ?, ?, ?, ?, ?)", record.runId, env.digest, s.name, s.source, s.commit, s.sha256, s.placement);
|
|
709
1203
|
}
|
|
1204
|
+
const envOf = new Map(record.environments.map((env) => [env.digest, env]));
|
|
710
1205
|
for (const e of record.evals) {
|
|
711
|
-
|
|
1206
|
+
const cellEnv = new Map(e.cells.map((c) => [c.key, c.environmentDigest ?? ""]));
|
|
1207
|
+
run(`INSERT INTO evals VALUES (${Array(14).fill("?").join(", ")})`, record.runId, e.key, e.id, e.slug, e.file, json(e.group), e.name, json(e.tags), e.fingerprint, e.outcome, e.passRate, json(e.sources), e.family?.id ?? null, e.family?.case ?? null);
|
|
712
1208
|
for (const c of e.cells) {
|
|
713
1209
|
const p = c.fingerprintParts;
|
|
714
|
-
run(`INSERT INTO cells VALUES (${Array(
|
|
1210
|
+
run(`INSERT INTO cells VALUES (${Array(36).fill("?").join(", ")})`, record.runId, e.key, c.key, c.role, c.variant ?? null, c.harness, c.harnessKind, c.model, c.effort ?? null, c.environment, c.environmentDigest, c.sandbox, typeof c.gate === "string" ? c.gate : "passRate", typeof c.gate === "string" ? null : c.gate.passRate, c.fingerprint, p.sources, p.harness, p.environment, p.image, p.agentCli, p.judge, p.context, c.runs, c.pass, c.fail, c.infraError, c.skipped, c.passRate, c.outcome, c.lift?.vs ?? null, c.lift?.points ?? null, c.lift?.interval.lo ?? null, c.lift?.interval.hi ?? null, c.lift ? c.lift.withinNoise ? 1 : 0 : null, c.lift?.minLift ?? null, comparableFingerprint(c, e.attempts));
|
|
1211
|
+
for (const k of c.checks ?? []) run(`INSERT INTO cell_checks VALUES (${Array(13).fill("?").join(", ")})`, record.runId, e.key, c.key, k.label, k.pass, k.fail, k.error, k.notRun, k.control?.pass ?? null, k.control?.fail ?? null, k.control?.error ?? null, k.control?.notRun ?? null, k.verdict ?? null);
|
|
1212
|
+
}
|
|
1213
|
+
for (const answer of e.answers ?? []) {
|
|
1214
|
+
for (const v of answer.votes) run(`INSERT INTO votes VALUES (${Array(11).fill("?").join(", ")})`, record.runId, e.key, answer.question, v.cut, v.harness ?? v.arm ?? null, v.run, v.a, v.b, v.winner, v.swapped ? 1 : 0, v.reason ?? null);
|
|
1215
|
+
for (const t of pairTallies(answer.votes)) run(`INSERT INTO question_pairs_m VALUES (${Array(13).fill("?").join(", ")})`, record.runId, e.key, answer.question, t.cut, t.held, t.a, t.b, t.pairs, t.aWins, t.bWins, t.ties, t.splits, t.splitsFirst);
|
|
715
1216
|
}
|
|
716
1217
|
for (const a of e.attempts) {
|
|
717
|
-
run(`INSERT INTO attempts VALUES (${Array(
|
|
718
|
-
|
|
1218
|
+
run(`INSERT INTO attempts VALUES (${Array(30).fill("?").join(", ")})`, record.runId, e.key, a.cell, a.key, a.id, a.n, a.seq, a.startedAt, a.outcome, a.error?.kind ?? null, a.error?.message ?? null, a.durationMs, a.imageId, a.turns.length, a.activity.tools, a.activity.fileEdits, a.timings.setupMs, a.timings.agentMs, a.timings.checksMs, a.timings.judgeMs, a.turns.at(-1)?.text.slice(0, 2048) ?? null, a.usage?.input ?? null, a.usage?.output ?? null, a.usage?.cacheRead ?? null, a.usage?.cacheWrite ?? null, a.usage?.reasoning ?? null, a.turns.findLast((t) => t.model)?.model ?? null, a.error?.resource?.cause === "oom" ? a.error.resource.kills : 0, a.effort ?? null, a.servedEffort ?? null);
|
|
1219
|
+
const env = envOf.get(cellEnv.get(a.cell) ?? "");
|
|
1220
|
+
const skills = env?.skills.map((x) => x.name) ?? [];
|
|
1221
|
+
for (const c of a.context) run("INSERT INTO attempt_context VALUES (?, ?, ?, ?, ?, ?)", record.runId, a.key, c.path, c.sha256, isRuntimeState(c.path) ? 1 : 0, declaredContext(c.path, skills) ? 1 : 0);
|
|
1222
|
+
for (const [i, x] of (a.assertions ?? []).entries()) run(`INSERT INTO assertions VALUES (${Array(12).fill("?").join(", ")})`, record.runId, a.key, e.key, a.cell, i + 1, x.label, x.labelled ? 1 : 0, x.matcher, x.status, x.soft ? 1 : 0, x.message ?? null, x.durationMs ?? null);
|
|
719
1223
|
const transcript = transcripts.get(a.key);
|
|
720
|
-
|
|
1224
|
+
const ctx = {
|
|
1225
|
+
skills,
|
|
1226
|
+
files: a.context.map((c) => c.path).filter((p) => declaredContext(p, skills)),
|
|
1227
|
+
mcp: env?.mcp ?? [],
|
|
1228
|
+
verify: a.checks.map((c) => c.command)
|
|
1229
|
+
};
|
|
1230
|
+
for (const t of transcript ? toolCalls(transcript) : []) {
|
|
1231
|
+
const call = classifyOrWorkspace(t.tool, t.target, ctx);
|
|
1232
|
+
run("INSERT INTO tool_calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", record.runId, a.key, t.line, t.turn, t.tool, t.target, t.ok ? 1 : 0, t.durationMs, call.class);
|
|
1233
|
+
for (const path of call.files) run("INSERT INTO context_reads VALUES (?, ?, ?, ?)", record.runId, a.key, t.line, path);
|
|
1234
|
+
}
|
|
721
1235
|
for (const j of a.judgements) run("INSERT OR IGNORE INTO judgements VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", record.runId, a.key, j.key, j.question, j.verdict, j.score, j.threshold, j.model, j.resolvedModel ?? null, a.files.judgeInput?.path ?? null);
|
|
722
1236
|
for (const [kind, ref] of Object.entries(a.files)) {
|
|
723
1237
|
if (ref == null || Array.isArray(ref) || typeof ref.path !== "string") continue;
|
|
@@ -729,10 +1243,22 @@ function insertRun(db, record, recorded, transcripts) {
|
|
|
729
1243
|
});
|
|
730
1244
|
}
|
|
731
1245
|
}
|
|
1246
|
+
for (const f of record.families ?? []) {
|
|
1247
|
+
for (const r of f.rates) run(`INSERT INTO families VALUES (${Array(16).fill("?").join(", ")})`, record.runId, f.id, f.file, json(f.group), f.name, f.cases, f.ran, r.cell, r.cases, r.pass, r.counted, r.rate, r.interval.lo, r.interval.hi, r.interval.method, f.outcome);
|
|
1248
|
+
for (const l of f.lifts) {
|
|
1249
|
+
const e = l.effort;
|
|
1250
|
+
const cell = record.evals.find((x) => x.family?.id === f.id && x.cells.some((c) => c.key === l.variant))?.cells.find((c) => c.key === l.variant);
|
|
1251
|
+
run(`INSERT INTO family_lift_m VALUES (${Array(30).fill("?").join(", ")})`, record.runId, f.id, f.name, cell?.harness ?? null, cell?.variant ?? cell?.environment ?? null, l.variant, l.vs, l.pairs, l.variantRate, l.controlRate, l.discordant?.variantOnly ?? null, l.discordant?.controlOnly ?? null, l.points, l.interval.lo, l.interval.hi, l.interval.method, l.p, l.withinNoise ? 1 : 0, l.verdict, l.minLift ?? null, l.outcome, e?.tools.ratio ?? null, e?.tools.p ?? null, e?.tools.verdict ?? null, e?.agentMs.ratio ?? null, e?.agentMs.p ?? null, e?.agentMs.verdict ?? null, e?.tokens?.ratio ?? null, e?.tokens?.p ?? null, e?.tokens?.verdict ?? null);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
732
1254
|
}
|
|
733
1255
|
const DATA_TABLES = [
|
|
734
1256
|
"runs",
|
|
735
1257
|
"evals",
|
|
1258
|
+
"families",
|
|
1259
|
+
"family_lift_m",
|
|
1260
|
+
"votes",
|
|
1261
|
+
"question_pairs_m",
|
|
736
1262
|
"cells",
|
|
737
1263
|
"attempts",
|
|
738
1264
|
"judgements",
|
|
@@ -740,14 +1266,17 @@ const DATA_TABLES = [
|
|
|
740
1266
|
"env_skills",
|
|
741
1267
|
"artifacts",
|
|
742
1268
|
"attempt_context",
|
|
743
|
-
"tool_calls"
|
|
1269
|
+
"tool_calls",
|
|
1270
|
+
"context_reads",
|
|
1271
|
+
"assertions",
|
|
1272
|
+
"cell_checks"
|
|
744
1273
|
];
|
|
745
1274
|
function removeRun(db, runId) {
|
|
746
1275
|
for (const table of DATA_TABLES) db.prepare(`DELETE FROM ${table} WHERE run_id = ?`).run(runId);
|
|
747
1276
|
db.prepare("DELETE FROM files WHERE run_id = ?").run(runId);
|
|
748
1277
|
}
|
|
749
1278
|
function freshSchema(db) {
|
|
750
|
-
const objects = db.prepare("SELECT type, name FROM sqlite_schema WHERE type IN ('table', 'view')")
|
|
1279
|
+
const objects = rowsOf(db.prepare("SELECT type, name FROM sqlite_schema WHERE type IN ('table', 'view')"));
|
|
751
1280
|
for (const o of objects) {
|
|
752
1281
|
if (o.name.startsWith("sqlite_")) continue;
|
|
753
1282
|
db.exec(`DROP ${o.type === "view" ? "VIEW" : "TABLE"} IF EXISTS "${o.name}"`);
|
|
@@ -758,7 +1287,7 @@ function freshSchema(db) {
|
|
|
758
1287
|
}
|
|
759
1288
|
function current(db) {
|
|
760
1289
|
try {
|
|
761
|
-
const rows = db.prepare("SELECT key, value FROM meta")
|
|
1290
|
+
const rows = rowsOf(db.prepare("SELECT key, value FROM meta"));
|
|
762
1291
|
const meta = Object.fromEntries(rows.map((r) => [r.key, r.value]));
|
|
763
1292
|
return meta.version === String(DB_VERSION) && meta.build === String(BUILD);
|
|
764
1293
|
} catch {
|
|
@@ -792,7 +1321,7 @@ async function sync(db, root, historyDir) {
|
|
|
792
1321
|
recorded
|
|
793
1322
|
});
|
|
794
1323
|
}
|
|
795
|
-
const known = new Map(db.prepare("SELECT run_id, path, size, mtime_ms FROM files")
|
|
1324
|
+
const known = new Map(rowsOf(db.prepare("SELECT run_id, path, size, mtime_ms FROM files")).map((r) => [r.run_id, r]));
|
|
796
1325
|
let added = 0;
|
|
797
1326
|
let removed = 0;
|
|
798
1327
|
db.exec("BEGIN");
|
|
@@ -863,15 +1392,15 @@ async function openHistoryDb(root, historyDir, options = {}) {
|
|
|
863
1392
|
}
|
|
864
1393
|
},
|
|
865
1394
|
schema() {
|
|
866
|
-
return db.prepare(`SELECT name, type FROM sqlite_schema WHERE type IN ('table', 'view') AND name NOT IN ('meta', 'files', ${DERIVED.map((d) => `'${d}'`).join(", ")}) AND name NOT LIKE 'sqlite_%' ORDER BY type, name`)
|
|
1395
|
+
return rowsOf(db.prepare(`SELECT name, type FROM sqlite_schema WHERE type IN ('table', 'view') AND name NOT IN ('meta', 'files', 'family_lift_m', ${DERIVED.map((d) => `'${d}'`).join(", ")}) AND name NOT LIKE 'sqlite_%' ORDER BY type, name`)).map((o) => ({
|
|
867
1396
|
...o,
|
|
868
|
-
columns: db.prepare(`PRAGMA table_info("${o.name}")`)
|
|
1397
|
+
columns: rowsOf(db.prepare(`PRAGMA table_info("${o.name}")`)).map((c) => c.name)
|
|
869
1398
|
}));
|
|
870
1399
|
},
|
|
871
1400
|
close: () => db.close()
|
|
872
1401
|
};
|
|
873
1402
|
}
|
|
874
1403
|
//#endregion
|
|
875
|
-
export { historyDbPath as a, toolCalls as c, comparableFingerprint as i, SQLITE_NODE as n, nodeAtLeast as o, VIEW_NAMES as r, openHistoryDb as s, LAST_TEXT_LIMIT as t };
|
|
1404
|
+
export { historyDbPath as a, toolCalls as c, comparableFingerprint as i, TOOL_CLASSES as l, SQLITE_NODE as n, nodeAtLeast as o, VIEW_NAMES as r, openHistoryDb as s, LAST_TEXT_LIMIT as t };
|
|
876
1405
|
|
|
877
|
-
//# sourceMappingURL=db-
|
|
1406
|
+
//# sourceMappingURL=db-CdHizc4_.js.map
|