@tangle-network/agent-eval 0.216.0 → 0.217.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -57
- package/README.md +2 -2
- package/dist/adapters/http.d.ts +3 -3
- package/dist/{agent-profile-CIA2Atnt.d.ts → agent-profile-DTt8uGP9.d.ts} +5 -18
- package/dist/agent-profile-DTt8uGP9.d.ts.map +1 -0
- package/dist/{agent-profile-cell-BYc0bxsL.js → agent-profile-cell-B1V1gUZs.js} +4 -53
- package/dist/agent-profile-cell-B1V1gUZs.js.map +1 -0
- package/dist/{agent-profile-cell-BNp-Js9F.d.ts → agent-profile-cell-BcpFbNd5.d.ts} +2 -22
- package/dist/agent-profile-cell-BcpFbNd5.d.ts.map +1 -0
- package/dist/{agreement-irr-DsTURxdr.js → agreement-irr-BhAqjluA.js} +5 -5
- package/dist/agreement-irr-BhAqjluA.js.map +1 -0
- package/dist/analyst/index.d.ts +37 -170
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +17 -192
- package/dist/analyst/index.js.map +1 -1
- package/dist/{analyze-runs-3xpby3p2.js → analyze-runs-DqPJaJ4X.js} +763 -555
- package/dist/analyze-runs-DqPJaJ4X.js.map +1 -0
- package/dist/{analyze-runs-CSDAh8A7.d.ts → analyze-runs-DyeNcenW.d.ts} +18 -16
- package/dist/analyze-runs-DyeNcenW.d.ts.map +1 -0
- package/dist/authenticity/index.d.ts +0 -23
- package/dist/authenticity/index.d.ts.map +1 -1
- package/dist/authenticity/index.js +1 -34
- package/dist/authenticity/index.js.map +1 -1
- package/dist/{benchmark-command-CByl9dxG.js → benchmark-command-xQK8nOI6.js} +591 -109
- package/dist/benchmark-command-xQK8nOI6.js.map +1 -0
- package/dist/benchmarks/index.d.ts +5 -6
- package/dist/benchmarks/index.d.ts.map +1 -1
- package/dist/benchmarks/index.js +4 -4
- package/dist/benchmarks/index.js.map +1 -1
- package/dist/builder-eval/index.d.ts +3 -3
- package/dist/builder-eval/index.js +2 -2
- package/dist/builder-eval/index.js.map +1 -1
- package/dist/campaign/index.d.ts +8 -8
- package/dist/campaign/index.js +15 -15
- package/dist/{campaign-BQ-Jujuj.js → campaign-CJGkxAQ6.js} +256 -765
- package/dist/campaign-CJGkxAQ6.js.map +1 -0
- package/dist/{campaign-evidence-OcUciD-N.js → campaign-evidence-CQYw8_0H.js} +10 -18
- package/dist/{campaign-evidence-OcUciD-N.js.map → campaign-evidence-CQYw8_0H.js.map} +1 -1
- package/dist/{canonical-BsZVgBhW.js → canonical-Dq2hOQ8L.js} +2 -2
- package/dist/{canonical-BsZVgBhW.js.map → canonical-Dq2hOQ8L.js.map} +1 -1
- package/dist/cell-spend-DEWR3nj-.js +90 -0
- package/dist/cell-spend-DEWR3nj-.js.map +1 -0
- package/dist/{chat-client-DthPOYGd.js → chat-client-ldqxYYTN.js} +2 -2
- package/dist/{chat-client-DthPOYGd.js.map → chat-client-ldqxYYTN.js.map} +1 -1
- package/dist/{chat-json-call-BrKsyspg.js → chat-json-call-DavzexSp.js} +3 -2
- package/dist/chat-json-call-DavzexSp.js.map +1 -0
- package/dist/{claim-BXcZw-jo.js → claim-BPVuyHuy.js} +4 -4
- package/dist/claim-BPVuyHuy.js.map +1 -0
- package/dist/cli.js +113 -12
- package/dist/cli.js.map +1 -1
- package/dist/{client-BzL9niqi.d.ts → client-hwo3cJjR.d.ts} +3 -16
- package/dist/client-hwo3cJjR.d.ts.map +1 -0
- package/dist/{cluster-bootstrap-B3JywQQn.js → cluster-bootstrap-DEwwhl0C.js} +3 -3
- package/dist/{cluster-bootstrap-B3JywQQn.js.map → cluster-bootstrap-DEwwhl0C.js.map} +1 -1
- package/dist/{produced-state-ZCtDBxAE.js → completion-verifier-B_jw6C9p.js} +9 -64
- package/dist/completion-verifier-B_jw6C9p.js.map +1 -0
- package/dist/contract/index.d.ts +13 -13
- package/dist/contract/index.js +1041 -1473
- package/dist/contract/index.js.map +1 -1
- package/dist/{cost-ledger-D2FnJPBF.js → cost-ledger-D0352Z4d.js} +832 -817
- package/dist/cost-ledger-D0352Z4d.js.map +1 -0
- package/dist/{cost-ledger-CO7UyEcQ.d.ts → cost-ledger-Jk62OBfF.d.ts} +12 -47
- package/dist/cost-ledger-Jk62OBfF.d.ts.map +1 -0
- package/dist/dataset-DQqhOCPt.d.ts.map +1 -1
- package/dist/{default-registry-Cn1LQ2Ve.js → default-registry-ClYjq3QE.js} +8 -11
- package/dist/default-registry-ClYjq3QE.js.map +1 -0
- package/dist/{default-registry-BrWh62zf.d.ts → default-registry-DXgLmoDI.d.ts} +7 -50
- package/dist/default-registry-DXgLmoDI.d.ts.map +1 -0
- package/dist/{define-agent-eval-Ch3MWX6k.js → define-agent-eval-BDxNlP3D.js} +10 -10
- package/dist/define-agent-eval-BDxNlP3D.js.map +1 -0
- package/dist/{define-agent-eval-CEWkX5wZ.d.ts → define-agent-eval-BIkH_gAR.d.ts} +9 -9
- package/dist/define-agent-eval-BIkH_gAR.d.ts.map +1 -0
- package/dist/{descriptive-CnU8Yq29.js → descriptive-CVNy48rR.js} +2 -2
- package/dist/{descriptive-CnU8Yq29.js.map → descriptive-CVNy48rR.js.map} +1 -1
- package/dist/diagnosis/index.d.ts +4 -14
- package/dist/diagnosis/index.d.ts.map +1 -1
- package/dist/diagnosis/index.js +67 -28
- package/dist/diagnosis/index.js.map +1 -1
- package/dist/{dspy-rlm-engine-D-KX_e64.js → dspy-rlm-engine-DhdCr1Dc.js} +5 -10
- package/dist/dspy-rlm-engine-DhdCr1Dc.js.map +1 -0
- package/dist/{emitter-HcCmFQl_.d.ts → emitter-DABYYTcH.d.ts} +5 -5
- package/dist/emitter-DABYYTcH.d.ts.map +1 -0
- package/dist/emitter-DbMXUIVP.js.map +1 -1
- package/dist/{engine-C_zNWfM8.d.ts → engine-BvZ0R-36.d.ts} +18 -22
- package/dist/engine-BvZ0R-36.d.ts.map +1 -0
- package/dist/{equal-terms-Blx9Zk5I.js → equal-terms-DbPGcVtI.js} +2 -2
- package/dist/equal-terms-DbPGcVtI.js.map +1 -0
- package/dist/{errors-Dngq5h35.js → errors-BcOs5MKW.js} +6 -8
- package/dist/{errors-Dngq5h35.js.map → errors-BcOs5MKW.js.map} +1 -1
- package/dist/{eval-campaign-4byTtqrf.js → eval-campaign-BLEfBGbA.js} +6 -6
- package/dist/{eval-campaign-4byTtqrf.js.map → eval-campaign-BLEfBGbA.js.map} +1 -1
- package/dist/{evaluation-Cn2dRZIz.d.ts → evaluation-jTjC_QQD.d.ts} +8 -8
- package/dist/evaluation-jTjC_QQD.d.ts.map +1 -0
- package/dist/evaluation.d.ts +2 -2
- package/dist/evaluation.js +1 -1
- package/dist/evaluation.js.map +1 -1
- package/dist/{exact-types-CD0lf5Qd.d.ts → exact-types-CflbJ9f3.d.ts} +2 -2
- package/dist/{exact-types-CD0lf5Qd.d.ts.map → exact-types-CflbJ9f3.d.ts.map} +1 -1
- package/dist/{exec-ChJ6d5if.js → exec-CpbtOXVt.js} +2 -24
- package/dist/{exec-ChJ6d5if.js.map → exec-CpbtOXVt.js.map} +1 -1
- package/dist/execution-tracks-CpgFPpS5.js.map +1 -1
- package/dist/experiment/index.d.ts +331 -33
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +303 -101
- package/dist/experiment/index.js.map +1 -1
- package/dist/{exporters-X4xwla8A.js → exporters-Cl6IeNAu.js} +3 -3
- package/dist/exporters-Cl6IeNAu.js.map +1 -0
- package/dist/{exporters-ChTnR90l.d.ts → exporters-Dk3oEbK_.d.ts} +2 -4
- package/dist/{exporters-ChTnR90l.d.ts.map → exporters-Dk3oEbK_.d.ts.map} +1 -1
- package/dist/{external-optimizer-process-nnsY5D_4.js → external-optimizer-process-KVFGvYX1.js} +4 -3
- package/dist/external-optimizer-process-KVFGvYX1.js.map +1 -0
- package/dist/{external-optimizer-subprocess-DcerlZSG.js → external-optimizer-subprocess-XIHBOSKt.js} +551 -553
- package/dist/external-optimizer-subprocess-XIHBOSKt.js.map +1 -0
- package/dist/{extract-usage-BrnzRJ6H.js → extract-usage-BZLU01kR.js} +2 -23
- package/dist/{extract-usage-BrnzRJ6H.js.map → extract-usage-BZLU01kR.js.map} +1 -1
- package/dist/{failure-cluster-CbgEDcFJ.d.ts → failure-cluster-DN0t63Z0.d.ts} +4 -43
- package/dist/failure-cluster-DN0t63Z0.d.ts.map +1 -0
- package/dist/{failure-taxonomy-CjabTATj.js → failure-taxonomy-Bx5oWqaW.js} +2 -19
- package/dist/{failure-taxonomy-CjabTATj.js.map → failure-taxonomy-Bx5oWqaW.js.map} +1 -1
- package/dist/{feedback-trajectory-DkaDj0dj.d.ts → feedback-trajectory-BWmhRBGu.d.ts} +8 -13
- package/dist/feedback-trajectory-BWmhRBGu.d.ts.map +1 -0
- package/dist/{semantic-concept-judge-zQBG9hHU.js → findings-store-BMVQtEsm.js} +13 -255
- package/dist/findings-store-BMVQtEsm.js.map +1 -0
- package/dist/fuzz.d.ts +20 -63
- package/dist/fuzz.d.ts.map +1 -1
- package/dist/fuzz.js +62 -108
- package/dist/fuzz.js.map +1 -1
- package/dist/{hf-dataset-BR2yhuNn.js → hf-dataset-D9f7-oX7.js} +4 -24
- package/dist/hf-dataset-D9f7-oX7.js.map +1 -0
- package/dist/hosted/index.d.ts +2 -2
- package/dist/hosted/index.js +2 -2
- package/dist/{index-DHKEAv3s.d.ts → index-9jJ2fKSX.d.ts} +2 -64
- package/dist/index-9jJ2fKSX.d.ts.map +1 -0
- package/dist/{index-oQ4aHziK.d.ts → index-BLGqZ81N.d.ts} +11 -16
- package/dist/{index-oQ4aHziK.d.ts.map → index-BLGqZ81N.d.ts.map} +1 -1
- package/dist/{index-DlH0Y9gI.d.ts → index-BiT6RtNH.d.ts} +31 -43
- package/dist/index-BiT6RtNH.d.ts.map +1 -0
- package/dist/{index-Ch9VxCpK.d.ts → index-CX-GAUpw.d.ts} +4 -8
- package/dist/index-CX-GAUpw.d.ts.map +1 -0
- package/dist/{index-CPJJr98o.d.ts → index-CiRwLv2R.d.ts} +5 -68
- package/dist/index-CiRwLv2R.d.ts.map +1 -0
- package/dist/{index-NvGBiO8H.d.ts → index-ZuWx52WG.d.ts} +266 -495
- package/dist/index-ZuWx52WG.d.ts.map +1 -0
- package/dist/index.d.ts +2256 -2165
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +514 -1192
- package/dist/index.js.map +1 -1
- package/dist/{integrity-BV1ZDf42.js → integrity-DOd9Q86O.js} +7 -12
- package/dist/integrity-DOd9Q86O.js.map +1 -0
- package/dist/{integrity-BvnVARVl.js → integrity-W4CADcFc.js} +3 -7
- package/dist/{integrity-BvnVARVl.js.map → integrity-W4CADcFc.js.map} +1 -1
- package/dist/{integrity-CCAxGVK6.d.ts → integrity-_qgZLA5p.d.ts} +4 -6
- package/dist/{integrity-CCAxGVK6.d.ts.map → integrity-_qgZLA5p.d.ts.map} +1 -1
- package/dist/{internal-CRHwS9iz.js → internal-BTK91Bqt.js} +3 -3
- package/dist/{internal-CRHwS9iz.js.map → internal-BTK91Bqt.js.map} +1 -1
- package/dist/interval-Dq9gt7jx.js +219 -0
- package/dist/interval-Dq9gt7jx.js.map +1 -0
- package/dist/interval-ohuOJurX.d.ts +47 -0
- package/dist/interval-ohuOJurX.d.ts.map +1 -0
- package/dist/{journal-DvKCvjty.js → journal-CR4QikYp.js} +110 -110
- package/dist/journal-CR4QikYp.js.map +1 -0
- package/dist/json-BhdsJaOQ.js +111 -0
- package/dist/json-BhdsJaOQ.js.map +1 -0
- package/dist/{judge-calibration-N44V04Se.js → judge-calibration-BkXMIWA4.js} +3 -3
- package/dist/{judge-calibration-N44V04Se.js.map → judge-calibration-BkXMIWA4.js.map} +1 -1
- package/dist/{judge-gate-B1qYnkpi.js → judge-gate-Co5tuh57.js} +4 -27
- package/dist/judge-gate-Co5tuh57.js.map +1 -0
- package/dist/{judge-gate-DNcUrRFA.d.ts → judge-gate-DsL0yFcb.d.ts} +9 -10
- package/dist/judge-gate-DsL0yFcb.d.ts.map +1 -0
- package/dist/{kind-factory-CbZ-6tvu.js → kind-factory-Gy4fXixd.js} +88 -17
- package/dist/kind-factory-Gy4fXixd.js.map +1 -0
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +4 -4
- package/dist/{ledger-core-B2hahzrt.js → ledger-core-DrJhbms9.js} +5 -84
- package/dist/ledger-core-DrJhbms9.js.map +1 -0
- package/dist/{llm-client-DQveoxSM.js → llm-client-BshCREn6.js} +90 -219
- package/dist/llm-client-BshCREn6.js.map +1 -0
- package/dist/{llm-judge-PXV7Xljl.js → llm-judge-C8jMTNNG.js} +501 -931
- package/dist/llm-judge-C8jMTNNG.js.map +1 -0
- package/dist/matrix/index.d.ts +4 -4
- package/dist/matrix/index.js +3 -2
- package/dist/{matrix-_BV9-Lk5.js → matrix-B8l-Nsxd.js} +7 -96
- package/dist/matrix-B8l-Nsxd.js.map +1 -0
- package/dist/{matrix-CHMiebFx.d.ts → matrix-DHe-dwVJ.d.ts} +10 -19
- package/dist/matrix-DHe-dwVJ.d.ts.map +1 -0
- package/dist/{paired-tests-jbwPdSz5.js → mean-BbA_JCzW.js} +45 -5
- package/dist/mean-BbA_JCzW.js.map +1 -0
- package/dist/meta-eval/index.d.ts +6 -6
- package/dist/meta-eval/index.js +10 -10
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/metrics-BKaPBtIG.js.map +1 -1
- package/dist/mint-BRZXuwRi.d.ts +81 -0
- package/dist/mint-BRZXuwRi.d.ts.map +1 -0
- package/dist/{mint-Csor1BLJ.js → mint-zszyYlpA.js} +4 -4
- package/dist/{mint-Csor1BLJ.js.map → mint-zszyYlpA.js.map} +1 -1
- package/dist/{multi-layer-verifier-BUaQ4C17.d.ts → multi-layer-verifier-DEgMUk6v.d.ts} +2 -2
- package/dist/{multi-layer-verifier-BUaQ4C17.d.ts.map → multi-layer-verifier-DEgMUk6v.d.ts.map} +1 -1
- package/dist/{multiplicity-D9cjmStq.js → multiplicity-Sg0U7h8j.js} +2 -2
- package/dist/{multiplicity-D9cjmStq.js.map → multiplicity-Sg0U7h8j.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +1 -23
- package/dist/multishot/golden/index.d.ts.map +1 -1
- package/dist/multishot/golden/index.js +5 -8
- package/dist/multishot/golden/index.js.map +1 -1
- package/dist/multishot/index.d.ts +3 -12
- package/dist/multishot/index.d.ts.map +1 -1
- package/dist/multishot/index.js +4 -3
- package/dist/multishot/index.js.map +1 -1
- package/dist/nonnegative-number-DvdMxg_f.js +9 -0
- package/dist/nonnegative-number-DvdMxg_f.js.map +1 -0
- package/dist/openapi.json +114 -10
- package/dist/{otel-spans-C8YIJWy1.js → otel-spans-CdN909k1.js} +3 -3
- package/dist/{otel-spans-C8YIJWy1.js.map → otel-spans-CdN909k1.js.map} +1 -1
- package/dist/{paired-arms-DzKn0TfY.js → paired-arms-Ct4LTKc1.js} +32 -9
- package/dist/paired-arms-Ct4LTKc1.js.map +1 -0
- package/dist/{paired-binary-Q36bhn2R.js → paired-binary-B_nejA44.js} +3 -36
- package/dist/paired-binary-B_nejA44.js.map +1 -0
- package/dist/{paired-promotion-decision-DPKz8ZnF.d.ts → paired-promotion-decision-CQMJ5xGN.d.ts} +2 -34
- package/dist/paired-promotion-decision-CQMJ5xGN.d.ts.map +1 -0
- package/dist/{paired-promotion-decision-BN6IQTiu.js → paired-promotion-decision-D0SHb-ZL.js} +3 -3
- package/dist/{paired-promotion-decision-BN6IQTiu.js.map → paired-promotion-decision-D0SHb-ZL.js.map} +1 -1
- package/dist/{search-kernel-BztlERLv.js → pareto-BzsxidFD.js} +883 -861
- package/dist/pareto-BzsxidFD.js.map +1 -0
- package/dist/pipelines/index.d.ts +16 -19
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +4 -68
- package/dist/pipelines/index.js.map +1 -1
- package/dist/{power-and-mde-fK5Qocwo.js → power-and-mde-N5nU4_Ly.js} +3 -3
- package/dist/{power-and-mde-fK5Qocwo.js.map → power-and-mde-N5nU4_Ly.js.map} +1 -1
- package/dist/predicate-FdKmElA_.js +38 -0
- package/dist/predicate-FdKmElA_.js.map +1 -0
- package/dist/{prime-protocol-DcAK9pC8.js → prime-protocol-BFgGrEMP.js} +3 -3
- package/dist/prime-protocol-BFgGrEMP.js.map +1 -0
- package/dist/{prime-protocol-CEE4BR9N.d.ts → prime-protocol-BWG2DQIk.d.ts} +4 -22
- package/dist/prime-protocol-BWG2DQIk.d.ts.map +1 -0
- package/dist/profile-cell.d.ts +2 -2
- package/dist/profile-cell.js +2 -2
- package/dist/{release-confidence-BK2QCB5M.d.ts → promotion-gate-DaY95yU6.d.ts} +105 -106
- package/dist/promotion-gate-DaY95yU6.d.ts.map +1 -0
- package/dist/{promotion-policy-CWW35UWq.js → promotion-policy-6A8osGr_.js} +4 -4
- package/dist/{promotion-policy-CWW35UWq.js.map → promotion-policy-6A8osGr_.js.map} +1 -1
- package/dist/{proposal-findings-BZiMTzAF.js → proposal-findings-BbWidvUk.js} +3 -3
- package/dist/proposal-findings-BbWidvUk.js.map +1 -0
- package/dist/{query-B1D1qp2Z.js → query-B_RZ36an.js} +5 -5
- package/dist/query-B_RZ36an.js.map +1 -0
- package/dist/{query-DK1nWcmp.d.ts → query-Cmv_U8vf.d.ts} +4 -24
- package/dist/{query-DK1nWcmp.d.ts.map → query-Cmv_U8vf.d.ts.map} +1 -1
- package/dist/{random-Dn5fPWkt.js → random-DDDcC7YU.js} +2 -2
- package/dist/{random-Dn5fPWkt.js.map → random-DDDcC7YU.js.map} +1 -1
- package/dist/{raw-provider-sink-rB2DYxr6.js → raw-provider-sink-75w4FWBj.js} +2 -2
- package/dist/{raw-provider-sink-rB2DYxr6.js.map → raw-provider-sink-75w4FWBj.js.map} +1 -1
- package/dist/{redact-Cveoq6fJ.d.ts → redact-DXdlFb_U.d.ts} +4 -21
- package/dist/redact-DXdlFb_U.d.ts.map +1 -0
- package/dist/{redact-Dk1ZdJEm.js → redact-mtkTiJVk.js} +92 -98
- package/dist/redact-mtkTiJVk.js.map +1 -0
- package/dist/{registry-JYfPxcVz.d.ts → registry-ssNoHzwD.d.ts} +5 -5
- package/dist/{registry-JYfPxcVz.d.ts.map → registry-ssNoHzwD.d.ts.map} +1 -1
- package/dist/{release-confidence-Dbe9AS_X.js → release-confidence-CYIFH-fp.js} +6 -11
- package/dist/release-confidence-CYIFH-fp.js.map +1 -0
- package/dist/{report-command-y8H6RSX8.js → render-C-w2EZ6p.js} +331 -554
- package/dist/render-C-w2EZ6p.js.map +1 -0
- package/dist/reporting-html-Kvlc8oMt.js +100 -0
- package/dist/reporting-html-Kvlc8oMt.js.map +1 -0
- package/dist/reporting.d.ts +6 -6
- package/dist/reporting.js +8 -8
- package/dist/{researcher-f6mZhh58.d.ts → researcher-0ABVIdGa.d.ts} +9 -9
- package/dist/{researcher-f6mZhh58.d.ts.map → researcher-0ABVIdGa.d.ts.map} +1 -1
- package/dist/reward-DrZ71vnf.d.ts +55 -0
- package/dist/reward-DrZ71vnf.d.ts.map +1 -0
- package/dist/{reward-hacking-BFcQgkux.js → reward-hacking-ByuETaIb.js} +3 -3
- package/dist/{reward-hacking-BFcQgkux.js.map → reward-hacking-ByuETaIb.js.map} +1 -1
- package/dist/{reward-hacking-DHA7c1l8.d.ts → reward-hacking-E52wq86n.d.ts} +5 -18
- package/dist/reward-hacking-E52wq86n.d.ts.map +1 -0
- package/dist/reward-nw2xZGZG.js.map +1 -1
- package/dist/rl.d.ts +117 -295
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +27 -747
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +5 -4
- package/dist/rollout/index.js +7 -8
- package/dist/{rollout-D9bKKBnZ.js → rollout-D6C50mfA.js} +88 -13
- package/dist/rollout-D6C50mfA.js.map +1 -0
- package/dist/round-decimal-COrKglMh.js +10 -0
- package/dist/round-decimal-COrKglMh.js.map +1 -0
- package/dist/{rubric-predictive-validity-BsgkBfT0.js → rubric-predictive-validity-D3_oI72N.js} +3 -3
- package/dist/{rubric-predictive-validity-BsgkBfT0.js.map → rubric-predictive-validity-D3_oI72N.js.map} +1 -1
- package/dist/{rubric-predictive-validity-2SgHxoa5.d.ts → rubric-predictive-validity-DiwT8PbL.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-2SgHxoa5.d.ts.map → rubric-predictive-validity-DiwT8PbL.d.ts.map} +1 -1
- package/dist/{run-record-D1Hw-Jml.d.ts → run-record-CaxbLq6Y.d.ts} +5 -11
- package/dist/run-record-CaxbLq6Y.d.ts.map +1 -0
- package/dist/{run-record-ES07wfz9.js → run-record-CysKLB93.js} +3 -5
- package/dist/run-record-CysKLB93.js.map +1 -0
- package/dist/{run-record-DlTZ_lqe.js → run-record-DhEJgoPz.js} +4 -4
- package/dist/{run-record-DlTZ_lqe.js.map → run-record-DhEJgoPz.js.map} +1 -1
- package/dist/sandbox-harness-BlSOu4LX.d.ts.map +1 -1
- package/dist/{schema-CSf6qWgZ.js → schema-Bt2vLFm3.js} +2 -14
- package/dist/schema-Bt2vLFm3.js.map +1 -0
- package/dist/schema-C-ziyJD7.d.ts.map +1 -1
- package/dist/{schema-2g7trUwH.d.ts → schema-D6EVKzTB.d.ts} +4 -5
- package/dist/schema-D6EVKzTB.d.ts.map +1 -0
- package/dist/{schema-BuiujZ-g.js → schema-DxcKTzbi.js} +2 -2
- package/dist/schema-DxcKTzbi.js.map +1 -0
- package/dist/search/index.d.ts +39 -53
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/{search-kernel-CpcKH5Ih.d.ts → search-kernel-DxqjBxA-.d.ts} +18 -31
- package/dist/search-kernel-DxqjBxA-.d.ts.map +1 -0
- package/dist/{search-ledger-d7V8o9Lk.js → search-ledger-TUvB5gWH.js} +189 -199
- package/dist/search-ledger-TUvB5gWH.js.map +1 -0
- package/dist/{search-ledger-file-BqOo-bVo.js → search-ledger-file-UKCO2r8a.js} +4 -4
- package/dist/search-ledger-file-UKCO2r8a.js.map +1 -0
- package/dist/search-ledger-types-p2xKfiDJ.d.ts.map +1 -1
- package/dist/{search-shipper-er4pK5_Y.js → search-shipper-Cw2z3-td.js} +4 -4
- package/dist/search-shipper-Cw2z3-td.js.map +1 -0
- package/dist/{search-summary-CBvz3u_S.js → search-summary-DQIvJsSB.js} +5 -5
- package/dist/{search-summary-CBvz3u_S.js.map → search-summary-DQIvJsSB.js.map} +1 -1
- package/dist/{sequential-CzK5DarL.js → sequential-BVv1sjsw.js} +2 -32
- package/dist/{sequential-CzK5DarL.js.map → sequential-BVv1sjsw.js.map} +1 -1
- package/dist/{sequential-D-1PPCmM.js → sequential-CimQrbjv.js} +5 -5
- package/dist/sequential-CimQrbjv.js.map +1 -0
- package/dist/{sequential-BhsrMupG.d.ts → sequential-KwGspfeR.d.ts} +2 -9
- package/dist/{sequential-BhsrMupG.d.ts.map → sequential-KwGspfeR.d.ts.map} +1 -1
- package/dist/{sequential-eprocess-D1jKoihe.js → sequential-eprocess-DodI6RoF.js} +2 -2
- package/dist/{sequential-eprocess-D1jKoihe.js.map → sequential-eprocess-DodI6RoF.js.map} +1 -1
- package/dist/{server-DbcC7xMl.js → server-DoVbqqtJ.js} +101 -101
- package/dist/server-DoVbqqtJ.js.map +1 -0
- package/dist/{single-run-lock-fVu3MZWH.js → single-run-lock-U58yf8N6.js} +2 -2
- package/dist/{single-run-lock-fVu3MZWH.js.map → single-run-lock-U58yf8N6.js.map} +1 -1
- package/dist/{skillopt-optimization-method-CCtzralq.js → skillopt-optimization-method-kyL94-ri.js} +428 -91
- package/dist/skillopt-optimization-method-kyL94-ri.js.map +1 -0
- package/dist/{spans-D9_ehFuk.d.ts → spans-CVngGij3.d.ts} +2 -2
- package/dist/{spans-D9_ehFuk.d.ts.map → spans-CVngGij3.d.ts.map} +1 -1
- package/dist/{statistical-heldout-1Gbmex7v.js → statistical-heldout-Bksv92Th.js} +3 -3
- package/dist/statistical-heldout-Bksv92Th.js.map +1 -0
- package/dist/{statistical-heldout-BeR4bOdg.d.ts → statistical-heldout-C9AbgREN.d.ts} +8 -67
- package/dist/statistical-heldout-C9AbgREN.d.ts.map +1 -0
- package/dist/{steps-Bg5-KVx1.d.ts → steps-DlepJPwD.d.ts} +2 -56
- package/dist/steps-DlepJPwD.d.ts.map +1 -0
- package/dist/{store-C4avFjIi.d.ts → store-B3nWRy3B.d.ts} +2 -2
- package/dist/{store-C4avFjIi.d.ts.map → store-B3nWRy3B.d.ts.map} +1 -1
- package/dist/{store-otlp-DtB4Slsr.js → store-otlp-BteDAbHK.js} +135 -132
- package/dist/store-otlp-BteDAbHK.js.map +1 -0
- package/dist/{store-tool-spans-fZIigrpP.js → store-tool-spans-D5l_OfTJ.js} +9 -9
- package/dist/store-tool-spans-D5l_OfTJ.js.map +1 -0
- package/dist/{store-tool-spans-DR1SrCLK.d.ts → store-tool-spans-DZS0HWVf.d.ts} +157 -165
- package/dist/store-tool-spans-DZS0HWVf.d.ts.map +1 -0
- package/dist/storyboard/index.d.ts +4 -11
- package/dist/storyboard/index.d.ts.map +1 -1
- package/dist/storyboard/index.js +21 -19
- package/dist/storyboard/index.js.map +1 -1
- package/dist/{summary-report-DtdRucM0.js → summary-report-BsXJoYX5.js} +588 -598
- package/dist/summary-report-BsXJoYX5.js.map +1 -0
- package/dist/{summary-report-C-CtItCN.d.ts → summary-report-DM7tlml1.d.ts} +16 -20
- package/dist/summary-report-DM7tlml1.d.ts.map +1 -0
- package/dist/supervisor-run/index.d.ts +189 -153
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +58 -450
- package/dist/supervisor-run/index.js.map +1 -1
- package/dist/{systemone-CpTLAlqb.d.ts → systemone-Bp_Ac0p1.d.ts} +6 -6
- package/dist/{systemone-CpTLAlqb.d.ts.map → systemone-Bp_Ac0p1.d.ts.map} +1 -1
- package/dist/systemone-protocol.js +1 -1
- package/dist/{systemone-review-B_yo1xsd.d.ts → systemone-review-CwE6JGIp.d.ts} +2 -2
- package/dist/{systemone-review-B_yo1xsd.d.ts.map → systemone-review-CwE6JGIp.d.ts.map} +1 -1
- package/dist/{systemone-review-BZWfrtq1.js → systemone-review-DzdOJ8I6.js} +3 -3
- package/dist/{systemone-review-BZWfrtq1.js.map → systemone-review-DzdOJ8I6.js.map} +1 -1
- package/dist/systemone.d.ts +5 -5
- package/dist/systemone.js +5 -5
- package/dist/systemone.js.map +1 -1
- package/dist/{task-failure-attributes-DngaLdE4.js → task-failure-attributes-BMsblaDh.js} +3 -3
- package/dist/task-failure-attributes-BMsblaDh.js.map +1 -0
- package/dist/{terminal-record-BHocwFw1.js → terminal-record-78g6E4vh.js} +17 -13
- package/dist/terminal-record-78g6E4vh.js.map +1 -0
- package/dist/{tool-groups-mcxOXVlb.d.ts → tool-groups-DyNz2JZ_.d.ts} +3 -3
- package/dist/tool-groups-DyNz2JZ_.d.ts.map +1 -0
- package/dist/{tool-waste-Wi4g6Ekb.d.ts → tool-waste-CkjzWmeY.d.ts} +53 -56
- package/dist/tool-waste-CkjzWmeY.d.ts.map +1 -0
- package/dist/{tool-waste-D52PqU9Q.js → tool-waste-DLsjS_p-.js} +5 -5
- package/dist/{tool-waste-D52PqU9Q.js.map → tool-waste-DLsjS_p-.js.map} +1 -1
- package/dist/{trace-questions-DG7nqLQ7.d.ts → trace-questions-xxwgsuMi.d.ts} +5 -10
- package/dist/{trace-questions-DG7nqLQ7.d.ts.map → trace-questions-xxwgsuMi.d.ts.map} +1 -1
- package/dist/trace-repair/index.d.ts +15 -212
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +865 -987
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +76 -86
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +13 -13
- package/dist/traces.js.map +1 -1
- package/dist/trajectory-replay/index.d.ts +3 -117
- package/dist/trajectory-replay/index.d.ts.map +1 -1
- package/dist/trajectory-replay/index.js +98 -56
- package/dist/trajectory-replay/index.js.map +1 -1
- package/dist/{tree-rXLW3M_4.js → tree-BGRglkKd.js} +2355 -2414
- package/dist/tree-BGRglkKd.js.map +1 -0
- package/dist/{types-B3jzCp0p.js → types-BXgASBCL.js} +2 -2
- package/dist/{types-B3jzCp0p.js.map → types-BXgASBCL.js.map} +1 -1
- package/dist/{types-oKRhQAde.d.ts → types-CW8ewATZ.d.ts} +5 -114
- package/dist/types-CW8ewATZ.d.ts.map +1 -0
- package/dist/{types-BqkVmHfv.d.ts → types-CmXY0PQf.d.ts} +2 -4
- package/dist/types-CmXY0PQf.d.ts.map +1 -0
- package/dist/{types-DBZ7keha.d.ts → types-D-mgRzlh.d.ts} +9 -72
- package/dist/types-D-mgRzlh.d.ts.map +1 -0
- package/dist/{types-B4C5nFw6.d.ts → types-D8GhJoHk.d.ts} +79 -75
- package/dist/types-D8GhJoHk.d.ts.map +1 -0
- package/dist/{types-IXD2HJzu.js → types-DqFMNTgK.js} +2 -4
- package/dist/types-DqFMNTgK.js.map +1 -0
- package/dist/{types-CfZMIzB_.d.ts → types-DtMbFw6U.d.ts} +3 -3
- package/dist/{types-CfZMIzB_.d.ts.map → types-DtMbFw6U.d.ts.map} +1 -1
- package/dist/{verdict-DhPoXApk.js → verdict-BGQmxQ8A.js} +3 -3
- package/dist/verdict-BGQmxQ8A.js.map +1 -0
- package/dist/{verdict-E4eRNf7-.d.ts → verdict-C24NELtN.d.ts} +2 -15
- package/dist/{verdict-E4eRNf7-.d.ts.map → verdict-C24NELtN.d.ts.map} +1 -1
- package/dist/{verdict-cache-BQEsVy9n.js → verdict-cache-CL_7tePD.js} +2 -2
- package/dist/verdict-cache-CL_7tePD.js.map +1 -0
- package/dist/wire/index.d.ts +32 -411
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +2 -2
- package/docs/changes/jev-evidence-review.md +1 -1
- package/docs/changes/jev-product-adoption.md +1 -1
- package/docs/changes/jev-recorded-evidence.md +1 -1
- package/docs/design/mlbenchmarks-book-review.md +1 -1
- package/docs/design/mlbenchmarks-review/probes.mts +23 -31
- package/docs/design/statistics-decisions.md +17 -17
- package/docs/design.md +1 -1
- package/docs/evaluation-integrity.md +1 -1
- package/docs/experiment.md +1 -1
- package/docs/proofs/campaign-attempt-retention-20261001/README.md +2 -2
- package/docs/public-api.md +138 -529
- package/docs/rollout.md +1 -1
- package/docs/trace-repair-admission.md +1 -1
- package/docs/wire-protocol.md +1 -1
- package/package.json +1 -1
- package/dist/active-curriculum-B_Lc9kfO.js +0 -61
- package/dist/active-curriculum-B_Lc9kfO.js.map +0 -1
- package/dist/agent-profile-CIA2Atnt.d.ts.map +0 -1
- package/dist/agent-profile-cell-BNp-Js9F.d.ts.map +0 -1
- package/dist/agent-profile-cell-BYc0bxsL.js.map +0 -1
- package/dist/agreement-irr-DsTURxdr.js.map +0 -1
- package/dist/analyze-runs-3xpby3p2.js.map +0 -1
- package/dist/analyze-runs-CSDAh8A7.d.ts.map +0 -1
- package/dist/ast-DJ6Bc7ab.js +0 -558
- package/dist/ast-DJ6Bc7ab.js.map +0 -1
- package/dist/ast-hI-vjW6J.d.ts +0 -457
- package/dist/ast-hI-vjW6J.d.ts.map +0 -1
- package/dist/baseline-Dm8966du.js +0 -259
- package/dist/baseline-Dm8966du.js.map +0 -1
- package/dist/benchmark-BywPeAUo.js +0 -562
- package/dist/benchmark-BywPeAUo.js.map +0 -1
- package/dist/benchmark-command-CByl9dxG.js.map +0 -1
- package/dist/campaign-BQ-Jujuj.js.map +0 -1
- package/dist/chat-json-call-BrKsyspg.js.map +0 -1
- package/dist/claim-BXcZw-jo.js.map +0 -1
- package/dist/claude-jsonl-dZir12m6.js +0 -86
- package/dist/claude-jsonl-dZir12m6.js.map +0 -1
- package/dist/client-BzL9niqi.d.ts.map +0 -1
- package/dist/cost-ledger-CO7UyEcQ.d.ts.map +0 -1
- package/dist/cost-ledger-D2FnJPBF.js.map +0 -1
- package/dist/counterfactual-CPaWN99-.d.ts +0 -60
- package/dist/counterfactual-CPaWN99-.d.ts.map +0 -1
- package/dist/counterfactual-DtMWvn7D.js +0 -98
- package/dist/counterfactual-DtMWvn7D.js.map +0 -1
- package/dist/default-registry-BrWh62zf.d.ts.map +0 -1
- package/dist/default-registry-Cn1LQ2Ve.js.map +0 -1
- package/dist/define-agent-eval-CEWkX5wZ.d.ts.map +0 -1
- package/dist/define-agent-eval-Ch3MWX6k.js.map +0 -1
- package/dist/dspy-rlm-engine-D-KX_e64.js.map +0 -1
- package/dist/effect-sizes-DiH8MGOH.js +0 -82
- package/dist/effect-sizes-DiH8MGOH.js.map +0 -1
- package/dist/emitter-HcCmFQl_.d.ts.map +0 -1
- package/dist/engine-C_zNWfM8.d.ts.map +0 -1
- package/dist/equal-terms-Blx9Zk5I.js.map +0 -1
- package/dist/evaluation-Cn2dRZIz.d.ts.map +0 -1
- package/dist/exporters-X4xwla8A.js.map +0 -1
- package/dist/external-optimizer-process-nnsY5D_4.js.map +0 -1
- package/dist/external-optimizer-subprocess-DcerlZSG.js.map +0 -1
- package/dist/failure-cluster-CbgEDcFJ.d.ts.map +0 -1
- package/dist/feedback-trajectory-DkaDj0dj.d.ts.map +0 -1
- package/dist/hf-dataset-BR2yhuNn.js.map +0 -1
- package/dist/index-CPJJr98o.d.ts.map +0 -1
- package/dist/index-Ch9VxCpK.d.ts.map +0 -1
- package/dist/index-DHKEAv3s.d.ts.map +0 -1
- package/dist/index-DlH0Y9gI.d.ts.map +0 -1
- package/dist/index-NvGBiO8H.d.ts.map +0 -1
- package/dist/integrity-BV1ZDf42.js.map +0 -1
- package/dist/journal-DvKCvjty.js.map +0 -1
- package/dist/judge-gate-B1qYnkpi.js.map +0 -1
- package/dist/judge-gate-DNcUrRFA.d.ts.map +0 -1
- package/dist/kind-factory-CbZ-6tvu.js.map +0 -1
- package/dist/ledger-core-B2hahzrt.js.map +0 -1
- package/dist/llm-client-DQveoxSM.js.map +0 -1
- package/dist/llm-judge-PXV7Xljl.js.map +0 -1
- package/dist/matrix-CHMiebFx.d.ts.map +0 -1
- package/dist/matrix-_BV9-Lk5.js.map +0 -1
- package/dist/mint-DCGoBYhB.d.ts +0 -155
- package/dist/mint-DCGoBYhB.d.ts.map +0 -1
- package/dist/normal-DsJZtrJc.js +0 -25
- package/dist/normal-DsJZtrJc.js.map +0 -1
- package/dist/paired-arms-DzKn0TfY.js.map +0 -1
- package/dist/paired-binary-Q36bhn2R.js.map +0 -1
- package/dist/paired-promotion-decision-DPKz8ZnF.d.ts.map +0 -1
- package/dist/paired-tests-jbwPdSz5.js.map +0 -1
- package/dist/prime-protocol-CEE4BR9N.d.ts.map +0 -1
- package/dist/prime-protocol-DcAK9pC8.js.map +0 -1
- package/dist/produced-state-ZCtDBxAE.js.map +0 -1
- package/dist/proposal-findings-BZiMTzAF.js.map +0 -1
- package/dist/query-B1D1qp2Z.js.map +0 -1
- package/dist/redact-Cveoq6fJ.d.ts.map +0 -1
- package/dist/redact-Dk1ZdJEm.js.map +0 -1
- package/dist/release-confidence-BK2QCB5M.d.ts.map +0 -1
- package/dist/release-confidence-Dbe9AS_X.js.map +0 -1
- package/dist/report-command-y8H6RSX8.js.map +0 -1
- package/dist/reward-hacking-DHA7c1l8.d.ts.map +0 -1
- package/dist/rollout-D9bKKBnZ.js.map +0 -1
- package/dist/run-record-D1Hw-Jml.d.ts.map +0 -1
- package/dist/run-record-ES07wfz9.js.map +0 -1
- package/dist/schema-2g7trUwH.d.ts.map +0 -1
- package/dist/schema-BuiujZ-g.js.map +0 -1
- package/dist/schema-CSf6qWgZ.js.map +0 -1
- package/dist/search-kernel-BztlERLv.js.map +0 -1
- package/dist/search-kernel-CpcKH5Ih.d.ts.map +0 -1
- package/dist/search-ledger-d7V8o9Lk.js.map +0 -1
- package/dist/search-ledger-file-BqOo-bVo.js.map +0 -1
- package/dist/search-shipper-er4pK5_Y.js.map +0 -1
- package/dist/semantic-concept-judge-zQBG9hHU.js.map +0 -1
- package/dist/sequential-D-1PPCmM.js.map +0 -1
- package/dist/server-DbcC7xMl.js.map +0 -1
- package/dist/skillopt-optimization-method-CCtzralq.js.map +0 -1
- package/dist/statistical-heldout-1Gbmex7v.js.map +0 -1
- package/dist/statistical-heldout-BeR4bOdg.d.ts.map +0 -1
- package/dist/steps-Bg5-KVx1.d.ts.map +0 -1
- package/dist/store-otlp-DtB4Slsr.js.map +0 -1
- package/dist/store-tool-spans-DR1SrCLK.d.ts.map +0 -1
- package/dist/store-tool-spans-fZIigrpP.js.map +0 -1
- package/dist/student-t-BQeKJx2N.js +0 -39
- package/dist/student-t-BQeKJx2N.js.map +0 -1
- package/dist/summary-report-C-CtItCN.d.ts.map +0 -1
- package/dist/summary-report-DtdRucM0.js.map +0 -1
- package/dist/task-failure-attributes-DngaLdE4.js.map +0 -1
- package/dist/terminal-record-BHocwFw1.js.map +0 -1
- package/dist/tool-groups-mcxOXVlb.d.ts.map +0 -1
- package/dist/tool-waste-Wi4g6Ekb.d.ts.map +0 -1
- package/dist/trajectory-Y1fmdlw7.d.ts +0 -24
- package/dist/trajectory-Y1fmdlw7.d.ts.map +0 -1
- package/dist/tree-rXLW3M_4.js.map +0 -1
- package/dist/types-B4C5nFw6.d.ts.map +0 -1
- package/dist/types-BqkVmHfv.d.ts.map +0 -1
- package/dist/types-DBZ7keha.d.ts.map +0 -1
- package/dist/types-IXD2HJzu.js.map +0 -1
- package/dist/types-oKRhQAde.d.ts.map +0 -1
- package/dist/usage-receipt-Cx3xNeyB.js +0 -76
- package/dist/usage-receipt-Cx3xNeyB.js.map +0 -1
- package/dist/verdict-DhPoXApk.js.map +0 -1
- package/dist/verdict-cache-BQEsVy9n.js.map +0 -1
- package/docs/design/self-improvement-evidence-audit.md +0 -263
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dspy-rlm-engine-DhdCr1Dc.js","names":[],"sources":["../src/analyst/finding-codec.ts","../src/analyst/trace-tool-callback.ts","../src/analyst/dspy-rlm-engine.ts"],"sourcesContent":["/**\n * The raw-finding wire contract — one decoder for both sides of the process\n * boundary.\n *\n * A finding array crosses a process boundary twice: an optimizer bridge writes\n * it in Python, TypeScript reads it back. Two decoders written independently\n * accept different shapes, so Python could report a completed investigation\n * whose rows TypeScript then dropped — the paid work disappearing between two\n * \"successes\". This module is the TypeScript half; `finding_contract.json`\n * carries the same rules to the Python half, generated from the schema here.\n *\n * Decoding never invents an empty result. A value that is not an array of rows\n * fails with the exact type it was, and a malformed row is reported with its\n * index and path while its valid siblings survive.\n */\n\nimport { type RawAnalystFinding, RawAnalystFindingSchema } from './finding-signature'\nimport { parseFindingSubject } from './finding-subject'\nimport { coerceJson } from './parse-tolerant'\n\n/**\n * Version of the wire contract both languages implement. Bump when the\n * accepted row shape changes; the Python package pins the same value, and the\n * emitted contract carries it so a mismatched pair is visible.\n */\nexport const FINDING_WIRE_CONTRACT_VERSION = 1\n\n/** Why one row was refused. Stable across languages: Python reports the same codes. */\ntype FindingRejectionCode = 'not-an-object' | 'schema' | 'invalid-subject' | 'row-limit'\n\n/** A refused row, named precisely enough to repair or report. */\ninterface RejectedFindingRow {\n /** Position in the submitted array. */\n readonly index: number\n /** Dotted path to the offending field, `''` for the row itself. */\n readonly path: string\n readonly code: FindingRejectionCode\n readonly message: string\n}\n\ninterface DecodedFindingArray {\n readonly accepted: RawAnalystFinding[]\n readonly rejected: RejectedFindingRow[]\n /**\n * Set when the value was not a finding array at all — the array itself is\n * the failure, so `accepted` and `rejected` are both empty and a caller must\n * not read the result as \"no findings\".\n */\n readonly topLevelError?: string\n}\n\n/**\n * Rows past this count are refused rather than validated. A model that emits\n * thousands of rows has lost the plot, and the diagnostics for them would\n * dwarf the answer they came with.\n */\nexport const MAX_FINDING_ROWS = 500\n\n/**\n * Decode a submitted findings value into accepted rows plus per-row\n * diagnostics.\n *\n * Accepts an array of rows, or a string carrying one (a JSON array, possibly\n * fenced). Anything else — an object, a number, null, undefined — sets\n * `topLevelError` naming the type received: a caller that asked for findings\n * and got a number has a defect to report, not an empty result to record.\n */\nexport function decodeRawFindingArray(value: unknown): DecodedFindingArray {\n const rows = findingRows(value)\n if (typeof rows === 'string') return { accepted: [], rejected: [], topLevelError: rows }\n\n const accepted: RawAnalystFinding[] = []\n const rejected: RejectedFindingRow[] = []\n for (const [index, row] of rows.entries()) {\n if (index >= MAX_FINDING_ROWS) {\n rejected.push({\n index,\n path: '',\n code: 'row-limit',\n message: `findings array exceeds ${MAX_FINDING_ROWS} rows`,\n })\n continue\n }\n const decoded = decodeRow(row, index)\n if ('finding' in decoded) accepted.push(decoded.finding)\n else rejected.push(decoded.rejection)\n }\n return { accepted, rejected }\n}\n\nfunction decodeRow(\n row: unknown,\n index: number,\n): { finding: RawAnalystFinding } | { rejection: RejectedFindingRow } {\n if (row === null || typeof row !== 'object' || Array.isArray(row)) {\n return {\n rejection: {\n index,\n path: '',\n code: 'not-an-object',\n message: `finding row must be an object, received ${describe(row)}`,\n },\n }\n }\n const parsed = RawAnalystFindingSchema.safeParse(row)\n if (!parsed.success) {\n const issue = parsed.error.issues[0]\n const path = (issue?.path ?? []).join('.')\n // The schema refines `subject` against the grammar; name that refusal\n // separately so a repair turn can be told which rule the row broke.\n const code: FindingRejectionCode =\n path === 'subject' && parseFindingSubject((row as { subject?: string }).subject) === null\n ? 'invalid-subject'\n : 'schema'\n return {\n rejection: { index, path, code, message: issue?.message ?? 'row does not match the schema' },\n }\n }\n return { finding: parsed.data }\n}\n\n/**\n * Narrow a submitted value to candidate rows, or return the message naming why\n * it is not a findings array at all.\n */\nfunction findingRows(value: unknown): unknown[] | string {\n if (Array.isArray(value)) return value\n if (typeof value === 'string') {\n const parsed = coerceJson(value)\n if (parsed === undefined) {\n return 'findings must be a JSON array; the string received is not JSON'\n }\n if (Array.isArray(parsed)) return parsed\n const unwrapped = findingsProperty(parsed)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be a JSON array, received ${describe(parsed)}`\n }\n const unwrapped = findingsProperty(value)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be an array, received ${describe(value)}`\n}\n\n/** `{ findings: [...] }` is the one wrapper models emit often enough to unwrap. */\nfunction findingsProperty(value: unknown): unknown[] | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\n const inner = (value as Record<string, unknown>).findings\n return Array.isArray(inner) ? inner : undefined\n}\n\nfunction describe(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'an array'\n return `a ${typeof value}`\n}\n\n\n","import { randomBytes } from 'node:crypto'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport {\n type ExternalOptimizerCallbackLimits,\n resolveExternalOptimizerCallbackLimits,\n} from '../campaign/external-optimizer-contracts'\nimport {\n closeServer,\n listenLocal,\n sendJsonIfOpen,\n waitForActiveHandlers,\n} from '../campaign/external-optimizer-http'\nimport type { TraceAnalysisToolDescriptor } from '../trace-analyst/tools'\n\nimport { isRecord } from '../llm-client/json'\ninterface TraceToolCallback {\n url: string\n token: string\n calls: () => number\n close: () => Promise<void>\n}\n\nexport type TraceToolCallbackLimits = ExternalOptimizerCallbackLimits\n\n/** Expose one bounded trace-tool set only on an authenticated loopback socket. */\nexport async function startTraceToolCallback(args: {\n tools: readonly TraceAnalysisToolDescriptor[]\n maxCalls: number\n /** Trace-tool request/response byte limits. Omitted fields use finite defaults. */\n limits?: Partial<TraceToolCallbackLimits>\n signal?: AbortSignal\n}): Promise<TraceToolCallback> {\n if (!Number.isSafeInteger(args.maxCalls) || args.maxCalls <= 0) {\n throw new TypeError('trace tool callback maxCalls must be a positive safe integer')\n }\n const limits = resolveExternalOptimizerCallbackLimits(args.limits, 'trace tool callback limits')\n args.signal?.throwIfAborted()\n const byName = new Map(args.tools.map((tool) => [tool.name, tool]))\n if (byName.size !== args.tools.length) {\n throw new Error('trace tool callback received duplicate tool names')\n }\n\n const token = randomBytes(32).toString('hex')\n let calls = 0\n let accepting = true\n let closePromise: Promise<void> | undefined\n const activeControllers = new Set<AbortController>()\n const activeHandlers = new Set<Promise<void>>()\n const server = createServer((request, response) => {\n if (!accepting) {\n sendJsonIfOpen(response, 503, { error: 'trace tool callback is closing' })\n return\n }\n const controller = new AbortController()\n const abortRequest = (): void => {\n request.destroy()\n response.destroy()\n }\n activeControllers.add(controller)\n controller.signal.addEventListener('abort', abortRequest, { once: true })\n\n let handler!: Promise<void>\n handler = handleRequest(request, response, controller.signal).finally(() => {\n controller.signal.removeEventListener('abort', abortRequest)\n activeControllers.delete(controller)\n activeHandlers.delete(handler)\n })\n activeHandlers.add(handler)\n void handler.catch(() => undefined)\n })\n const port = await listenLocal(server)\n const close = (): Promise<void> => {\n closePromise ??= closeCallback()\n return closePromise\n }\n const onAbort = (): void => {\n void close().catch(() => undefined)\n }\n args.signal?.addEventListener('abort', onAbort, { once: true })\n if (args.signal?.aborted) onAbort()\n\n return {\n url: `http://127.0.0.1:${port}/call`,\n token,\n calls: () => calls,\n close,\n }\n\n async function handleRequest(\n request: IncomingMessage,\n response: ServerResponse,\n signal: AbortSignal,\n ): Promise<void> {\n try {\n if (request.method !== 'POST' || request.url !== '/call') {\n sendJsonIfOpen(response, 404, { error: 'not found' })\n return\n }\n if (request.headers.authorization !== `Bearer ${token}`) {\n sendJsonIfOpen(response, 401, { error: 'unauthorized' })\n return\n }\n if (calls >= args.maxCalls) {\n sendJsonIfOpen(response, 429, { error: 'trace tool call limit reached' })\n return\n }\n const body = await readJson(request, limits.maxRequestBytes)\n if (!isRecord(body) || typeof body.name !== 'string' || !('args' in body)) {\n sendJsonIfOpen(response, 400, { error: 'name and args are required' })\n return\n }\n const tool = byName.get(body.name)\n if (!tool) {\n sendJsonIfOpen(response, 404, { error: `unknown trace tool '${body.name}'` })\n return\n }\n calls += 1\n const result = await tool.handler(body.args, { signal })\n const encoded = JSON.stringify({ result })\n if (Buffer.byteLength(encoded) > limits.maxResponseBytes) {\n sendJsonIfOpen(response, 413, { error: 'trace tool response too large' })\n return\n }\n response.writeHead(200, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': String(Buffer.byteLength(encoded)),\n })\n response.end(encoded)\n } catch (error) {\n sendJsonIfOpen(response, signal.aborted ? 499 : 400, {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n async function closeCallback(): Promise<void> {\n args.signal?.removeEventListener('abort', onAbort)\n accepting = false\n const closingServer = closeServer(server)\n server.closeIdleConnections?.()\n for (const controller of activeControllers) controller.abort()\n const [serverResult] = await Promise.allSettled([\n closingServer,\n waitForActiveHandlers(activeHandlers),\n ])\n if (activeControllers.size !== 0 || activeHandlers.size !== 0) {\n throw new Error('trace tool callback closed with active requests')\n }\n if (serverResult?.status === 'rejected') throw serverResult.reason\n }\n}\n\nfunction readJson(request: IncomingMessage, maxRequestBytes: number): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let size = 0\n const chunks: Buffer[] = []\n request.on('data', (chunk: Buffer) => {\n size += chunk.length\n if (size > maxRequestBytes) {\n reject(new Error('trace tool request too large'))\n request.destroy()\n return\n }\n chunks.push(chunk)\n })\n request.on('error', reject)\n request.on('end', () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')))\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n","import {\n assertExternalOptimizerModelBudget,\n type ExternalOptimizerModelCall,\n type ExternalOptimizerModelExecutionObservation,\n type ExternalOptimizerModelProxy,\n type ExternalOptimizerRunnerCommand,\n removeCredentialEnvironment,\n resolveExternalOptimizerCallbackLimits,\n resolveExternalOptimizerProcessLimits,\n} from '../campaign/external-optimizer-contracts'\nimport { startExternalOptimizerModelProxy } from '../campaign/external-optimizer-model-proxy'\nimport { runWithCleanup } from '../campaign/external-optimizer-resources'\nimport { runExternalOptimizerProcess } from '../campaign/external-optimizer-subprocess'\nimport type { CustomTokenPricing } from '../cost-ledger'\nimport { resolveModelPricing } from '../metrics'\nimport {\n DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS,\n type TraceAnalysisEngine,\n type TraceAnalysisEngineResult,\n} from './engine'\nimport { decodeRawFindingArray } from './finding-codec'\nimport { startTraceToolCallback, type TraceToolCallbackLimits } from './trace-tool-callback'\n\nimport { isRecord } from '../llm-client/json'\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000\nconst DEFAULT_MAX_COST_USD = 1\nconst DEFAULT_MAX_MODEL_REQUEST_BYTES = 16 * 1024 * 1024\nconst DEFAULT_MAX_MODEL_RESPONSE_BYTES = 4 * 1024 * 1024\nconst DEFAULT_TRACE_TOOL_TIMEOUT_MS = 60_000\nconst MAX_TIMER_DELAY_MS = 2_147_483_647\nconst BRIDGE_MODULE = 'agent_eval_rpc.dspy_rlm_bridge'\n/** Bumped whenever this engine's execution behavior changes. */\nconst DSPY_RLM_ENGINE_VERSION = '1.0.0'\n\nexport interface DspyRlmTraceEngineOptions {\n /** Caller-owned execution path. Agent Eval never receives provider credentials. */\n call: ExternalOptimizerModelCall\n /** Stable public identity for the caller-owned path, such as an AgentProfile digest. */\n callRef: string\n /** Persist the finite execution record returned for every admitted call. */\n recordExecution: (observation: ExternalOptimizerModelExecutionObservation) => void\n model: string\n /** Exact provider rates. Required when the model is absent from the pricing table. */\n pricing?: CustomTokenPricing\n /** Maximum provider spend for one investigation. Default: 1 USD. */\n maxCostUsd?: number\n /** Controller response cap. Default: {@link DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS}. */\n maxOutputTokens?: number\n /**\n * Thinking tokens one controller turn may bill on top of its completion.\n * A reasoning model bills these beyond `maxOutputTokens`, so the cost\n * reservation must cover them. Default: four times the completion cap.\n */\n maxReasoningTokens?: number\n /** Maximum caller-owned model invocations. Default derives from the analysis limits. */\n maxModelRequests?: number\n /** Maximum model request bytes. Default: 16 MiB. */\n maxModelRequestBytes?: number\n /** Maximum model response bytes. Default: 4 MiB. */\n maxModelResponseBytes?: number\n /** Deadline for one caller-owned model invocation. Default: the whole analysis deadline. */\n modelRequestTimeoutMs?: number\n /** Trace-tool loopback request/response byte limits. */\n traceToolLimits?: Partial<TraceToolCallbackLimits>\n /** Deadline for one Python-to-Node trace-tool call. Default: 60 seconds. */\n traceToolTimeoutMs?: number\n /**\n * How the controller's reasoning and code fields are obtained.\n *\n * `tolerant` parses marker output strictly first, then recovers the fields\n * deterministically from prose plus a fenced code block — the shape coding\n * models naturally emit — at no extra model cost. `two-step` extracts with a\n * second call per turn. `chat` accepts marker output only. Default:\n * `tolerant`.\n */\n controlAdapter?: 'chat' | 'two-step' | 'tolerant'\n /** Python command used to load agent-eval-rpc[dspy]. Default: python. */\n runner?: ExternalOptimizerRunnerCommand\n /** Whole investigation deadline. Default: 10 minutes. */\n timeoutMs?: number\n}\n\n/** Use the official DSPy RLM as a bounded recursive trace-analysis engine. */\nexport function createDspyRlmTraceEngine(options: DspyRlmTraceEngineOptions): TraceAnalysisEngine {\n assertOptions(options)\n const maxOutputTokens = options.maxOutputTokens ?? DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS\n if (!Number.isSafeInteger(maxOutputTokens) || maxOutputTokens <= 0) {\n throw new TypeError('DSPy RLM maxOutputTokens must be a positive safe integer')\n }\n const controlAdapter = options.controlAdapter ?? 'tolerant'\n const maxReasoningTokens = options.maxReasoningTokens ?? maxOutputTokens * 4\n if (!Number.isSafeInteger(maxReasoningTokens) || maxReasoningTokens < 0) {\n throw new TypeError('DSPy RLM maxReasoningTokens must be a non-negative safe integer')\n }\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n assertTimerDelay(timeoutMs, 'timeoutMs')\n const maxCostUsd = options.maxCostUsd ?? DEFAULT_MAX_COST_USD\n if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {\n throw new TypeError('DSPy RLM maxCostUsd must be positive and finite')\n }\n const pricing = options.pricing ?? pricingForModel(options.model)\n const maxModelRequestBytes = options.maxModelRequestBytes ?? DEFAULT_MAX_MODEL_REQUEST_BYTES\n const maxModelResponseBytes = options.maxModelResponseBytes ?? DEFAULT_MAX_MODEL_RESPONSE_BYTES\n const modelRequestTimeoutMs = options.modelRequestTimeoutMs ?? timeoutMs\n const traceToolTimeoutMs = options.traceToolTimeoutMs ?? DEFAULT_TRACE_TOOL_TIMEOUT_MS\n assertExternalOptimizerModelBudget(\n {\n maxCostUsd,\n maxRequests: options.maxModelRequests ?? 1,\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n pricing,\n requestTimeoutMs: modelRequestTimeoutMs,\n },\n 'DSPy RLM model limits',\n )\n resolveExternalOptimizerCallbackLimits(options.traceToolLimits, 'DSPy RLM trace tool limits')\n assertTimerDelay(traceToolTimeoutMs, 'traceToolTimeoutMs')\n\n const runner = sanitizedRunner(options.runner)\n const processLimits = resolveExternalOptimizerProcessLimits(runner?.limits)\n return {\n id: 'dspy-rlm',\n description: 'Official DSPy RLM with bounded trace tools and metered model calls.',\n model: options.model,\n version: DSPY_RLM_ENGINE_VERSION,\n executionConfig: {\n bridge_module: BRIDGE_MODULE,\n call_ref: options.callRef,\n model: options.model,\n pricing: { ...pricing },\n max_cost_usd: maxCostUsd,\n max_output_tokens: maxOutputTokens,\n max_reasoning_tokens: maxReasoningTokens,\n control_adapter: controlAdapter,\n timeout_ms: timeoutMs,\n max_model_requests: options.maxModelRequests ?? null,\n max_request_bytes: maxModelRequestBytes,\n max_response_bytes: maxModelResponseBytes,\n model_request_timeout_ms: modelRequestTimeoutMs,\n trace_tool_limits: options.traceToolLimits ?? null,\n trace_tool_timeout_ms: traceToolTimeoutMs,\n process_limits: processLimits,\n runner: runner ? 'caller-supplied' : 'default',\n runner_command: runner?.command ?? null,\n },\n async analyze(request) {\n const callback = await startTraceToolCallback({\n tools: request.tools,\n maxCalls: request.limits.maxToolCalls,\n ...(options.traceToolLimits ? { limits: options.traceToolLimits } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n let modelProxy: ExternalOptimizerModelProxy | undefined\n const modelExecutions: ExternalOptimizerModelExecutionObservation[] = []\n const result = await runWithCleanup({\n label: 'DSPy RLM trace-analysis resources',\n run: async () => {\n modelProxy = await startExternalOptimizerModelProxy({\n call: options.call,\n callRef: options.callRef,\n recordExecution: (observation) => {\n modelExecutions.push(structuredClone(observation))\n options.recordExecution(observation)\n },\n model: options.model,\n budget: {\n maxCostUsd,\n maxRequests: resolveMaxModelRequests(options.maxModelRequests, request.limits),\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n requestTimeoutMs: modelRequestTimeoutMs,\n pricing,\n },\n costLedger: request.costLedger,\n channel: 'analyst',\n phase: request.costPhase,\n actor: request.analystId,\n ...(request.costTags ? { tags: request.costTags } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n request.log?.('trace analyst engine started', {\n engine: 'dspy-rlm',\n model: options.model,\n tools: request.tools.map((tool) => tool.name),\n limits: request.limits,\n })\n const raw = await runExternalOptimizerProcess<unknown>({\n label: 'DSPy RLM trace analysis',\n tempPrefix: 'agent-eval-dspy-rlm-',\n module: BRIDGE_MODULE,\n input: {\n operation: 'analyze',\n question: request.question,\n instructions: request.instructions,\n modelProxy: {\n baseUrl: modelProxy.baseUrl,\n apiKey: modelProxy.apiKey,\n model: options.model,\n maxOutputTokens,\n },\n toolCallback: {\n url: callback.url,\n token: callback.token,\n timeoutMs: traceToolTimeoutMs,\n },\n toolSpecs: request.tools.map(({ name, description, parameters }) => ({\n name,\n description,\n parameters,\n })),\n controlAdapter,\n limits: {\n maxIterations: request.limits.maxIterations,\n maxLlmCalls: request.limits.maxLlmCalls,\n maxOutputChars: request.limits.maxOutputChars,\n },\n // Omitted entirely when the caller supplied none, so a request\n // without structured inputs sends the payload it always sent.\n ...(request.taskInputs ? { taskInputs: request.taskInputs } : {}),\n },\n ...(runner ? { runner } : {}),\n additionalArgs: ['--max-input-bytes', String(processLimits.maxInputBytes)],\n timeoutMs,\n ...(request.signal ? { signal: request.signal } : {}),\n })\n const parsed = parseBridgeOutput(raw, (index, reason) => {\n request.log?.('finding rejected: bridge row failed schema validation', {\n engine: 'dspy-rlm',\n index,\n reason,\n })\n })\n const successfulCompletions = modelProxy.successfulCompletions()\n const requestAttempts = modelProxy.requestAttempts()\n if (parsed.modelCalls !== successfulCompletions) {\n throw new Error(\n `DSPy RLM reported ${parsed.modelCalls} model calls, but the provider proxy recorded ${successfulCompletions}`,\n )\n }\n modelProxy.assertExecutionComplete()\n return {\n ...parsed,\n toolCalls: callback.calls(),\n runtime: {\n ...parsed.runtime,\n modelRequestAttempts: requestAttempts,\n modelSuccessfulCompletions: successfulCompletions,\n modelExecutions,\n },\n } satisfies TraceAnalysisEngineResult\n },\n cleanup: async () => {\n const results = await Promise.allSettled([\n ...(modelProxy ? [modelProxy.close()] : []),\n callback.close(),\n ])\n const errors = results.flatMap((entry) =>\n entry.status === 'rejected' ? [entry.reason] : [],\n )\n if (errors.length > 0) {\n throw new AggregateError(errors, 'DSPy RLM resource cleanup failed')\n }\n },\n })\n request.log?.('trace analyst engine completed', {\n engine: 'dspy-rlm',\n model_calls: result.modelCalls,\n model_request_attempts: result.runtime.modelRequestAttempts,\n tool_calls: result.toolCalls,\n findings: result.findings.length,\n })\n return result\n },\n }\n}\n\nfunction parseBridgeOutput(\n value: unknown,\n onRejectedFinding: (index: number, reason: string) => void,\n): Omit<TraceAnalysisEngineResult, 'toolCalls'> {\n if (!isRecord(value)) throw new Error('DSPy RLM bridge output must be an object')\n if (typeof value.answer !== 'string' || !value.answer.trim()) {\n throw new Error('DSPy RLM bridge returned no answer')\n }\n // Findings are model output: one malformed row is model noise, not a bridge\n // fault, and the rest of the paid investigation must survive it. The codec\n // is the same decoder the Python side runs, so a row this bridge accepts is\n // a row the optimizer could report, and vice versa.\n const decoded = decodeRawFindingArray(value.findings)\n if (decoded.topLevelError !== undefined) {\n throw new Error(`DSPy RLM bridge findings must be an array: ${decoded.topLevelError}`)\n }\n const findings = decoded.accepted\n const rejectedFindings = decoded.rejected.length\n for (const rejection of decoded.rejected) {\n onRejectedFinding(\n rejection.index,\n `${rejection.code}${rejection.path ? ` at ${rejection.path}` : ''}: ${rejection.message}`,\n )\n }\n if (!Array.isArray(value.trajectory)) {\n throw new Error('DSPy RLM bridge trajectory must be an array')\n }\n if (!Number.isSafeInteger(value.modelCalls) || (value.modelCalls as number) <= 0) {\n throw new Error('DSPy RLM bridge modelCalls must be a positive safe integer')\n }\n if (!isRecord(value.runtime)) {\n throw new Error('DSPy RLM bridge runtime must be an object')\n }\n return {\n answer: value.answer,\n findings,\n trajectory: value.trajectory,\n modelCalls: value.modelCalls as number,\n runtime: { ...value.runtime, rejectedFindings },\n }\n}\n\nfunction assertOptions(options: DspyRlmTraceEngineOptions): void {\n for (const [name, value] of [\n ['callRef', options.callRef],\n ['model', options.model],\n ] as const) {\n if (typeof value !== 'string' || !value.trim() || value !== value.trim()) {\n throw new TypeError(`DSPy RLM ${name} must be a trimmed non-empty string`)\n }\n }\n if (typeof options.call !== 'function') {\n throw new TypeError('DSPy RLM call must be a function')\n }\n if (typeof options.recordExecution !== 'function') {\n throw new TypeError('DSPy RLM recordExecution must be a function')\n }\n if (\n options.maxModelRequests !== undefined &&\n (!Number.isSafeInteger(options.maxModelRequests) || options.maxModelRequests <= 0)\n ) {\n throw new TypeError('DSPy RLM maxModelRequests must be a positive safe integer')\n }\n}\n\nfunction resolveMaxModelRequests(\n configured: number | undefined,\n limits: { maxIterations: number; maxLlmCalls: number },\n): number {\n if (configured !== undefined) return configured\n const derived = limits.maxIterations + limits.maxLlmCalls + 1\n if (!Number.isSafeInteger(derived) || derived <= 0) {\n throw new Error('DSPy RLM analysis limits produce an invalid model request limit')\n }\n return derived\n}\n\nfunction assertTimerDelay(value: number, field: string): void {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_TIMER_DELAY_MS) {\n throw new TypeError(`DSPy RLM ${field} must be between 1 and ${MAX_TIMER_DELAY_MS}`)\n }\n}\n\nfunction pricingForModel(model: string): CustomTokenPricing {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n throw new Error(\n `no pricing is configured for '${model}'; provide DspyRlmTraceEngineOptions.pricing`,\n )\n }\n return {\n inputUsdPerMillion: pricing.input * 1_000,\n outputUsdPerMillion: pricing.output * 1_000,\n }\n}\n\nfunction sanitizedRunner(\n runner: ExternalOptimizerRunnerCommand | undefined,\n): ExternalOptimizerRunnerCommand | undefined {\n if (!runner) return undefined\n return {\n ...(runner.command ? { command: runner.command } : {}),\n ...(runner.args ? { args: runner.args } : {}),\n ...(runner.env ? { env: removeCredentialEnvironment(runner.env) } : {}),\n ...(runner.limits ? { limits: { ...runner.limits } } : {}),\n }\n}\n\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
import { s as TraceStore } from "./store-
|
|
1
|
+
import { C as TraceRunOutcome, S as TraceEvent, _ as Span, c as JudgeSpan, d as RetrievalSpan, f as Run, g as SandboxSpan, i as EventKind, l as LlmSpan, n as BudgetLedgerEntry, p as RunCaptureReport, t as Artifact, x as ToolSpan, y as SpanKind } from "./schema-D6EVKzTB.js";
|
|
2
|
+
import { s as TraceStore } from "./store-B3nWRy3B.js";
|
|
3
3
|
//#region src/trace/emitter.d.ts
|
|
4
4
|
interface SpanHandle<S extends Span = Span> {
|
|
5
5
|
span: S;
|
|
@@ -11,7 +11,7 @@ interface RunCompleteHookContext {
|
|
|
11
11
|
emitter: TraceEmitter;
|
|
12
12
|
store: TraceStore;
|
|
13
13
|
/** Outcome the caller passed to `endRun` (undefined for `abortRun`). */
|
|
14
|
-
outcome?:
|
|
14
|
+
outcome?: TraceRunOutcome;
|
|
15
15
|
/** Final run status. */
|
|
16
16
|
status: 'completed' | 'failed' | 'aborted';
|
|
17
17
|
}
|
|
@@ -84,7 +84,7 @@ declare class TraceEmitter {
|
|
|
84
84
|
* End the Run. The final record carries `capture`: the store writes made
|
|
85
85
|
* before it and how many were dropped.
|
|
86
86
|
*/
|
|
87
|
-
endRun(outcome?:
|
|
87
|
+
endRun(outcome?: TraceRunOutcome): Promise<void>;
|
|
88
88
|
abortRun(reason: string): Promise<void>;
|
|
89
89
|
private runHooks;
|
|
90
90
|
span<S extends Span = Span>(init: {
|
|
@@ -125,4 +125,4 @@ declare class TraceEmitter {
|
|
|
125
125
|
}
|
|
126
126
|
//#endregion
|
|
127
127
|
export { SpanHandle as a, RunCompleteHookContext as i, CaptureWrite as n, TraceEmitter as o, RunCompleteHook as r, TraceEmitterOptions as s, CaptureErrorHandler as t };
|
|
128
|
-
//# sourceMappingURL=emitter-
|
|
128
|
+
//# sourceMappingURL=emitter-DABYYTcH.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter-DABYYTcH.d.ts","names":[],"sources":["../src/trace/emitter.ts"],"mappings":";;;UAuCiB,WAAW,UAAU,OAAO;EAC3C,MAAM;EACN,IAAI,QAAQ,QAAQ,KAAK;EACzB,KAAK,gBAAgB,OAAO,QAAQ,QAAQ,KAAK;;UAGlC;EACf;EACA,SAAS;EACT,OAAO;;EAEP,UAAU;;EAEV;;KAGU,mBAAmB,KAAK,2BAA2B;;KAGnD;KASA,uBAAuB,gBAAgB,OAAO;UAQzC;EACf;;EAEA;;EAEA;;;;;;;;;;EAUA,gBAAgB;;EAEhB;;;;;;;EAOA,iBAAiB;;cAGN;UACH;mBACS;mBACA;UACT;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YAAY,OAAO,YAAY,UAAS;MAUpC;MAIA,cAAc;;EAKlB,gBAAgB;;EAKhB;UAKQ;UAIM;;EAkBd,mBAAmB,MAAM;;;;;;;;;;;EAgBnB,SACJ,KAAK,KAAK;IAA0D;MACnE,QAAQ;;;;;EAiBL,OAAO,UAAU,kBAAkB;EASnC,SAAS,iBAAiB;UAoBlB;EAwBR,KAAK,UAAU,OAAO,MAC1B;IACE,MAAM;IACN;IACA;IACA,aAAa;MACX,QAAQ,KAAK,0DAChB,QAAQ,WAAW;;;;;;UASR;UAkBN;EAqCR,IACE,MAAM,KAAK,sDACV,QAAQ,WAAW;EAItB,KACE,MAAM,KAAK,uDACV,QAAQ,WAAW;EAItB,UACE,MAAM,KAAK,4DACV,QAAQ,WAAW;EAIhB,YACJ,SAAS,KAAK,oEACb,QAAQ;EAgBX,QACE,MAAM,KAAK,0DACV,QAAQ,WAAW;EAMhB,KAAK;IACT,MAAM;IACN;IACA,UAAU;MACR,QAAQ;EAeN,aACJ,OAAO,KAAK;IAA8C;MACzD,QAAQ;EAwBL,eAAe,UAAU,KAAK,oCAAoC,QAAQ;;;;;;;;EAe1E,OAAO,GACX,MAAM,WAAW,0BACjB,KAAK,QAAQ,eAAe,QAAQ,KACnC,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter-DbMXUIVP.js","names":[],"sources":["../src/trace/emitter.ts"],"sourcesContent":["/**\n * TraceEmitter — hierarchical span builder for one Run. Emitters do NOT\n * share state.\n *\n * Parenting. A new span's parent is, in order: the explicit `parentSpanId`,\n * the innermost handle still open in the current async context, then the span\n * of the enclosing `within`. `within` runs its callback in an async context of\n * its own, so parallel `within` calls each parent their own children with no\n * ids passed by hand. Handles from `span`/`llm`/`tool`/`retrieval`/`sandbox`\n * nest by call order inside one async context; open parallel work with\n * `within`, or pass `parentSpanId`.\n *\n * Capture never throws into the traced run. A store write that fails is\n * counted as dropped, handed to `onCaptureError`, and the counts are written\n * onto the Run as `capture` when it ends, where `assertRunCaptured` reads them.\n * A Run whose records are incomplete therefore says so instead of reading as a\n * shorter run.\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { newRecordId } from '../record-id'\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n JudgeSpan,\n LlmSpan,\n RetrievalSpan,\n Run,\n RunCaptureReport,\n RunOutcome,\n SandboxSpan,\n Span,\n SpanKind,\n ToolSpan,\n TraceEvent,\n} from './schema'\nimport type { TraceStore } from './store'\n\nexport interface SpanHandle<S extends Span = Span> {\n span: S\n end(patch?: Partial<S>): Promise<void>\n fail(error: string | Error, patch?: Partial<S>): Promise<void>\n}\n\nexport interface RunCompleteHookContext {\n runId: string\n emitter: TraceEmitter\n store: TraceStore\n /** Outcome the caller passed to `endRun` (undefined for `abortRun`). */\n outcome?: RunOutcome\n /** Final run status. */\n status: 'completed' | 'failed' | 'aborted'\n}\n\nexport type RunCompleteHook = (ctx: RunCompleteHookContext) => Promise<void> | void\n\n/** The store write that failed, for `onCaptureError`. */\nexport type CaptureWrite =\n | 'appendRun'\n | 'updateRun'\n | 'appendSpan'\n | 'updateSpan'\n | 'appendEvent'\n | 'appendBudgetEntry'\n | 'appendArtifact'\n\nexport type CaptureErrorHandler = (error: unknown, write: CaptureWrite) => void\n\n/** Parent state for one async context: open handles, then the enclosing `within` span. */\ninterface ParentFrame {\n parentSpanId: string | undefined\n open: string[]\n}\n\nexport interface TraceEmitterOptions {\n runId?: string\n /** Inject a clock for deterministic tests. */\n now?: () => number\n /** Inject an id generator for deterministic tests. */\n id?: () => string\n /**\n * Hooks fired after `endRun` / `abortRun` writes the final run state.\n * Designed for trace-analyst auto-execution, integrity assertions, and\n * outbound notifications. Hooks run sequentially in the order supplied.\n *\n * By default a hook that throws is swallowed and logged as a `note` event\n * on the run — auto-orchestration must not crash the underlying flow.\n * Set `hookErrors: 'throw'` to propagate.\n */\n onRunComplete?: RunCompleteHook[]\n /** `'swallow'` (default) | `'throw'`. */\n hookErrors?: 'swallow' | 'throw'\n /**\n * Called once per failed store write. The write is already counted as\n * dropped; the handler reports it. Default: one process warning per emitter\n * (code `AGENT_EVAL_TRACE_CAPTURE`) on the first failure. A handler that\n * throws is ignored, because reporting must not break the traced run either.\n */\n onCaptureError?: CaptureErrorHandler\n}\n\nexport class TraceEmitter {\n private store: TraceStore\n private readonly context = new AsyncLocalStorage<ParentFrame>()\n private readonly rootFrame: ParentFrame = { parentSpanId: undefined, open: [] }\n private _runId: string\n private now: () => number\n private id: () => string\n private hooks: RunCompleteHook[]\n private hookErrors: 'swallow' | 'throw'\n private onCaptureError: CaptureErrorHandler\n private capture: RunCaptureReport = { written: 0, dropped: 0 }\n\n constructor(store: TraceStore, options: TraceEmitterOptions = {}) {\n this.store = store\n this.now = options.now ?? (() => Date.now())\n this.id = options.id ?? (() => newRecordId())\n this._runId = options.runId ?? this.id()\n this.hooks = options.onRunComplete ?? []\n this.hookErrors = options.hookErrors ?? 'swallow'\n this.onCaptureError = options.onCaptureError ?? warnOnFirstCaptureError(this._runId)\n }\n\n get runId(): string {\n return this._runId\n }\n\n get traceStore(): TraceStore {\n return this.store\n }\n\n /** Store writes so far: how many landed, how many were dropped, and the last failure. */\n captureStats(): RunCaptureReport {\n return { ...this.capture }\n }\n\n /** The span a new span would be parented to in the current async context. */\n currentSpanId(): string | undefined {\n const frame = this.frame()\n return frame.open[frame.open.length - 1] ?? frame.parentSpanId\n }\n\n private frame(): ParentFrame {\n return this.context.getStore() ?? this.rootFrame\n }\n\n private async write(write: CaptureWrite, fn: () => Promise<unknown>): Promise<boolean> {\n try {\n await fn()\n this.capture.written += 1\n return true\n } catch (error) {\n this.capture.dropped += 1\n this.capture.lastError = `${write}: ${error instanceof Error ? error.message : String(error)}`\n try {\n this.onCaptureError(error, write)\n } catch {\n // A failing reporter must not reach the traced run.\n }\n return false\n }\n }\n\n /** Append a hook after construction (e.g. attach the trace analyst). */\n addRunCompleteHook(hook: RunCompleteHook): void {\n this.hooks.push(hook)\n }\n\n // ── Run lifecycle ──────────────────────────────────────────────────\n\n /**\n * Begin a Run.\n *\n * `scenarioId` is required on the persisted Run shape — every Run downstream\n * gets a non-empty scenarioId so filters and aggregations stay simple — but\n * the INPUT here accepts it as optional. When omitted, startRun substitutes\n * a sensible default (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) so\n * runtime / operator / meta-eval runs that have no curated-scenario corpus\n * to anchor to don't have to invent placeholder strings at the call site.\n */\n async startRun(\n run: Omit<Run, 'runId' | 'scenarioId' | 'startedAt' | 'status'> & { scenarioId?: string },\n ): Promise<Run> {\n const scenarioId = run.scenarioId ?? run.layer ?? run.tags?.kind ?? 'runtime'\n const full: Run = {\n ...run,\n scenarioId,\n runId: this._runId,\n startedAt: this.now(),\n status: 'running',\n }\n await this.write('appendRun', () => this.store.appendRun(full))\n return full\n }\n\n /**\n * End the Run. The final record carries `capture`: the store writes made\n * before it and how many were dropped.\n */\n async endRun(outcome?: RunOutcome): Promise<void> {\n const status: 'completed' | 'failed' = outcome?.pass === false ? 'failed' : 'completed'\n const capture = this.captureStats()\n await this.write('updateRun', () =>\n this.store.updateRun(this._runId, { endedAt: this.now(), status, outcome, capture }),\n )\n await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status })\n }\n\n async abortRun(reason: string): Promise<void> {\n const outcome = { pass: false, notes: reason }\n const capture = this.captureStats()\n await this.write('updateRun', () =>\n this.store.updateRun(this._runId, {\n endedAt: this.now(),\n status: 'aborted',\n outcome,\n capture,\n }),\n )\n await this.runHooks({\n runId: this._runId,\n emitter: this,\n store: this.store,\n outcome,\n status: 'aborted',\n })\n }\n\n private async runHooks(ctx: RunCompleteHookContext): Promise<void> {\n for (const hook of this.hooks) {\n try {\n await hook(ctx)\n } catch (err) {\n if (this.hookErrors === 'throw') throw err\n await this.write('appendEvent', () =>\n this.store.appendEvent({\n eventId: this.id(),\n runId: this._runId,\n kind: 'log',\n timestamp: this.now(),\n payload: {\n source: 'run_complete_hook',\n error: err instanceof Error ? err.message : String(err),\n },\n }),\n )\n }\n }\n }\n\n // ── Generic span ───────────────────────────────────────────────────\n\n async span<S extends Span = Span>(\n init: {\n kind: SpanKind\n name: string\n parentSpanId?: string\n attributes?: Record<string, unknown>\n } & Partial<Omit<S, 'spanId' | 'runId' | 'startedAt' | 'kind' | 'name'>>,\n ): Promise<SpanHandle<S>> {\n return this.open<S>(init, this.frame())\n }\n\n /**\n * Create a span parented in the current async context. `frame` is the\n * context the handle stays open in, or null for a `within` span, which\n * parents its children through its own context instead.\n */\n private async open<S extends Span>(\n init: { kind: SpanKind; name: string; parentSpanId?: string },\n frame: ParentFrame | null,\n ): Promise<SpanHandle<S>> {\n const spanId = this.id()\n const parent = init.parentSpanId ?? this.currentSpanId()\n const span = {\n spanId,\n runId: this._runId,\n startedAt: this.now(),\n ...init,\n parentSpanId: parent,\n } as unknown as S\n frame?.open.push(spanId)\n await this.write('appendSpan', () => this.store.appendSpan(span))\n return this.handle<S>(span, frame)\n }\n\n private handle<S extends Span>(span: S, frame: ParentFrame | null): SpanHandle<S> {\n const close = () => {\n if (!frame) return\n const idx = frame.open.lastIndexOf(span.spanId)\n if (idx >= 0) frame.open.splice(idx, 1)\n }\n return {\n span,\n end: async (patch?: Partial<S>) => {\n const endedAt = this.now()\n close()\n await this.write('updateSpan', () =>\n this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'ok',\n ...patch,\n } as Partial<Span>),\n )\n },\n fail: async (error: string | Error, patch?: Partial<S>) => {\n const endedAt = this.now()\n const errStr = error instanceof Error ? error.message : error\n close()\n await this.write('updateSpan', () =>\n this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'error',\n error: errStr,\n ...patch,\n } as Partial<Span>),\n )\n },\n }\n }\n\n // ── Typed span conveniences ────────────────────────────────────────\n\n llm(\n init: Omit<LlmSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<LlmSpan>> {\n return this.span<LlmSpan>({ kind: 'llm', ...init })\n }\n\n tool(\n init: Omit<ToolSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<ToolSpan>> {\n return this.span<ToolSpan>({ kind: 'tool', ...init })\n }\n\n retrieval(\n init: Omit<RetrievalSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<RetrievalSpan>> {\n return this.span<RetrievalSpan>({ kind: 'retrieval', ...init })\n }\n\n async recordJudge(\n verdict: Omit<JudgeSpan, 'spanId' | 'runId' | 'kind' | 'startedAt' | 'endedAt'>,\n ): Promise<JudgeSpan> {\n const spanId = this.id()\n const now = this.now()\n const full: JudgeSpan = {\n spanId,\n runId: this._runId,\n kind: 'judge',\n startedAt: now,\n endedAt: now,\n status: 'ok',\n ...verdict,\n }\n await this.write('appendSpan', () => this.store.appendSpan(full))\n return full\n }\n\n sandbox(\n init: Omit<SandboxSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<SandboxSpan>> {\n return this.span<SandboxSpan>({ kind: 'sandbox', ...init })\n }\n\n // ── Events ─────────────────────────────────────────────────────────\n\n async emit(event: {\n kind: EventKind\n spanId?: string\n payload?: Record<string, unknown>\n }): Promise<TraceEvent> {\n const full: TraceEvent = {\n eventId: this.id(),\n runId: this._runId,\n spanId: event.spanId ?? this.currentSpanId(),\n kind: event.kind,\n timestamp: this.now(),\n payload: event.payload ?? {},\n }\n await this.write('appendEvent', () => this.store.appendEvent(full))\n return full\n }\n\n // ── Budget ledger ──────────────────────────────────────────────────\n\n async recordBudget(\n entry: Omit<BudgetLedgerEntry, 'runId' | 'timestamp'> & { timestamp?: number },\n ): Promise<BudgetLedgerEntry> {\n const full: BudgetLedgerEntry = {\n runId: this._runId,\n timestamp: entry.timestamp ?? this.now(),\n dimension: entry.dimension,\n limit: entry.limit,\n consumed: entry.consumed,\n remaining: entry.remaining,\n breached: entry.breached,\n spanId: entry.spanId ?? this.currentSpanId(),\n }\n await this.write('appendBudgetEntry', () => this.store.appendBudgetEntry(full))\n if (full.breached) {\n await this.emit({\n kind: 'budget_breach',\n spanId: full.spanId,\n payload: { dimension: full.dimension, limit: full.limit, consumed: full.consumed },\n })\n }\n return full\n }\n\n // ── Artifacts ──────────────────────────────────────────────────────\n\n async recordArtifact(artifact: Omit<Artifact, 'artifactId' | 'runId'>): Promise<Artifact> {\n const full: Artifact = { artifactId: this.id(), runId: this._runId, ...artifact }\n await this.write('appendArtifact', () => this.store.appendArtifact(full))\n return full\n }\n\n // ── Nested composition ─────────────────────────────────────────────\n\n /**\n * Runs `fn` inside a span; auto-ends on success, auto-fails on throw.\n * Returns the fn's return value. Use this for the 95% case.\n *\n * `fn` runs in an async context of its own, so spans it opens are parented\n * to this span even while sibling `within` calls run in parallel.\n */\n async within<T>(\n init: Parameters<TraceEmitter['span']>[0],\n fn: (handle: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const handle = await this.open<Span>(init, null)\n const frame: ParentFrame = { parentSpanId: handle.span.spanId, open: [] }\n try {\n const result = await this.context.run(frame, () => fn(handle))\n await handle.end()\n return result\n } catch (err) {\n await handle.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n// Helpers -------------------------------------------------------------\n\nfunction warnOnFirstCaptureError(runId: string): CaptureErrorHandler {\n let warned = false\n return (error, write) => {\n if (warned) return\n warned = true\n const reason = error instanceof Error ? error.message : String(error)\n globalThis.process?.emitWarning?.(\n `TraceEmitter run ${runId}: ${write} failed (${reason}); this and later failed writes are counted in the run's capture report.`,\n { code: 'AGENT_EVAL_TRACE_CAPTURE' },\n )\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"emitter-DbMXUIVP.js","names":[],"sources":["../src/trace/emitter.ts"],"sourcesContent":["/**\n * TraceEmitter — hierarchical span builder for one Run. Emitters do NOT\n * share state.\n *\n * Parenting. A new span's parent is, in order: the explicit `parentSpanId`,\n * the innermost handle still open in the current async context, then the span\n * of the enclosing `within`. `within` runs its callback in an async context of\n * its own, so parallel `within` calls each parent their own children with no\n * ids passed by hand. Handles from `span`/`llm`/`tool`/`retrieval`/`sandbox`\n * nest by call order inside one async context; open parallel work with\n * `within`, or pass `parentSpanId`.\n *\n * Capture never throws into the traced run. A store write that fails is\n * counted as dropped, handed to `onCaptureError`, and the counts are written\n * onto the Run as `capture` when it ends, where `assertRunCaptured` reads them.\n * A Run whose records are incomplete therefore says so instead of reading as a\n * shorter run.\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { newRecordId } from '../record-id'\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n JudgeSpan,\n LlmSpan,\n RetrievalSpan,\n Run,\n RunCaptureReport,\n TraceRunOutcome,\n SandboxSpan,\n Span,\n SpanKind,\n ToolSpan,\n TraceEvent,\n} from './schema'\nimport type { TraceStore } from './store'\n\nexport interface SpanHandle<S extends Span = Span> {\n span: S\n end(patch?: Partial<S>): Promise<void>\n fail(error: string | Error, patch?: Partial<S>): Promise<void>\n}\n\nexport interface RunCompleteHookContext {\n runId: string\n emitter: TraceEmitter\n store: TraceStore\n /** Outcome the caller passed to `endRun` (undefined for `abortRun`). */\n outcome?: TraceRunOutcome\n /** Final run status. */\n status: 'completed' | 'failed' | 'aborted'\n}\n\nexport type RunCompleteHook = (ctx: RunCompleteHookContext) => Promise<void> | void\n\n/** The store write that failed, for `onCaptureError`. */\nexport type CaptureWrite =\n | 'appendRun'\n | 'updateRun'\n | 'appendSpan'\n | 'updateSpan'\n | 'appendEvent'\n | 'appendBudgetEntry'\n | 'appendArtifact'\n\nexport type CaptureErrorHandler = (error: unknown, write: CaptureWrite) => void\n\n/** Parent state for one async context: open handles, then the enclosing `within` span. */\ninterface ParentFrame {\n parentSpanId: string | undefined\n open: string[]\n}\n\nexport interface TraceEmitterOptions {\n runId?: string\n /** Inject a clock for deterministic tests. */\n now?: () => number\n /** Inject an id generator for deterministic tests. */\n id?: () => string\n /**\n * Hooks fired after `endRun` / `abortRun` writes the final run state.\n * Designed for trace-analyst auto-execution, integrity assertions, and\n * outbound notifications. Hooks run sequentially in the order supplied.\n *\n * By default a hook that throws is swallowed and logged as a `note` event\n * on the run — auto-orchestration must not crash the underlying flow.\n * Set `hookErrors: 'throw'` to propagate.\n */\n onRunComplete?: RunCompleteHook[]\n /** `'swallow'` (default) | `'throw'`. */\n hookErrors?: 'swallow' | 'throw'\n /**\n * Called once per failed store write. The write is already counted as\n * dropped; the handler reports it. Default: one process warning per emitter\n * (code `AGENT_EVAL_TRACE_CAPTURE`) on the first failure. A handler that\n * throws is ignored, because reporting must not break the traced run either.\n */\n onCaptureError?: CaptureErrorHandler\n}\n\nexport class TraceEmitter {\n private store: TraceStore\n private readonly context = new AsyncLocalStorage<ParentFrame>()\n private readonly rootFrame: ParentFrame = { parentSpanId: undefined, open: [] }\n private _runId: string\n private now: () => number\n private id: () => string\n private hooks: RunCompleteHook[]\n private hookErrors: 'swallow' | 'throw'\n private onCaptureError: CaptureErrorHandler\n private capture: RunCaptureReport = { written: 0, dropped: 0 }\n\n constructor(store: TraceStore, options: TraceEmitterOptions = {}) {\n this.store = store\n this.now = options.now ?? (() => Date.now())\n this.id = options.id ?? (() => newRecordId())\n this._runId = options.runId ?? this.id()\n this.hooks = options.onRunComplete ?? []\n this.hookErrors = options.hookErrors ?? 'swallow'\n this.onCaptureError = options.onCaptureError ?? warnOnFirstCaptureError(this._runId)\n }\n\n get runId(): string {\n return this._runId\n }\n\n get traceStore(): TraceStore {\n return this.store\n }\n\n /** Store writes so far: how many landed, how many were dropped, and the last failure. */\n captureStats(): RunCaptureReport {\n return { ...this.capture }\n }\n\n /** The span a new span would be parented to in the current async context. */\n currentSpanId(): string | undefined {\n const frame = this.frame()\n return frame.open[frame.open.length - 1] ?? frame.parentSpanId\n }\n\n private frame(): ParentFrame {\n return this.context.getStore() ?? this.rootFrame\n }\n\n private async write(write: CaptureWrite, fn: () => Promise<unknown>): Promise<boolean> {\n try {\n await fn()\n this.capture.written += 1\n return true\n } catch (error) {\n this.capture.dropped += 1\n this.capture.lastError = `${write}: ${error instanceof Error ? error.message : String(error)}`\n try {\n this.onCaptureError(error, write)\n } catch {\n // A failing reporter must not reach the traced run.\n }\n return false\n }\n }\n\n /** Append a hook after construction (e.g. attach the trace analyst). */\n addRunCompleteHook(hook: RunCompleteHook): void {\n this.hooks.push(hook)\n }\n\n // ── Run lifecycle ──────────────────────────────────────────────────\n\n /**\n * Begin a Run.\n *\n * `scenarioId` is required on the persisted Run shape — every Run downstream\n * gets a non-empty scenarioId so filters and aggregations stay simple — but\n * the INPUT here accepts it as optional. When omitted, startRun substitutes\n * a sensible default (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) so\n * runtime / operator / meta-eval runs that have no curated-scenario corpus\n * to anchor to don't have to invent placeholder strings at the call site.\n */\n async startRun(\n run: Omit<Run, 'runId' | 'scenarioId' | 'startedAt' | 'status'> & { scenarioId?: string },\n ): Promise<Run> {\n const scenarioId = run.scenarioId ?? run.layer ?? run.tags?.kind ?? 'runtime'\n const full: Run = {\n ...run,\n scenarioId,\n runId: this._runId,\n startedAt: this.now(),\n status: 'running',\n }\n await this.write('appendRun', () => this.store.appendRun(full))\n return full\n }\n\n /**\n * End the Run. The final record carries `capture`: the store writes made\n * before it and how many were dropped.\n */\n async endRun(outcome?: TraceRunOutcome): Promise<void> {\n const status: 'completed' | 'failed' = outcome?.pass === false ? 'failed' : 'completed'\n const capture = this.captureStats()\n await this.write('updateRun', () =>\n this.store.updateRun(this._runId, { endedAt: this.now(), status, outcome, capture }),\n )\n await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status })\n }\n\n async abortRun(reason: string): Promise<void> {\n const outcome = { pass: false, notes: reason }\n const capture = this.captureStats()\n await this.write('updateRun', () =>\n this.store.updateRun(this._runId, {\n endedAt: this.now(),\n status: 'aborted',\n outcome,\n capture,\n }),\n )\n await this.runHooks({\n runId: this._runId,\n emitter: this,\n store: this.store,\n outcome,\n status: 'aborted',\n })\n }\n\n private async runHooks(ctx: RunCompleteHookContext): Promise<void> {\n for (const hook of this.hooks) {\n try {\n await hook(ctx)\n } catch (err) {\n if (this.hookErrors === 'throw') throw err\n await this.write('appendEvent', () =>\n this.store.appendEvent({\n eventId: this.id(),\n runId: this._runId,\n kind: 'log',\n timestamp: this.now(),\n payload: {\n source: 'run_complete_hook',\n error: err instanceof Error ? err.message : String(err),\n },\n }),\n )\n }\n }\n }\n\n // ── Generic span ───────────────────────────────────────────────────\n\n async span<S extends Span = Span>(\n init: {\n kind: SpanKind\n name: string\n parentSpanId?: string\n attributes?: Record<string, unknown>\n } & Partial<Omit<S, 'spanId' | 'runId' | 'startedAt' | 'kind' | 'name'>>,\n ): Promise<SpanHandle<S>> {\n return this.open<S>(init, this.frame())\n }\n\n /**\n * Create a span parented in the current async context. `frame` is the\n * context the handle stays open in, or null for a `within` span, which\n * parents its children through its own context instead.\n */\n private async open<S extends Span>(\n init: { kind: SpanKind; name: string; parentSpanId?: string },\n frame: ParentFrame | null,\n ): Promise<SpanHandle<S>> {\n const spanId = this.id()\n const parent = init.parentSpanId ?? this.currentSpanId()\n const span = {\n spanId,\n runId: this._runId,\n startedAt: this.now(),\n ...init,\n parentSpanId: parent,\n } as unknown as S\n frame?.open.push(spanId)\n await this.write('appendSpan', () => this.store.appendSpan(span))\n return this.handle<S>(span, frame)\n }\n\n private handle<S extends Span>(span: S, frame: ParentFrame | null): SpanHandle<S> {\n const close = () => {\n if (!frame) return\n const idx = frame.open.lastIndexOf(span.spanId)\n if (idx >= 0) frame.open.splice(idx, 1)\n }\n return {\n span,\n end: async (patch?: Partial<S>) => {\n const endedAt = this.now()\n close()\n await this.write('updateSpan', () =>\n this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'ok',\n ...patch,\n } as Partial<Span>),\n )\n },\n fail: async (error: string | Error, patch?: Partial<S>) => {\n const endedAt = this.now()\n const errStr = error instanceof Error ? error.message : error\n close()\n await this.write('updateSpan', () =>\n this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'error',\n error: errStr,\n ...patch,\n } as Partial<Span>),\n )\n },\n }\n }\n\n // ── Typed span conveniences ────────────────────────────────────────\n\n llm(\n init: Omit<LlmSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<LlmSpan>> {\n return this.span<LlmSpan>({ kind: 'llm', ...init })\n }\n\n tool(\n init: Omit<ToolSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<ToolSpan>> {\n return this.span<ToolSpan>({ kind: 'tool', ...init })\n }\n\n retrieval(\n init: Omit<RetrievalSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<RetrievalSpan>> {\n return this.span<RetrievalSpan>({ kind: 'retrieval', ...init })\n }\n\n async recordJudge(\n verdict: Omit<JudgeSpan, 'spanId' | 'runId' | 'kind' | 'startedAt' | 'endedAt'>,\n ): Promise<JudgeSpan> {\n const spanId = this.id()\n const now = this.now()\n const full: JudgeSpan = {\n spanId,\n runId: this._runId,\n kind: 'judge',\n startedAt: now,\n endedAt: now,\n status: 'ok',\n ...verdict,\n }\n await this.write('appendSpan', () => this.store.appendSpan(full))\n return full\n }\n\n sandbox(\n init: Omit<SandboxSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<SandboxSpan>> {\n return this.span<SandboxSpan>({ kind: 'sandbox', ...init })\n }\n\n // ── Events ─────────────────────────────────────────────────────────\n\n async emit(event: {\n kind: EventKind\n spanId?: string\n payload?: Record<string, unknown>\n }): Promise<TraceEvent> {\n const full: TraceEvent = {\n eventId: this.id(),\n runId: this._runId,\n spanId: event.spanId ?? this.currentSpanId(),\n kind: event.kind,\n timestamp: this.now(),\n payload: event.payload ?? {},\n }\n await this.write('appendEvent', () => this.store.appendEvent(full))\n return full\n }\n\n // ── Budget ledger ──────────────────────────────────────────────────\n\n async recordBudget(\n entry: Omit<BudgetLedgerEntry, 'runId' | 'timestamp'> & { timestamp?: number },\n ): Promise<BudgetLedgerEntry> {\n const full: BudgetLedgerEntry = {\n runId: this._runId,\n timestamp: entry.timestamp ?? this.now(),\n dimension: entry.dimension,\n limit: entry.limit,\n consumed: entry.consumed,\n remaining: entry.remaining,\n breached: entry.breached,\n spanId: entry.spanId ?? this.currentSpanId(),\n }\n await this.write('appendBudgetEntry', () => this.store.appendBudgetEntry(full))\n if (full.breached) {\n await this.emit({\n kind: 'budget_breach',\n spanId: full.spanId,\n payload: { dimension: full.dimension, limit: full.limit, consumed: full.consumed },\n })\n }\n return full\n }\n\n // ── Artifacts ──────────────────────────────────────────────────────\n\n async recordArtifact(artifact: Omit<Artifact, 'artifactId' | 'runId'>): Promise<Artifact> {\n const full: Artifact = { artifactId: this.id(), runId: this._runId, ...artifact }\n await this.write('appendArtifact', () => this.store.appendArtifact(full))\n return full\n }\n\n // ── Nested composition ─────────────────────────────────────────────\n\n /**\n * Runs `fn` inside a span; auto-ends on success, auto-fails on throw.\n * Returns the fn's return value. Use this for the 95% case.\n *\n * `fn` runs in an async context of its own, so spans it opens are parented\n * to this span even while sibling `within` calls run in parallel.\n */\n async within<T>(\n init: Parameters<TraceEmitter['span']>[0],\n fn: (handle: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const handle = await this.open<Span>(init, null)\n const frame: ParentFrame = { parentSpanId: handle.span.spanId, open: [] }\n try {\n const result = await this.context.run(frame, () => fn(handle))\n await handle.end()\n return result\n } catch (err) {\n await handle.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n// Helpers -------------------------------------------------------------\n\nfunction warnOnFirstCaptureError(runId: string): CaptureErrorHandler {\n let warned = false\n return (error, write) => {\n if (warned) return\n warned = true\n const reason = error instanceof Error ? error.message : String(error)\n globalThis.process?.emitWarning?.(\n `TraceEmitter run ${runId}: ${write} failed (${reason}); this and later failed writes are counted in the run's capture report.`,\n { code: 'AGENT_EVAL_TRACE_CAPTURE' },\n )\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import "./types-B4C5nFw6.js";
|
|
4
|
-
import "./analyze-runs-CSDAh8A7.js";
|
|
1
|
+
import { a as CostLedgerHandle } from "./cost-ledger-Jk62OBfF.js";
|
|
2
|
+
import { W as TraceAnalysisStore, m as EvidenceRef, z as BoundedTraceAnalysisStoreOptions } from "./types-CW8ewATZ.js";
|
|
5
3
|
import { z } from "zod";
|
|
6
4
|
//#region src/eval-tools.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Eval primitives as agent tools — `makeEvalTools` packages the substrate's
|
|
7
|
+
* judge / completion / analysis entry points as JSON-Schema tool definitions
|
|
8
|
+
* an LLM agent loop can call. The host closes over the live config (judge
|
|
9
|
+
* panels, the correctness checker, analyst registry); the agent passes only
|
|
10
|
+
* data over the wire.
|
|
11
|
+
*
|
|
12
|
+
* Three tools, each present only when its config section is supplied:
|
|
13
|
+
* - `run_judges` — score an artifact with the configured `JudgeConfig`s
|
|
14
|
+
* - `verify_completion` — gold-spec requirement check → `CompletionVerdict`
|
|
15
|
+
* - `analyze_runs` — `RunRecord[]` (inline or from a file) → `InsightReport`
|
|
16
|
+
*
|
|
17
|
+
* `toOpenAiTool` converts a definition to the OpenAI function-tool wire shape.
|
|
18
|
+
*/
|
|
7
19
|
/** One agent-callable tool. `parameters` is a JSON Schema (draft-07+) object. */
|
|
8
20
|
interface EvalToolDef {
|
|
9
21
|
name: string;
|
|
@@ -82,21 +94,6 @@ interface TraceAnalystLimits {
|
|
|
82
94
|
/** Maximum controller output retained between iterations. */
|
|
83
95
|
maxOutputChars: number;
|
|
84
96
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Completion cap one engine turn asks for when the caller names none.
|
|
87
|
-
*
|
|
88
|
-
* Shared by every engine because the number is load-bearing and has one
|
|
89
|
-
* failure story, not two: 4096 is below what current coding models emit for a
|
|
90
|
-
* full findings array — glm-5.2 through an OpenAI-compatible gateway returns
|
|
91
|
-
* 8192 and the request is rejected outright (`502 — provider reported 8192
|
|
92
|
-
* completion tokens, exceeding requested limit 4096`), which failed 2 of 2
|
|
93
|
-
* smoke cases before any analysis ran. Two engines holding private copies of
|
|
94
|
-
* this would have to move in lockstep or diverge on spend behaviour silently.
|
|
95
|
-
*
|
|
96
|
-
* The cap exists to bound a single response, not to bound spend: the cost
|
|
97
|
-
* ledger does that directly, so this starts above what a real report needs.
|
|
98
|
-
*/
|
|
99
|
-
declare const DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS = 16384;
|
|
100
97
|
interface TraceAnalysisEngineRequest {
|
|
101
98
|
analystId: string;
|
|
102
99
|
question: string;
|
|
@@ -158,7 +155,6 @@ interface TraceAnalysisEngine {
|
|
|
158
155
|
readonly executionConfig: Readonly<Record<string, unknown>>;
|
|
159
156
|
analyze(request: TraceAnalysisEngineRequest): Promise<TraceAnalysisEngineResult>;
|
|
160
157
|
}
|
|
161
|
-
declare function resolveTraceAnalystLimits(limits: Partial<TraceAnalystLimits> | undefined): TraceAnalystLimits;
|
|
162
158
|
//#endregion
|
|
163
|
-
export {
|
|
164
|
-
//# sourceMappingURL=engine-
|
|
159
|
+
export { RAW_FINDING_SCHEMA_PROMPT as a, RawAnalystFindingSchema as c, BuildTraceAnalysisToolsOptions as d, TRACE_ANALYST_TOOL_NAMESPACE as f, buildTraceAnalysisToolDescriptors as h, TraceAnalystLimits as i, evidenceRefsFromRawFinding as l, UNTRUSTED_TRACE_TEXT as m, TraceAnalysisEngineRequest as n, RawAnalystEvidence as o, TraceAnalysisToolDescriptor as p, TraceAnalysisEngineResult as r, RawAnalystFinding as s, TraceAnalysisEngine as t, parseRawFinding as u };
|
|
160
|
+
//# sourceMappingURL=engine-BvZ0R-36.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-BvZ0R-36.d.ts","names":[],"sources":["../src/eval-tools.ts","../src/trace-analyst/tools.ts","../src/analyst/finding-signature.ts","../src/analyst/engine.ts"],"mappings":";;;;;;;;;;;;;;;;;;;UAsBiB;EACf;EACA;EACA,YAAY;EACZ,UAAU,eAAe;IAAQ,SAAS;QAAkB;;;;cCZjD;;;;;;cAOA;UAGI,uCAAuC;EACtD,OAAO;;UAGQ,oCAAoC;EACnD,kBAAkB;;EAElB;;EAEA;;;iBAMc,kCACd,SAAS,iCACR;;;cC7BG,0BAAwB,EAAA;;;GAKnB,EAAA,KAAA;KAEC,qBAAqB,EAAE,aAAa;cAiBnC,yBAAuB,EAAA;;;;;;;;;;;;;;;;;GAKzB,EAAA,KAAA;KAEC,oBAAoB,EAAE,aAAa;;;;;;cAOlC;;iBAYG,2BAA2B,SAAS,oBAAoB;iBAQxD,gBACd,cACA,OAAO,aAAa,SAAS,mCAC5B;;;;UCpEc;;EAEf;;EAEA;;EAEA;;EAEA;;UA0Be;EACf;EACA;EACA;EACA,gBAAgB;;;;;;;;;;;EAWhB,aAAa,SAAS;EACtB,QAAQ;EACR,YAAY;EACZ;EACA,WAAW;EACX,SAAS;EACT,OAAO,iBAAiB,SAAS;;;UAIlB;EACf;EACA,UAAU;;EAEV;;;;;EAKA;;EAEA;EACA,SAAS;;;;;;;;;UAUM;WACN;WACA;WACA;;WAEA;;;;;;;;WAQA,iBAAiB,SAAS;EACnC,QAAQ,SAAS,6BAA6B,QAAQ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as ValidationError } from "./errors-
|
|
1
|
+
import { s as ValidationError } from "./errors-BcOs5MKW.js";
|
|
2
2
|
//#region src/analyst/equal-terms.ts
|
|
3
3
|
/**
|
|
4
4
|
* Refuses a comparison whose arms are not on equal terms: an empty set, a
|
|
@@ -22,4 +22,4 @@ function assertEqualDeclarativeTerms(noun, terms) {
|
|
|
22
22
|
//#endregion
|
|
23
23
|
export { assertEqualDeclarativeTerms as t };
|
|
24
24
|
|
|
25
|
-
//# sourceMappingURL=equal-terms-
|
|
25
|
+
//# sourceMappingURL=equal-terms-DbPGcVtI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"equal-terms-DbPGcVtI.js","names":[],"sources":["../src/analyst/equal-terms.ts"],"sourcesContent":["import { ValidationError } from '../errors'\n\n/**\n * The terms every declarative-arm comparison must hold equal before any\n * per-kind check runs. Arm kinds (analyst definitions, repair arms) extend\n * the comparison with their own fields; the refusals here are the floor.\n */\ninterface DeclarativeArmTerms {\n readonly id: string\n /** Bounded repair turns the arm earns on a malformed reply. */\n readonly repairTurns: number\n}\n\ninterface EqualDeclarativeTerms {\n readonly ids: readonly string[]\n readonly repairTurns: number\n}\n\n/**\n * Refuses a comparison whose arms are not on equal terms: an empty set, a\n * duplicated id, or unequal repair turns — a retry is a second sample the\n * other arms never got. `noun` names the arm kind in every message so a\n * refusal reads in the caller's vocabulary.\n */\nexport function assertEqualDeclarativeTerms(\n noun: string,\n terms: ReadonlyArray<DeclarativeArmTerms>,\n): EqualDeclarativeTerms {\n if (terms.length === 0) {\n throw new ValidationError(`a ${noun} comparison needs at least one ${noun}`)\n }\n const ids = terms.map((term) => term.id)\n const duplicate = ids.find((id, index) => ids.indexOf(id) !== index)\n if (duplicate !== undefined) {\n throw new ValidationError(`${noun} '${duplicate}' is declared twice`)\n }\n const repairTurns = terms[0]!.repairTurns\n const unequal = terms.find((term) => term.repairTurns !== repairTurns)\n if (unequal) {\n throw new ValidationError(\n `${noun} '${unequal.id}' gets ${unequal.repairTurns} bounded repair turns and ` +\n `${noun} '${terms[0]!.id}' gets ${repairTurns}; a retry is a second sample ` +\n 'the other arms never got',\n )\n }\n return { ids, repairTurns }\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,4BACd,MACA,OACuB;CACvB,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,gBAAgB,KAAK,KAAK,iCAAiC,MAAM;CAE7E,MAAM,MAAM,MAAM,KAAK,SAAS,KAAK,EAAE;CACvC,MAAM,YAAY,IAAI,MAAM,IAAI,UAAU,IAAI,QAAQ,EAAE,MAAM,KAAK;CACnE,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,gBAAgB,GAAG,KAAK,IAAI,UAAU,oBAAoB;CAEtE,MAAM,cAAc,MAAM,EAAE,CAAE;CAC9B,MAAM,UAAU,MAAM,MAAM,SAAS,KAAK,gBAAgB,WAAW;CACrE,IAAI,SACF,MAAM,IAAI,gBACR,GAAG,KAAK,IAAI,QAAQ,GAAG,SAAS,QAAQ,YAAY,4BAC/C,KAAK,IAAI,MAAM,EAAE,CAAE,GAAG,SAAS,YAAY,sDAElD;CAEF,OAAO;EAAE;EAAK;CAAY;AAC5B"}
|
|
@@ -52,13 +52,11 @@ var JudgeError = class extends AgentEvalError {
|
|
|
52
52
|
super("judge", message, options);
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
};
|
|
55
|
+
/** Preserve an arbitrary thrown value as a public diagnostic message. */
|
|
56
|
+
function errorMessage(error) {
|
|
57
|
+
return error instanceof Error ? error.message : String(error);
|
|
58
|
+
}
|
|
61
59
|
//#endregion
|
|
62
|
-
export { LimitExceededError as a,
|
|
60
|
+
export { LimitExceededError as a, errorMessage as c, JudgeError as i, CaptureIntegrityError as n, NotFoundError as o, ConfigError as r, ValidationError as s, AgentEvalError as t };
|
|
63
61
|
|
|
64
|
-
//# sourceMappingURL=errors-
|
|
62
|
+
//# sourceMappingURL=errors-BcOs5MKW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
1
|
+
{"version":3,"file":"errors-BcOs5MKW.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Error taxonomy for `@tangle-network/agent-eval`.\n *\n * Every error this package throws as part of its *public contract* extends\n * `AgentEvalError`. Consumers can pattern-match by `instanceof <Subclass>` or\n * by the stable string `code` carried on the base class.\n *\n * The codes are stable across minor versions; new codes can be added, but\n * existing codes never change meaning. New subclasses are non-breaking.\n *\n * Internal invariant guards (`throw new Error('this should never happen')`)\n * remain plain `Error`s on purpose — they're programmer-mistake assertions,\n * not consumer-catchable contract failures.\n */\n\nexport type AgentEvalErrorCode =\n | 'validation'\n | 'limit_exceeded'\n | 'not_found'\n | 'config'\n | 'capture_integrity'\n | 'judge'\n | 'verification'\n | 'replay'\n | 'backend_integrity'\n | 'model_substitution'\n | 'profile_matrix'\n\n/**\n * Base class for every contract error this package throws — carries the stable\n * string `code` taxonomy so consumers can `instanceof`-match or switch on `code`.\n */\nexport class AgentEvalError extends Error {\n /** Stable string code. Survives minification; safe to switch on. */\n readonly code: AgentEvalErrorCode\n\n constructor(code: AgentEvalErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = this.constructor.name\n this.code = code\n }\n}\n\n/** Caller passed invalid arguments (out of range, mutually-exclusive options, bad shape). */\nexport class ValidationError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n\n/** A bounded operation or resource exceeds its documented hard limit. */\nexport class LimitExceededError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('limit_exceeded', message, options)\n }\n}\n\n/** A named resource (run, span, rubric, scenario, dataset row, route) does not exist. */\nexport class NotFoundError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('not_found', message, options)\n }\n}\n\n/** Configuration missing or malformed (`HOME` unset, required image not supplied, env var absent). */\nexport class ConfigError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('config', message, options)\n }\n}\n\n/**\n * A run is missing the artifacts a launch-grade check requires:\n * raw HTTP capture absent, no LLM spans, route assertion failed, run-end\n * assertion tripped. Block ship on this; do not catch and move on.\n */\nexport class CaptureIntegrityError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('capture_integrity', message, options)\n }\n}\n\n/** A judge call failed in a way that's not retryable: schema parse failure, bad rubric, conflicting dimensions. */\nexport class JudgeError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('judge', message, options)\n }\n}\n\n/** A verifier signalled a hard failure (compile, test, schema) — distinct from a low judge score. */\nexport class VerificationError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('verification', message, options)\n }\n}\n\n\n\n/** Preserve an arbitrary thrown value as a public diagnostic message. */\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n"],"mappings":";;;;;AAgCA,IAAa,iBAAb,cAAoC,MAAM;;CAExC;CAEA,YAAY,MAA0B,SAAiB,SAA+B;EACpF,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO,KAAK,YAAY;EAC7B,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,kBAAb,cAAqC,eAAe;CAClD,YAAY,SAAiB,SAA+B;EAC1D,MAAM,cAAc,SAAS,OAAO;CACtC;AACF;;AAGA,IAAa,qBAAb,cAAwC,eAAe;CACrD,YAAY,SAAiB,SAA+B;EAC1D,MAAM,kBAAkB,SAAS,OAAO;CAC1C;AACF;;AAGA,IAAa,gBAAb,cAAmC,eAAe;CAChD,YAAY,SAAiB,SAA+B;EAC1D,MAAM,aAAa,SAAS,OAAO;CACrC;AACF;;AAGA,IAAa,cAAb,cAAiC,eAAe;CAC9C,YAAY,SAAiB,SAA+B;EAC1D,MAAM,UAAU,SAAS,OAAO;CAClC;AACF;;;;;;AAOA,IAAa,wBAAb,cAA2C,eAAe;CACxD,YAAY,SAAiB,SAA+B;EAC1D,MAAM,qBAAqB,SAAS,OAAO;CAC7C;AACF;;AAGA,IAAa,aAAb,cAAgC,eAAe;CAC7C,YAAY,SAAiB,SAA+B;EAC1D,MAAM,SAAS,SAAS,OAAO;CACjC;AACF;;AAYA,SAAgB,aAAa,OAAwB;CACnD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as validateRunRecord } from "./run-record-
|
|
3
|
-
import {
|
|
1
|
+
import { c as verifyAgentProfileCell, i as buildAgentProfileCell, l as hashJson } from "./agent-profile-cell-B1V1gUZs.js";
|
|
2
|
+
import { c as validateRunRecord } from "./run-record-DhEJgoPz.js";
|
|
3
|
+
import { t as researchReport } from "./summary-report-BsXJoYX5.js";
|
|
4
|
+
import { t as FileSystemRawProviderSink } from "./raw-provider-sink-75w4FWBj.js";
|
|
4
5
|
import { t as TraceEmitter } from "./emitter-DbMXUIVP.js";
|
|
5
|
-
import { t as
|
|
6
|
-
import { n as assertRunCaptured, t as RunIntegrityError } from "./integrity-BvnVARVl.js";
|
|
6
|
+
import { n as assertRunCaptured, t as RunIntegrityError } from "./integrity-W4CADcFc.js";
|
|
7
7
|
//#region src/eval-campaign.ts
|
|
8
8
|
/**
|
|
9
9
|
* EvalCampaign — opinionated matrix runner that wires the four
|
|
@@ -340,4 +340,4 @@ function defaultRunId(params) {
|
|
|
340
340
|
//#endregion
|
|
341
341
|
export { runEvalCampaign as t };
|
|
342
342
|
|
|
343
|
-
//# sourceMappingURL=eval-campaign-
|
|
343
|
+
//# sourceMappingURL=eval-campaign-BLEfBGbA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval-campaign-4byTtqrf.js","names":[],"sources":["../src/eval-campaign.ts"],"sourcesContent":["/**\n * EvalCampaign — opinionated matrix runner that wires the four\n * capture-integrity directives by construction.\n *\n * The canonical benchmark shape — matrix runner → for each\n * (variant, scenario, seed) → start a TraceEmitter → call LLMs → end the\n * run → analyze — has a bug class at the integration boundary: raw\n * events not captured, route silently wrong, integrity not asserted,\n * analyst never run. The directives in `SKILL.md § Capture integrity`\n * are the mitigations.\n *\n * `EvalCampaign` is the structural fix — consumers don't wire the\n * integrity surface themselves; the campaign owns it. Specifically:\n *\n * - constructs a per-run `TraceStore` and `RawProviderSink` via factories\n * - builds the run's `ChatClient` through `chatFactory`, handing it the\n * run's raw sink and trace context — a transport built any other way has\n * no raw HTTP envelope, and `assertRunCaptured` says so\n * - calls `assertRunCaptured` after every `endRun` and routes failures\n * through a configurable policy (`throw` / `mark_failed` / `log`)\n * - assembles per-run `RunRecord`s and runs `researchReport` at the end\n * so the campaign artifact is launch-decision-grade by default\n * - embeds the campaign fingerprint (a SHA-256 over the canonicalised\n * run set) and optional `preregistrationHash` in the report\n *\n * The runner contract is intentionally narrow: produce a `CampaignRunOutcome`\n * given a fully-wired `CampaignRunContext`. Everything orchestration-shaped\n * lives in the campaign. This is the inversion-of-control point — consumers\n * stop writing matrix runners and start writing scenario-runners.\n *\n * Out of scope for v1 (tracked in `docs/research-report-methodology.md`):\n *\n * - Distributed/cluster execution (concurrency is local async)\n * - Adaptive sampling / sequential interim looks\n * - Resume from partial state across crashes\n * - LLM-call retry beyond what the caller's transport already does\n */\n\nimport {\n type AgentProfileCell,\n type AgentProfileCellInput,\n buildAgentProfileCell,\n verifyAgentProfileCell,\n} from './agent-profile-cell'\nimport type { ChatClient } from './analyst/chat-client'\nimport { hashJson } from './pre-registration'\nimport type {\n JudgeScoresRecord,\n RunCostProvenance,\n RunJudgeMetadata,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTaskFailure,\n RunTokenUsage,\n} from './run-record'\nimport { validateRunRecord } from './run-record'\nimport { type ResearchReport, type ResearchReportOptions, researchReport } from './summary-report'\nimport type { RunCompleteHook } from './trace/emitter'\nimport { TraceEmitter } from './trace/emitter'\nimport {\n assertRunCaptured,\n RunIntegrityError,\n type RunIntegrityExpectations,\n type RunIntegrityReport,\n} from './trace/integrity'\nimport { FileSystemRawProviderSink, type RawProviderSink } from './trace/raw-provider-sink'\nimport type { TraceStore } from './trace/store'\n\n// ── Public types ─────────────────────────────────────────────────────────\n\nexport interface CampaignVariant<V> {\n id: string\n payload: V\n}\n\nexport interface CampaignScenario {\n scenarioId: string\n /** Free-form metadata propagated to runs and reports. */\n tags?: Record<string, string>\n}\n\nexport interface CampaignRunContext<V> {\n /** Stable run id. The campaign generates this; the runner does not. */\n runId: string\n /** Logical experiment id (campaignId by default; overridable per-run via opts). */\n experimentId: string\n variant: V\n variantId: string\n scenarioId: string\n scenarioTags: Record<string, string>\n seed: number\n splitTag: RunSplitTag\n /**\n * The TraceEmitter for this run, with `onRunComplete` hooks pre-wired\n * (analyst auto-execution if configured, plus integrity check). The\n * runner MUST call `emitter.startRun` before doing any work and either\n * `emitter.endRun` or `emitter.abortRun` before returning.\n */\n emitter: TraceEmitter\n store: TraceStore\n rawSink: RawProviderSink\n /**\n * The run's model transport, built by `chatFactory` with this run's\n * `rawSink` and `runId` already bound.\n */\n chat: ChatClient\n}\n\n/** What the campaign binds into the run's transport. */\nexport interface CampaignChatWiring {\n /**\n * Raw provider sink for this run. Bind it into the transport: the campaign's\n * integrity check requires every LLM span to carry a matching raw request\n * event, so a transport built without it fails `assertRunCaptured`.\n */\n rawSink: RawProviderSink\n runId: string\n}\n\ninterface CampaignRunOutcomeFields {\n /** Did the run pass? Mirrors `RunOutcome.pass` semantics. */\n pass: boolean\n /** Score for the run on its split. Maps to `searchScore` or `holdoutScore`. */\n score: number\n /** Cost in USD, or null when the runner could not capture it. */\n costUsd: number | null\n /** Source of the cost amount. */\n costProvenance: RunCostProvenance\n tokenUsage: RunTokenUsage\n /** Snapshot model id (e.g. `claude-sonnet-4-6@2025-04-15`). */\n model: string\n /** sha256 of the effective prompt sent to the model. */\n promptHash: string\n /** sha256 of the effective config (model, temperature, tools, judges, splits). */\n configHash: string\n /** Optional extra numeric metrics to land in `outcome.raw`. */\n raw?: Record<string, number>\n /** Optional judge metadata when a judge was used. */\n judgeMetadata?: RunJudgeMetadata\n /**\n * Optional per-judge / per-dim breakdown for ensemble-judged runs.\n * Propagated to `outcome.judgeScores` on the resulting `RunRecord`.\n * Single-judge or scalar-only runs leave this unset.\n */\n judgeScores?: JudgeScoresRecord\n /**\n * Agent profile cell observed by the runner. When supplied, it overrides\n * `EvalCampaignOptions.agentProfile` for this run and must match the\n * outcome's `model` and `promptHash`.\n */\n agentProfile?: AgentProfileCell | AgentProfileCellInput\n}\n\n/** Campaign result with the same task-failure invariant as `RunRecord`. */\nexport type CampaignRunOutcome = CampaignRunOutcomeFields & RunTaskFailure\n\nexport type CampaignRunner<V> = (ctx: CampaignRunContext<V>) => Promise<CampaignRunOutcome>\n\nexport type CampaignIntegrityPolicy = 'throw' | 'mark_failed' | 'log'\n\nexport interface EvalCampaignOptions<V> {\n /**\n * Stable id for the campaign. Used as the default `experimentId` on\n * every run, and folded into the campaign fingerprint.\n */\n campaignId: string\n variants: CampaignVariant<V>[]\n scenarios: CampaignScenario[]\n /** Default `[0, 1, 2]`. */\n seeds?: number[]\n /** Default `'holdout'` — the split that anchors a launch decision. */\n splitTag?: RunSplitTag\n /** Git SHA the campaign is run against. Mandatory; `RunRecord` rejects unset. */\n commitSha: string\n /**\n * Build the model transport for one run. agent-eval executes no paid model:\n * the caller owns the transport and the credential never enters this\n * package. The campaign calls this once per run and passes the run's raw\n * provider sink and `runId`, so a transport that binds them captures the\n * raw HTTP envelope `assertRunCaptured` checks for.\n */\n chatFactory: (wiring: CampaignChatWiring) => ChatClient\n /**\n * Caller-declared identity of the execution route, folded into the campaign\n * fingerprint so two campaigns run against different endpoints do not share\n * one identity. agent-eval no longer knows the endpoint; the owner of\n * execution names it.\n */\n executionRef?: string\n /**\n * Per-run TraceStore factory. Common shape: a fresh store per run keyed\n * on `runId`. Implementations that share a store across the campaign\n * are valid — the campaign only writes through `emitter`.\n */\n storeFactory: (params: CampaignFactoryParams) => TraceStore\n /**\n * Per-run RawProviderSink factory. Defaults to `FileSystemRawProviderSink`\n * rooted at `${workDir}/raw-events/${runId}` if `workDir` is supplied;\n * otherwise required. Forensic capture is non-negotiable in a campaign\n * run — pass `NoopRawProviderSink` explicitly if you want to opt out.\n */\n rawSinkFactory?: (params: CampaignFactoryParams) => RawProviderSink\n /**\n * Filesystem root for default `rawSinkFactory`. Ignored if\n * `rawSinkFactory` is supplied.\n */\n workDir?: string\n /**\n * Extra `onRunComplete` hooks the campaign appends (after its own\n * integrity-check hook). Pass `traceAnalystOnRunComplete(...)` here.\n */\n onRunComplete?: RunCompleteHook[]\n /**\n * Per-run integrity expectations. Defaults to:\n * `{ llmSpansMin: 1, requireRawCoverageOfLlmSpans: true, requireOutcome: true }`.\n * Override (e.g. `{ llmSpansMin: 0 }`) for runs that don't call LLMs.\n */\n integrity?: RunIntegrityExpectations\n /** Behaviour when integrity fails. Default `'mark_failed'`. */\n onIntegrityFailure?: CampaignIntegrityPolicy\n /**\n * Per-run runner. Receives a fully-wired context; produces an outcome\n * the campaign converts into a `RunRecord`.\n */\n runner: CampaignRunner<V>\n /**\n * If set, the campaign computes `researchReport` at the end. `comparator`\n * is a `variantId`. Other fields are forwarded verbatim.\n */\n report?: { comparator?: string } & Omit<\n ResearchReportOptions,\n 'comparator' | 'preregistrationHash' | 'generatedAt'\n >\n /**\n * Hash of a signed `HypothesisManifest` (see `pre-registration.ts`).\n * Embedded in the campaign fingerprint and the research report.\n */\n preregistrationHash?: string\n /** Local concurrency. Default `1` (sequential). */\n concurrency?: number\n /**\n * Override the time source. Tests pass a mock to make wallMs deterministic.\n */\n now?: () => number\n /** Override the runId generator. Tests pin this. */\n runId?: (params: CampaignFactoryParams) => string\n /**\n * Agent profile cell for campaign runs. Static profiles can pass an object;\n * routers or variant-specific harnesses can pass a factory. The campaign\n * stamps the built cell onto every `RunRecord` and rejects profile/model or\n * profile/prompt contradictions.\n */\n agentProfile?:\n | AgentProfileCell\n | AgentProfileCellInput\n | ((\n params: CampaignFactoryParams & {\n variant: V\n scenarioTags: Record<string, string>\n },\n ) =>\n | AgentProfileCell\n | AgentProfileCellInput\n | Promise<AgentProfileCell | AgentProfileCellInput>)\n}\n\nexport interface CampaignFactoryParams {\n campaignId: string\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n}\n\nexport interface FailedRun {\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n reason: string\n error?: string\n}\n\nexport interface EvalCampaignResult {\n campaignId: string\n /** SHA-256 over canonicalised `(variantIds, scenarioIds, seeds, comparator, splitTag, executionRef, preregistrationHash)`. */\n campaignFingerprint: string\n preregistrationHash: string | null\n /** Successful runs only. Failed runs land in `failedRuns`. */\n runs: RunRecord[]\n /** Integrity reports for every successful run. */\n integrityReports: RunIntegrityReport[]\n failedRuns: FailedRun[]\n /** Computed when `report` is set on options. */\n report?: ResearchReport\n startedAt: string\n endedAt: string\n}\n\n// ── Implementation ───────────────────────────────────────────────────────\n\nconst DEFAULT_INTEGRITY: RunIntegrityExpectations = {\n llmSpansMin: 1,\n requireRawCoverageOfLlmSpans: true,\n requireOutcome: true,\n}\n\nexport async function runEvalCampaign<V>(\n opts: EvalCampaignOptions<V>,\n): Promise<EvalCampaignResult> {\n // ── Preflight ──────────────────────────────────────────────────────\n if (opts.variants.length === 0) {\n throw new Error('runEvalCampaign: variants must be non-empty.')\n }\n if (opts.scenarios.length === 0) {\n throw new Error('runEvalCampaign: scenarios must be non-empty.')\n }\n const variantIds = new Set<string>()\n for (const v of opts.variants) {\n if (variantIds.has(v.id)) {\n throw new Error(`runEvalCampaign: duplicate variant id \"${v.id}\".`)\n }\n variantIds.add(v.id)\n }\n const scenarioIds = new Set<string>()\n for (const s of opts.scenarios) {\n if (scenarioIds.has(s.scenarioId)) {\n throw new Error(`runEvalCampaign: duplicate scenarioId \"${s.scenarioId}\".`)\n }\n scenarioIds.add(s.scenarioId)\n }\n if (opts.report?.comparator && !variantIds.has(opts.report.comparator)) {\n throw new Error(\n `runEvalCampaign: report.comparator \"${opts.report.comparator}\" is not a configured variantId.`,\n )\n }\n if (!opts.commitSha) {\n throw new Error('runEvalCampaign: commitSha is required (every RunRecord needs it).')\n }\n\n const seeds = opts.seeds ?? [0, 1, 2]\n const splitTag: RunSplitTag = opts.splitTag ?? 'holdout'\n const concurrency = Math.max(1, opts.concurrency ?? 1)\n const integrity = { ...DEFAULT_INTEGRITY, ...(opts.integrity ?? {}) }\n const onIntegrityFailure: CampaignIntegrityPolicy = opts.onIntegrityFailure ?? 'mark_failed'\n const now = opts.now ?? (() => Date.now())\n const executionRef = opts.executionRef ?? null\n const preregistrationHash = opts.preregistrationHash ?? null\n\n const rawSinkFactory = opts.rawSinkFactory ?? defaultRawSinkFactory(opts.workDir)\n\n // ── Fingerprint ────────────────────────────────────────────────────\n const campaignFingerprint = await hashJson({\n campaignId: opts.campaignId,\n variants: opts.variants.map((v) => v.id).sort(),\n scenarios: opts.scenarios.map((s) => s.scenarioId).sort(),\n seeds: [...seeds].sort((a, b) => a - b),\n splitTag,\n comparator: opts.report?.comparator ?? null,\n executionRef,\n preregistrationHash,\n })\n\n // ── Plan the matrix ────────────────────────────────────────────────\n type Cell = { variant: CampaignVariant<V>; scenario: CampaignScenario; seed: number }\n const cells: Cell[] = []\n for (const variant of opts.variants) {\n for (const scenario of opts.scenarios) {\n for (const seed of seeds) {\n cells.push({ variant, scenario, seed })\n }\n }\n }\n\n const startedAt = new Date(now()).toISOString()\n const runs: RunRecord[] = []\n const integrityReports: RunIntegrityReport[] = []\n const failedRuns: FailedRun[] = []\n\n // ── Execute (bounded-concurrency worker pool) ──────────────────────\n // A genuine (non-CellExecutionError) error from any worker is a bug, not a\n // run-level failure. We must NOT let `Promise.all` reject mid-flight and\n // orphan the other workers' in-progress runs (emitters never finalized,\n // sinks/handles leak, partial work silently discarded). Instead: capture the\n // first genuine error, stop dispatching new cells so in-flight workers wind\n // down, finalize every still-open run, then re-throw the aggregated error.\n let cursor = 0\n let aborting = false\n const genuineErrors: unknown[] = []\n // Emitters for runs that are currently mid-flight, keyed by runId. A worker\n // registers its emitter before invoking the runner and removes it once the\n // run is finalized (via endRun/abortRun, success or failure). Anything left\n // here after the pool settles is an orphan we must abort.\n const openRuns = new Map<string, TraceEmitter>()\n\n async function worker(): Promise<void> {\n while (!aborting) {\n const i = cursor++\n if (i >= cells.length) return\n const cell = cells[i]!\n try {\n const result = await runOneCell(cell)\n runs.push(result.record)\n integrityReports.push(result.integrity)\n } catch (err) {\n if (err instanceof CellExecutionError) {\n failedRuns.push(err.failed)\n if (err.integrity) integrityReports.push(err.integrity)\n } else {\n // Genuine bug — not a runner failure, not an integrity failure.\n // Capture it and stop dispatching so peers wind down gracefully;\n // re-thrown after the pool settles. Do not surface here — that would\n // reject Promise.all and orphan the other workers' runs.\n genuineErrors.push(err)\n aborting = true\n return\n }\n }\n }\n }\n\n async function runOneCell(\n cell: Cell,\n ): Promise<{ record: RunRecord; integrity: RunIntegrityReport }> {\n const runId = (opts.runId ?? defaultRunId)({\n campaignId: opts.campaignId,\n runId: '', // unused by default generator\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n })\n const factoryParams: CampaignFactoryParams = {\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n }\n const store = opts.storeFactory(factoryParams)\n const rawSink = rawSinkFactory(factoryParams)\n\n const emitter = new TraceEmitter(store, {\n runId,\n now: opts.now,\n onRunComplete: opts.onRunComplete,\n })\n // Track this run as open so a genuine error elsewhere in the pool can\n // finalize it instead of orphaning it. Removed in the finally below.\n openRuns.set(runId, emitter)\n\n const chat = opts.chatFactory({ rawSink, runId })\n\n const ctx: CampaignRunContext<V> = {\n runId,\n experimentId: opts.campaignId,\n variant: cell.variant.payload,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n scenarioTags: cell.scenario.tags ?? {},\n seed: cell.seed,\n splitTag,\n emitter,\n store,\n rawSink,\n chat,\n }\n\n try {\n const wallStart = now()\n let outcome: CampaignRunOutcome\n try {\n outcome = await opts.runner(ctx)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // The runner threw mid-execution. Abort the run so the emitter\n // finalizes. The only benign abortRun failure is \"the runner never\n // started the run\" (nothing to finalize). A store-write failure (disk\n // full, FS error) is a genuine diagnostic — surface it rather than\n // masking it as a plain runner failure.\n await finalizeAbort(emitter, runId, message)\n throw new CellExecutionError({\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'runner_threw',\n error: message,\n })\n }\n const wallMs = now() - wallStart\n\n const integrityReport = await assertRunCaptured(store, runId, { ...integrity, rawSink })\n if (!integrityReport.ok) {\n switch (onIntegrityFailure) {\n case 'throw':\n throw new RunIntegrityError(integrityReport)\n case 'mark_failed':\n throw new CellExecutionError(\n {\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'integrity_failed',\n error: integrityReport.issues.map((i) => i.code).join(', '),\n },\n integrityReport,\n )\n case 'log':\n // Caller wants the run admitted with a flagged report; fall through.\n break\n }\n }\n\n const recordOutcome: RunOutcome = {\n raw: outcome.raw ?? {},\n }\n if (splitTag === 'holdout') recordOutcome.holdoutScore = outcome.score\n else recordOutcome.searchScore = outcome.score\n if (outcome.judgeScores !== undefined) recordOutcome.judgeScores = outcome.judgeScores\n\n const record: RunRecord = {\n runId,\n experimentId: opts.campaignId,\n candidateId: cell.variant.id,\n seed: cell.seed,\n model: outcome.model,\n promptHash: outcome.promptHash,\n configHash: outcome.configHash,\n commitSha: opts.commitSha,\n wallMs,\n costUsd: outcome.costUsd,\n costProvenance: outcome.costProvenance,\n tokenUsage: outcome.tokenUsage,\n terminalOutcome: 'succeeded',\n judgeMetadata: outcome.judgeMetadata,\n outcome: recordOutcome,\n ...(outcome.failureClass ? { failureClass: outcome.failureClass } : {}),\n failureMode: outcome.failureMode,\n splitTag,\n scenarioId: cell.scenario.scenarioId,\n }\n const profileSource =\n outcome.agentProfile ??\n (typeof opts.agentProfile === 'function'\n ? await opts.agentProfile({\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n variant: cell.variant.payload,\n scenarioTags: cell.scenario.tags ?? {},\n })\n : opts.agentProfile)\n if (profileSource !== undefined) {\n const agentProfile = await resolveAgentProfileCell(profileSource)\n assertAgentProfileMatchesRun(agentProfile, outcome.model, outcome.promptHash)\n record.agentProfile = agentProfile\n }\n return { record: validateRunRecord(record), integrity: integrityReport }\n } finally {\n // This run's worker has finished with it (success, run-level failure, or\n // genuine error). It is no longer the pool's job to finalize — drop it so\n // the post-settle sweep doesn't double-abort a finalized run.\n openRuns.delete(runId)\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, cells.length) }, () => worker())\n // allSettled (not all): a genuine error in one worker must not reject the\n // pool mid-flight and orphan the others. Each worker captures its own\n // genuine error into `genuineErrors` and returns; we re-throw below.\n await Promise.allSettled(workers)\n\n // Finalize any run still open after the pool wound down. With the\n // stop-dispatch flag these are the runs that were mid-flight in peer workers\n // when the first genuine error fired — abort them so their emitters finalize\n // (hooks fire, store records a terminal status) instead of leaking.\n for (const [runId, emitter] of openRuns) {\n await finalizeAbort(emitter, runId, 'campaign aborted: genuine error in a sibling run')\n }\n openRuns.clear()\n\n if (genuineErrors.length > 0) {\n throw genuineErrors.length === 1\n ? genuineErrors[0]\n : new AggregateError(\n genuineErrors,\n `runEvalCampaign: ${genuineErrors.length} runs failed with genuine (non-run-level) errors`,\n )\n }\n\n // ── Optional research report ───────────────────────────────────────\n let report: ResearchReport | undefined\n if (opts.report) {\n const reportOpts: ResearchReportOptions = {\n ...opts.report,\n comparator: opts.report.comparator,\n split: splitTag === 'dev' ? 'search' : splitTag,\n generatedAt: new Date(now()).toISOString(),\n preregistrationHash: preregistrationHash ?? undefined,\n }\n report = await researchReport(runs, reportOpts)\n }\n\n const endedAt = new Date(now()).toISOString()\n\n return {\n campaignId: opts.campaignId,\n campaignFingerprint,\n preregistrationHash,\n runs,\n integrityReports,\n failedRuns,\n report,\n startedAt,\n endedAt,\n }\n}\n\n// ── Internal ─────────────────────────────────────────────────────────────\n\nclass CellExecutionError extends Error {\n readonly failed: FailedRun\n readonly integrity?: RunIntegrityReport\n constructor(failed: FailedRun, integrity?: RunIntegrityReport) {\n super(`cell ${failed.variantId}/${failed.scenarioId}@${failed.seed} failed: ${failed.reason}`)\n this.failed = failed\n this.integrity = integrity\n }\n}\n\n/**\n * Abort a run whose owning work threw or was orphaned by a sibling's genuine\n * error, finalizing the emitter so hooks fire and the store records a terminal\n * status. Safe to call unconditionally: it only aborts runs that are still\n * `running`. Two no-op cases are intentional and benign:\n *\n * - the run was never started (absent from the store) — nothing to finalize\n * - the run is already terminal (`completed` / `failed` / `aborted`) —\n * finalizing again would overwrite the real outcome (e.g. flip a passed run\n * to `aborted` with `{ pass: false, notes: reason }`), so we leave it alone\n *\n * Any OTHER failure of the store read or the abort write (disk full, FS fault,\n * backend down) is a genuine diagnostic and propagates rather than being\n * swallowed.\n */\nexport async function finalizeAbort(\n emitter: TraceEmitter,\n runId: string,\n reason: string,\n): Promise<void> {\n const existing = await emitter.traceStore.getRun(runId)\n if (existing === undefined) return // run never started; nothing to abort\n if (existing.status !== 'running') return // already finalized; never overwrite a real outcome\n // The emitter never throws on a failed store write; it counts it. A failed\n // abort write is a genuine diagnostic here, so read the count and surface it.\n const droppedBefore = emitter.captureStats().dropped\n await emitter.abortRun(reason)\n const after = emitter.captureStats()\n if (after.dropped > droppedBefore) {\n throw new Error(`finalizeAbort: run ${runId} could not be finalized: ${after.lastError}`)\n }\n}\n\nfunction defaultRawSinkFactory(workDir: string | undefined) {\n return (params: CampaignFactoryParams): RawProviderSink => {\n if (!workDir) {\n throw new Error(\n 'runEvalCampaign: rawSinkFactory not supplied and workDir not set. Pass either to enable raw provider capture, or pass `new NoopRawProviderSink()` via rawSinkFactory to opt out explicitly.',\n )\n }\n return new FileSystemRawProviderSink({\n dir: `${workDir}/raw-events/${params.runId}`,\n })\n }\n}\n\nasync function resolveAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n if (isAgentProfileCell(input)) {\n if (!(await verifyAgentProfileCell(input))) {\n throw new Error(`runEvalCampaign: agentProfile.cellId does not match its content`)\n }\n return input\n }\n return buildAgentProfileCell(input)\n}\n\nfunction isAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): input is AgentProfileCell {\n return 'schemaVersion' in input && 'cellId' in input\n}\n\nfunction assertAgentProfileMatchesRun(\n profile: AgentProfileCell,\n model: string,\n promptHash: string,\n): void {\n if (profile.model !== undefined && profile.model !== model) {\n throw new Error(\n `runEvalCampaign: agentProfile.model \"${profile.model}\" does not match outcome.model \"${model}\"`,\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== promptHash) {\n throw new Error(\n `runEvalCampaign: agentProfile.promptHash \"${profile.promptHash}\" does not match outcome.promptHash \"${promptHash}\"`,\n )\n }\n}\n\nfunction defaultRunId(params: CampaignFactoryParams): string {\n // Stable across re-runs: fingerprint of (campaignId, variantId, scenarioId, seed).\n // Caller can override via opts.runId for non-deterministic IDs.\n const base = `${params.campaignId}::${params.variantId}::${params.scenarioId}::${params.seed}`\n // TWO 32-bit FNV-1a accumulators with different offsets, concatenated for a\n // 64-bit-wide id. Not crypto-grade; stability and uniqueness are what this\n // needs. Frozen: the value names a persisted cell, and the second\n // accumulator's offset is part of the identity, so no single-accumulator\n // helper can replace it.\n let h1 = 0x811c9dc5\n let h2 = 0x12345678\n for (let i = 0; i < base.length; i++) {\n const c = base.charCodeAt(i)\n h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0\n h2 = Math.imul(h2 ^ c, 0x9e3779b1) >>> 0\n }\n return `run-${h1.toString(16).padStart(8, '0')}${h2.toString(16).padStart(8, '0')}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8SA,MAAM,oBAA8C;CAClD,aAAa;CACb,8BAA8B;CAC9B,gBAAgB;AAClB;AAEA,eAAsB,gBACpB,MAC6B;CAE7B,IAAI,KAAK,SAAS,WAAW,GAC3B,MAAM,IAAI,MAAM,8CAA8C;CAEhE,IAAI,KAAK,UAAU,WAAW,GAC5B,MAAM,IAAI,MAAM,+CAA+C;CAEjE,MAAM,6BAAa,IAAI,IAAY;CACnC,KAAK,MAAM,KAAK,KAAK,UAAU;EAC7B,IAAI,WAAW,IAAI,EAAE,EAAE,GACrB,MAAM,IAAI,MAAM,0CAA0C,EAAE,GAAG,GAAG;EAEpE,WAAW,IAAI,EAAE,EAAE;CACrB;CACA,MAAM,8BAAc,IAAI,IAAY;CACpC,KAAK,MAAM,KAAK,KAAK,WAAW;EAC9B,IAAI,YAAY,IAAI,EAAE,UAAU,GAC9B,MAAM,IAAI,MAAM,0CAA0C,EAAE,WAAW,GAAG;EAE5E,YAAY,IAAI,EAAE,UAAU;CAC9B;CACA,IAAI,KAAK,QAAQ,cAAc,CAAC,WAAW,IAAI,KAAK,OAAO,UAAU,GACnE,MAAM,IAAI,MACR,uCAAuC,KAAK,OAAO,WAAW,iCAChE;CAEF,IAAI,CAAC,KAAK,WACR,MAAM,IAAI,MAAM,oEAAoE;CAGtF,MAAM,QAAQ,KAAK,SAAS;EAAC;EAAG;EAAG;CAAC;CACpC,MAAM,WAAwB,KAAK,YAAY;CAC/C,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,eAAe,CAAC;CACrD,MAAM,YAAY;EAAE,GAAG;EAAmB,GAAI,KAAK,aAAa,CAAC;CAAG;CACpE,MAAM,qBAA8C,KAAK,sBAAsB;CAC/E,MAAM,MAAM,KAAK,cAAc,KAAK,IAAI;CACxC,MAAM,eAAe,KAAK,gBAAgB;CAC1C,MAAM,sBAAsB,KAAK,uBAAuB;CAExD,MAAM,iBAAiB,KAAK,kBAAkB,sBAAsB,KAAK,OAAO;CAGhF,MAAM,sBAAsB,MAAM,SAAS;EACzC,YAAY,KAAK;EACjB,UAAU,KAAK,SAAS,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK;EAC9C,WAAW,KAAK,UAAU,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC,KAAK;EACxD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;EACtC;EACA,YAAY,KAAK,QAAQ,cAAc;EACvC;EACA;CACF,CAAC;CAID,MAAM,QAAgB,CAAC;CACvB,KAAK,MAAM,WAAW,KAAK,UACzB,KAAK,MAAM,YAAY,KAAK,WAC1B,KAAK,MAAM,QAAQ,OACjB,MAAM,KAAK;EAAE;EAAS;EAAU;CAAK,CAAC;CAK5C,MAAM,YAAY,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY;CAC9C,MAAM,OAAoB,CAAC;CAC3B,MAAM,mBAAyC,CAAC;CAChD,MAAM,aAA0B,CAAC;CASjC,IAAI,SAAS;CACb,IAAI,WAAW;CACf,MAAM,gBAA2B,CAAC;CAKlC,MAAM,2BAAW,IAAI,IAA0B;CAE/C,eAAe,SAAwB;EACrC,OAAO,CAAC,UAAU;GAChB,MAAM,IAAI;GACV,IAAI,KAAK,MAAM,QAAQ;GACvB,MAAM,OAAO,MAAM;GACnB,IAAI;IACF,MAAM,SAAS,MAAM,WAAW,IAAI;IACpC,KAAK,KAAK,OAAO,MAAM;IACvB,iBAAiB,KAAK,OAAO,SAAS;GACxC,SAAS,KAAK;IACZ,IAAI,eAAe,oBAAoB;KACrC,WAAW,KAAK,IAAI,MAAM;KAC1B,IAAI,IAAI,WAAW,iBAAiB,KAAK,IAAI,SAAS;IACxD,OAAO;KAKL,cAAc,KAAK,GAAG;KACtB,WAAW;KACX;IACF;GACF;EACF;CACF;CAEA,eAAe,WACb,MAC+D;EAC/D,MAAM,SAAS,KAAK,SAAS,aAAA,CAAc;GACzC,YAAY,KAAK;GACjB,OAAO;GACP,WAAW,KAAK,QAAQ;GACxB,YAAY,KAAK,SAAS;GAC1B,MAAM,KAAK;EACb,CAAC;EACD,MAAM,gBAAuC;GAC3C,YAAY,KAAK;GACjB;GACA,WAAW,KAAK,QAAQ;GACxB,YAAY,KAAK,SAAS;GAC1B,MAAM,KAAK;EACb;EACA,MAAM,QAAQ,KAAK,aAAa,aAAa;EAC7C,MAAM,UAAU,eAAe,aAAa;EAE5C,MAAM,UAAU,IAAI,aAAa,OAAO;GACtC;GACA,KAAK,KAAK;GACV,eAAe,KAAK;EACtB,CAAC;EAGD,SAAS,IAAI,OAAO,OAAO;EAE3B,MAAM,OAAO,KAAK,YAAY;GAAE;GAAS;EAAM,CAAC;EAEhD,MAAM,MAA6B;GACjC;GACA,cAAc,KAAK;GACnB,SAAS,KAAK,QAAQ;GACtB,WAAW,KAAK,QAAQ;GACxB,YAAY,KAAK,SAAS;GAC1B,cAAc,KAAK,SAAS,QAAQ,CAAC;GACrC,MAAM,KAAK;GACX;GACA;GACA;GACA;GACA;EACF;EAEA,IAAI;GACF,MAAM,YAAY,IAAI;GACtB,IAAI;GACJ,IAAI;IACF,UAAU,MAAM,KAAK,OAAO,GAAG;GACjC,SAAS,KAAK;IACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;IAM/D,MAAM,cAAc,SAAS,OAAO,OAAO;IAC3C,MAAM,IAAI,mBAAmB;KAC3B;KACA,WAAW,KAAK,QAAQ;KACxB,YAAY,KAAK,SAAS;KAC1B,MAAM,KAAK;KACX,QAAQ;KACR,OAAO;IACT,CAAC;GACH;GACA,MAAM,SAAS,IAAI,IAAI;GAEvB,MAAM,kBAAkB,MAAM,kBAAkB,OAAO,OAAO;IAAE,GAAG;IAAW;GAAQ,CAAC;GACvF,IAAI,CAAC,gBAAgB,IACnB,QAAQ,oBAAR;IACE,KAAK,SACH,MAAM,IAAI,kBAAkB,eAAe;IAC7C,KAAK,eACH,MAAM,IAAI,mBACR;KACE;KACA,WAAW,KAAK,QAAQ;KACxB,YAAY,KAAK,SAAS;KAC1B,MAAM,KAAK;KACX,QAAQ;KACR,OAAO,gBAAgB,OAAO,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI;IAC5D,GACA,eACF;GAIJ;GAGF,MAAM,gBAA4B,EAChC,KAAK,QAAQ,OAAO,CAAC,EACvB;GACA,IAAI,aAAa,WAAW,cAAc,eAAe,QAAQ;QAC5D,cAAc,cAAc,QAAQ;GACzC,IAAI,QAAQ,gBAAgB,KAAA,GAAW,cAAc,cAAc,QAAQ;GAE3E,MAAM,SAAoB;IACxB;IACA,cAAc,KAAK;IACnB,aAAa,KAAK,QAAQ;IAC1B,MAAM,KAAK;IACX,OAAO,QAAQ;IACf,YAAY,QAAQ;IACpB,YAAY,QAAQ;IACpB,WAAW,KAAK;IAChB;IACA,SAAS,QAAQ;IACjB,gBAAgB,QAAQ;IACxB,YAAY,QAAQ;IACpB,iBAAiB;IACjB,eAAe,QAAQ;IACvB,SAAS;IACT,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;IACrE,aAAa,QAAQ;IACrB;IACA,YAAY,KAAK,SAAS;GAC5B;GACA,MAAM,gBACJ,QAAQ,iBACP,OAAO,KAAK,iBAAiB,aAC1B,MAAM,KAAK,aAAa;IACtB,YAAY,KAAK;IACjB;IACA,WAAW,KAAK,QAAQ;IACxB,YAAY,KAAK,SAAS;IAC1B,MAAM,KAAK;IACX,SAAS,KAAK,QAAQ;IACtB,cAAc,KAAK,SAAS,QAAQ,CAAC;GACvC,CAAC,IACD,KAAK;GACX,IAAI,kBAAkB,KAAA,GAAW;IAC/B,MAAM,eAAe,MAAM,wBAAwB,aAAa;IAChE,6BAA6B,cAAc,QAAQ,OAAO,QAAQ,UAAU;IAC5E,OAAO,eAAe;GACxB;GACA,OAAO;IAAE,QAAQ,kBAAkB,MAAM;IAAG,WAAW;GAAgB;EACzE,UAAU;GAIR,SAAS,OAAO,KAAK;EACvB;CACF;CAEA,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,SAAS,OAAO,CAAC;CAI1F,MAAM,QAAQ,WAAW,OAAO;CAMhC,KAAK,MAAM,CAAC,OAAO,YAAY,UAC7B,MAAM,cAAc,SAAS,OAAO,kDAAkD;CAExF,SAAS,MAAM;CAEf,IAAI,cAAc,SAAS,GACzB,MAAM,cAAc,WAAW,IAC3B,cAAc,KACd,IAAI,eACF,eACA,oBAAoB,cAAc,OAAO,iDAC3C;CAIN,IAAI;CACJ,IAAI,KAAK,QAAQ;EACf,MAAM,aAAoC;GACxC,GAAG,KAAK;GACR,YAAY,KAAK,OAAO;GACxB,OAAO,aAAa,QAAQ,WAAW;GACvC,aAAa,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY;GACzC,qBAAqB,uBAAuB,KAAA;EAC9C;EACA,SAAS,MAAM,eAAe,MAAM,UAAU;CAChD;CAEA,MAAM,UAAU,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY;CAE5C,OAAO;EACL,YAAY,KAAK;EACjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAIA,IAAM,qBAAN,cAAiC,MAAM;CACrC;CACA;CACA,YAAY,QAAmB,WAAgC;EAC7D,MAAM,QAAQ,OAAO,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,KAAK,WAAW,OAAO,QAAQ;EAC7F,KAAK,SAAS;EACd,KAAK,YAAY;CACnB;AACF;;;;;;;;;;;;;;;;AAiBA,eAAsB,cACpB,SACA,OACA,QACe;CACf,MAAM,WAAW,MAAM,QAAQ,WAAW,OAAO,KAAK;CACtD,IAAI,aAAa,KAAA,GAAW;CAC5B,IAAI,SAAS,WAAW,WAAW;CAGnC,MAAM,gBAAgB,QAAQ,aAAa,CAAC,CAAC;CAC7C,MAAM,QAAQ,SAAS,MAAM;CAC7B,MAAM,QAAQ,QAAQ,aAAa;CACnC,IAAI,MAAM,UAAU,eAClB,MAAM,IAAI,MAAM,sBAAsB,MAAM,2BAA2B,MAAM,WAAW;AAE5F;AAEA,SAAS,sBAAsB,SAA6B;CAC1D,QAAQ,WAAmD;EACzD,IAAI,CAAC,SACH,MAAM,IAAI,MACR,6LACF;EAEF,OAAO,IAAI,0BAA0B,EACnC,KAAK,GAAG,QAAQ,cAAc,OAAO,QACvC,CAAC;CACH;AACF;AAEA,eAAe,wBACb,OAC2B;CAC3B,IAAI,mBAAmB,KAAK,GAAG;EAC7B,IAAI,CAAE,MAAM,uBAAuB,KAAK,GACtC,MAAM,IAAI,MAAM,iEAAiE;EAEnF,OAAO;CACT;CACA,OAAO,sBAAsB,KAAK;AACpC;AAEA,SAAS,mBACP,OAC2B;CAC3B,OAAO,mBAAmB,SAAS,YAAY;AACjD;AAEA,SAAS,6BACP,SACA,OACA,YACM;CACN,IAAI,QAAQ,UAAU,KAAA,KAAa,QAAQ,UAAU,OACnD,MAAM,IAAI,MACR,wCAAwC,QAAQ,MAAM,kCAAkC,MAAM,EAChG;CAEF,IAAI,QAAQ,eAAe,KAAA,KAAa,QAAQ,eAAe,YAC7D,MAAM,IAAI,MACR,6CAA6C,QAAQ,WAAW,uCAAuC,WAAW,EACpH;AAEJ;AAEA,SAAS,aAAa,QAAuC;CAG3D,MAAM,OAAO,GAAG,OAAO,WAAW,IAAI,OAAO,UAAU,IAAI,OAAO,WAAW,IAAI,OAAO;CAMxF,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,IAAI,KAAK,WAAW,CAAC;EAC3B,KAAK,KAAK,KAAK,KAAK,GAAG,QAAU,MAAM;EACvC,KAAK,KAAK,KAAK,KAAK,GAAG,UAAU,MAAM;CACzC;CACA,OAAO,OAAO,GAAG,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;AAClF"}
|
|
1
|
+
{"version":3,"file":"eval-campaign-BLEfBGbA.js","names":[],"sources":["../src/eval-campaign.ts"],"sourcesContent":["/**\n * EvalCampaign — opinionated matrix runner that wires the four\n * capture-integrity directives by construction.\n *\n * The canonical benchmark shape — matrix runner → for each\n * (variant, scenario, seed) → start a TraceEmitter → call LLMs → end the\n * run → analyze — has a bug class at the integration boundary: raw\n * events not captured, route silently wrong, integrity not asserted,\n * analyst never run. The directives in `SKILL.md § Capture integrity`\n * are the mitigations.\n *\n * `EvalCampaign` is the structural fix — consumers don't wire the\n * integrity surface themselves; the campaign owns it. Specifically:\n *\n * - constructs a per-run `TraceStore` and `RawProviderSink` via factories\n * - builds the run's `ChatClient` through `chatFactory`, handing it the\n * run's raw sink and trace context — a transport built any other way has\n * no raw HTTP envelope, and `assertRunCaptured` says so\n * - calls `assertRunCaptured` after every `endRun` and routes failures\n * through a configurable policy (`throw` / `mark_failed` / `log`)\n * - assembles per-run `RunRecord`s and runs `researchReport` at the end\n * so the campaign artifact is launch-decision-grade by default\n * - embeds the campaign fingerprint (a SHA-256 over the canonicalised\n * run set) and optional `preregistrationHash` in the report\n *\n * The runner contract is intentionally narrow: produce a `CampaignRunOutcome`\n * given a fully-wired `CampaignRunContext`. Everything orchestration-shaped\n * lives in the campaign. This is the inversion-of-control point — consumers\n * stop writing matrix runners and start writing scenario-runners.\n *\n * Out of scope for v1 (tracked in `docs/research-report-methodology.md`):\n *\n * - Distributed/cluster execution (concurrency is local async)\n * - Adaptive sampling / sequential interim looks\n * - Resume from partial state across crashes\n * - LLM-call retry beyond what the caller's transport already does\n */\n\nimport {\n type AgentProfileCell,\n type AgentProfileCellInput,\n buildAgentProfileCell,\n verifyAgentProfileCell,\n} from './agent-profile-cell'\nimport type { ChatClient } from './analyst/chat-client'\nimport { hashJson } from './pre-registration'\nimport type {\n JudgeScoresRecord,\n RunCostProvenance,\n RunJudgeMetadata,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTaskFailure,\n RunTokenUsage,\n} from './run-record'\nimport { validateRunRecord } from './run-record'\nimport { type ResearchReport, type ResearchReportOptions, researchReport } from './summary-report'\nimport type { RunCompleteHook } from './trace/emitter'\nimport { TraceEmitter } from './trace/emitter'\nimport {\n assertRunCaptured,\n RunIntegrityError,\n type RunIntegrityExpectations,\n type RunIntegrityReport,\n} from './trace/integrity'\nimport { FileSystemRawProviderSink, type RawProviderSink } from './trace/raw-provider-sink'\nimport type { TraceStore } from './trace/store'\n\n// ── Public types ─────────────────────────────────────────────────────────\n\nexport interface CampaignVariant<V> {\n id: string\n payload: V\n}\n\nexport interface CampaignScenario {\n scenarioId: string\n /** Free-form metadata propagated to runs and reports. */\n tags?: Record<string, string>\n}\n\nexport interface CampaignRunContext<V> {\n /** Stable run id. The campaign generates this; the runner does not. */\n runId: string\n /** Logical experiment id (campaignId by default; overridable per-run via opts). */\n experimentId: string\n variant: V\n variantId: string\n scenarioId: string\n scenarioTags: Record<string, string>\n seed: number\n splitTag: RunSplitTag\n /**\n * The TraceEmitter for this run, with `onRunComplete` hooks pre-wired\n * (analyst auto-execution if configured, plus integrity check). The\n * runner MUST call `emitter.startRun` before doing any work and either\n * `emitter.endRun` or `emitter.abortRun` before returning.\n */\n emitter: TraceEmitter\n store: TraceStore\n rawSink: RawProviderSink\n /**\n * The run's model transport, built by `chatFactory` with this run's\n * `rawSink` and `runId` already bound.\n */\n chat: ChatClient\n}\n\n/** What the campaign binds into the run's transport. */\nexport interface CampaignChatWiring {\n /**\n * Raw provider sink for this run. Bind it into the transport: the campaign's\n * integrity check requires every LLM span to carry a matching raw request\n * event, so a transport built without it fails `assertRunCaptured`.\n */\n rawSink: RawProviderSink\n runId: string\n}\n\ninterface CampaignRunOutcomeFields {\n /** Did the run pass? Mirrors `RunOutcome.pass` semantics. */\n pass: boolean\n /** Score for the run on its split. Maps to `searchScore` or `holdoutScore`. */\n score: number\n /** Cost in USD, or null when the runner could not capture it. */\n costUsd: number | null\n /** Source of the cost amount. */\n costProvenance: RunCostProvenance\n tokenUsage: RunTokenUsage\n /** Snapshot model id (e.g. `claude-sonnet-4-6@2025-04-15`). */\n model: string\n /** sha256 of the effective prompt sent to the model. */\n promptHash: string\n /** sha256 of the effective config (model, temperature, tools, judges, splits). */\n configHash: string\n /** Optional extra numeric metrics to land in `outcome.raw`. */\n raw?: Record<string, number>\n /** Optional judge metadata when a judge was used. */\n judgeMetadata?: RunJudgeMetadata\n /**\n * Optional per-judge / per-dim breakdown for ensemble-judged runs.\n * Propagated to `outcome.judgeScores` on the resulting `RunRecord`.\n * Single-judge or scalar-only runs leave this unset.\n */\n judgeScores?: JudgeScoresRecord\n /**\n * Agent profile cell observed by the runner. When supplied, it overrides\n * `EvalCampaignOptions.agentProfile` for this run and must match the\n * outcome's `model` and `promptHash`.\n */\n agentProfile?: AgentProfileCell | AgentProfileCellInput\n}\n\n/** Campaign result with the same task-failure invariant as `RunRecord`. */\nexport type CampaignRunOutcome = CampaignRunOutcomeFields & RunTaskFailure\n\nexport type CampaignRunner<V> = (ctx: CampaignRunContext<V>) => Promise<CampaignRunOutcome>\n\nexport type CampaignIntegrityPolicy = 'throw' | 'mark_failed' | 'log'\n\nexport interface EvalCampaignOptions<V> {\n /**\n * Stable id for the campaign. Used as the default `experimentId` on\n * every run, and folded into the campaign fingerprint.\n */\n campaignId: string\n variants: CampaignVariant<V>[]\n scenarios: CampaignScenario[]\n /** Default `[0, 1, 2]`. */\n seeds?: number[]\n /** Default `'holdout'` — the split that anchors a launch decision. */\n splitTag?: RunSplitTag\n /** Git SHA the campaign is run against. Mandatory; `RunRecord` rejects unset. */\n commitSha: string\n /**\n * Build the model transport for one run. agent-eval executes no paid model:\n * the caller owns the transport and the credential never enters this\n * package. The campaign calls this once per run and passes the run's raw\n * provider sink and `runId`, so a transport that binds them captures the\n * raw HTTP envelope `assertRunCaptured` checks for.\n */\n chatFactory: (wiring: CampaignChatWiring) => ChatClient\n /**\n * Caller-declared identity of the execution route, folded into the campaign\n * fingerprint so two campaigns run against different endpoints do not share\n * one identity. agent-eval no longer knows the endpoint; the owner of\n * execution names it.\n */\n executionRef?: string\n /**\n * Per-run TraceStore factory. Common shape: a fresh store per run keyed\n * on `runId`. Implementations that share a store across the campaign\n * are valid — the campaign only writes through `emitter`.\n */\n storeFactory: (params: CampaignFactoryParams) => TraceStore\n /**\n * Per-run RawProviderSink factory. Defaults to `FileSystemRawProviderSink`\n * rooted at `${workDir}/raw-events/${runId}` if `workDir` is supplied;\n * otherwise required. Forensic capture is non-negotiable in a campaign\n * run — pass `NoopRawProviderSink` explicitly if you want to opt out.\n */\n rawSinkFactory?: (params: CampaignFactoryParams) => RawProviderSink\n /**\n * Filesystem root for default `rawSinkFactory`. Ignored if\n * `rawSinkFactory` is supplied.\n */\n workDir?: string\n /**\n * Extra `onRunComplete` hooks the campaign appends (after its own\n * integrity-check hook). Pass `traceAnalystOnRunComplete(...)` here.\n */\n onRunComplete?: RunCompleteHook[]\n /**\n * Per-run integrity expectations. Defaults to:\n * `{ llmSpansMin: 1, requireRawCoverageOfLlmSpans: true, requireOutcome: true }`.\n * Override (e.g. `{ llmSpansMin: 0 }`) for runs that don't call LLMs.\n */\n integrity?: RunIntegrityExpectations\n /** Behaviour when integrity fails. Default `'mark_failed'`. */\n onIntegrityFailure?: CampaignIntegrityPolicy\n /**\n * Per-run runner. Receives a fully-wired context; produces an outcome\n * the campaign converts into a `RunRecord`.\n */\n runner: CampaignRunner<V>\n /**\n * If set, the campaign computes `researchReport` at the end. `comparator`\n * is a `variantId`. Other fields are forwarded verbatim.\n */\n report?: { comparator?: string } & Omit<\n ResearchReportOptions,\n 'comparator' | 'preregistrationHash' | 'generatedAt'\n >\n /**\n * Hash of a signed `HypothesisManifest` (see `pre-registration.ts`).\n * Embedded in the campaign fingerprint and the research report.\n */\n preregistrationHash?: string\n /** Local concurrency. Default `1` (sequential). */\n concurrency?: number\n /**\n * Override the time source. Tests pass a mock to make wallMs deterministic.\n */\n now?: () => number\n /** Override the runId generator. Tests pin this. */\n runId?: (params: CampaignFactoryParams) => string\n /**\n * Agent profile cell for campaign runs. Static profiles can pass an object;\n * routers or variant-specific harnesses can pass a factory. The campaign\n * stamps the built cell onto every `RunRecord` and rejects profile/model or\n * profile/prompt contradictions.\n */\n agentProfile?:\n | AgentProfileCell\n | AgentProfileCellInput\n | ((\n params: CampaignFactoryParams & {\n variant: V\n scenarioTags: Record<string, string>\n },\n ) =>\n | AgentProfileCell\n | AgentProfileCellInput\n | Promise<AgentProfileCell | AgentProfileCellInput>)\n}\n\nexport interface CampaignFactoryParams {\n campaignId: string\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n}\n\nexport interface FailedRun {\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n reason: string\n error?: string\n}\n\nexport interface EvalCampaignResult {\n campaignId: string\n /** SHA-256 over canonicalised `(variantIds, scenarioIds, seeds, comparator, splitTag, executionRef, preregistrationHash)`. */\n campaignFingerprint: string\n preregistrationHash: string | null\n /** Successful runs only. Failed runs land in `failedRuns`. */\n runs: RunRecord[]\n /** Integrity reports for every successful run. */\n integrityReports: RunIntegrityReport[]\n failedRuns: FailedRun[]\n /** Computed when `report` is set on options. */\n report?: ResearchReport\n startedAt: string\n endedAt: string\n}\n\n// ── Implementation ───────────────────────────────────────────────────────\n\nconst DEFAULT_INTEGRITY: RunIntegrityExpectations = {\n llmSpansMin: 1,\n requireRawCoverageOfLlmSpans: true,\n requireOutcome: true,\n}\n\nexport async function runEvalCampaign<V>(\n opts: EvalCampaignOptions<V>,\n): Promise<EvalCampaignResult> {\n // ── Preflight ──────────────────────────────────────────────────────\n if (opts.variants.length === 0) {\n throw new Error('runEvalCampaign: variants must be non-empty.')\n }\n if (opts.scenarios.length === 0) {\n throw new Error('runEvalCampaign: scenarios must be non-empty.')\n }\n const variantIds = new Set<string>()\n for (const v of opts.variants) {\n if (variantIds.has(v.id)) {\n throw new Error(`runEvalCampaign: duplicate variant id \"${v.id}\".`)\n }\n variantIds.add(v.id)\n }\n const scenarioIds = new Set<string>()\n for (const s of opts.scenarios) {\n if (scenarioIds.has(s.scenarioId)) {\n throw new Error(`runEvalCampaign: duplicate scenarioId \"${s.scenarioId}\".`)\n }\n scenarioIds.add(s.scenarioId)\n }\n if (opts.report?.comparator && !variantIds.has(opts.report.comparator)) {\n throw new Error(\n `runEvalCampaign: report.comparator \"${opts.report.comparator}\" is not a configured variantId.`,\n )\n }\n if (!opts.commitSha) {\n throw new Error('runEvalCampaign: commitSha is required (every RunRecord needs it).')\n }\n\n const seeds = opts.seeds ?? [0, 1, 2]\n const splitTag: RunSplitTag = opts.splitTag ?? 'holdout'\n const concurrency = Math.max(1, opts.concurrency ?? 1)\n const integrity = { ...DEFAULT_INTEGRITY, ...(opts.integrity ?? {}) }\n const onIntegrityFailure: CampaignIntegrityPolicy = opts.onIntegrityFailure ?? 'mark_failed'\n const now = opts.now ?? (() => Date.now())\n const executionRef = opts.executionRef ?? null\n const preregistrationHash = opts.preregistrationHash ?? null\n\n const rawSinkFactory = opts.rawSinkFactory ?? defaultRawSinkFactory(opts.workDir)\n\n // ── Fingerprint ────────────────────────────────────────────────────\n const campaignFingerprint = await hashJson({\n campaignId: opts.campaignId,\n variants: opts.variants.map((v) => v.id).sort(),\n scenarios: opts.scenarios.map((s) => s.scenarioId).sort(),\n seeds: [...seeds].sort((a, b) => a - b),\n splitTag,\n comparator: opts.report?.comparator ?? null,\n executionRef,\n preregistrationHash,\n })\n\n // ── Plan the matrix ────────────────────────────────────────────────\n type Cell = { variant: CampaignVariant<V>; scenario: CampaignScenario; seed: number }\n const cells: Cell[] = []\n for (const variant of opts.variants) {\n for (const scenario of opts.scenarios) {\n for (const seed of seeds) {\n cells.push({ variant, scenario, seed })\n }\n }\n }\n\n const startedAt = new Date(now()).toISOString()\n const runs: RunRecord[] = []\n const integrityReports: RunIntegrityReport[] = []\n const failedRuns: FailedRun[] = []\n\n // ── Execute (bounded-concurrency worker pool) ──────────────────────\n // A genuine (non-CellExecutionError) error from any worker is a bug, not a\n // run-level failure. We must NOT let `Promise.all` reject mid-flight and\n // orphan the other workers' in-progress runs (emitters never finalized,\n // sinks/handles leak, partial work silently discarded). Instead: capture the\n // first genuine error, stop dispatching new cells so in-flight workers wind\n // down, finalize every still-open run, then re-throw the aggregated error.\n let cursor = 0\n let aborting = false\n const genuineErrors: unknown[] = []\n // Emitters for runs that are currently mid-flight, keyed by runId. A worker\n // registers its emitter before invoking the runner and removes it once the\n // run is finalized (via endRun/abortRun, success or failure). Anything left\n // here after the pool settles is an orphan we must abort.\n const openRuns = new Map<string, TraceEmitter>()\n\n async function worker(): Promise<void> {\n while (!aborting) {\n const i = cursor++\n if (i >= cells.length) return\n const cell = cells[i]!\n try {\n const result = await runOneCell(cell)\n runs.push(result.record)\n integrityReports.push(result.integrity)\n } catch (err) {\n if (err instanceof CellExecutionError) {\n failedRuns.push(err.failed)\n if (err.integrity) integrityReports.push(err.integrity)\n } else {\n // Genuine bug — not a runner failure, not an integrity failure.\n // Capture it and stop dispatching so peers wind down gracefully;\n // re-thrown after the pool settles. Do not surface here — that would\n // reject Promise.all and orphan the other workers' runs.\n genuineErrors.push(err)\n aborting = true\n return\n }\n }\n }\n }\n\n async function runOneCell(\n cell: Cell,\n ): Promise<{ record: RunRecord; integrity: RunIntegrityReport }> {\n const runId = (opts.runId ?? defaultRunId)({\n campaignId: opts.campaignId,\n runId: '', // unused by default generator\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n })\n const factoryParams: CampaignFactoryParams = {\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n }\n const store = opts.storeFactory(factoryParams)\n const rawSink = rawSinkFactory(factoryParams)\n\n const emitter = new TraceEmitter(store, {\n runId,\n now: opts.now,\n onRunComplete: opts.onRunComplete,\n })\n // Track this run as open so a genuine error elsewhere in the pool can\n // finalize it instead of orphaning it. Removed in the finally below.\n openRuns.set(runId, emitter)\n\n const chat = opts.chatFactory({ rawSink, runId })\n\n const ctx: CampaignRunContext<V> = {\n runId,\n experimentId: opts.campaignId,\n variant: cell.variant.payload,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n scenarioTags: cell.scenario.tags ?? {},\n seed: cell.seed,\n splitTag,\n emitter,\n store,\n rawSink,\n chat,\n }\n\n try {\n const wallStart = now()\n let outcome: CampaignRunOutcome\n try {\n outcome = await opts.runner(ctx)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // The runner threw mid-execution. Abort the run so the emitter\n // finalizes. The only benign abortRun failure is \"the runner never\n // started the run\" (nothing to finalize). A store-write failure (disk\n // full, FS error) is a genuine diagnostic — surface it rather than\n // masking it as a plain runner failure.\n await finalizeAbort(emitter, runId, message)\n throw new CellExecutionError({\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'runner_threw',\n error: message,\n })\n }\n const wallMs = now() - wallStart\n\n const integrityReport = await assertRunCaptured(store, runId, { ...integrity, rawSink })\n if (!integrityReport.ok) {\n switch (onIntegrityFailure) {\n case 'throw':\n throw new RunIntegrityError(integrityReport)\n case 'mark_failed':\n throw new CellExecutionError(\n {\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'integrity_failed',\n error: integrityReport.issues.map((i) => i.code).join(', '),\n },\n integrityReport,\n )\n case 'log':\n // Caller wants the run admitted with a flagged report; fall through.\n break\n }\n }\n\n const recordOutcome: RunOutcome = {\n raw: outcome.raw ?? {},\n }\n if (splitTag === 'holdout') recordOutcome.holdoutScore = outcome.score\n else recordOutcome.searchScore = outcome.score\n if (outcome.judgeScores !== undefined) recordOutcome.judgeScores = outcome.judgeScores\n\n const record: RunRecord = {\n runId,\n experimentId: opts.campaignId,\n candidateId: cell.variant.id,\n seed: cell.seed,\n model: outcome.model,\n promptHash: outcome.promptHash,\n configHash: outcome.configHash,\n commitSha: opts.commitSha,\n wallMs,\n costUsd: outcome.costUsd,\n costProvenance: outcome.costProvenance,\n tokenUsage: outcome.tokenUsage,\n terminalOutcome: 'succeeded',\n judgeMetadata: outcome.judgeMetadata,\n outcome: recordOutcome,\n ...(outcome.failureClass ? { failureClass: outcome.failureClass } : {}),\n failureMode: outcome.failureMode,\n splitTag,\n scenarioId: cell.scenario.scenarioId,\n }\n const profileSource =\n outcome.agentProfile ??\n (typeof opts.agentProfile === 'function'\n ? await opts.agentProfile({\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n variant: cell.variant.payload,\n scenarioTags: cell.scenario.tags ?? {},\n })\n : opts.agentProfile)\n if (profileSource !== undefined) {\n const agentProfile = await resolveAgentProfileCell(profileSource)\n assertAgentProfileMatchesRun(agentProfile, outcome.model, outcome.promptHash)\n record.agentProfile = agentProfile\n }\n return { record: validateRunRecord(record), integrity: integrityReport }\n } finally {\n // This run's worker has finished with it (success, run-level failure, or\n // genuine error). It is no longer the pool's job to finalize — drop it so\n // the post-settle sweep doesn't double-abort a finalized run.\n openRuns.delete(runId)\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, cells.length) }, () => worker())\n // allSettled (not all): a genuine error in one worker must not reject the\n // pool mid-flight and orphan the others. Each worker captures its own\n // genuine error into `genuineErrors` and returns; we re-throw below.\n await Promise.allSettled(workers)\n\n // Finalize any run still open after the pool wound down. With the\n // stop-dispatch flag these are the runs that were mid-flight in peer workers\n // when the first genuine error fired — abort them so their emitters finalize\n // (hooks fire, store records a terminal status) instead of leaking.\n for (const [runId, emitter] of openRuns) {\n await finalizeAbort(emitter, runId, 'campaign aborted: genuine error in a sibling run')\n }\n openRuns.clear()\n\n if (genuineErrors.length > 0) {\n throw genuineErrors.length === 1\n ? genuineErrors[0]\n : new AggregateError(\n genuineErrors,\n `runEvalCampaign: ${genuineErrors.length} runs failed with genuine (non-run-level) errors`,\n )\n }\n\n // ── Optional research report ───────────────────────────────────────\n let report: ResearchReport | undefined\n if (opts.report) {\n const reportOpts: ResearchReportOptions = {\n ...opts.report,\n comparator: opts.report.comparator,\n split: splitTag === 'dev' ? 'search' : splitTag,\n generatedAt: new Date(now()).toISOString(),\n preregistrationHash: preregistrationHash ?? undefined,\n }\n report = await researchReport(runs, reportOpts)\n }\n\n const endedAt = new Date(now()).toISOString()\n\n return {\n campaignId: opts.campaignId,\n campaignFingerprint,\n preregistrationHash,\n runs,\n integrityReports,\n failedRuns,\n report,\n startedAt,\n endedAt,\n }\n}\n\n// ── Internal ─────────────────────────────────────────────────────────────\n\nclass CellExecutionError extends Error {\n readonly failed: FailedRun\n readonly integrity?: RunIntegrityReport\n constructor(failed: FailedRun, integrity?: RunIntegrityReport) {\n super(`cell ${failed.variantId}/${failed.scenarioId}@${failed.seed} failed: ${failed.reason}`)\n this.failed = failed\n this.integrity = integrity\n }\n}\n\n/**\n * Abort a run whose owning work threw or was orphaned by a sibling's genuine\n * error, finalizing the emitter so hooks fire and the store records a terminal\n * status. Safe to call unconditionally: it only aborts runs that are still\n * `running`. Two no-op cases are intentional and benign:\n *\n * - the run was never started (absent from the store) — nothing to finalize\n * - the run is already terminal (`completed` / `failed` / `aborted`) —\n * finalizing again would overwrite the real outcome (e.g. flip a passed run\n * to `aborted` with `{ pass: false, notes: reason }`), so we leave it alone\n *\n * Any OTHER failure of the store read or the abort write (disk full, FS fault,\n * backend down) is a genuine diagnostic and propagates rather than being\n * swallowed.\n */\nasync function finalizeAbort(\n emitter: TraceEmitter,\n runId: string,\n reason: string,\n): Promise<void> {\n const existing = await emitter.traceStore.getRun(runId)\n if (existing === undefined) return // run never started; nothing to abort\n if (existing.status !== 'running') return // already finalized; never overwrite a real outcome\n // The emitter never throws on a failed store write; it counts it. A failed\n // abort write is a genuine diagnostic here, so read the count and surface it.\n const droppedBefore = emitter.captureStats().dropped\n await emitter.abortRun(reason)\n const after = emitter.captureStats()\n if (after.dropped > droppedBefore) {\n throw new Error(`finalizeAbort: run ${runId} could not be finalized: ${after.lastError}`)\n }\n}\n\nfunction defaultRawSinkFactory(workDir: string | undefined) {\n return (params: CampaignFactoryParams): RawProviderSink => {\n if (!workDir) {\n throw new Error(\n 'runEvalCampaign: rawSinkFactory not supplied and workDir not set. Pass either to enable raw provider capture, or pass `new NoopRawProviderSink()` via rawSinkFactory to opt out explicitly.',\n )\n }\n return new FileSystemRawProviderSink({\n dir: `${workDir}/raw-events/${params.runId}`,\n })\n }\n}\n\nasync function resolveAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n if (isAgentProfileCell(input)) {\n if (!(await verifyAgentProfileCell(input))) {\n throw new Error(`runEvalCampaign: agentProfile.cellId does not match its content`)\n }\n return input\n }\n return buildAgentProfileCell(input)\n}\n\nfunction isAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): input is AgentProfileCell {\n return 'schemaVersion' in input && 'cellId' in input\n}\n\nfunction assertAgentProfileMatchesRun(\n profile: AgentProfileCell,\n model: string,\n promptHash: string,\n): void {\n if (profile.model !== undefined && profile.model !== model) {\n throw new Error(\n `runEvalCampaign: agentProfile.model \"${profile.model}\" does not match outcome.model \"${model}\"`,\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== promptHash) {\n throw new Error(\n `runEvalCampaign: agentProfile.promptHash \"${profile.promptHash}\" does not match outcome.promptHash \"${promptHash}\"`,\n )\n }\n}\n\nfunction defaultRunId(params: CampaignFactoryParams): string {\n // Stable across re-runs: fingerprint of (campaignId, variantId, scenarioId, seed).\n // Caller can override via opts.runId for non-deterministic IDs.\n const base = `${params.campaignId}::${params.variantId}::${params.scenarioId}::${params.seed}`\n // TWO 32-bit FNV-1a accumulators with different offsets, concatenated for a\n // 64-bit-wide id. Not crypto-grade; stability and uniqueness are what this\n // needs. Frozen: the value names a persisted cell, and the second\n // accumulator's offset is part of the identity, so no single-accumulator\n // helper can replace it.\n let h1 = 0x811c9dc5\n let h2 = 0x12345678\n for (let i = 0; i < base.length; i++) {\n const c = base.charCodeAt(i)\n h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0\n h2 = Math.imul(h2 ^ c, 0x9e3779b1) >>> 0\n }\n return `run-${h1.toString(16).padStart(8, '0')}${h2.toString(16).padStart(8, '0')}`\n}\n"],"mappings":"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"}
|