reeval 0.9.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 +42 -30
- 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-6FefIhX7.js → agent-CURAwx_q.js} +6 -6
- package/dist/{agent-6FefIhX7.js.map → agent-CURAwx_q.js.map} +1 -1
- package/dist/{agent-WSmTaesf.js → agent-CaS_2Sce.js} +46 -15
- package/dist/agent-CaS_2Sce.js.map +1 -0
- package/dist/{analysis-DlGBDjTj.js → analysis-Bxub9LMT.js} +4 -4
- package/dist/{analysis-DlGBDjTj.js.map → analysis-Bxub9LMT.js.map} +1 -1
- package/dist/{assemble-BCZzTyR7.js → assemble-B9Alds-z.js} +69 -41
- package/dist/assemble-B9Alds-z.js.map +1 -0
- package/dist/assemble-J5MukZFY.js +1 -0
- package/dist/{client-Bbo9SPlK.js → assert-EUIoRdIt.js} +10 -113
- package/dist/assert-EUIoRdIt.js.map +1 -0
- package/dist/bridge/index.mjs +248 -55
- package/dist/{capture-Bp74Z6Fr.js → capture-CNb9SuU5.js} +145 -31
- package/dist/capture-CNb9SuU5.js.map +1 -0
- package/dist/capture-jquXZBKK.js +1 -0
- package/dist/{cli-CVrMh_qz.js → cli-D303Vj5N.js} +133 -115
- package/dist/cli-D303Vj5N.js.map +1 -0
- package/dist/{cli-spec-CKEYa8V2.js → cli-spec-BPZbQG2p.js} +36 -17
- 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-CzIFp1JQ.js → command-BLfT7vnQ.js} +18 -17
- package/dist/command-BLfT7vnQ.js.map +1 -0
- package/dist/{command-C5xFPKHM.js → command-BT9a37ZR.js} +374 -72
- package/dist/command-BT9a37ZR.js.map +1 -0
- package/dist/{command-DUT5l13I.js → command-Bge8F7Ko.js} +316 -83
- package/dist/command-Bge8F7Ko.js.map +1 -0
- package/dist/command-BkFjijN2.js +1 -0
- package/dist/{command-BFP0hKEb.js → command-CMJtHKRa.js} +14 -14
- package/dist/{command-BFP0hKEb.js.map → command-CMJtHKRa.js.map} +1 -1
- package/dist/commands-1p-bIWhN.js +1 -0
- package/dist/{commands-CLmPBrTS.js → commands-BFx16WB8.js} +7 -7
- 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-DbSMEVKs.js → context-C1mxXh80.js} +11 -3
- package/dist/context-C1mxXh80.js.map +1 -0
- package/dist/{db-CfQFwJtq.js → db-CdHizc4_.js} +455 -36
- 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-CRQGQbIt.js → docker-7b_2SaH7.js} +22 -21
- package/dist/docker-7b_2SaH7.js.map +1 -0
- package/dist/{docker-DV2GNgle.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-DlKycx5H.js → doctor-BYNok4UO.js} +262 -83
- 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-BhzNh7Yi.js → egress-C4PZTSSe.js} +146 -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/files-BAt0i00X.js +1 -0
- package/dist/{files-CSzVADHn.js → files-BXUdY8tr.js} +9 -8
- package/dist/{files-CSzVADHn.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-DJUFg-4e.js → files-DQmHE7pb.js} +5 -5
- package/dist/{files-DJUFg-4e.js.map → files-DQmHE7pb.js.map} +1 -1
- package/dist/files-ZZPqfAo6.js +1 -0
- package/dist/harness-B8QC9u0O.js +323 -0
- package/dist/harness-B8QC9u0O.js.map +1 -0
- package/dist/harness.d.ts +16 -30
- package/dist/harness.js +1 -2
- package/dist/{header-CALhmafp.js → header-hK-Z_Po9.js} +2 -2
- package/dist/{header-CALhmafp.js.map → header-hK-Z_Po9.js.map} +1 -1
- package/dist/{images-BMgdpMAX.js → images-0On0cztu.js} +114 -45
- package/dist/images-0On0cztu.js.map +1 -0
- package/dist/index.d.ts +9 -37
- package/dist/index.js +6 -2138
- package/dist/{init-BIdLF0F9.js → init-B77Rpcqc.js} +26 -8
- package/dist/init-B77Rpcqc.js.map +1 -0
- package/dist/init-BrOWin3W.js +1 -0
- package/dist/{invocations-CLaL8AuW.js → invocations-DbGfBAA_.js} +4 -4
- package/dist/{invocations-CLaL8AuW.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-B1BZoZ9b.js → model-h_cDtcRr.js} +18 -17
- package/dist/model-h_cDtcRr.js.map +1 -0
- package/dist/model-nwWJvaUR.js +1 -0
- package/dist/{model-BOnlAPzs.js → model-oqcDplJG.js} +111 -19
- 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-bDV8YFW0.js → patch-Zac5aIRM.js} +6 -6
- package/dist/{patch-bDV8YFW0.js.map → patch-Zac5aIRM.js.map} +1 -1
- package/dist/{plan-DUydFc_1.js → plan-C9Cy27Ay.js} +24 -9
- package/dist/plan-C9Cy27Ay.js.map +1 -0
- package/dist/preflight-CPWpQeBI.js +1 -0
- package/dist/{preflight-BkoSxf4C.js → preflight-D7iFPKeK.js} +8 -7
- package/dist/preflight-D7iFPKeK.js.map +1 -0
- package/dist/prepare-BGjePFQl.js +2 -0
- package/dist/{prepare-CUAWHebF.js → prepare-doGxaAGR.js} +38 -30
- package/dist/prepare-doGxaAGR.js.map +1 -0
- package/dist/{provenance-D7HK3vzt.js → provenance-DmE9uPVt.js} +3 -3
- package/dist/{provenance-D7HK3vzt.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-BjBMLa-C.js → query-Bes9Kh6Y.js} +3 -3
- package/dist/{query-BjBMLa-C.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-Di7m8dQ3.js → results-DuauQI3Z.js} +4 -4
- package/dist/{results-Di7m8dQ3.js.map → results-DuauQI3Z.js.map} +1 -1
- package/dist/{resume-SUz1GskV.js → resume-BRfa8E_s.js} +10 -10
- package/dist/{resume-SUz1GskV.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-DdsfnRz_.js → runtime-PX_oXiCS.js} +23 -71
- 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 +19 -6
- package/dist/sandbox.js +1 -2
- package/dist/server-C7sg1ndo.js +1 -0
- package/dist/{server-BNnXtmS8.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-Dof0NQBm.js → source-C8xumIWj.js} +2 -2
- package/dist/{source-Dof0NQBm.js.map → source-C8xumIWj.js.map} +1 -1
- package/dist/source-fGd0SaKP.js +1 -0
- package/dist/{src-8rRXy4u9.js → src-B7treWa8.js} +1538 -180
- 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-C_4Umgh2.js → src-CFp86GtV.js} +52 -51
- 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-COgE7991.js → src-DvK0EIZx.js} +5 -5
- package/dist/{src-COgE7991.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-CiXyLqg0.js → state-C__9swoG.js} +35 -23
- 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-CROH2NB3.js → index-DrQc2Yxd.js} +11 -11
- package/dist/studio-app/index.html +2 -2
- package/dist/{summary-BTksrIxn.js → summary-BLAVLySU.js} +150 -19
- package/dist/summary-BLAVLySU.js.map +1 -0
- package/dist/{summary-2OAWF2N7.js → summary-DgyjUh_l.js} +7 -7
- package/dist/{summary-2OAWF2N7.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-B10Uj7OI.js → tools-GCyNYSc1.js} +6 -6
- 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-D8RLfkFP.d.ts → types-g17bRAzt.d.ts} +389 -42
- 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 +42 -8
- package/dist/view/index.js +6 -6
- package/dist/views-BW6oCDUQ.js +2 -0
- package/dist/{views-Dqa5ojfZ.js → views-BmQF4UCI.js} +13 -8
- package/dist/views-BmQF4UCI.js.map +1 -0
- package/dist/{worker-entry-BAikHl9F.js → worker-entry-yOchGYYv.js} +16 -229
- package/dist/worker-entry-yOchGYYv.js.map +1 -0
- package/dist/{workspace-C-TrNIUc.js → workspace-CgyHEM0l.js} +6 -6
- package/dist/{workspace-C-TrNIUc.js.map → workspace-CgyHEM0l.js.map} +1 -1
- package/dist/workspace-D8sSgpiy.js +1 -0
- package/package.json +12 -12
- package/dist/agent-WSmTaesf.js.map +0 -1
- package/dist/assemble-BCZzTyR7.js.map +0 -1
- package/dist/assemble-C5qq5yT2.js +0 -2
- package/dist/capture-Bp74Z6Fr.js.map +0 -1
- package/dist/capture-DS-cPyuE.js +0 -2
- package/dist/cli-CVrMh_qz.js.map +0 -1
- package/dist/cli-spec-CKEYa8V2.js.map +0 -1
- package/dist/client-Bbo9SPlK.js.map +0 -1
- package/dist/command-BrmXUC-W.js +0 -2
- package/dist/command-C5xFPKHM.js.map +0 -1
- package/dist/command-CzIFp1JQ.js.map +0 -1
- package/dist/command-DUT5l13I.js.map +0 -1
- package/dist/commands-CLmPBrTS.js.map +0 -1
- package/dist/commands-fI3G2Wnh.js +0 -2
- package/dist/config-CGvBeewH.js +0 -457
- package/dist/config-CGvBeewH.js.map +0 -1
- package/dist/context-DbSMEVKs.js.map +0 -1
- package/dist/db-CSSFtGcN.js +0 -3
- package/dist/db-CfQFwJtq.js.map +0 -1
- package/dist/debug-SEmW4w8f.js +0 -2
- package/dist/dist-CTzThfu_.js.map +0 -1
- package/dist/docker-CRQGQbIt.js.map +0 -1
- package/dist/docker-DV2GNgle.js.map +0 -1
- package/dist/docker-Df_YOxxB.js +0 -2
- package/dist/doctor-DlKycx5H.js.map +0 -1
- package/dist/egress-BhzNh7Yi.js.map +0 -1
- package/dist/environment-1jE-HhO-.js +0 -657
- package/dist/environment-1jE-HhO-.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-AiEKuEZe.js +0 -2
- package/dist/files-BM78_nnF.js +0 -2
- package/dist/files-BMCvfB4X.js +0 -2
- package/dist/harness-CeCp2GSW.js +0 -171
- package/dist/harness-CeCp2GSW.js.map +0 -1
- package/dist/images-BMgdpMAX.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init-B6vegaP_.js +0 -2
- package/dist/init-BIdLF0F9.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-B1BZoZ9b.js.map +0 -1
- package/dist/model-BOnlAPzs.js.map +0 -1
- package/dist/model-DWeg5J7z.js +0 -2
- package/dist/model-FXko2kl7.js +0 -2
- package/dist/node-Co7EXge0.js.map +0 -1
- package/dist/opencode-providers-ByD85Q0l.js.map +0 -1
- package/dist/options-CKqyPGxX.js +0 -739
- package/dist/options-CKqyPGxX.js.map +0 -1
- package/dist/plan-DUydFc_1.js.map +0 -1
- package/dist/preflight-BkoSxf4C.js.map +0 -1
- package/dist/preflight-D5LW7Oqi.js +0 -2
- package/dist/prepare-CUAWHebF.js.map +0 -1
- package/dist/prepare-oji2oO8W.js +0 -3
- package/dist/provider-BDbNOQhQ.js +0 -2
- package/dist/providers-B1DzMvmH.js +0 -107
- package/dist/providers-B1DzMvmH.js.map +0 -1
- package/dist/providers-CpEfNU1F.js +0 -2
- package/dist/query-oPO_XrTy.js +0 -2
- package/dist/questions-B8by4Bbt.js +0 -234
- package/dist/questions-B8by4Bbt.js.map +0 -1
- package/dist/runtime-DdsfnRz_.js.map +0 -1
- package/dist/sandbox-D5v-of6d.js +0 -139
- package/dist/sandbox-D5v-of6d.js.map +0 -1
- package/dist/server-BNnXtmS8.js.map +0 -1
- package/dist/server-BNwoKzlm.js +0 -2
- package/dist/source-Bk_0ZaEY.js +0 -2
- package/dist/src-8rRXy4u9.js.map +0 -1
- package/dist/src-BGWuWp6I.js +0 -3
- package/dist/src-BRt0O02i.js +0 -3
- package/dist/src-Bx2x1ekD.js +0 -3
- package/dist/src-C_4Umgh2.js.map +0 -1
- package/dist/src-D95O-Smv.js.map +0 -1
- package/dist/src-DDNXsD9H.js.map +0 -1
- package/dist/src-DLa-ESW0.js +0 -4
- package/dist/src-cN0aB-WR.js +0 -3
- package/dist/src-cdIVjC5b.js +0 -2
- package/dist/src-sIsDHWYq.js +0 -3
- package/dist/state-Bo5zg4da.js +0 -2
- package/dist/state-CiXyLqg0.js.map +0 -1
- package/dist/studio-app/assets/index-B9MCTfuu.css +0 -2
- package/dist/summary-BTksrIxn.js.map +0 -1
- package/dist/tool-target-BU1JnSE9.js.map +0 -1
- package/dist/tools-B10Uj7OI.js.map +0 -1
- package/dist/views-Cs2Oqayd.js +0 -3
- package/dist/views-Dqa5ojfZ.js.map +0 -1
- package/dist/worker-entry-BAikHl9F.js.map +0 -1
- package/dist/workspace-Do_SiWBs.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,
|
|
@@ -62,6 +285,7 @@ const FAMILY_COLUMNS = [
|
|
|
62
285
|
];
|
|
63
286
|
const DERIVED = [
|
|
64
287
|
"effort_m",
|
|
288
|
+
"contrasts_m",
|
|
65
289
|
"factor_effects_m",
|
|
66
290
|
"flaky_m",
|
|
67
291
|
"drift_m"
|
|
@@ -177,18 +401,19 @@ const merge = (sides) => ({
|
|
|
177
401
|
});
|
|
178
402
|
function insertAll(db, table, rows) {
|
|
179
403
|
if (rows.length === 0) return;
|
|
180
|
-
const cols = db.prepare(`PRAGMA table_info("${table}")`)
|
|
404
|
+
const cols = rowsOf(db.prepare(`PRAGMA table_info("${table}")`)).map((c) => c.name);
|
|
181
405
|
const statement = db.prepare(`INSERT INTO ${table} (${cols.join(", ")}) VALUES (${cols.map(() => "?").join(", ")})`);
|
|
182
406
|
for (const row of rows) statement.run(...cols.map((c) => row[c] ?? null));
|
|
183
407
|
}
|
|
184
408
|
/** Recomputes every derived table from the projected rows; run inside the sync's transaction. */
|
|
185
409
|
function deriveFacts(db) {
|
|
186
410
|
for (const table of DERIVED) db.exec(`DELETE FROM ${table}`);
|
|
187
|
-
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")
|
|
188
|
-
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,
|
|
189
413
|
input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, reasoning_tokens
|
|
190
|
-
FROM attempts ORDER BY run_id, rowid`)
|
|
191
|
-
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]] : []));
|
|
192
417
|
const samples = /* @__PURE__ */ new Map();
|
|
193
418
|
const byCell = /* @__PURE__ */ new Map();
|
|
194
419
|
for (const a of attempts) {
|
|
@@ -209,6 +434,20 @@ function deriveFacts(db) {
|
|
|
209
434
|
samples: samples.get(cellId(c.run_id, c.eval_key, c.key)) ?? []
|
|
210
435
|
});
|
|
211
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
|
+
};
|
|
212
451
|
insertAll(db, "effort_m", cells.map((c) => {
|
|
213
452
|
const own = effortOf(side(c).samples);
|
|
214
453
|
const control = c.lift_vs ? find(c.run_id, c.eval_key, c.lift_vs) : void 0;
|
|
@@ -245,12 +484,83 @@ function deriveFacts(db) {
|
|
|
245
484
|
agent_s_p: r4(vs?.agentMsP ?? null),
|
|
246
485
|
tokens_p: r4(vs?.tokensP ?? null),
|
|
247
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,
|
|
248
489
|
verdict: vs?.verdict ?? null,
|
|
249
490
|
time_verdict: vs?.timeVerdict ?? null,
|
|
250
491
|
tokens_verdict: vs?.tokensVerdict ?? null,
|
|
251
|
-
tokens_note: vs?.tokensNote ?? null
|
|
492
|
+
tokens_note: vs?.tokensNote ?? null,
|
|
493
|
+
...classMedians(c)
|
|
252
494
|
};
|
|
253
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);
|
|
254
564
|
const pairs = [];
|
|
255
565
|
const groups = /* @__PURE__ */ new Map();
|
|
256
566
|
for (const c of cells) {
|
|
@@ -380,7 +690,7 @@ function deriveFacts(db) {
|
|
|
380
690
|
note: "pass@1: summed counts; effort: an effect in at least 2/3 of strata"
|
|
381
691
|
});
|
|
382
692
|
}
|
|
383
|
-
const familyLifts = db.prepare(`SELECT ${FAMILY_COLUMNS.join(", ")} FROM family_lift_m`)
|
|
693
|
+
const familyLifts = rowsOf(db.prepare(`SELECT ${FAMILY_COLUMNS.join(", ")} FROM family_lift_m`));
|
|
384
694
|
for (const f of familyLifts) factorRows.push({
|
|
385
695
|
factor: "environment",
|
|
386
696
|
level: f.variant,
|
|
@@ -414,7 +724,7 @@ function deriveFacts(db) {
|
|
|
414
724
|
const contextOf = db.prepare("SELECT path, sha256 FROM attempt_context WHERE run_id = ? AND attempt_key = ?");
|
|
415
725
|
const cellContext = (c) => {
|
|
416
726
|
const files = /* @__PURE__ */ new Map();
|
|
417
|
-
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);
|
|
418
728
|
return files;
|
|
419
729
|
};
|
|
420
730
|
for (const list of series.values()) {
|
|
@@ -497,7 +807,12 @@ function deriveFacts(db) {
|
|
|
497
807
|
const infra = list.reduce((n, c) => n + c.infra_error, 0);
|
|
498
808
|
const failing = list.flatMap((c) => (byCell.get(cellId(c.run_id, c.eval_key, c.key)) ?? []).filter((a) => a.outcome === "fail"));
|
|
499
809
|
const w = wilson(pass, pass + fail);
|
|
500
|
-
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";
|
|
501
816
|
const starts = list.map((c) => c.started_at).sort();
|
|
502
817
|
flakyRows.push({
|
|
503
818
|
eval_key: first.eval_key,
|
|
@@ -524,7 +839,7 @@ function deriveFacts(db) {
|
|
|
524
839
|
//#endregion
|
|
525
840
|
//#region src/history/db.ts
|
|
526
841
|
/** Bump when the tables or views change: a database from another version is rebuilt. */
|
|
527
|
-
const DB_VERSION =
|
|
842
|
+
const DB_VERSION = 10;
|
|
528
843
|
/** This build of reeval, like the header cache: another reeval re-derives every row. */
|
|
529
844
|
const BUILD = BUILD_ID;
|
|
530
845
|
const historyDbPath = (root) => join(root, ".reeval", "history.db");
|
|
@@ -556,7 +871,7 @@ CREATE TABLE files (run_id TEXT PRIMARY KEY, path TEXT NOT NULL, size INTEGER NO
|
|
|
556
871
|
CREATE TABLE runs (
|
|
557
872
|
run_id TEXT PRIMARY KEY, recorded INTEGER NOT NULL, status TEXT, started_at TEXT, ended_at TEXT,
|
|
558
873
|
duration_ms INTEGER, author TEXT, git_sha TEXT, branch TEXT, dirty INTEGER, runner TEXT,
|
|
559
|
-
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,
|
|
560
875
|
judge_version TEXT, profile TEXT, evals INTEGER, attempts INTEGER, pass INTEGER, fail INTEGER,
|
|
561
876
|
not_gated INTEGER, infra_error INTEGER, skipped INTEGER
|
|
562
877
|
);
|
|
@@ -566,17 +881,32 @@ CREATE TABLE evals (
|
|
|
566
881
|
case_index INTEGER,
|
|
567
882
|
PRIMARY KEY (run_id, key)
|
|
568
883
|
);
|
|
569
|
-
-- Each pooled evaluate.each per run: its cases, and each cell's pass
|
|
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).
|
|
570
886
|
CREATE TABLE families (
|
|
571
887
|
run_id TEXT NOT NULL, family_id TEXT NOT NULL, file TEXT, groups TEXT, name TEXT,
|
|
572
888
|
cases INTEGER, ran INTEGER, cell_key TEXT NOT NULL, cell_cases INTEGER, pass INTEGER,
|
|
573
|
-
counted INTEGER,
|
|
889
|
+
counted INTEGER, pass_at_1 REAL, lo REAL, hi REAL, method TEXT, outcome TEXT,
|
|
574
890
|
PRIMARY KEY (run_id, family_id, cell_key)
|
|
575
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
|
+
);
|
|
576
906
|
CREATE TABLE family_lift_m (
|
|
577
907
|
run_id TEXT NOT NULL, family_id TEXT NOT NULL, name TEXT, harness TEXT, variant TEXT,
|
|
578
908
|
cell_key TEXT, control TEXT,
|
|
579
|
-
pairs INTEGER,
|
|
909
|
+
pairs INTEGER, variant_pass_at_1 REAL, control_pass_at_1 REAL, discordant_vc INTEGER,
|
|
580
910
|
discordant_cv INTEGER, points REAL, lo REAL, hi REAL, method TEXT, p REAL,
|
|
581
911
|
within_noise INTEGER, verdict TEXT, min_lift REAL, outcome TEXT, tools_ratio REAL,
|
|
582
912
|
tools_p REAL, effort_verdict TEXT, agent_s_ratio REAL, agent_s_p REAL, time_verdict TEXT,
|
|
@@ -619,14 +949,21 @@ CREATE TABLE artifacts (
|
|
|
619
949
|
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, kind TEXT NOT NULL, path TEXT NOT NULL,
|
|
620
950
|
sha256 TEXT, bytes INTEGER
|
|
621
951
|
);
|
|
622
|
-
-- 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).
|
|
623
954
|
CREATE TABLE attempt_context (
|
|
624
|
-
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
|
|
625
957
|
);
|
|
626
|
-
-- 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).
|
|
627
960
|
CREATE TABLE tool_calls (
|
|
628
961
|
run_id TEXT NOT NULL, attempt_key TEXT NOT NULL, line INTEGER NOT NULL, turn INTEGER,
|
|
629
|
-
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
|
|
630
967
|
);
|
|
631
968
|
-- Every expect / expect.soft matcher call each attempt made, in call order (seq from 1).
|
|
632
969
|
CREATE TABLE assertions (
|
|
@@ -645,10 +982,11 @@ CREATE INDEX assertions_by_attempt ON assertions (run_id, attempt_key);
|
|
|
645
982
|
CREATE INDEX cells_by_eval ON cells (eval_key, key);
|
|
646
983
|
CREATE INDEX tool_calls_by_attempt ON tool_calls (run_id, attempt_key);
|
|
647
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);
|
|
648
986
|
CREATE INDEX attempts_by_cell ON attempts (run_id, eval_key, cell_key);
|
|
649
987
|
CREATE INDEX env_skills_by_digest ON env_skills (run_id, digest);
|
|
650
988
|
`;
|
|
651
|
-
/**
|
|
989
|
+
/** Canned questions about the history, as views to filter. */
|
|
652
990
|
const VIEWS = `
|
|
653
991
|
-- Variant against control, per harness, per run.
|
|
654
992
|
CREATE VIEW lift AS
|
|
@@ -677,6 +1015,15 @@ CREATE VIEW drift AS SELECT * FROM drift_m;
|
|
|
677
1015
|
-- Tool calls, agent time and tokens per cell, and a variant's against its control in the same run.
|
|
678
1016
|
CREATE VIEW effort AS SELECT * FROM effort_m;
|
|
679
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
|
+
|
|
680
1027
|
-- What a factor (environment, harness, model) did, by evidence tier: controlled (one run),
|
|
681
1028
|
-- pooled (comparable runs, and across evals), observed (over time), not_measured (one level).
|
|
682
1029
|
CREATE VIEW factor_effects AS SELECT * FROM factor_effects_m;
|
|
@@ -697,6 +1044,34 @@ CREATE VIEW skill_reads AS
|
|
|
697
1044
|
JOIN cells c ON c.run_id = a.run_id AND c.eval_key = a.eval_key AND c.key = a.cell_key
|
|
698
1045
|
JOIN env_skills s ON s.run_id = c.run_id AND s.digest = c.environment_digest;
|
|
699
1046
|
|
|
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
|
+
|
|
700
1075
|
-- Failed attempts and infra errors (an OOM kill among them) with the cell's harness, model, each
|
|
701
1076
|
-- of its environment's skills and the label of the first check that failed.
|
|
702
1077
|
CREATE VIEW failing_attempts AS
|
|
@@ -744,8 +1119,12 @@ const VIEW_NAMES = [
|
|
|
744
1119
|
"lift",
|
|
745
1120
|
"family_lift",
|
|
746
1121
|
"effort",
|
|
1122
|
+
"contrasts",
|
|
1123
|
+
"question_pairs",
|
|
747
1124
|
"factor_effects",
|
|
748
1125
|
"skill_reads",
|
|
1126
|
+
"context_use",
|
|
1127
|
+
"skill_files",
|
|
749
1128
|
"flaky_cells",
|
|
750
1129
|
"drift",
|
|
751
1130
|
"failing_attempts",
|
|
@@ -754,6 +1133,14 @@ const VIEW_NAMES = [
|
|
|
754
1133
|
"check_discrimination"
|
|
755
1134
|
];
|
|
756
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));
|
|
757
1144
|
/** `attempts.last_text` is the agent's final message, capped: most "why" questions start there. */
|
|
758
1145
|
const LAST_TEXT_LIMIT = 2048;
|
|
759
1146
|
/** The tool calls in a transcript.jsonl, numbered by line from 1; lines that aren't JSON are skipped. */
|
|
@@ -779,6 +1166,17 @@ function toolCalls(transcript) {
|
|
|
779
1166
|
});
|
|
780
1167
|
return calls;
|
|
781
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
|
+
}
|
|
782
1180
|
/**
|
|
783
1181
|
* What a cell's results can be pooled on across runs: its fingerprint parts, with the context
|
|
784
1182
|
* part replaced by the context files that aren't an agent CLI's own runtime state.
|
|
@@ -798,24 +1196,42 @@ function comparableFingerprint(cell, attempts) {
|
|
|
798
1196
|
function insertRun(db, record, recorded, transcripts) {
|
|
799
1197
|
const run = (sql, ...values) => db.prepare(sql).run(...values);
|
|
800
1198
|
const { runner, summary, git } = record;
|
|
801
|
-
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);
|
|
802
1200
|
for (const env of record.environments) {
|
|
803
1201
|
run("INSERT OR IGNORE INTO environments VALUES (?, ?, ?, ?, ?)", record.runId, env.name, env.digest, env.parent, json(env.overrides));
|
|
804
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);
|
|
805
1203
|
}
|
|
1204
|
+
const envOf = new Map(record.environments.map((env) => [env.digest, env]));
|
|
806
1205
|
for (const e of record.evals) {
|
|
1206
|
+
const cellEnv = new Map(e.cells.map((c) => [c.key, c.environmentDigest ?? ""]));
|
|
807
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);
|
|
808
1208
|
for (const c of e.cells) {
|
|
809
1209
|
const p = c.fingerprintParts;
|
|
810
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));
|
|
811
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);
|
|
812
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);
|
|
1216
|
+
}
|
|
813
1217
|
for (const a of e.attempts) {
|
|
814
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);
|
|
815
|
-
|
|
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);
|
|
816
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);
|
|
817
1223
|
const transcript = transcripts.get(a.key);
|
|
818
|
-
|
|
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
|
+
}
|
|
819
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);
|
|
820
1236
|
for (const [kind, ref] of Object.entries(a.files)) {
|
|
821
1237
|
if (ref == null || Array.isArray(ref) || typeof ref.path !== "string") continue;
|
|
@@ -841,6 +1257,8 @@ const DATA_TABLES = [
|
|
|
841
1257
|
"evals",
|
|
842
1258
|
"families",
|
|
843
1259
|
"family_lift_m",
|
|
1260
|
+
"votes",
|
|
1261
|
+
"question_pairs_m",
|
|
844
1262
|
"cells",
|
|
845
1263
|
"attempts",
|
|
846
1264
|
"judgements",
|
|
@@ -849,6 +1267,7 @@ const DATA_TABLES = [
|
|
|
849
1267
|
"artifacts",
|
|
850
1268
|
"attempt_context",
|
|
851
1269
|
"tool_calls",
|
|
1270
|
+
"context_reads",
|
|
852
1271
|
"assertions",
|
|
853
1272
|
"cell_checks"
|
|
854
1273
|
];
|
|
@@ -857,7 +1276,7 @@ function removeRun(db, runId) {
|
|
|
857
1276
|
db.prepare("DELETE FROM files WHERE run_id = ?").run(runId);
|
|
858
1277
|
}
|
|
859
1278
|
function freshSchema(db) {
|
|
860
|
-
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')"));
|
|
861
1280
|
for (const o of objects) {
|
|
862
1281
|
if (o.name.startsWith("sqlite_")) continue;
|
|
863
1282
|
db.exec(`DROP ${o.type === "view" ? "VIEW" : "TABLE"} IF EXISTS "${o.name}"`);
|
|
@@ -868,7 +1287,7 @@ function freshSchema(db) {
|
|
|
868
1287
|
}
|
|
869
1288
|
function current(db) {
|
|
870
1289
|
try {
|
|
871
|
-
const rows = db.prepare("SELECT key, value FROM meta")
|
|
1290
|
+
const rows = rowsOf(db.prepare("SELECT key, value FROM meta"));
|
|
872
1291
|
const meta = Object.fromEntries(rows.map((r) => [r.key, r.value]));
|
|
873
1292
|
return meta.version === String(DB_VERSION) && meta.build === String(BUILD);
|
|
874
1293
|
} catch {
|
|
@@ -902,7 +1321,7 @@ async function sync(db, root, historyDir) {
|
|
|
902
1321
|
recorded
|
|
903
1322
|
});
|
|
904
1323
|
}
|
|
905
|
-
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]));
|
|
906
1325
|
let added = 0;
|
|
907
1326
|
let removed = 0;
|
|
908
1327
|
db.exec("BEGIN");
|
|
@@ -973,15 +1392,15 @@ async function openHistoryDb(root, historyDir, options = {}) {
|
|
|
973
1392
|
}
|
|
974
1393
|
},
|
|
975
1394
|
schema() {
|
|
976
|
-
return 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`)
|
|
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) => ({
|
|
977
1396
|
...o,
|
|
978
|
-
columns: db.prepare(`PRAGMA table_info("${o.name}")`)
|
|
1397
|
+
columns: rowsOf(db.prepare(`PRAGMA table_info("${o.name}")`)).map((c) => c.name)
|
|
979
1398
|
}));
|
|
980
1399
|
},
|
|
981
1400
|
close: () => db.close()
|
|
982
1401
|
};
|
|
983
1402
|
}
|
|
984
1403
|
//#endregion
|
|
985
|
-
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 };
|
|
986
1405
|
|
|
987
|
-
//# sourceMappingURL=db-
|
|
1406
|
+
//# sourceMappingURL=db-CdHizc4_.js.map
|