@tangle-network/agent-eval 0.150.2 → 0.161.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 +158 -1
- package/README.md +7 -3
- package/dist/{active-curriculum-C4mk67HP.js → active-curriculum-CD5TU2yW.js} +3 -13
- package/dist/active-curriculum-CD5TU2yW.js.map +1 -0
- package/dist/{agent-profile-cell-BkcRDikH.d.ts → agent-profile-cell-CTOZJUuE.d.ts} +4 -2
- package/dist/agent-profile-cell-CTOZJUuE.d.ts.map +1 -0
- package/dist/analyst/index.d.ts +19 -36
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +8 -8
- package/dist/analyst/index.js.map +1 -1
- package/dist/{backend-integrity-DOCa_QrR.d.ts → backend-integrity-DxuQCu_A.d.ts} +4 -3
- package/dist/backend-integrity-DxuQCu_A.d.ts.map +1 -0
- package/dist/{benchmark-BtAWA8nT.d.ts → benchmark-CGPp-kDC.d.ts} +3 -3
- package/dist/{benchmark-BtAWA8nT.d.ts.map → benchmark-CGPp-kDC.d.ts.map} +1 -1
- package/dist/{benchmark-command-BU1Las59.js → benchmark-command-BDC3Gocz.js} +26 -31
- package/dist/benchmark-command-BDC3Gocz.js.map +1 -0
- package/dist/benchmarks/index.d.ts +6 -19
- 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/campaign/index.d.ts +9 -9
- package/dist/campaign/index.js +7 -7
- package/dist/{campaign-la-gEYNz.js → campaign-BSmOwskD.js} +77 -795
- package/dist/campaign-BSmOwskD.js.map +1 -0
- package/dist/{canonical-D-XsTQ6_.js → canonical-IL-Bu-14.js} +26 -2
- package/dist/canonical-IL-Bu-14.js.map +1 -0
- package/dist/{capture-fetch-BBVFzhkk.d.ts → capture-fetch-CqwsJkkG.d.ts} +3 -3
- package/dist/{capture-fetch-BBVFzhkk.d.ts.map → capture-fetch-CqwsJkkG.d.ts.map} +1 -1
- package/dist/{chat-client-Bvmxedyv.js → chat-client-DlMlAeYI.js} +5 -55
- package/dist/{chat-client-Bvmxedyv.js.map → chat-client-DlMlAeYI.js.map} +1 -1
- package/dist/chat-json-call-6g5sJobJ.js +53 -0
- package/dist/chat-json-call-6g5sJobJ.js.map +1 -0
- package/dist/cli.js +54 -19
- package/dist/cli.js.map +1 -1
- package/dist/{client-LIuo-KPv.js → client-CX7KqIdB.js} +3 -3
- package/dist/client-CX7KqIdB.js.map +1 -0
- package/dist/{client-kPQYT_56.d.ts → client-L9VVPkim.d.ts} +4 -4
- package/dist/{client-kPQYT_56.d.ts.map → client-L9VVPkim.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +13 -27
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +14 -17
- package/dist/contract/index.js.map +1 -1
- package/dist/{counterfactual--bpysZF0.d.ts → counterfactual-BaFUWK3H.d.ts} +4 -4
- package/dist/{counterfactual--bpysZF0.d.ts.map → counterfactual-BaFUWK3H.d.ts.map} +1 -1
- package/dist/{counterfactual-lDfCx0Uz.js → counterfactual-D_VWavVm.js} +2 -2
- package/dist/{counterfactual-lDfCx0Uz.js.map → counterfactual-D_VWavVm.js.map} +1 -1
- package/dist/{dataset-CJjKqQfA.d.ts → dataset-DQqhOCPt.d.ts} +5 -4
- package/dist/{dataset-CJjKqQfA.d.ts.map → dataset-DQqhOCPt.d.ts.map} +1 -1
- package/dist/{default-registry-Cw0Ohdoj.d.ts → default-registry-G9CKMNkc.d.ts} +7 -8
- package/dist/{default-registry-Cw0Ohdoj.d.ts.map → default-registry-G9CKMNkc.d.ts.map} +1 -1
- package/dist/{define-agent-eval-CEQWL9Hy.d.ts → define-agent-eval-Dx1JnPEa.d.ts} +26 -6
- package/dist/define-agent-eval-Dx1JnPEa.d.ts.map +1 -0
- package/dist/{define-agent-eval-C8V8sMqP.js → define-agent-eval-h-s-sI-v.js} +15 -9
- package/dist/define-agent-eval-h-s-sI-v.js.map +1 -0
- package/dist/{dspy-rlm-engine-CBYlPvNy.js → dspy-rlm-engine-DptEII26.js} +95 -15
- package/dist/dspy-rlm-engine-DptEII26.js.map +1 -0
- package/dist/{emitter-CPBAhxum.js → emitter-BpYFQPj4.js} +2 -18
- package/dist/emitter-BpYFQPj4.js.map +1 -0
- package/dist/{emitter-DGQGoLyj.d.ts → emitter-D_jYSGRd.d.ts} +4 -20
- package/dist/{emitter-DGQGoLyj.d.ts.map → emitter-D_jYSGRd.d.ts.map} +1 -1
- package/dist/{engine-BLzhNzoY.d.ts → engine-Cu5qD5Fc.d.ts} +9 -11
- package/dist/{engine-BLzhNzoY.d.ts.map → engine-Cu5qD5Fc.d.ts.map} +1 -1
- package/dist/{eval-campaign-CQuZrLR_.js → eval-campaign-BsXWL2-2.js} +17 -28
- package/dist/eval-campaign-BsXWL2-2.js.map +1 -0
- package/dist/{exact-types-ccQAyut1.d.ts → exact-types-qnexxJ1Z.d.ts} +2 -2
- package/dist/{exact-types-ccQAyut1.d.ts.map → exact-types-qnexxJ1Z.d.ts.map} +1 -1
- package/dist/{exec-y-DCLqK7.js → exec-D9WpA2p-.js} +2 -2
- package/dist/exec-D9WpA2p-.js.map +1 -0
- package/dist/experiment/index.d.ts +45 -11
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +30 -11
- package/dist/experiment/index.js.map +1 -1
- package/dist/{experiment-tracker-0MhuPArU.d.ts → experiment-tracker-DCO6Cz4s.d.ts} +2 -2
- package/dist/{experiment-tracker-0MhuPArU.d.ts.map → experiment-tracker-DCO6Cz4s.d.ts.map} +1 -1
- package/dist/{exporters-q9iL-2Jf.js → exporters-Df7TgHFv.js} +3 -3
- package/dist/exporters-Df7TgHFv.js.map +1 -0
- package/dist/{external-optimizer-contracts-DbLsm4Po.d.ts → external-optimizer-contracts-szBJ_1vh.d.ts} +2 -2
- package/dist/{external-optimizer-contracts-DbLsm4Po.d.ts.map → external-optimizer-contracts-szBJ_1vh.d.ts.map} +1 -1
- package/dist/{external-optimizer-process-x9oEXKsU.js → external-optimizer-process-WosTBChy.js} +4 -4
- package/dist/{external-optimizer-process-x9oEXKsU.js.map → external-optimizer-process-WosTBChy.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-CKNb42oM.js → external-optimizer-subprocess-BIWbHpgD.js} +4 -4
- package/dist/{external-optimizer-subprocess-CKNb42oM.js.map → external-optimizer-subprocess-BIWbHpgD.js.map} +1 -1
- package/dist/{failure-cluster-BLURuWG4.d.ts → failure-cluster-CXL8NbEw.d.ts} +3 -3
- package/dist/{failure-cluster-BLURuWG4.d.ts.map → failure-cluster-CXL8NbEw.d.ts.map} +1 -1
- package/dist/{feedback-trajectory-DpTTjo0q.d.ts → feedback-trajectory-B3ZHaHV_.d.ts} +7 -7
- package/dist/{feedback-trajectory-DpTTjo0q.d.ts.map → feedback-trajectory-B3ZHaHV_.d.ts.map} +1 -1
- package/dist/fuzz.js +1 -1
- package/dist/{hf-dataset-XggBupCr.js → hf-dataset-D8_RNIis.js} +4 -4
- package/dist/{hf-dataset-XggBupCr.js.map → hf-dataset-D8_RNIis.js.map} +1 -1
- package/dist/hosted/index.d.ts +3 -14
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +2 -2
- package/dist/{index-Aj3WO3_a.d.ts → index-CGtH1piv.d.ts} +48 -26
- package/dist/index-CGtH1piv.d.ts.map +1 -0
- package/dist/{index-BNPtkBPf.d.ts → index-D-IiQIBB.d.ts} +5 -10
- package/dist/index-D-IiQIBB.d.ts.map +1 -0
- package/dist/{index-IQccV3Ou.d.ts → index-D-V8gCs_.d.ts} +13 -90
- package/dist/index-D-V8gCs_.d.ts.map +1 -0
- package/dist/{index-B8Ui1mr1.d.ts → index-lfaSeKSD.d.ts} +18 -2
- package/dist/index-lfaSeKSD.d.ts.map +1 -0
- package/dist/index-vrJugRal.d.ts +1 -0
- package/dist/index.d.ts +68 -56
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -110
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-BeT8KCgI.d.ts → insight-report-DRe8LB6d.d.ts} +4 -4
- package/dist/{insight-report-BeT8KCgI.d.ts.map → insight-report-DRe8LB6d.d.ts.map} +1 -1
- package/dist/{integrity-DL91tucI.js → integrity-CyWSSoQS.js} +2 -2
- package/dist/{integrity-DL91tucI.js.map → integrity-CyWSSoQS.js.map} +1 -1
- package/dist/{integrity-B0dZ96EO.d.ts → integrity-DUNX9Fao.d.ts} +3 -3
- package/dist/{integrity-B0dZ96EO.d.ts.map → integrity-DUNX9Fao.d.ts.map} +1 -1
- package/dist/{kind-factory-DmAa0h3K.js → kind-factory-DY8FdoXf.js} +3 -71
- package/dist/kind-factory-DY8FdoXf.js.map +1 -0
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +3 -3
- package/dist/{ledger-core-DTae9rv_.js → ledger-core-BOzlRygb.js} +2 -2
- package/dist/{ledger-core-DTae9rv_.js.map → ledger-core-BOzlRygb.js.map} +1 -1
- package/dist/{llm-client-Bg32RW0j.js → llm-client-hgDieDNN.js} +53 -98
- package/dist/llm-client-hgDieDNN.js.map +1 -0
- package/dist/{llm-judge-BqqMS8t7.js → llm-judge-BhasIPFT.js} +1135 -77
- package/dist/llm-judge-BhasIPFT.js.map +1 -0
- package/dist/{matrix-DrVnRp4G.d.ts → matrix-eXKRMHnL.d.ts} +74 -72
- package/dist/matrix-eXKRMHnL.d.ts.map +1 -0
- package/dist/meta-eval/index.d.ts +8 -6
- package/dist/meta-eval/index.d.ts.map +1 -1
- package/dist/meta-eval/index.js +8 -6
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/{mint-BV6tLVWl.js → mint-DfODW1KW.js} +3 -3
- package/dist/{mint-BV6tLVWl.js.map → mint-DfODW1KW.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +2 -8
- package/dist/multishot/golden/index.d.ts.map +1 -1
- package/dist/multishot/golden/index.js +56 -86
- package/dist/multishot/golden/index.js.map +1 -1
- package/dist/multishot/index.d.ts +11 -46
- package/dist/multishot/index.d.ts.map +1 -1
- package/dist/multishot/index.js +30 -83
- package/dist/multishot/index.js.map +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{opencode-sqlite-DJWAXLms.js → opencode-sqlite-eK6HW6dr.js} +2 -6
- package/dist/{opencode-sqlite-DJWAXLms.js.map → opencode-sqlite-eK6HW6dr.js.map} +1 -1
- package/dist/pipelines/index.d.ts +5 -5
- package/dist/pipelines/index.js +3 -3
- package/dist/{pre-registration-zFSLEiFU.d.ts → pre-registration-CzFCcwYk.d.ts} +55 -40
- package/dist/pre-registration-CzFCcwYk.d.ts.map +1 -0
- package/dist/pre-registration-KN9jkh58.js +110 -0
- package/dist/pre-registration-KN9jkh58.js.map +1 -0
- package/dist/{produced-state-Bnq4FaDO.js → produced-state-DZ89riy5.js} +8 -8
- package/dist/produced-state-DZ89riy5.js.map +1 -0
- package/dist/profile-cell.d.ts +1 -1
- package/dist/profile-cell.js +31 -5
- package/dist/profile-cell.js.map +1 -1
- package/dist/{promotion-policy-DLOUkYhI.d.ts → promotion-policy-DtnOIZvk.d.ts} +2 -2
- package/dist/{promotion-policy-DLOUkYhI.d.ts.map → promotion-policy-DtnOIZvk.d.ts.map} +1 -1
- package/dist/{query-Di7eEQ79.js → query-CHmMP42p.js} +20 -11
- package/dist/query-CHmMP42p.js.map +1 -0
- package/dist/{query-CJ_DX8vl.d.ts → query-DxPYqpmT.d.ts} +10 -4
- package/dist/query-DxPYqpmT.d.ts.map +1 -0
- package/dist/raw-provider-sink-BU29Sh8h.d.ts +134 -0
- package/dist/raw-provider-sink-BU29Sh8h.d.ts.map +1 -0
- package/dist/{registry-BQwrSYpC.d.ts → registry-8You7OK1.d.ts} +5 -7
- package/dist/{registry-BQwrSYpC.d.ts.map → registry-8You7OK1.d.ts.map} +1 -1
- package/dist/{release-confidence-BknrpBnO.js → release-confidence-DKfD2RYU.js} +28 -14
- package/dist/release-confidence-DKfD2RYU.js.map +1 -0
- package/dist/{release-confidence-4XrqlpFD.d.ts → release-confidence-Dqt0NFep.d.ts} +7 -6
- package/dist/release-confidence-Dqt0NFep.d.ts.map +1 -0
- package/dist/reporting.d.ts +3 -3
- package/dist/reporting.js +3 -3
- package/dist/{researcher-DJnoUE8c.d.ts → researcher-Cz565b7D.d.ts} +34 -21
- package/dist/researcher-Cz565b7D.d.ts.map +1 -0
- package/dist/{reward-hacking-62tojkQd.d.ts → reward-hacking-MBf7qpSB.d.ts} +2 -2
- package/dist/{reward-hacking-62tojkQd.d.ts.map → reward-hacking-MBf7qpSB.d.ts.map} +1 -1
- package/dist/{reward-hacking-C0x0xihA.js → reward-hacking-t4lB1yt8.js} +2 -2
- package/dist/{reward-hacking-C0x0xihA.js.map → reward-hacking-t4lB1yt8.js.map} +1 -1
- package/dist/rl.d.ts +11 -42
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +41 -24
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +3 -3
- package/dist/rollout/index.js +7 -7
- package/dist/{rollout-ytVQ7WT8.js → rollout-Dm2tSdiQ.js} +6 -6
- package/dist/{rollout-ytVQ7WT8.js.map → rollout-Dm2tSdiQ.js.map} +1 -1
- package/dist/{rubric-predictive-validity-CzxLoZge.js → rubric-predictive-validity-CK8SCOg-.js} +5 -15
- package/dist/rubric-predictive-validity-CK8SCOg-.js.map +1 -0
- package/dist/{rubric-predictive-validity-C7LnNvF2.d.ts → rubric-predictive-validity-CxycqzX5.d.ts} +4 -3
- package/dist/rubric-predictive-validity-CxycqzX5.d.ts.map +1 -0
- package/dist/{run-record-D2lDdSAz.js → run-record-BC0ebuRP.js} +2 -2
- package/dist/{run-record-D2lDdSAz.js.map → run-record-BC0ebuRP.js.map} +1 -1
- package/dist/{run-record-DVV82Gwh.d.ts → run-record-VVy4T9OW.d.ts} +3 -3
- package/dist/{run-record-DVV82Gwh.d.ts.map → run-record-VVy4T9OW.d.ts.map} +1 -1
- package/dist/{schema-BtVldJ3T.d.ts → schema-Bjgdsn73.d.ts} +2 -4
- package/dist/{schema-BtVldJ3T.d.ts.map → schema-Bjgdsn73.d.ts.map} +1 -1
- package/dist/{schema-Cef2cFmb.d.ts → schema-BzWDXhOR.d.ts} +2 -5
- package/dist/schema-BzWDXhOR.d.ts.map +1 -0
- package/dist/{schema-C6DW4ZHR.js → schema-C1aaAxTf.js} +2 -2
- package/dist/schema-C1aaAxTf.js.map +1 -0
- package/dist/{schema-CRhEY1SO.js → schema-k6ZBftVv.js} +2 -8
- package/dist/{schema-CRhEY1SO.js.map → schema-k6ZBftVv.js.map} +1 -1
- package/dist/{semantic-concept-judge-laMCnTLn.js → semantic-concept-judge-BSkKKHeq.js} +14 -38
- package/dist/semantic-concept-judge-BSkKKHeq.js.map +1 -0
- package/dist/{sequential-eprocess-CbUt2htw.js → sequential-eprocess-D1jKoihe.js} +49 -2
- package/dist/sequential-eprocess-D1jKoihe.js.map +1 -0
- package/dist/{sequential-C458DXNf.js → sequential-rYW-Ophm.js} +41 -16
- package/dist/sequential-rYW-Ophm.js.map +1 -0
- package/dist/{series-convergence-BxKEgBwA.d.ts → series-convergence-D9WgpXGi.d.ts} +2 -2
- package/dist/{series-convergence-BxKEgBwA.d.ts.map → series-convergence-D9WgpXGi.d.ts.map} +1 -1
- package/dist/{server-dIWwF3j_.js → server-BtFd4uzB.js} +19 -42
- package/dist/server-BtFd4uzB.js.map +1 -0
- package/dist/{skillopt-optimization-method-CPBlTcj5.js → skillopt-optimization-method-DbaekMcn.js} +794 -8
- package/dist/skillopt-optimization-method-DbaekMcn.js.map +1 -0
- package/dist/{skillopt-optimization-method-BDD_o1xE.d.ts → skillopt-optimization-method-x7TTF23P.d.ts} +20 -7
- package/dist/{skillopt-optimization-method-BDD_o1xE.d.ts.map → skillopt-optimization-method-x7TTF23P.d.ts.map} +1 -1
- package/dist/{statistical-heldout-_woZ9q9j.d.ts → statistical-heldout-Cy3EhjlC.d.ts} +21 -8
- package/dist/statistical-heldout-Cy3EhjlC.d.ts.map +1 -0
- package/dist/{steps-AmkT-GIM.d.ts → steps-CiNVJry_.d.ts} +2 -17
- package/dist/steps-CiNVJry_.d.ts.map +1 -0
- package/dist/{store-CT9YIIve.d.ts → store-B06JdC56.d.ts} +2 -2
- package/dist/{store-CT9YIIve.d.ts.map → store-B06JdC56.d.ts.map} +1 -1
- package/dist/{store-otlp-CDYWW_8N.js → store-otlp-C_Rq5I4D.js} +2 -2
- package/dist/{store-otlp-CDYWW_8N.js.map → store-otlp-C_Rq5I4D.js.map} +1 -1
- package/dist/{store-tool-spans-Br2_IUhm.d.ts → store-tool-spans-DPUG7UUY.d.ts} +6 -6
- package/dist/{store-tool-spans-Br2_IUhm.d.ts.map → store-tool-spans-DPUG7UUY.d.ts.map} +1 -1
- package/dist/{store-tool-spans-CykkbOlv.js → store-tool-spans-Dlh9vkFK.js} +3 -3
- package/dist/{store-tool-spans-CykkbOlv.js.map → store-tool-spans-Dlh9vkFK.js.map} +1 -1
- package/dist/storyboard/index.d.ts +1 -1
- package/dist/{summary-report-DW2bEpdB.js → summary-report-BI5hUtvK.js} +6 -16
- package/dist/summary-report-BI5hUtvK.js.map +1 -0
- package/dist/{summary-report-B__Y5ub3.d.ts → summary-report-CC07PhEL.d.ts} +6 -5
- package/dist/summary-report-CC07PhEL.d.ts.map +1 -0
- package/dist/supervisor-run/index.d.ts +3 -16
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +3 -3
- package/dist/supervisor-run/index.js.map +1 -1
- package/dist/{task-failure-attributes--ZTP3tYO.js → task-failure-attributes-DTl-7-Kw.js} +3 -3
- package/dist/{task-failure-attributes--ZTP3tYO.js.map → task-failure-attributes-DTl-7-Kw.js.map} +1 -1
- package/dist/{tool-groups-B4tqh8jB.d.ts → tool-groups-Ci8i9ErB.d.ts} +3 -3
- package/dist/tool-groups-Ci8i9ErB.d.ts.map +1 -0
- package/dist/{tool-waste-C-VHSRwF.js → tool-waste-BqzmVdJk.js} +2 -2
- package/dist/{tool-waste-C-VHSRwF.js.map → tool-waste-BqzmVdJk.js.map} +1 -1
- package/dist/{tool-waste-DjRDEsuI.d.ts → tool-waste-Dro0gJi3.d.ts} +4 -4
- package/dist/{tool-waste-DjRDEsuI.d.ts.map → tool-waste-Dro0gJi3.d.ts.map} +1 -1
- package/dist/trace-repair/index.d.ts +4 -77
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +5 -15
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +13 -23
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +9 -20
- package/dist/traces.js.map +1 -1
- package/dist/{trajectory-YC15QDYQ.d.ts → trajectory-Bi157Gun.d.ts} +3 -3
- package/dist/{trajectory-YC15QDYQ.d.ts.map → trajectory-Bi157Gun.d.ts.map} +1 -1
- package/dist/trajectory-replay/index.d.ts +5 -5
- package/dist/trajectory-replay/index.js +5 -5
- package/dist/{provenance-oA4-zUqm.d.ts → transient-failure-DKF5Mofa.d.ts} +468 -13
- package/dist/transient-failure-DKF5Mofa.d.ts.map +1 -0
- package/dist/types-B3jzCp0p.js.map +1 -1
- package/dist/{types-CLAwnY-L.d.ts → types-BPb2Kf_C2.d.ts} +3 -3
- package/dist/types-BPb2Kf_C2.d.ts.map +1 -0
- package/dist/types-Bfk0uxRj.d.ts +443 -0
- package/dist/types-Bfk0uxRj.d.ts.map +1 -0
- package/dist/{types-DdFNuyxQ.d.ts → types-D4s7Z6nq.d.ts} +30 -6
- package/dist/types-D4s7Z6nq.d.ts.map +1 -0
- package/dist/{types-B2NsbrNy.d.ts → types-D9ssmxKL.d.ts} +3 -3
- package/dist/{types-B2NsbrNy.d.ts.map → types-D9ssmxKL.d.ts.map} +1 -1
- package/dist/{types-I5WwVzQ7.d.ts → types-DeIUdzNd.d.ts} +2 -2
- package/dist/{types-I5WwVzQ7.d.ts.map → types-DeIUdzNd.d.ts.map} +1 -1
- package/dist/{verdict-BndeTAh_.js → verdict-B0xltqu6.js} +2 -2
- package/dist/{verdict-BndeTAh_.js.map → verdict-B0xltqu6.js.map} +1 -1
- package/dist/verdict-cache-CdVVTVmn.js +88 -0
- package/dist/verdict-cache-CdVVTVmn.js.map +1 -0
- package/dist/wire/index.d.ts +21 -111
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +2 -2
- package/docs/building-doctrine.md +3 -3
- package/docs/campaign-proposers.md +41 -10
- package/docs/design/statistics-decisions.md +89 -1
- package/docs/eval-surface-map.md +14 -0
- package/docs/experiment.md +19 -2
- package/docs/feedback-trajectories.md +1 -1
- package/docs/multishot-golden-records.md +4 -4
- package/docs/public-api.md +1616 -0
- package/docs/research-report-methodology.md +1 -1
- package/docs/search-history-receipts.md +39 -1
- package/docs/trace-analysis.md +1 -1
- package/docs/trace-repair-admission.md +1 -1
- package/docs/trace-repair-continuation.md +1 -1
- package/docs/verdicts.md +24 -0
- package/package.json +7 -3
- package/dist/active-curriculum-C4mk67HP.js.map +0 -1
- package/dist/agent-profile-cell-BkcRDikH.d.ts.map +0 -1
- package/dist/backend-integrity-DOCa_QrR.d.ts.map +0 -1
- package/dist/benchmark-command-BU1Las59.js.map +0 -1
- package/dist/campaign-la-gEYNz.js.map +0 -1
- package/dist/canonical-D-XsTQ6_.js.map +0 -1
- package/dist/client-LIuo-KPv.js.map +0 -1
- package/dist/define-agent-eval-C8V8sMqP.js.map +0 -1
- package/dist/define-agent-eval-CEQWL9Hy.d.ts.map +0 -1
- package/dist/dspy-rlm-engine-CBYlPvNy.js.map +0 -1
- package/dist/emitter-CPBAhxum.js.map +0 -1
- package/dist/eval-campaign-CQuZrLR_.js.map +0 -1
- package/dist/exec-y-DCLqK7.js.map +0 -1
- package/dist/exporters-q9iL-2Jf.js.map +0 -1
- package/dist/index-Aj3WO3_a.d.ts.map +0 -1
- package/dist/index-B8Ui1mr1.d.ts.map +0 -1
- package/dist/index-BNPtkBPf.d.ts.map +0 -1
- package/dist/index-C1ravkGA.d.ts +0 -1
- package/dist/index-IQccV3Ou.d.ts.map +0 -1
- package/dist/kind-factory-DmAa0h3K.js.map +0 -1
- package/dist/llm-client-Bg32RW0j.js.map +0 -1
- package/dist/llm-judge-BqqMS8t7.js.map +0 -1
- package/dist/matrix-DrVnRp4G.d.ts.map +0 -1
- package/dist/pre-registration-DakwTRXk.js +0 -96
- package/dist/pre-registration-DakwTRXk.js.map +0 -1
- package/dist/pre-registration-zFSLEiFU.d.ts.map +0 -1
- package/dist/produced-state-Bnq4FaDO.js.map +0 -1
- package/dist/provenance-oA4-zUqm.d.ts.map +0 -1
- package/dist/query-CJ_DX8vl.d.ts.map +0 -1
- package/dist/query-Di7eEQ79.js.map +0 -1
- package/dist/release-confidence-4XrqlpFD.d.ts.map +0 -1
- package/dist/release-confidence-BknrpBnO.js.map +0 -1
- package/dist/researcher-DJnoUE8c.d.ts.map +0 -1
- package/dist/rubric-predictive-validity-C7LnNvF2.d.ts.map +0 -1
- package/dist/rubric-predictive-validity-CzxLoZge.js.map +0 -1
- package/dist/schema-C6DW4ZHR.js.map +0 -1
- package/dist/schema-Cef2cFmb.d.ts.map +0 -1
- package/dist/semantic-concept-judge-laMCnTLn.js.map +0 -1
- package/dist/sequential-C458DXNf.js.map +0 -1
- package/dist/sequential-eprocess-CbUt2htw.js.map +0 -1
- package/dist/server-dIWwF3j_.js.map +0 -1
- package/dist/skillopt-optimization-method-CPBlTcj5.js.map +0 -1
- package/dist/statistical-heldout-_woZ9q9j.d.ts.map +0 -1
- package/dist/steps-AmkT-GIM.d.ts.map +0 -1
- package/dist/summary-report-B__Y5ub3.d.ts.map +0 -1
- package/dist/summary-report-DW2bEpdB.js.map +0 -1
- package/dist/tool-groups-B4tqh8jB.d.ts.map +0 -1
- package/dist/types-CLAwnY-L.d.ts.map +0 -1
- package/dist/types-DdFNuyxQ.d.ts.map +0 -1
- package/dist/types-jUBXJ7Iz.d.ts +0 -884
- package/dist/types-jUBXJ7Iz.d.ts.map +0 -1
- package/dist/verdict-cache-mZf5FEiY.js +0 -107
- package/dist/verdict-cache-mZf5FEiY.js.map +0 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { i as JudgeError, s as ValidationError, t as AgentEvalError } from "./errors-Dngq5h35.js";
|
|
2
|
+
import { i as hashCanonical, r as canonicalString } from "./canonical-IL-Bu-14.js";
|
|
2
3
|
import { s as weightedComposite, t as confidenceInterval } from "./descriptive-jDOuI6mz.js";
|
|
3
4
|
import { r as pairedBootstrap } from "./paired-tests-BHIhYVdu.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { i as modelHasSnapshot } from "./run-record-BC0ebuRP.js";
|
|
6
|
+
import { n as contentHash } from "./verdict-cache-CdVVTVmn.js";
|
|
7
|
+
import { a as campaignCellCostProvenance, o as campaignCellExecutionEvidence, t as detectRewardHacking, u as projectCampaignCellQuality } from "./reward-hacking-t4lB1yt8.js";
|
|
6
8
|
import { i as CostLedger, t as CostAccountingIncompleteError } from "./cost-ledger-B1qx30B4.js";
|
|
7
|
-
import { u as mapConcurrent } from "./ledger-core-
|
|
8
|
-
import {
|
|
9
|
-
import { b as createRunCostLedger, h as isRecord, m as isExternalTextCandidate, x as fsCampaignStorage } from "./external-optimizer-subprocess-CKNb42oM.js";
|
|
9
|
+
import { u as mapConcurrent } from "./ledger-core-BOzlRygb.js";
|
|
10
|
+
import { b as createRunCostLedger, h as isRecord, m as isExternalTextCandidate, x as fsCampaignStorage } from "./external-optimizer-subprocess-BIWbHpgD.js";
|
|
10
11
|
import { t as DEFAULT_REDACTION_RULES } from "./redact-7Aq1ukl-.js";
|
|
11
12
|
import { a as heldoutSignificance, i as dimensionRegressions, o as pairHoldout } from "./power-preflight-DEw-uC7q.js";
|
|
12
13
|
import { a as combineAbortSignals, n as clamp01, r as assertProposalFindings } from "./run-score-lDzV0X8j.js";
|
|
13
14
|
import { c as deepFreezeCanonicalJson } from "./types-BI4fT3HN.js";
|
|
14
|
-
import {
|
|
15
|
+
import { d as stripFencedJson, o as costReceiptFromLlm, s as costReceiptFromLlmError, u as maximumChargeForLlmRequest } from "./llm-client-hgDieDNN.js";
|
|
15
16
|
import { createHash } from "node:crypto";
|
|
16
17
|
import { writeFileSync } from "node:fs";
|
|
17
18
|
import { z } from "zod";
|
|
@@ -795,12 +796,13 @@ async function executeCell(args) {
|
|
|
795
796
|
durationMs: Date.now() - startMs,
|
|
796
797
|
seed: args.slot.cellSeed,
|
|
797
798
|
cached: false,
|
|
799
|
+
...args.attempt > 1 ? { retryAttempts: args.attempt - 1 } : {},
|
|
798
800
|
...failure ? { errorStage: failure.stage } : {},
|
|
799
801
|
...failure?.judge ? { errorJudge: failure.judge } : {},
|
|
800
802
|
error: errorMessage
|
|
801
803
|
};
|
|
804
|
+
let retry = false;
|
|
802
805
|
if (failure) {
|
|
803
|
-
const failurePath = join(cellDir, "failure-receipt.json");
|
|
804
806
|
const receipt = {
|
|
805
807
|
schemaVersion: 1,
|
|
806
808
|
runAttemptId: args.runAttemptId,
|
|
@@ -816,9 +818,12 @@ async function executeCell(args) {
|
|
|
816
818
|
tags: costTags
|
|
817
819
|
})
|
|
818
820
|
};
|
|
821
|
+
retry = args.cellRetry !== void 0 && args.attempt < args.cellRetry.attempts && !args.signal.aborted && fatalCellError === void 0 && args.cellRetry.retryable(receipt.failure);
|
|
822
|
+
const receiptName = retry ? `failure-receipt.attempt-${args.attempt}.json` : "failure-receipt.json";
|
|
823
|
+
const failurePath = join(cellDir, receiptName);
|
|
819
824
|
storage.write(failurePath, JSON.stringify(receipt, null, 2));
|
|
820
|
-
artifactsByPath[`${args.slot.cellId}
|
|
821
|
-
args.onFailure?.(failure);
|
|
825
|
+
artifactsByPath[`${args.slot.cellId}/${receiptName}`] = failurePath;
|
|
826
|
+
if (!retry) args.onFailure?.(failure);
|
|
822
827
|
}
|
|
823
828
|
await trace.flush();
|
|
824
829
|
if (!errorMessage && args.resumable) storage.write(cachePath, JSON.stringify(cell));
|
|
@@ -826,7 +831,8 @@ async function executeCell(args) {
|
|
|
826
831
|
return {
|
|
827
832
|
cell,
|
|
828
833
|
artifactsByPath,
|
|
829
|
-
...failure ? { failure } : {}
|
|
834
|
+
...failure ? { failure } : {},
|
|
835
|
+
...retry ? { retry } : {}
|
|
830
836
|
};
|
|
831
837
|
}
|
|
832
838
|
async function waitForFailedCellCostSettlement(input) {
|
|
@@ -1047,6 +1053,11 @@ async function runCampaign(opts) {
|
|
|
1047
1053
|
const dispatchShutdownTimeoutMs = opts.dispatchShutdownTimeoutMs ?? 5e3;
|
|
1048
1054
|
assertCampaignDesign(opts.scenarios, reps);
|
|
1049
1055
|
if (!Number.isSafeInteger(dispatchShutdownTimeoutMs) || dispatchShutdownTimeoutMs <= 0) throw new Error("runCampaign: dispatchShutdownTimeoutMs must be a positive safe integer");
|
|
1056
|
+
const cellRetry = opts.cellRetry;
|
|
1057
|
+
if (cellRetry !== void 0) {
|
|
1058
|
+
if (!Number.isSafeInteger(cellRetry.attempts) || cellRetry.attempts < 1) throw new Error("runCampaign: cellRetry.attempts must be a positive safe integer (total attempts, including the first)");
|
|
1059
|
+
if (typeof cellRetry.retryable !== "function") throw new Error("runCampaign: cellRetry.retryable must be a function");
|
|
1060
|
+
}
|
|
1050
1061
|
if (typeof opts.runDir !== "string" || opts.runDir.trim().length === 0) throw new Error("runCampaign: runDir is required and must be a non-empty string");
|
|
1051
1062
|
opts.runDir = resolveRunDir(opts.runDir, opts.repo);
|
|
1052
1063
|
storage.ensureDir(opts.runDir);
|
|
@@ -1099,29 +1110,37 @@ async function runCampaign(opts) {
|
|
|
1099
1110
|
const myIdx = nextIdx++;
|
|
1100
1111
|
if (myIdx >= schedule.length) return;
|
|
1101
1112
|
const slot = schedule[myIdx];
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1113
|
+
let attempt = 1;
|
|
1114
|
+
let result;
|
|
1115
|
+
while (true) {
|
|
1116
|
+
result = await executeCell({
|
|
1117
|
+
slot,
|
|
1118
|
+
opts,
|
|
1119
|
+
manifestHash,
|
|
1120
|
+
resumable,
|
|
1121
|
+
now,
|
|
1122
|
+
storage,
|
|
1123
|
+
buildTraceWriter: opts.buildTraceWriter ?? defaultBuildTraceWriter(storage),
|
|
1124
|
+
signal: campaignSignal,
|
|
1125
|
+
dispatchTimeoutMs: opts.dispatchTimeoutMs,
|
|
1126
|
+
dispatchShutdownTimeoutMs,
|
|
1127
|
+
costLedger,
|
|
1128
|
+
costPhase,
|
|
1129
|
+
runAttemptId,
|
|
1130
|
+
attempt,
|
|
1131
|
+
cellRetry,
|
|
1132
|
+
onFailure: opts.abortOnCellError ? (failure) => {
|
|
1133
|
+
if (firstCellFailure === void 0) {
|
|
1134
|
+
firstCellFailure = failure;
|
|
1135
|
+
campaignAbort.abort(failure.cause);
|
|
1136
|
+
}
|
|
1137
|
+
} : void 0
|
|
1138
|
+
});
|
|
1139
|
+
Object.assign(artifactsByPath, result.artifactsByPath);
|
|
1140
|
+
if (!result.retry) break;
|
|
1141
|
+
attempt += 1;
|
|
1142
|
+
}
|
|
1123
1143
|
cellsRef.push(result.cell);
|
|
1124
|
-
Object.assign(artifactsByPath, result.artifactsByPath);
|
|
1125
1144
|
if (opts.labeledStore && opts.labeledStore !== "off" && !result.cell.error) await captureToStore({
|
|
1126
1145
|
store: opts.labeledStore,
|
|
1127
1146
|
cell: result.cell,
|
|
@@ -1641,11 +1660,12 @@ var Dataset = class Dataset {
|
|
|
1641
1660
|
this.scenarios.splice(idx, 1);
|
|
1642
1661
|
}
|
|
1643
1662
|
/**
|
|
1644
|
-
* Stable JSON-Lines serialization —
|
|
1645
|
-
* Write to disk for
|
|
1663
|
+
* Stable JSON-Lines serialization — one RFC 8785 canonical row per scenario,
|
|
1664
|
+
* sorted by id, deterministic byte-for-byte. Write to disk for
|
|
1665
|
+
* contamination-verifiable archives.
|
|
1646
1666
|
*/
|
|
1647
1667
|
toJsonl() {
|
|
1648
|
-
return `${this.scenarios.slice().sort((a, b) => a.id.localeCompare(b.id)).map((s) =>
|
|
1668
|
+
return `${this.scenarios.slice().sort((a, b) => a.id.localeCompare(b.id)).map((s) => canonicalString(s)).join("\n")}\n`;
|
|
1649
1669
|
}
|
|
1650
1670
|
static fromJsonl(jsonl, manifest) {
|
|
1651
1671
|
const scenarios = [];
|
|
@@ -1661,20 +1681,15 @@ var Dataset = class Dataset {
|
|
|
1661
1681
|
});
|
|
1662
1682
|
}
|
|
1663
1683
|
};
|
|
1684
|
+
/**
|
|
1685
|
+
* Hex sha-256 over the RFC 8785 canonical JSON of the scenarios sorted by id,
|
|
1686
|
+
* so the digest is independent of insertion order. A scenario with no
|
|
1687
|
+
* canonical JSON form (an `undefined`-valued field, a non-finite number, a
|
|
1688
|
+
* class instance) is refused: the digest is the dataset's identity and a
|
|
1689
|
+
* coerced field would let two different datasets share one.
|
|
1690
|
+
*/
|
|
1664
1691
|
async function hashScenarios(scenarios) {
|
|
1665
|
-
|
|
1666
|
-
const text = JSON.stringify(canonical);
|
|
1667
|
-
const bytes = new TextEncoder().encode(text);
|
|
1668
|
-
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
1669
|
-
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1670
|
-
}
|
|
1671
|
-
function canonicalize(v) {
|
|
1672
|
-
if (v === null || typeof v !== "object") return v;
|
|
1673
|
-
if (Array.isArray(v)) return v.map(canonicalize);
|
|
1674
|
-
const keys = Object.keys(v).sort();
|
|
1675
|
-
const out = {};
|
|
1676
|
-
for (const k of keys) out[k] = canonicalize(v[k]);
|
|
1677
|
-
return out;
|
|
1692
|
+
return hashCanonical(scenarios.slice().sort((a, b) => a.id.localeCompare(b.id))).slice(7);
|
|
1678
1693
|
}
|
|
1679
1694
|
/** Splitmix-ish deterministic shuffle — small, self-contained, no deps. */
|
|
1680
1695
|
function seededShuffle(items, seed) {
|
|
@@ -2893,9 +2908,9 @@ function createSearchHistoryReceipt(input) {
|
|
|
2893
2908
|
/** Verify the bounded receipt. Full ledger bytes are verified by SearchLedger. */
|
|
2894
2909
|
function verifySearchHistoryReceipt(receipt) {
|
|
2895
2910
|
if (!receipt || typeof receipt !== "object") throw new TypeError("search history receipt is required");
|
|
2896
|
-
if (receipt.schemaVersion !==
|
|
2911
|
+
if (receipt.schemaVersion !== SEARCH_HISTORY_RECEIPT_SCHEMA_VERSION) throw new Error(`unsupported search history schemaVersion '${receipt.schemaVersion}'`);
|
|
2897
2912
|
if (receipt.kind !== "search-history-receipt") throw new Error(`search history kind must be 'search-history-receipt'`);
|
|
2898
|
-
if (receipt.digestAlgorithm !==
|
|
2913
|
+
if (receipt.digestAlgorithm !== SEARCH_HISTORY_RECEIPT_DIGEST_ALGORITHM) throw new Error(`unsupported search history digestAlgorithm '${receipt.digestAlgorithm}'`);
|
|
2899
2914
|
const producerId = nonEmpty(receipt.producerId, "search history producerId");
|
|
2900
2915
|
const runId = nonEmpty(receipt.runId, "search history runId");
|
|
2901
2916
|
const ledger = normalizeArtifactRef(receipt.ledger);
|
|
@@ -3833,6 +3848,845 @@ function paretoFrontier(candidates, objectives) {
|
|
|
3833
3848
|
}))
|
|
3834
3849
|
};
|
|
3835
3850
|
}
|
|
3851
|
+
/**
|
|
3852
|
+
* NSGA-II crowding distance — secondary sort for ties on the frontier.
|
|
3853
|
+
*
|
|
3854
|
+
* When the Pareto front collapses to a single point (or many candidates tie
|
|
3855
|
+
* on dominance), naive selection picks arbitrarily and the population
|
|
3856
|
+
* degenerates over generations. NSGA-II preserves diversity by preferring
|
|
3857
|
+
* candidates with more empty space around them on the frontier.
|
|
3858
|
+
*
|
|
3859
|
+
* Returns an array of `{ candidate, distance }` in the SAME order as the
|
|
3860
|
+
* input. Higher distance = more isolated = should be preferred when
|
|
3861
|
+
* preserving diversity.
|
|
3862
|
+
*/
|
|
3863
|
+
function crowdingDistance(candidates, objectives) {
|
|
3864
|
+
const distances = new Map(candidates.map((c) => [c, 0]));
|
|
3865
|
+
for (const obj of objectives) {
|
|
3866
|
+
const sorted = [...candidates].sort((a, b) => obj.value(a) - obj.value(b));
|
|
3867
|
+
const min = obj.value(sorted[0]);
|
|
3868
|
+
const range = obj.value(sorted[sorted.length - 1]) - min || 1;
|
|
3869
|
+
distances.set(sorted[0], Infinity);
|
|
3870
|
+
distances.set(sorted[sorted.length - 1], Infinity);
|
|
3871
|
+
for (let i = 1; i < sorted.length - 1; i++) {
|
|
3872
|
+
const prev = obj.value(sorted[i - 1]);
|
|
3873
|
+
const next = obj.value(sorted[i + 1]);
|
|
3874
|
+
const current = distances.get(sorted[i]);
|
|
3875
|
+
if (current === Infinity) continue;
|
|
3876
|
+
distances.set(sorted[i], current + (next - prev) / range);
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
return candidates.map((c) => ({
|
|
3880
|
+
candidate: c,
|
|
3881
|
+
distance: distances.get(c) ?? 0
|
|
3882
|
+
}));
|
|
3883
|
+
}
|
|
3884
|
+
/**
|
|
3885
|
+
* Pareto frontier with tie-break by crowding distance — the canonical
|
|
3886
|
+
* NSGA-II selection step. Returns the frontier sorted by descending crowding
|
|
3887
|
+
* distance so callers can `.slice(0, k)` to pick K diverse winners.
|
|
3888
|
+
*/
|
|
3889
|
+
function paretoFrontierWithCrowding(candidates, objectives) {
|
|
3890
|
+
const { frontier } = paretoFrontier(candidates, objectives);
|
|
3891
|
+
if (frontier.length === 0) return [];
|
|
3892
|
+
return crowdingDistance(frontier, objectives).sort((a, b) => b.distance - a.distance);
|
|
3893
|
+
}
|
|
3894
|
+
//#endregion
|
|
3895
|
+
//#region src/campaign/search-ledger-recording.ts
|
|
3896
|
+
const SEARCH_LEDGER_DIR = "search-ledger";
|
|
3897
|
+
/**
|
|
3898
|
+
* Recorder for one `runOptimization` run: `open()`, then `recordGeneration()`
|
|
3899
|
+
* and `recordResults()` per generation, then `finish()`.
|
|
3900
|
+
*
|
|
3901
|
+
* Every event id is derived from the run, and an id already durable is not
|
|
3902
|
+
* appended again, so a resumed run continues one ledger instead of conflicting
|
|
3903
|
+
* with its own history.
|
|
3904
|
+
*/
|
|
3905
|
+
var SearchRecorder = class SearchRecorder {
|
|
3906
|
+
opts;
|
|
3907
|
+
tasks;
|
|
3908
|
+
registered = /* @__PURE__ */ new Map();
|
|
3909
|
+
order = [];
|
|
3910
|
+
coverage = /* @__PURE__ */ new Map();
|
|
3911
|
+
openSlots = /* @__PURE__ */ new Set();
|
|
3912
|
+
durableEventIds = /* @__PURE__ */ new Set();
|
|
3913
|
+
lastStampMs = 0;
|
|
3914
|
+
proposalReceiptCount = 0;
|
|
3915
|
+
constructor(opts) {
|
|
3916
|
+
this.opts = opts;
|
|
3917
|
+
this.tasks = plannedTasks(opts.scenarios, opts.reps, opts.runDir, opts.splitDigest);
|
|
3918
|
+
}
|
|
3919
|
+
/** Open the recorder and append the plan. An existing ledger for the same
|
|
3920
|
+
* run is re-read first, so a resumed run keeps one plan and one lineage. */
|
|
3921
|
+
static async open(opts) {
|
|
3922
|
+
const recorder = new SearchRecorder(opts);
|
|
3923
|
+
await recorder.hydrate();
|
|
3924
|
+
await recorder.plan();
|
|
3925
|
+
return recorder;
|
|
3926
|
+
}
|
|
3927
|
+
/**
|
|
3928
|
+
* Record one generation's candidate-generation call and the candidates it
|
|
3929
|
+
* produced. A proposal larger than the planned population extends the plan
|
|
3930
|
+
* with the extra slots; a proposal that fills fewer closes the rest.
|
|
3931
|
+
*/
|
|
3932
|
+
async recordGeneration(input) {
|
|
3933
|
+
const { generation, candidates } = input;
|
|
3934
|
+
const planned = this.opts.populationSize;
|
|
3935
|
+
if (candidates.length > planned) {
|
|
3936
|
+
const extra = [];
|
|
3937
|
+
for (let index = planned; index < candidates.length; index++) {
|
|
3938
|
+
const slot = {
|
|
3939
|
+
slotId: slotId(generation, index),
|
|
3940
|
+
generationOperationId: generationOperationId(generation)
|
|
3941
|
+
};
|
|
3942
|
+
extra.push(slot);
|
|
3943
|
+
this.openSlots.add(slot.slotId);
|
|
3944
|
+
}
|
|
3945
|
+
await this.append({
|
|
3946
|
+
kind: "search-plan-extended",
|
|
3947
|
+
eventId: `search:plan-extended:gen-${generation}`,
|
|
3948
|
+
occurredAt: this.stamp(),
|
|
3949
|
+
artifacts: [this.proposalArtifact(generation, candidates)],
|
|
3950
|
+
extension: {
|
|
3951
|
+
candidateSlots: extra,
|
|
3952
|
+
operations: []
|
|
3953
|
+
}
|
|
3954
|
+
});
|
|
3955
|
+
}
|
|
3956
|
+
await this.recordGenerationOperation(generation, candidates, planned - candidates.length);
|
|
3957
|
+
const parent = this.registered.get(input.parentSurfaceHash);
|
|
3958
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
3959
|
+
const candidateId = candidate.surfaceHash;
|
|
3960
|
+
const slot = slotId(generation, index);
|
|
3961
|
+
const surfaceArtifact = this.writeArtifact("candidate-surface", `candidate-${candidateId}.json`, {
|
|
3962
|
+
surfaceHash: candidateId,
|
|
3963
|
+
surface: candidate.surface,
|
|
3964
|
+
label: candidate.label ?? ""
|
|
3965
|
+
});
|
|
3966
|
+
const ledgerGeneration = parent ? parent.generation + 1 : 0;
|
|
3967
|
+
await this.append({
|
|
3968
|
+
kind: "candidate-registered",
|
|
3969
|
+
eventId: `candidate:${candidateId}`,
|
|
3970
|
+
occurredAt: this.stamp(),
|
|
3971
|
+
artifacts: [surfaceArtifact],
|
|
3972
|
+
slotId: slot,
|
|
3973
|
+
generationOperationId: generationOperationId(generation),
|
|
3974
|
+
candidateId,
|
|
3975
|
+
lineage: {
|
|
3976
|
+
lineageNodeId: candidateId,
|
|
3977
|
+
parentCandidateIds: parent ? [parent.candidateId] : [],
|
|
3978
|
+
generation: ledgerGeneration,
|
|
3979
|
+
proposer: this.opts.proposerLabel,
|
|
3980
|
+
proposerSource: this.opts.binding.identity.proposer.source
|
|
3981
|
+
},
|
|
3982
|
+
surfaces: candidateSurfaces(candidate.surface, surfaceArtifact)
|
|
3983
|
+
});
|
|
3984
|
+
this.remember({
|
|
3985
|
+
candidateId,
|
|
3986
|
+
slotId: slot,
|
|
3987
|
+
generation: ledgerGeneration
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
for (let index = candidates.length; index < planned; index++) await this.closeSlot(slotId(generation, index), generationOperationId(generation), {
|
|
3991
|
+
code: "proposal-short",
|
|
3992
|
+
message: `generation ${generation} proposed ${candidates.length} of ${planned} planned candidates`
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3995
|
+
/** Append one task attempt per designed cell of each candidate campaign. */
|
|
3996
|
+
async recordResults(candidates) {
|
|
3997
|
+
for (const candidate of candidates) {
|
|
3998
|
+
const registered = this.registered.get(candidate.surfaceHash);
|
|
3999
|
+
if (!registered) throw new Error(`search ledger: candidate ${candidate.surfaceHash} produced results without a registration`);
|
|
4000
|
+
this.coverage.set(registered.candidateId, candidate.coverageComplete);
|
|
4001
|
+
const evidence = this.writeArtifact("candidate-cells", `cells-${registered.candidateId}.json`, {
|
|
4002
|
+
surfaceHash: candidate.surfaceHash,
|
|
4003
|
+
runDir: candidate.runDir,
|
|
4004
|
+
cells: candidate.cells.map((cell) => ({
|
|
4005
|
+
cellId: cell.cellId,
|
|
4006
|
+
scenarioId: cell.scenarioId,
|
|
4007
|
+
rep: cell.rep,
|
|
4008
|
+
judgeScores: cell.judgeScores,
|
|
4009
|
+
costUsd: cell.costUsd,
|
|
4010
|
+
costProvenance: cell.costProvenance,
|
|
4011
|
+
tokenUsage: cell.tokenUsage,
|
|
4012
|
+
...cell.error === void 0 ? {} : {
|
|
4013
|
+
error: cell.error,
|
|
4014
|
+
errorStage: cell.errorStage
|
|
4015
|
+
}
|
|
4016
|
+
}))
|
|
4017
|
+
});
|
|
4018
|
+
const surfaceIds = candidateSurfaces(candidate.surface, evidence).map((surface) => surface.surfaceId);
|
|
4019
|
+
for (const cell of candidate.cells) {
|
|
4020
|
+
const taskId = taskIdFor(cell.scenarioId, cell.rep);
|
|
4021
|
+
const task = this.tasks.find((planned) => planned.taskId === taskId);
|
|
4022
|
+
if (!task) throw new Error(`search ledger: cell ${cell.cellId} is outside the planned task set`);
|
|
4023
|
+
await this.append({
|
|
4024
|
+
kind: "task-attempted",
|
|
4025
|
+
eventId: `attempt:${registered.candidateId}:${taskId}`,
|
|
4026
|
+
occurredAt: this.stamp(),
|
|
4027
|
+
artifacts: [evidence],
|
|
4028
|
+
candidateId: registered.candidateId,
|
|
4029
|
+
runId: `${registered.candidateId}:${cell.cellId}`,
|
|
4030
|
+
attemptIndex: 0,
|
|
4031
|
+
task: {
|
|
4032
|
+
taskId,
|
|
4033
|
+
source: task.source
|
|
4034
|
+
},
|
|
4035
|
+
identity: {
|
|
4036
|
+
model: this.cellModel(cell),
|
|
4037
|
+
agent: this.opts.binding.identity.agent,
|
|
4038
|
+
benchmark: task.benchmark
|
|
4039
|
+
},
|
|
4040
|
+
outcome: cellOutcome(cell),
|
|
4041
|
+
accounting: cellAccounting(cell),
|
|
4042
|
+
surfaceEvidence: surfaceIds.map((surfaceId) => surfaceEvidenceFor(surfaceId, evidence))
|
|
4043
|
+
});
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
/**
|
|
4048
|
+
* Close the search: unreached generations, the selection operation, one
|
|
4049
|
+
* decision per candidate, then the terminal event.
|
|
4050
|
+
*
|
|
4051
|
+
* The terminal event is appended only when canonical replay accounts for the
|
|
4052
|
+
* whole planned denominator. An interrupted or partly unscored search stays
|
|
4053
|
+
* `in-progress` and its receipt reports the exact gap, instead of claiming a
|
|
4054
|
+
* closed search.
|
|
4055
|
+
*/
|
|
4056
|
+
async finish(input) {
|
|
4057
|
+
const stopped = {
|
|
4058
|
+
code: "generation-not-reached",
|
|
4059
|
+
message: `the search stopped after ${input.generationsRun} generation(s)`
|
|
4060
|
+
};
|
|
4061
|
+
for (let generation = input.generationsRun; generation < this.opts.maxGenerations; generation++) {
|
|
4062
|
+
await this.recordGenerationOperation(generation, [], this.opts.populationSize, stopped);
|
|
4063
|
+
for (let index = 0; index < this.opts.populationSize; index++) await this.closeSlot(slotId(generation, index), generationOperationId(generation), stopped);
|
|
4064
|
+
}
|
|
4065
|
+
const decisions = this.writeArtifact("search-decisions", "decisions.json", {
|
|
4066
|
+
winnerSurfaceHash: input.winnerSurfaceHash,
|
|
4067
|
+
candidates: this.order.map((entry) => entry.candidateId)
|
|
4068
|
+
});
|
|
4069
|
+
await this.append({
|
|
4070
|
+
kind: "search-operation-recorded",
|
|
4071
|
+
eventId: "operation:selection",
|
|
4072
|
+
occurredAt: this.stamp(),
|
|
4073
|
+
artifacts: [decisions],
|
|
4074
|
+
operationId: "selection",
|
|
4075
|
+
operationKind: "selection",
|
|
4076
|
+
execution: {
|
|
4077
|
+
kind: "deterministic",
|
|
4078
|
+
source: this.opts.binding.identity.search
|
|
4079
|
+
},
|
|
4080
|
+
outcome: { status: "completed" },
|
|
4081
|
+
accounting: {
|
|
4082
|
+
tokens: {
|
|
4083
|
+
status: "known",
|
|
4084
|
+
inputTokens: 0,
|
|
4085
|
+
outputTokens: 0,
|
|
4086
|
+
cachedTokens: 0
|
|
4087
|
+
},
|
|
4088
|
+
cost: {
|
|
4089
|
+
status: "known",
|
|
4090
|
+
usd: 0,
|
|
4091
|
+
source: "free"
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
});
|
|
4095
|
+
const winner = this.registered.get(input.winnerSurfaceHash);
|
|
4096
|
+
for (const entry of this.order) await this.append({
|
|
4097
|
+
kind: "candidate-decided",
|
|
4098
|
+
eventId: `decision:${entry.candidateId}`,
|
|
4099
|
+
occurredAt: this.stamp(),
|
|
4100
|
+
artifacts: [decisions],
|
|
4101
|
+
candidateId: entry.candidateId,
|
|
4102
|
+
decision: winner?.candidateId === entry.candidateId ? { status: "selected" } : {
|
|
4103
|
+
status: "rejected",
|
|
4104
|
+
reason: this.coverage.get(entry.candidateId) === false ? {
|
|
4105
|
+
code: "coverage-incomplete",
|
|
4106
|
+
message: "the candidate missed a designed cell and could not be ranked"
|
|
4107
|
+
} : {
|
|
4108
|
+
code: "not-promoted",
|
|
4109
|
+
message: "the candidate did not beat the incumbent"
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
});
|
|
4113
|
+
const replay = await this.opts.binding.ledger.replay();
|
|
4114
|
+
const { missingCandidateSlots, missingTaskOutcomes, missingOperations } = replay.audit.expected;
|
|
4115
|
+
if (missingCandidateSlots.length === 0 && missingTaskOutcomes.length === 0 && missingOperations.length === 0 && replay.audit.decisions.pending === 0) await this.append({
|
|
4116
|
+
kind: "search-completed",
|
|
4117
|
+
eventId: "search:completed",
|
|
4118
|
+
occurredAt: this.stamp(),
|
|
4119
|
+
artifacts: [decisions],
|
|
4120
|
+
result: winner ? {
|
|
4121
|
+
status: "selected",
|
|
4122
|
+
candidateId: winner.candidateId
|
|
4123
|
+
} : {
|
|
4124
|
+
status: "all-rejected",
|
|
4125
|
+
reason: {
|
|
4126
|
+
code: "no-promoted-candidate",
|
|
4127
|
+
message: "no candidate beat the incumbent on the designed denominator"
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
});
|
|
4131
|
+
return this.receipt(input.runId);
|
|
4132
|
+
}
|
|
4133
|
+
/** Bounded receipt over the exact ledger bytes this run produced. */
|
|
4134
|
+
async receipt(runId) {
|
|
4135
|
+
const { ledger } = this.opts.binding;
|
|
4136
|
+
const replay = await ledger.replay();
|
|
4137
|
+
const bytes = replay.entries.map((entry) => `${canonicalString(entry)}\n`).join("");
|
|
4138
|
+
return createSearchHistoryReceipt({
|
|
4139
|
+
producerId: this.opts.proposerLabel,
|
|
4140
|
+
runId,
|
|
4141
|
+
ledger: {
|
|
4142
|
+
role: "search-ledger",
|
|
4143
|
+
uri: `file://${ledger.path}`,
|
|
4144
|
+
sha256: hashCanonical(bytes),
|
|
4145
|
+
byteLength: new TextEncoder().encode(bytes).byteLength
|
|
4146
|
+
},
|
|
4147
|
+
replay
|
|
4148
|
+
});
|
|
4149
|
+
}
|
|
4150
|
+
/** Read an existing ledger for this run so a resume continues it. */
|
|
4151
|
+
async hydrate() {
|
|
4152
|
+
const replay = await this.opts.binding.ledger.replay();
|
|
4153
|
+
for (const entry of replay.entries) {
|
|
4154
|
+
this.durableEventIds.add(entry.event.eventId);
|
|
4155
|
+
const stamped = Date.parse(entry.event.occurredAt);
|
|
4156
|
+
if (stamped > this.lastStampMs) this.lastStampMs = stamped;
|
|
4157
|
+
}
|
|
4158
|
+
for (const slot of replay.plan?.plan.candidateSlots ?? []) this.openSlots.add(slot.slotId);
|
|
4159
|
+
for (const extension of replay.planExtensions) for (const slot of extension.extension.candidateSlots) this.openSlots.add(slot.slotId);
|
|
4160
|
+
for (const closed of replay.closedCandidateSlots) this.openSlots.delete(closed.slotId);
|
|
4161
|
+
for (const candidate of replay.candidates) {
|
|
4162
|
+
this.remember({
|
|
4163
|
+
candidateId: candidate.candidateId,
|
|
4164
|
+
slotId: candidate.slotId,
|
|
4165
|
+
generation: candidate.lineage.generation
|
|
4166
|
+
});
|
|
4167
|
+
this.openSlots.delete(candidate.slotId);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
async plan() {
|
|
4171
|
+
const candidateSlots = [];
|
|
4172
|
+
const operations = [{
|
|
4173
|
+
operationId: "selection",
|
|
4174
|
+
kind: "selection"
|
|
4175
|
+
}];
|
|
4176
|
+
for (let generation = 0; generation < this.opts.maxGenerations; generation++) {
|
|
4177
|
+
operations.push({
|
|
4178
|
+
operationId: generationOperationId(generation),
|
|
4179
|
+
kind: "candidate-generation"
|
|
4180
|
+
});
|
|
4181
|
+
for (let index = 0; index < this.opts.populationSize; index++) {
|
|
4182
|
+
const slot = {
|
|
4183
|
+
slotId: slotId(generation, index),
|
|
4184
|
+
generationOperationId: generationOperationId(generation)
|
|
4185
|
+
};
|
|
4186
|
+
candidateSlots.push(slot);
|
|
4187
|
+
if (!this.registeredSlot(slot.slotId)) this.openSlots.add(slot.slotId);
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
await this.append({
|
|
4191
|
+
kind: "search-planned",
|
|
4192
|
+
eventId: "search:plan",
|
|
4193
|
+
occurredAt: this.stamp(),
|
|
4194
|
+
artifacts: [this.writeArtifact("search-plan", "plan.json", {
|
|
4195
|
+
runDir: this.opts.runDir,
|
|
4196
|
+
splitDigest: this.opts.splitDigest,
|
|
4197
|
+
maxGenerations: this.opts.maxGenerations,
|
|
4198
|
+
populationSize: this.opts.populationSize,
|
|
4199
|
+
tasks: this.tasks
|
|
4200
|
+
})],
|
|
4201
|
+
plan: {
|
|
4202
|
+
candidateSlots,
|
|
4203
|
+
tasks: this.tasks,
|
|
4204
|
+
operations
|
|
4205
|
+
}
|
|
4206
|
+
});
|
|
4207
|
+
}
|
|
4208
|
+
registeredSlot(slot) {
|
|
4209
|
+
return this.order.some((entry) => entry.slotId === slot);
|
|
4210
|
+
}
|
|
4211
|
+
remember(entry) {
|
|
4212
|
+
if (this.registered.has(entry.candidateId)) return;
|
|
4213
|
+
this.registered.set(entry.candidateId, entry);
|
|
4214
|
+
this.order.push(entry);
|
|
4215
|
+
}
|
|
4216
|
+
async recordGenerationOperation(generation, candidates, unfilled, failure) {
|
|
4217
|
+
const shortfall = {
|
|
4218
|
+
code: "proposal-short",
|
|
4219
|
+
message: `generation ${generation} left ${unfilled} planned candidate slot(s) unfilled`
|
|
4220
|
+
};
|
|
4221
|
+
const outcome = failure ? {
|
|
4222
|
+
status: "failed",
|
|
4223
|
+
failure
|
|
4224
|
+
} : unfilled <= 0 ? { status: "completed" } : candidates.length === 0 ? {
|
|
4225
|
+
status: "failed",
|
|
4226
|
+
failure: shortfall
|
|
4227
|
+
} : {
|
|
4228
|
+
status: "partial",
|
|
4229
|
+
failure: shortfall
|
|
4230
|
+
};
|
|
4231
|
+
await this.append({
|
|
4232
|
+
kind: "search-operation-recorded",
|
|
4233
|
+
eventId: `operation:${generationOperationId(generation)}`,
|
|
4234
|
+
occurredAt: this.stamp(),
|
|
4235
|
+
artifacts: [this.proposalArtifact(generation, candidates)],
|
|
4236
|
+
operationId: generationOperationId(generation),
|
|
4237
|
+
operationKind: "candidate-generation",
|
|
4238
|
+
execution: this.opts.binding.identity.proposer,
|
|
4239
|
+
outcome,
|
|
4240
|
+
accounting: this.proposalAccounting()
|
|
4241
|
+
});
|
|
4242
|
+
}
|
|
4243
|
+
async closeSlot(slot, generationOperation, reason) {
|
|
4244
|
+
if (!this.openSlots.has(slot)) return;
|
|
4245
|
+
this.openSlots.delete(slot);
|
|
4246
|
+
await this.append({
|
|
4247
|
+
kind: "candidate-slot-closed",
|
|
4248
|
+
eventId: `slot-closed:${slot}`,
|
|
4249
|
+
occurredAt: this.stamp(),
|
|
4250
|
+
artifacts: [this.writeArtifact("closed-slot", `slot-${slot}.json`, {
|
|
4251
|
+
slot,
|
|
4252
|
+
reason
|
|
4253
|
+
})],
|
|
4254
|
+
slotId: slot,
|
|
4255
|
+
generationOperationId: generationOperation,
|
|
4256
|
+
reason
|
|
4257
|
+
});
|
|
4258
|
+
}
|
|
4259
|
+
/** Spend booked to candidate generation since the previous generation. */
|
|
4260
|
+
proposalAccounting() {
|
|
4261
|
+
const receipts = this.opts.costLedger.list({ phase: "search.proposal" });
|
|
4262
|
+
const fresh = receipts.slice(this.proposalReceiptCount);
|
|
4263
|
+
this.proposalReceiptCount = receipts.length;
|
|
4264
|
+
return receiptAccounting(fresh);
|
|
4265
|
+
}
|
|
4266
|
+
cellModel(cell) {
|
|
4267
|
+
const resolved = cell.resolvedModel;
|
|
4268
|
+
if (resolved === void 0) return this.opts.binding.identity.model;
|
|
4269
|
+
if (!modelHasSnapshot(resolved)) throw new Error(`search ledger: cell ${cell.cellId} ran model '${resolved}', which carries no immutable snapshot; the ledger cannot record a moving alias as execution identity`);
|
|
4270
|
+
return {
|
|
4271
|
+
provider: this.opts.binding.identity.model.provider,
|
|
4272
|
+
snapshot: resolved
|
|
4273
|
+
};
|
|
4274
|
+
}
|
|
4275
|
+
proposalArtifact(generation, candidates) {
|
|
4276
|
+
return this.writeArtifact("candidate-proposal", `proposal-gen-${generation}.json`, {
|
|
4277
|
+
generation,
|
|
4278
|
+
candidates: candidates.map((candidate) => ({
|
|
4279
|
+
surfaceHash: candidate.surfaceHash,
|
|
4280
|
+
label: candidate.label ?? ""
|
|
4281
|
+
}))
|
|
4282
|
+
});
|
|
4283
|
+
}
|
|
4284
|
+
/** Write one canonical evidence document and return its content address. */
|
|
4285
|
+
writeArtifact(role, name, body) {
|
|
4286
|
+
const directory = `${this.opts.runDir}/${SEARCH_LEDGER_DIR}`;
|
|
4287
|
+
const path = `${directory}/${name}`;
|
|
4288
|
+
const contents = canonicalString(body);
|
|
4289
|
+
this.opts.storage.ensureDir(directory);
|
|
4290
|
+
this.opts.storage.write(path, contents);
|
|
4291
|
+
return {
|
|
4292
|
+
role,
|
|
4293
|
+
uri: `file://${path}`,
|
|
4294
|
+
sha256: hashCanonical(contents),
|
|
4295
|
+
byteLength: new TextEncoder().encode(contents).byteLength
|
|
4296
|
+
};
|
|
4297
|
+
}
|
|
4298
|
+
async append(event) {
|
|
4299
|
+
if (this.durableEventIds.has(event.eventId)) return;
|
|
4300
|
+
await this.opts.binding.ledger.append(event);
|
|
4301
|
+
this.durableEventIds.add(event.eventId);
|
|
4302
|
+
}
|
|
4303
|
+
/** Non-decreasing ISO stamps; the ledger refuses an event that moves back. */
|
|
4304
|
+
stamp() {
|
|
4305
|
+
const now = Date.now();
|
|
4306
|
+
this.lastStampMs = now > this.lastStampMs ? now : this.lastStampMs + 1;
|
|
4307
|
+
return new Date(this.lastStampMs).toISOString();
|
|
4308
|
+
}
|
|
4309
|
+
};
|
|
4310
|
+
/** One task per designed (scenario, replicate) cell. */
|
|
4311
|
+
function plannedTasks(scenarios, reps, runDir, splitDigest) {
|
|
4312
|
+
const tasks = [];
|
|
4313
|
+
for (const scenario of scenarios) for (let rep = 0; rep < reps; rep++) tasks.push({
|
|
4314
|
+
taskId: taskIdFor(scenario.id, rep),
|
|
4315
|
+
source: {
|
|
4316
|
+
uri: `scenario://${scenario.id}`,
|
|
4317
|
+
revision: hashCanonical(scenario)
|
|
4318
|
+
},
|
|
4319
|
+
benchmark: {
|
|
4320
|
+
uri: `campaign://${runDir}`,
|
|
4321
|
+
revision: splitDigest
|
|
4322
|
+
},
|
|
4323
|
+
maxAttempts: 1
|
|
4324
|
+
});
|
|
4325
|
+
return tasks;
|
|
4326
|
+
}
|
|
4327
|
+
function taskIdFor(scenarioId, rep) {
|
|
4328
|
+
return `${scenarioId}#rep-${rep}`;
|
|
4329
|
+
}
|
|
4330
|
+
function slotId(generation, index) {
|
|
4331
|
+
return `gen-${generation}-slot-${index}`;
|
|
4332
|
+
}
|
|
4333
|
+
function generationOperationId(generation) {
|
|
4334
|
+
return `candidate-generation:gen-${generation}`;
|
|
4335
|
+
}
|
|
4336
|
+
/** Declared surfaces of one candidate. A component surface declares one
|
|
4337
|
+
* surface per named component, so per-component evidence stays addressable. */
|
|
4338
|
+
function candidateSurfaces(surface, artifact) {
|
|
4339
|
+
if (typeof surface === "string") return [{
|
|
4340
|
+
surfaceId: "prompt",
|
|
4341
|
+
kind: "prompt",
|
|
4342
|
+
artifact
|
|
4343
|
+
}];
|
|
4344
|
+
if (surface.kind === "code") return [{
|
|
4345
|
+
surfaceId: "code",
|
|
4346
|
+
kind: "code",
|
|
4347
|
+
artifact
|
|
4348
|
+
}];
|
|
4349
|
+
return Object.keys(surface.components).sort().map((name) => ({
|
|
4350
|
+
surfaceId: `component:${name}`,
|
|
4351
|
+
kind: "prompt",
|
|
4352
|
+
artifact
|
|
4353
|
+
}));
|
|
4354
|
+
}
|
|
4355
|
+
/** The campaign measures a candidate surface as a whole, so per-surface
|
|
4356
|
+
* attribution stays unmeasured instead of inventing a per-component delta. */
|
|
4357
|
+
function surfaceEvidenceFor(surfaceId, evidence) {
|
|
4358
|
+
return {
|
|
4359
|
+
surfaceId,
|
|
4360
|
+
fired: true,
|
|
4361
|
+
firingCount: 1,
|
|
4362
|
+
effect: {
|
|
4363
|
+
status: "not-measured",
|
|
4364
|
+
reason: "the campaign measures the candidate surface as a whole, not per surface"
|
|
4365
|
+
},
|
|
4366
|
+
evidence: [evidence]
|
|
4367
|
+
};
|
|
4368
|
+
}
|
|
4369
|
+
function cellOutcome(cell) {
|
|
4370
|
+
const scores = Object.entries(cell.judgeScores).filter(([, score]) => score.failed !== true && Number.isFinite(score.composite));
|
|
4371
|
+
if (cell.error !== void 0 || scores.length === 0) return {
|
|
4372
|
+
status: "errored",
|
|
4373
|
+
metrics: {},
|
|
4374
|
+
error: {
|
|
4375
|
+
code: cell.errorStage ?? "unscored",
|
|
4376
|
+
message: cell.error ?? "the cell produced no complete judge score",
|
|
4377
|
+
retryable: false
|
|
4378
|
+
}
|
|
4379
|
+
};
|
|
4380
|
+
const composite = scores.reduce((sum, [, score]) => sum + score.composite, 0) / scores.length;
|
|
4381
|
+
const metrics = { composite };
|
|
4382
|
+
for (const [judge, score] of scores) metrics[`judge.${judge}`] = score.composite;
|
|
4383
|
+
return {
|
|
4384
|
+
status: "passed",
|
|
4385
|
+
score: composite,
|
|
4386
|
+
metrics
|
|
4387
|
+
};
|
|
4388
|
+
}
|
|
4389
|
+
function cellAccounting(cell) {
|
|
4390
|
+
const usage = cell.tokenUsage;
|
|
4391
|
+
return {
|
|
4392
|
+
tokens: usage.tokensKnown === false ? {
|
|
4393
|
+
status: "unknown",
|
|
4394
|
+
reason: "a paid call in this cell reported no token usage"
|
|
4395
|
+
} : {
|
|
4396
|
+
status: "known",
|
|
4397
|
+
inputTokens: usage.input,
|
|
4398
|
+
outputTokens: usage.output,
|
|
4399
|
+
cachedTokens: 0
|
|
4400
|
+
},
|
|
4401
|
+
cost: cell.costProvenance.kind === "uncaptured" ? {
|
|
4402
|
+
status: "unknown",
|
|
4403
|
+
knownLowerBoundUsd: cell.costUsd,
|
|
4404
|
+
reason: "the cell recorded spend without a provider receipt"
|
|
4405
|
+
} : {
|
|
4406
|
+
status: "known",
|
|
4407
|
+
usd: cell.costUsd,
|
|
4408
|
+
source: cell.costProvenance.kind === "observed" ? "provider" : "pricing-table"
|
|
4409
|
+
}
|
|
4410
|
+
};
|
|
4411
|
+
}
|
|
4412
|
+
function receiptAccounting(receipts) {
|
|
4413
|
+
let inputTokens = 0;
|
|
4414
|
+
let outputTokens = 0;
|
|
4415
|
+
let cachedTokens = 0;
|
|
4416
|
+
let usd = 0;
|
|
4417
|
+
let tokensKnown = true;
|
|
4418
|
+
let costKnown = true;
|
|
4419
|
+
for (const receipt of receipts) {
|
|
4420
|
+
if (receipt.usageUnknown === true) tokensKnown = false;
|
|
4421
|
+
inputTokens += receipt.inputTokens;
|
|
4422
|
+
outputTokens += receipt.outputTokens;
|
|
4423
|
+
cachedTokens += receipt.cachedTokens ?? 0;
|
|
4424
|
+
if (receipt.costUnknown) costKnown = false;
|
|
4425
|
+
else usd += receipt.costUsd;
|
|
4426
|
+
}
|
|
4427
|
+
return {
|
|
4428
|
+
tokens: tokensKnown ? {
|
|
4429
|
+
status: "known",
|
|
4430
|
+
inputTokens,
|
|
4431
|
+
outputTokens,
|
|
4432
|
+
cachedTokens
|
|
4433
|
+
} : {
|
|
4434
|
+
status: "unknown",
|
|
4435
|
+
reason: "a candidate-generation call reported no token usage"
|
|
4436
|
+
},
|
|
4437
|
+
cost: costKnown ? {
|
|
4438
|
+
status: "known",
|
|
4439
|
+
usd,
|
|
4440
|
+
source: usd === 0 ? "free" : "provider"
|
|
4441
|
+
} : {
|
|
4442
|
+
status: "unknown",
|
|
4443
|
+
knownLowerBoundUsd: usd,
|
|
4444
|
+
reason: "a candidate-generation call recorded no provider cost"
|
|
4445
|
+
}
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
/**
|
|
4449
|
+
* Record an optimizer's own candidate graph into the same ledger.
|
|
4450
|
+
*
|
|
4451
|
+
* A complete optimization method searches inside its own process and reports
|
|
4452
|
+
* one artifact when it finishes: the candidate population, with each
|
|
4453
|
+
* candidate's parents and its score per selection scenario. This turns that
|
|
4454
|
+
* artifact into the canonical event stream, so a first-party method returns
|
|
4455
|
+
* the same `SearchHistoryReceipt` the in-process loop returns, and
|
|
4456
|
+
* `compareOptimizationMethods({ searchHistoryPolicy: 'require-complete' })`
|
|
4457
|
+
* accepts it.
|
|
4458
|
+
*
|
|
4459
|
+
* A candidate the optimizer left unscored on a planned scenario leaves the
|
|
4460
|
+
* planned denominator open, so the receipt reports the gap instead of closing
|
|
4461
|
+
* the search.
|
|
4462
|
+
*/
|
|
4463
|
+
async function recordCandidatePopulationSearch(input) {
|
|
4464
|
+
const { population, ledger, identity } = input;
|
|
4465
|
+
const stamps = monotonicStamps();
|
|
4466
|
+
const writeArtifact = artifactWriter(input.storage, input.runDir);
|
|
4467
|
+
const populationArtifact = {
|
|
4468
|
+
role: "candidate-population",
|
|
4469
|
+
uri: `file://${population.summary.path}`,
|
|
4470
|
+
sha256: population.summary.sha256,
|
|
4471
|
+
byteLength: population.summary.bytes
|
|
4472
|
+
};
|
|
4473
|
+
const tasks = input.scenarios.filter((scenario) => population.summary.scenarioIds.includes(scenario.id)).map((scenario) => ({
|
|
4474
|
+
taskId: taskIdFor(scenario.id, 0),
|
|
4475
|
+
source: {
|
|
4476
|
+
uri: `scenario://${scenario.id}`,
|
|
4477
|
+
revision: hashCanonical(scenario)
|
|
4478
|
+
},
|
|
4479
|
+
benchmark: {
|
|
4480
|
+
uri: `optimizer://${input.producerId}`,
|
|
4481
|
+
revision: population.summary.sha256
|
|
4482
|
+
},
|
|
4483
|
+
maxAttempts: 1
|
|
4484
|
+
}));
|
|
4485
|
+
if (tasks.length !== population.summary.scenarioIds.length) throw new Error(`search ledger: the candidate population scored ${population.summary.scenarioIds.length} scenarios, but ${tasks.length} were supplied`);
|
|
4486
|
+
const generationOperation = "candidate-generation:population";
|
|
4487
|
+
await ledger.append({
|
|
4488
|
+
kind: "search-planned",
|
|
4489
|
+
eventId: "search:plan",
|
|
4490
|
+
occurredAt: stamps(),
|
|
4491
|
+
artifacts: [populationArtifact],
|
|
4492
|
+
plan: {
|
|
4493
|
+
candidateSlots: population.candidates.map((candidate) => ({
|
|
4494
|
+
slotId: `candidate-${candidate.index}`,
|
|
4495
|
+
generationOperationId: generationOperation
|
|
4496
|
+
})),
|
|
4497
|
+
tasks,
|
|
4498
|
+
operations: [{
|
|
4499
|
+
operationId: generationOperation,
|
|
4500
|
+
kind: "candidate-generation"
|
|
4501
|
+
}, {
|
|
4502
|
+
operationId: "selection",
|
|
4503
|
+
kind: "selection"
|
|
4504
|
+
}]
|
|
4505
|
+
}
|
|
4506
|
+
});
|
|
4507
|
+
await ledger.append({
|
|
4508
|
+
kind: "search-operation-recorded",
|
|
4509
|
+
eventId: `operation:${generationOperation}`,
|
|
4510
|
+
occurredAt: stamps(),
|
|
4511
|
+
artifacts: [populationArtifact],
|
|
4512
|
+
operationId: generationOperation,
|
|
4513
|
+
operationKind: "candidate-generation",
|
|
4514
|
+
execution: identity.proposer,
|
|
4515
|
+
outcome: { status: "completed" },
|
|
4516
|
+
accounting: input.generationAccounting
|
|
4517
|
+
});
|
|
4518
|
+
const candidateIds = /* @__PURE__ */ new Map();
|
|
4519
|
+
const depths = /* @__PURE__ */ new Map();
|
|
4520
|
+
for (const candidate of population.candidates) {
|
|
4521
|
+
const parents = candidate.parentIndices.filter((index) => index !== null);
|
|
4522
|
+
const candidateId = candidate.candidateHash;
|
|
4523
|
+
candidateIds.set(candidate.index, candidateId);
|
|
4524
|
+
const depth = parents.length === 0 ? 0 : Math.max(...parents.map((index) => depths.get(index) ?? 0)) + 1;
|
|
4525
|
+
depths.set(candidate.index, depth);
|
|
4526
|
+
const surfaceArtifact = writeArtifact("candidate-surface", `candidate-${candidate.index}.json`, {
|
|
4527
|
+
index: candidate.index,
|
|
4528
|
+
candidateDigest: candidate.candidateDigest,
|
|
4529
|
+
candidate: candidate.candidate
|
|
4530
|
+
});
|
|
4531
|
+
await ledger.append({
|
|
4532
|
+
kind: "candidate-registered",
|
|
4533
|
+
eventId: `candidate:${candidate.index}`,
|
|
4534
|
+
occurredAt: stamps(),
|
|
4535
|
+
artifacts: [surfaceArtifact],
|
|
4536
|
+
slotId: `candidate-${candidate.index}`,
|
|
4537
|
+
generationOperationId: generationOperation,
|
|
4538
|
+
candidateId,
|
|
4539
|
+
lineage: {
|
|
4540
|
+
lineageNodeId: candidateId.slice(0, 16),
|
|
4541
|
+
parentCandidateIds: parents.map((index) => {
|
|
4542
|
+
const parentId = candidateIds.get(index);
|
|
4543
|
+
if (!parentId) throw new Error(`search ledger: candidate ${candidate.index} names parent ${index}, which precedes no registered candidate`);
|
|
4544
|
+
return parentId;
|
|
4545
|
+
}),
|
|
4546
|
+
generation: depth,
|
|
4547
|
+
proposer: input.producerId,
|
|
4548
|
+
proposerSource: identity.proposer.source
|
|
4549
|
+
},
|
|
4550
|
+
surfaces: candidateSurfaces(externalSurface(candidate.candidate), surfaceArtifact)
|
|
4551
|
+
});
|
|
4552
|
+
const surfaceIds = candidateSurfaces(externalSurface(candidate.candidate), surfaceArtifact).map((surface) => surface.surfaceId);
|
|
4553
|
+
for (const score of candidate.selectionScores) {
|
|
4554
|
+
const task = tasks.find((planned) => planned.taskId === taskIdFor(score.scenarioId, 0));
|
|
4555
|
+
if (!task) throw new Error(`search ledger: candidate ${candidate.index} scored unplanned scenario ${score.scenarioId}`);
|
|
4556
|
+
await ledger.append({
|
|
4557
|
+
kind: "task-attempted",
|
|
4558
|
+
eventId: `attempt:${candidate.index}:${task.taskId}`,
|
|
4559
|
+
occurredAt: stamps(),
|
|
4560
|
+
artifacts: [populationArtifact],
|
|
4561
|
+
candidateId,
|
|
4562
|
+
runId: `${input.runId}:${candidate.index}:${task.taskId}`,
|
|
4563
|
+
attemptIndex: 0,
|
|
4564
|
+
task: {
|
|
4565
|
+
taskId: task.taskId,
|
|
4566
|
+
source: task.source
|
|
4567
|
+
},
|
|
4568
|
+
identity: {
|
|
4569
|
+
model: identity.model,
|
|
4570
|
+
agent: identity.agent,
|
|
4571
|
+
benchmark: task.benchmark
|
|
4572
|
+
},
|
|
4573
|
+
outcome: {
|
|
4574
|
+
status: "passed",
|
|
4575
|
+
score: score.score,
|
|
4576
|
+
metrics: { composite: score.score }
|
|
4577
|
+
},
|
|
4578
|
+
accounting: {
|
|
4579
|
+
tokens: {
|
|
4580
|
+
status: "unknown",
|
|
4581
|
+
reason: "the optimizer reports no token usage per candidate evaluation"
|
|
4582
|
+
},
|
|
4583
|
+
cost: {
|
|
4584
|
+
status: "unknown",
|
|
4585
|
+
knownLowerBoundUsd: 0,
|
|
4586
|
+
reason: "the optimizer reports no cost per candidate evaluation"
|
|
4587
|
+
}
|
|
4588
|
+
},
|
|
4589
|
+
surfaceEvidence: surfaceIds.map((surfaceId) => surfaceEvidenceFor(surfaceId, populationArtifact))
|
|
4590
|
+
});
|
|
4591
|
+
}
|
|
4592
|
+
}
|
|
4593
|
+
await ledger.append({
|
|
4594
|
+
kind: "search-operation-recorded",
|
|
4595
|
+
eventId: "operation:selection",
|
|
4596
|
+
occurredAt: stamps(),
|
|
4597
|
+
artifacts: [populationArtifact],
|
|
4598
|
+
operationId: "selection",
|
|
4599
|
+
operationKind: "selection",
|
|
4600
|
+
execution: {
|
|
4601
|
+
kind: "deterministic",
|
|
4602
|
+
source: identity.search
|
|
4603
|
+
},
|
|
4604
|
+
outcome: { status: "completed" },
|
|
4605
|
+
accounting: {
|
|
4606
|
+
tokens: {
|
|
4607
|
+
status: "known",
|
|
4608
|
+
inputTokens: 0,
|
|
4609
|
+
outputTokens: 0,
|
|
4610
|
+
cachedTokens: 0
|
|
4611
|
+
},
|
|
4612
|
+
cost: {
|
|
4613
|
+
status: "known",
|
|
4614
|
+
usd: 0,
|
|
4615
|
+
source: "free"
|
|
4616
|
+
}
|
|
4617
|
+
}
|
|
4618
|
+
});
|
|
4619
|
+
const winnerId = candidateIds.get(population.bestIndex);
|
|
4620
|
+
for (const candidate of population.candidates) await ledger.append({
|
|
4621
|
+
kind: "candidate-decided",
|
|
4622
|
+
eventId: `decision:${candidate.index}`,
|
|
4623
|
+
occurredAt: stamps(),
|
|
4624
|
+
artifacts: [populationArtifact],
|
|
4625
|
+
candidateId: candidateIds.get(candidate.index),
|
|
4626
|
+
decision: candidate.index === population.bestIndex ? { status: "selected" } : {
|
|
4627
|
+
status: "rejected",
|
|
4628
|
+
reason: {
|
|
4629
|
+
code: "not-selected",
|
|
4630
|
+
message: "the optimizer selected another candidate"
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
});
|
|
4634
|
+
const replay = await ledger.replay();
|
|
4635
|
+
const { missingCandidateSlots, missingTaskOutcomes, missingOperations } = replay.audit.expected;
|
|
4636
|
+
if (winnerId && missingCandidateSlots.length === 0 && missingTaskOutcomes.length === 0 && missingOperations.length === 0 && replay.audit.decisions.pending === 0) await ledger.append({
|
|
4637
|
+
kind: "search-completed",
|
|
4638
|
+
eventId: "search:completed",
|
|
4639
|
+
occurredAt: stamps(),
|
|
4640
|
+
artifacts: [populationArtifact],
|
|
4641
|
+
result: {
|
|
4642
|
+
status: "selected",
|
|
4643
|
+
candidateId: winnerId
|
|
4644
|
+
}
|
|
4645
|
+
});
|
|
4646
|
+
const final = await ledger.replay();
|
|
4647
|
+
const bytes = final.entries.map((entry) => `${canonicalString(entry)}\n`).join("");
|
|
4648
|
+
return createSearchHistoryReceipt({
|
|
4649
|
+
producerId: input.producerId,
|
|
4650
|
+
runId: input.runId,
|
|
4651
|
+
ledger: {
|
|
4652
|
+
role: "search-ledger",
|
|
4653
|
+
uri: `file://${ledger.path}`,
|
|
4654
|
+
sha256: hashCanonical(bytes),
|
|
4655
|
+
byteLength: new TextEncoder().encode(bytes).byteLength
|
|
4656
|
+
},
|
|
4657
|
+
replay: final
|
|
4658
|
+
});
|
|
4659
|
+
}
|
|
4660
|
+
/** An optimizer candidate as the canonical mutable surface it represents. */
|
|
4661
|
+
function externalSurface(candidate) {
|
|
4662
|
+
return typeof candidate === "string" ? candidate : {
|
|
4663
|
+
kind: "components",
|
|
4664
|
+
components: candidate
|
|
4665
|
+
};
|
|
4666
|
+
}
|
|
4667
|
+
function artifactWriter(storage, runDir) {
|
|
4668
|
+
const directory = `${runDir}/${SEARCH_LEDGER_DIR}`;
|
|
4669
|
+
return (role, name, body) => {
|
|
4670
|
+
const contents = canonicalString(body);
|
|
4671
|
+
storage.ensureDir(directory);
|
|
4672
|
+
storage.write(`${directory}/${name}`, contents);
|
|
4673
|
+
return {
|
|
4674
|
+
role,
|
|
4675
|
+
uri: `file://${directory}/${name}`,
|
|
4676
|
+
sha256: hashCanonical(contents),
|
|
4677
|
+
byteLength: new TextEncoder().encode(contents).byteLength
|
|
4678
|
+
};
|
|
4679
|
+
};
|
|
4680
|
+
}
|
|
4681
|
+
/** Non-decreasing ISO stamps; the ledger refuses an event that moves back. */
|
|
4682
|
+
function monotonicStamps() {
|
|
4683
|
+
let last = 0;
|
|
4684
|
+
return () => {
|
|
4685
|
+
const now = Date.now();
|
|
4686
|
+
last = now > last ? now : last + 1;
|
|
4687
|
+
return new Date(last).toISOString();
|
|
4688
|
+
};
|
|
4689
|
+
}
|
|
3836
4690
|
//#endregion
|
|
3837
4691
|
//#region src/campaign/types.ts
|
|
3838
4692
|
/** Type guard: a proposal carrying its rationale vs a bare
|
|
@@ -3854,7 +4708,9 @@ function labelTrustRank(trust) {
|
|
|
3854
4708
|
/**
|
|
3855
4709
|
* `runOptimization` runs a caller-owned candidate generator for a bounded
|
|
3856
4710
|
* number of rounds. Each candidate is measured on the same cases, and only a
|
|
3857
|
-
* candidate that beats the current best becomes the
|
|
4711
|
+
* candidate that beats the current best becomes the incumbent. By default the
|
|
4712
|
+
* incumbent is also the parent every generation mutates; a `selectParent`
|
|
4713
|
+
* policy draws the parent from the Pareto frontier instead.
|
|
3858
4714
|
* The same loop accepts deterministic, model-backed, or agent-backed
|
|
3859
4715
|
* proposers; they differ only in how `propose()` picks candidates.
|
|
3860
4716
|
*
|
|
@@ -3862,7 +4718,7 @@ function labelTrustRank(trust) {
|
|
|
3862
4718
|
* and optional pull request creation.
|
|
3863
4719
|
*/
|
|
3864
4720
|
/**
|
|
3865
|
-
* Improvement loop body: N generations of propose → campaign → rank, maintaining a Pareto frontier and one global incumbent across generations.
|
|
4721
|
+
* Improvement loop body: N generations of propose → campaign → rank, maintaining a Pareto frontier and one global incumbent across generations. The parent each generation mutates is the incumbent unless `selectParent` draws it from the frontier.
|
|
3866
4722
|
*/
|
|
3867
4723
|
async function runOptimization(opts) {
|
|
3868
4724
|
const { proposer } = opts;
|
|
@@ -3899,6 +4755,18 @@ async function runOptimization(opts) {
|
|
|
3899
4755
|
const label = opts.premeasuredBaseline ? "premeasured baseline" : "baseline";
|
|
3900
4756
|
throw new Error(`runOptimization: ${label} is incomplete (${baselineCoverage.scorableCellIds.length}/${baselineCoverage.expectedCellIds.length} designed cells scorable) — ${formatCoverageFailures(baselineCoverage)}. Refusing to optimize against an incomplete incumbent.`);
|
|
3901
4757
|
}
|
|
4758
|
+
const recorder = opts.searchLedger ? await SearchRecorder.open({
|
|
4759
|
+
binding: opts.searchLedger,
|
|
4760
|
+
storage,
|
|
4761
|
+
runDir: opts.runDir,
|
|
4762
|
+
scenarios: opts.scenarios,
|
|
4763
|
+
reps,
|
|
4764
|
+
maxGenerations: opts.maxGenerations,
|
|
4765
|
+
populationSize: opts.populationSize,
|
|
4766
|
+
splitDigest: baselineCampaign.splitDigest,
|
|
4767
|
+
proposerLabel: proposer.kind,
|
|
4768
|
+
costLedger
|
|
4769
|
+
}) : void 0;
|
|
3902
4770
|
const generations = [];
|
|
3903
4771
|
const history = [];
|
|
3904
4772
|
let currentFindings = initialFindings;
|
|
@@ -3914,6 +4782,10 @@ async function runOptimization(opts) {
|
|
|
3914
4782
|
let winnerLabel;
|
|
3915
4783
|
let winnerRationale;
|
|
3916
4784
|
const scored = [toParetoParent(baselineSurface, winnerSurfaceHash, baselineCampaign, -1)];
|
|
4785
|
+
const measuredByHash = /* @__PURE__ */ new Map([[winnerSurfaceHash, {
|
|
4786
|
+
parent: scored[0],
|
|
4787
|
+
outcome: baselineOutcome
|
|
4788
|
+
}]]);
|
|
3917
4789
|
if (opts.analyzeGeneration && opts.maxGenerations > 0 && baselineCampaign.cells.length > 0) {
|
|
3918
4790
|
const fresh = await opts.analyzeGeneration({
|
|
3919
4791
|
generation: -1,
|
|
@@ -3933,20 +4805,30 @@ async function runOptimization(opts) {
|
|
|
3933
4805
|
for (let gen = 0; gen < opts.maxGenerations; gen++) {
|
|
3934
4806
|
const proposalHistory = immutableProposalSnapshot(history, "history");
|
|
3935
4807
|
if (proposer.decide?.({ history: proposalHistory }).stop) break;
|
|
3936
|
-
const paretoParents = computeParetoFrontier(scored);
|
|
3937
|
-
const
|
|
3938
|
-
const
|
|
4808
|
+
const paretoParents = immutableProposalSnapshot(computeParetoFrontier(scored), "Pareto parents");
|
|
4809
|
+
const incumbentOutcome = immutableProposalSnapshot(winnerOutcome, "incumbent outcome");
|
|
4810
|
+
const selected = opts.selectParent ? resolveSelectedParent(opts.selectParent(Object.freeze({
|
|
4811
|
+
frontier: paretoParents,
|
|
4812
|
+
incumbent: incumbentOutcome,
|
|
4813
|
+
history: proposalHistory,
|
|
4814
|
+
generation: gen
|
|
4815
|
+
})), measuredByHash, gen) : void 0;
|
|
4816
|
+
const parentSurface = selected ? selected.parent.surface : winnerSurface;
|
|
4817
|
+
const parentSurfaceHash = selected ? selected.parent.surfaceHash : winnerSurfaceHash;
|
|
4818
|
+
const parentComposite = selected ? selected.outcome.composite : winnerComposite;
|
|
4819
|
+
const parentOutcome = selected ? selected.outcome : winnerOutcome;
|
|
3939
4820
|
const proposalContext = Object.freeze({
|
|
3940
|
-
currentSurface: immutableProposalSnapshot(
|
|
4821
|
+
currentSurface: immutableProposalSnapshot(parentSurface, "current surface"),
|
|
3941
4822
|
history: proposalHistory,
|
|
3942
4823
|
findings: immutableProposalSnapshot(assertProposalFindings(currentFindings, "runOptimization proposal findings"), "findings"),
|
|
3943
4824
|
populationSize: opts.populationSize,
|
|
3944
4825
|
generation: gen,
|
|
3945
4826
|
signal: opts.signal ?? new AbortController().signal,
|
|
3946
4827
|
baselineOutcome: immutableProposalSnapshot(baselineOutcome, "baseline outcome"),
|
|
3947
|
-
incumbentOutcome
|
|
4828
|
+
incumbentOutcome,
|
|
4829
|
+
parentOutcome: immutableProposalSnapshot(parentOutcome, "parent outcome"),
|
|
3948
4830
|
maxImprovementShots: opts.maxImprovementShots,
|
|
3949
|
-
paretoParents
|
|
4831
|
+
paretoParents,
|
|
3950
4832
|
costLedger,
|
|
3951
4833
|
costPhase: "search.proposal"
|
|
3952
4834
|
});
|
|
@@ -3966,6 +4848,15 @@ async function runOptimization(opts) {
|
|
|
3966
4848
|
generationHashes.add(hash);
|
|
3967
4849
|
}
|
|
3968
4850
|
for (const hash of generationHashes) admittedCandidateHashes.add(hash);
|
|
4851
|
+
await recorder?.recordGeneration({
|
|
4852
|
+
generation: gen,
|
|
4853
|
+
parentSurfaceHash,
|
|
4854
|
+
candidates: candidates.map(({ surface, label }) => ({
|
|
4855
|
+
surface,
|
|
4856
|
+
surfaceHash: surfaceHash(surface),
|
|
4857
|
+
...label ? { label } : {}
|
|
4858
|
+
}))
|
|
4859
|
+
});
|
|
3969
4860
|
const surfaceResults = await mapConcurrent(candidates, candidateConcurrency, async ({ surface, label, rationale }, i, signal) => {
|
|
3970
4861
|
const hash = surfaceHash(surface);
|
|
3971
4862
|
const campaign = await runCampaign({
|
|
@@ -3993,8 +4884,22 @@ async function runOptimization(opts) {
|
|
|
3993
4884
|
}, opts.signal);
|
|
3994
4885
|
for (const result of surfaceResults) {
|
|
3995
4886
|
const { surface, surfaceHash: hash, campaign, coverage, label, rationale } = result;
|
|
3996
|
-
if (coverage.complete)
|
|
4887
|
+
if (coverage.complete) {
|
|
4888
|
+
const parent = toParetoParent(surface, hash, campaign, gen, label || void 0, rationale || void 0);
|
|
4889
|
+
scored.push(parent);
|
|
4890
|
+
measuredByHash.set(hash, {
|
|
4891
|
+
parent,
|
|
4892
|
+
outcome: toScoredSurfaceOutcome(hash, campaign, coverage, gen)
|
|
4893
|
+
});
|
|
4894
|
+
}
|
|
3997
4895
|
}
|
|
4896
|
+
await recorder?.recordResults(surfaceResults.map((result) => ({
|
|
4897
|
+
surface: result.surface,
|
|
4898
|
+
surfaceHash: result.surfaceHash,
|
|
4899
|
+
cells: result.campaign.cells,
|
|
4900
|
+
runDir: result.campaign.runDir,
|
|
4901
|
+
coverageComplete: result.coverage.complete
|
|
4902
|
+
})));
|
|
3998
4903
|
surfaceResults.sort((a, b) => {
|
|
3999
4904
|
if (a.coverage.complete !== b.coverage.complete) return a.coverage.complete ? -1 : 1;
|
|
4000
4905
|
if (a.rankKey && b.rankKey) return compareRankKeys(b.rankKey, a.rankKey);
|
|
@@ -4064,6 +4969,11 @@ async function runOptimization(opts) {
|
|
|
4064
4969
|
currentFindings = immutableProposalSnapshot(assertProposalFindings(fresh, "runOptimization generation analysis findings"), "generation analysis findings");
|
|
4065
4970
|
}
|
|
4066
4971
|
}
|
|
4972
|
+
const searchHistory = await recorder?.finish({
|
|
4973
|
+
winnerSurfaceHash,
|
|
4974
|
+
generationsRun: generations.length,
|
|
4975
|
+
runId: opts.runDir
|
|
4976
|
+
});
|
|
4067
4977
|
return {
|
|
4068
4978
|
generations,
|
|
4069
4979
|
baselineSurface,
|
|
@@ -4072,10 +4982,22 @@ async function runOptimization(opts) {
|
|
|
4072
4982
|
winnerLabel,
|
|
4073
4983
|
winnerRationale,
|
|
4074
4984
|
baselineCampaign,
|
|
4985
|
+
...searchHistory ? { searchHistory } : {},
|
|
4075
4986
|
paretoFrontier: computeParetoFrontier(scored),
|
|
4076
4987
|
cost: costLedger.summary()
|
|
4077
4988
|
};
|
|
4078
4989
|
}
|
|
4990
|
+
/** Resolve the parent a `selectParent` policy returned to the measured record
|
|
4991
|
+
* this run holds for it. Refuses a surface the run never measured to
|
|
4992
|
+
* completion, and a parent whose surface does not hash to its `surfaceHash`. */
|
|
4993
|
+
function resolveSelectedParent(returned, measuredByHash, generation) {
|
|
4994
|
+
if (typeof returned !== "object" || returned === null || typeof returned.surfaceHash !== "string") throw new TypeError(`runOptimization: selectParent must return a ParetoParent (generation ${generation})`);
|
|
4995
|
+
const parent = returned;
|
|
4996
|
+
const measured = measuredByHash.get(parent.surfaceHash);
|
|
4997
|
+
if (!measured) throw new Error(`runOptimization: selectParent returned surface "${parent.surfaceHash}" in generation ${generation}, which this run has not measured to completion; a parent must be a scored surface from the frontier`);
|
|
4998
|
+
if (surfaceHash(parent.surface) !== parent.surfaceHash) throw new Error(`runOptimization: selectParent returned a parent whose surface does not match its surfaceHash "${parent.surfaceHash}" (generation ${generation})`);
|
|
4999
|
+
return measured;
|
|
5000
|
+
}
|
|
4079
5001
|
function immutableProposalSnapshot(value, label) {
|
|
4080
5002
|
try {
|
|
4081
5003
|
return deepFreeze(structuredClone(value));
|
|
@@ -4508,7 +5430,7 @@ function buildLoopProvenanceRecord(args) {
|
|
|
4508
5430
|
gate: {
|
|
4509
5431
|
decision: args.gate.decision,
|
|
4510
5432
|
reasons: args.gate.reasons,
|
|
4511
|
-
delta: args.gate.delta,
|
|
5433
|
+
...args.gate.delta === void 0 ? {} : { delta: args.gate.delta },
|
|
4512
5434
|
contributingGates: args.gate.contributingGates.map((g) => ({
|
|
4513
5435
|
name: g.name,
|
|
4514
5436
|
status: g.status,
|
|
@@ -4544,7 +5466,7 @@ function durableOptimizationMethod(value) {
|
|
|
4544
5466
|
if (!value.cost || !Number.isFinite(value.cost.totalCostUsd) || value.cost.totalCostUsd < 0 || typeof value.cost.accountingComplete !== "boolean" || !Array.isArray(value.cost.incompleteReasons) || value.cost.incompleteReasons.some((reason) => typeof reason !== "string" || !reason.trim()) || value.cost.accountingComplete !== (value.cost.incompleteReasons.length === 0)) throw new Error("buildLoopProvenanceRecord: optimization method cost is invalid");
|
|
4545
5467
|
if (value.durationMs !== void 0 && (!Number.isFinite(value.durationMs) || value.durationMs < 0)) throw new Error("buildLoopProvenanceRecord: optimization method duration is invalid");
|
|
4546
5468
|
try {
|
|
4547
|
-
return JSON.parse(
|
|
5469
|
+
return JSON.parse(canonicalString(value));
|
|
4548
5470
|
} catch (cause) {
|
|
4549
5471
|
throw new Error("buildLoopProvenanceRecord: optimization method data must be canonical JSON", { cause });
|
|
4550
5472
|
}
|
|
@@ -4590,22 +5512,15 @@ function verifyLoopProvenanceRecord(record) {
|
|
|
4590
5512
|
assertGateContributions(record.gate?.contributingGates, "loop provenance");
|
|
4591
5513
|
return record;
|
|
4592
5514
|
}
|
|
4593
|
-
/**
|
|
5515
|
+
/** SHA-256 over the RFC 8785 canonical JSON of `value`. Throws
|
|
5516
|
+
* `LedgerCanonicalizationError` for a value with no canonical form. */
|
|
4594
5517
|
function canonicalDigest(value) {
|
|
4595
|
-
|
|
4596
|
-
if (typeof item === "number" && !Number.isFinite(item)) throw new Error("canonical digest cannot encode a non-finite number");
|
|
4597
|
-
if (typeof item === "bigint" || typeof item === "function" || typeof item === "symbol") throw new Error(`canonical digest cannot encode ${typeof item}`);
|
|
4598
|
-
if (item === void 0 && Array.isArray(this)) throw new Error("canonical digest cannot encode an undefined array item");
|
|
4599
|
-
if (item instanceof Map || item instanceof Set) throw new Error(`canonical digest cannot encode ${item instanceof Map ? "Map" : "Set"}`);
|
|
4600
|
-
return item;
|
|
4601
|
-
});
|
|
4602
|
-
if (json === void 0) throw new Error("canonical digest value is not serializable");
|
|
4603
|
-
return `sha256:${contentHash(JSON.parse(json))}`;
|
|
5518
|
+
return hashCanonical(value);
|
|
4604
5519
|
}
|
|
4605
5520
|
function durableGateDetail(detail) {
|
|
4606
5521
|
if (detail === void 0) return null;
|
|
4607
5522
|
try {
|
|
4608
|
-
return JSON.parse(
|
|
5523
|
+
return JSON.parse(canonicalString(detail));
|
|
4609
5524
|
} catch (cause) {
|
|
4610
5525
|
throw new Error("buildLoopProvenanceRecord: gate detail must be canonical JSON", { cause });
|
|
4611
5526
|
}
|
|
@@ -4890,6 +5805,33 @@ async function emitLoopProvenance(args) {
|
|
|
4890
5805
|
};
|
|
4891
5806
|
}
|
|
4892
5807
|
//#endregion
|
|
5808
|
+
//#region src/campaign/transient-failure.ts
|
|
5809
|
+
const BASE_TRANSIENT = /\b50[234]\b|no stream output|produced no stream|admission timed out|admission_rejected|queue_timeout|fetch failed|ECONNRESET|This operation was aborted/i;
|
|
5810
|
+
const TIMEOUT_PATTERN = /timeout after \d+ ?ms|cli-bridge timeout/i;
|
|
5811
|
+
/**
|
|
5812
|
+
* True when the error text describes an infrastructure hiccup that should be
|
|
5813
|
+
* retried rather than scored. Empty/undefined input is not transient.
|
|
5814
|
+
*/
|
|
5815
|
+
function isTransientTransportFailure(message, opts = {}) {
|
|
5816
|
+
if (!message) return false;
|
|
5817
|
+
if (BASE_TRANSIENT.test(message)) return true;
|
|
5818
|
+
if ((opts.retryFullDurationTimeouts ?? false) && TIMEOUT_PATTERN.test(message)) return true;
|
|
5819
|
+
for (const p of opts.extraPatterns ?? []) if (p.test(message)) return true;
|
|
5820
|
+
return false;
|
|
5821
|
+
}
|
|
5822
|
+
/**
|
|
5823
|
+
* Ready-made `cellRetry.retryable` predicate: true for a dispatch-stage
|
|
5824
|
+
* failure whose error message `isTransientTransportFailure` classifies as an
|
|
5825
|
+
* infrastructure hiccup. A judge-stage failure is never retried here — the
|
|
5826
|
+
* dispatch already produced an artifact, so re-dispatching would score a
|
|
5827
|
+
* different sample. A per-cell dispatch deadline ("dispatch exceeded <N>ms")
|
|
5828
|
+
* is not transient by default; opt in via `extraPatterns` or
|
|
5829
|
+
* `retryFullDurationTimeouts` when queue starvation eats the clock.
|
|
5830
|
+
*/
|
|
5831
|
+
function transientDispatchFailure(opts = {}) {
|
|
5832
|
+
return (failure) => failure.stage === "dispatch" && isTransientTransportFailure(failure.error.message, opts);
|
|
5833
|
+
}
|
|
5834
|
+
//#endregion
|
|
4893
5835
|
//#region src/judges.ts
|
|
4894
5836
|
/**
|
|
4895
5837
|
* A judge's model response could not be parsed into scored dimensions.
|
|
@@ -4950,6 +5892,8 @@ function llmJudge(name, prompt, opts) {
|
|
|
4950
5892
|
const dimensions = normalizeDimensions(opts.dimensions, name);
|
|
4951
5893
|
const scale = opts.scale ?? "unit";
|
|
4952
5894
|
const divisor = scale === "ten" ? 10 : 1;
|
|
5895
|
+
const scoring = opts.scoring ?? { method: "sampled" };
|
|
5896
|
+
if (scoring.method === "expectation" && scale !== "ten") throw new Error(`llmJudge '${name}': expectation scoring requires scale 'ten' — a [0,1] score is not one token, so no single position carries its distribution`);
|
|
4953
5897
|
const renderUser = opts.renderUser ?? ((input) => JSON.stringify({
|
|
4954
5898
|
scenario: input.scenario,
|
|
4955
5899
|
artifact: input.artifact
|
|
@@ -4983,6 +5927,7 @@ function llmJudge(name, prompt, opts) {
|
|
|
4983
5927
|
maxTokens: opts.maxTokens ?? 800,
|
|
4984
5928
|
weights: opts.weights ?? null,
|
|
4985
5929
|
scale,
|
|
5930
|
+
scoring,
|
|
4986
5931
|
jsonSchema: jsonSchema ?? null,
|
|
4987
5932
|
renderUser: opts.renderUser?.toString() ?? null
|
|
4988
5933
|
}),
|
|
@@ -5002,6 +5947,7 @@ function llmJudge(name, prompt, opts) {
|
|
|
5002
5947
|
}],
|
|
5003
5948
|
jsonMode: true,
|
|
5004
5949
|
jsonSchema,
|
|
5950
|
+
...scoring.method === "expectation" ? { logprobs: { topLogprobs: EXPECTATION_TOP_LOGPROBS } } : {},
|
|
5005
5951
|
temperature: opts.temperature ?? .1,
|
|
5006
5952
|
maxTokens: opts.maxTokens ?? 800
|
|
5007
5953
|
};
|
|
@@ -5037,7 +5983,7 @@ function llmJudge(name, prompt, opts) {
|
|
|
5037
5983
|
cause: /* @__PURE__ */ new Error("response has no `dimensions` object"),
|
|
5038
5984
|
llmCall
|
|
5039
5985
|
});
|
|
5040
|
-
const
|
|
5986
|
+
const sampled = {};
|
|
5041
5987
|
for (const { key } of dimensions) {
|
|
5042
5988
|
const raw = rawDims[key];
|
|
5043
5989
|
const value = Number(raw);
|
|
@@ -5045,8 +5991,26 @@ function llmJudge(name, prompt, opts) {
|
|
|
5045
5991
|
cause: /* @__PURE__ */ new Error(`dimension '${key}' missing or non-numeric (got ${JSON.stringify(raw)})`),
|
|
5046
5992
|
llmCall
|
|
5047
5993
|
});
|
|
5048
|
-
|
|
5994
|
+
sampled[key] = value;
|
|
5995
|
+
}
|
|
5996
|
+
let scoringMethod = "sampled";
|
|
5997
|
+
let distribution;
|
|
5998
|
+
const dims = {};
|
|
5999
|
+
if (scoring.method === "expectation") {
|
|
6000
|
+
const expectation = expectedDimensionScores({
|
|
6001
|
+
tokens: response.logprobs ?? null,
|
|
6002
|
+
sampled,
|
|
6003
|
+
maxScore: divisor
|
|
6004
|
+
});
|
|
6005
|
+
if (expectation.kind === "unavailable") {
|
|
6006
|
+
if (scoring.whenUnavailable === "fail") throw new Error(`llmJudge '${name}': expectation scoring is unavailable — ${expectation.reason}`);
|
|
6007
|
+
} else {
|
|
6008
|
+
scoringMethod = "expectation";
|
|
6009
|
+
distribution = expectation.distribution;
|
|
6010
|
+
for (const { key } of dimensions) dims[key] = clamp01(expectation.scores[key] / divisor);
|
|
6011
|
+
}
|
|
5049
6012
|
}
|
|
6013
|
+
if (scoringMethod === "sampled") for (const { key } of dimensions) dims[key] = clamp01(sampled[key] / divisor);
|
|
5050
6014
|
const { composite } = weightedComposite({
|
|
5051
6015
|
dims,
|
|
5052
6016
|
weights: opts.weights ?? Object.fromEntries(dimensions.map((d) => [d.key, 1 / dimensions.length]))
|
|
@@ -5055,11 +6019,105 @@ function llmJudge(name, prompt, opts) {
|
|
|
5055
6019
|
dimensions: dims,
|
|
5056
6020
|
composite,
|
|
5057
6021
|
notes: firstString(parsed.notes) ?? firstString(parsed.rationale) ?? `${name}: composite ${composite.toFixed(3)} over ${dimensions.length} dimension(s)`,
|
|
5058
|
-
llmCall
|
|
6022
|
+
llmCall,
|
|
6023
|
+
...opts.scoring ? { scoringMethod } : {},
|
|
6024
|
+
...distribution ? { distribution } : {}
|
|
5059
6025
|
};
|
|
5060
6026
|
}
|
|
5061
6027
|
};
|
|
5062
6028
|
}
|
|
6029
|
+
/** Alternatives requested per score token. Twenty is the documented ceiling of
|
|
6030
|
+
* the OpenAI-compatible `top_logprobs` field, and a grade scale has at most
|
|
6031
|
+
* eleven integer candidates, so the window always covers the whole scale. */
|
|
6032
|
+
const EXPECTATION_TOP_LOGPROBS = 20;
|
|
6033
|
+
/**
|
|
6034
|
+
* Expected grade per dimension: locate the token that carried each dimension's
|
|
6035
|
+
* integer score, then average the integer grades the model considered at that
|
|
6036
|
+
* position, weighted by their probabilities.
|
|
6037
|
+
*
|
|
6038
|
+
* Unavailable — never silently approximated — when the provider returned no
|
|
6039
|
+
* log probabilities, when a dimension's grade is not in the token stream, or
|
|
6040
|
+
* when the grade did not land in exactly one token (a two-token `10`, a float).
|
|
6041
|
+
*/
|
|
6042
|
+
function expectedDimensionScores(input) {
|
|
6043
|
+
const { tokens, sampled, maxScore } = input;
|
|
6044
|
+
if (tokens === null) return {
|
|
6045
|
+
kind: "unavailable",
|
|
6046
|
+
reason: "the provider returned no logprobs"
|
|
6047
|
+
};
|
|
6048
|
+
if (tokens.length === 0) return {
|
|
6049
|
+
kind: "unavailable",
|
|
6050
|
+
reason: "the provider returned an empty logprob stream"
|
|
6051
|
+
};
|
|
6052
|
+
const offsets = [];
|
|
6053
|
+
let text = "";
|
|
6054
|
+
for (const token of tokens) {
|
|
6055
|
+
offsets.push(text.length);
|
|
6056
|
+
text += token.token;
|
|
6057
|
+
}
|
|
6058
|
+
const scores = {};
|
|
6059
|
+
const distribution = {};
|
|
6060
|
+
for (const [key, value] of Object.entries(sampled)) {
|
|
6061
|
+
const match = new RegExp(`"${escapeRegExp(key)}"\\s*:\\s*`).exec(text);
|
|
6062
|
+
if (!match) return {
|
|
6063
|
+
kind: "unavailable",
|
|
6064
|
+
reason: `dimension '${key}' is not in the token stream`
|
|
6065
|
+
};
|
|
6066
|
+
const scoreOffset = match.index + match[0].length;
|
|
6067
|
+
let index = -1;
|
|
6068
|
+
for (let position = 0; position < offsets.length; position++) if (offsets[position] <= scoreOffset) index = position;
|
|
6069
|
+
else break;
|
|
6070
|
+
const token = tokens[index];
|
|
6071
|
+
if (!token) return {
|
|
6072
|
+
kind: "unavailable",
|
|
6073
|
+
reason: `dimension '${key}' has no token at its score position`
|
|
6074
|
+
};
|
|
6075
|
+
if (integerGrade(token.token, maxScore) !== value) return {
|
|
6076
|
+
kind: "unavailable",
|
|
6077
|
+
reason: `dimension '${key}' scored ${value}, which is not the whole of its token '${token.token}'`
|
|
6078
|
+
};
|
|
6079
|
+
const candidates = [];
|
|
6080
|
+
let total = 0;
|
|
6081
|
+
for (const alternative of token.top.length > 0 ? token.top : [token]) {
|
|
6082
|
+
const grade = integerGrade(alternative.token, maxScore);
|
|
6083
|
+
if (grade === null) continue;
|
|
6084
|
+
const probability = Math.exp(alternative.logprob);
|
|
6085
|
+
if (!Number.isFinite(probability) || probability <= 0) continue;
|
|
6086
|
+
candidates.push({
|
|
6087
|
+
score: grade,
|
|
6088
|
+
probability
|
|
6089
|
+
});
|
|
6090
|
+
total += probability;
|
|
6091
|
+
}
|
|
6092
|
+
if (candidates.length === 0 || total <= 0) return {
|
|
6093
|
+
kind: "unavailable",
|
|
6094
|
+
reason: `dimension '${key}' has no integer grade in its probability window`
|
|
6095
|
+
};
|
|
6096
|
+
let expectation = 0;
|
|
6097
|
+
for (const candidate of candidates) expectation += candidate.probability / total * candidate.score;
|
|
6098
|
+
scores[key] = expectation;
|
|
6099
|
+
distribution[key] = candidates.map((candidate) => ({
|
|
6100
|
+
score: candidate.score,
|
|
6101
|
+
probability: candidate.probability / total
|
|
6102
|
+
})).sort((left, right) => left.score - right.score);
|
|
6103
|
+
}
|
|
6104
|
+
return {
|
|
6105
|
+
kind: "expectation",
|
|
6106
|
+
scores,
|
|
6107
|
+
distribution
|
|
6108
|
+
};
|
|
6109
|
+
}
|
|
6110
|
+
/** The token's integer grade on the judge's scale, or null when the token is
|
|
6111
|
+
* not exactly one integer in range. */
|
|
6112
|
+
function integerGrade(token, maxScore) {
|
|
6113
|
+
const trimmed = token.trim();
|
|
6114
|
+
if (!/^\d+$/.test(trimmed)) return null;
|
|
6115
|
+
const value = Number(trimmed);
|
|
6116
|
+
return Number.isInteger(value) && value >= 0 && value <= maxScore ? value : null;
|
|
6117
|
+
}
|
|
6118
|
+
function escapeRegExp(value) {
|
|
6119
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6120
|
+
}
|
|
5063
6121
|
function normalizeDimensions(input, name) {
|
|
5064
6122
|
const raw = input && input.length > 0 ? input : ["quality"];
|
|
5065
6123
|
const out = [];
|
|
@@ -5115,6 +6173,6 @@ function firstString(value) {
|
|
|
5115
6173
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
5116
6174
|
}
|
|
5117
6175
|
//#endregion
|
|
5118
|
-
export {
|
|
6176
|
+
export { scoreRedTeamOutput as $, codeSurfaceIdentityMaterial as A, verifySearchHistoryReceipt as B, openAutoPr as C, costFromLedgerSummary as D, compareOptimizationMethods as E, SearchHistoryRequiredError as F, parseReflectionResponse as G, campaignMeanComposite as H, assertCompleteSearchHistory as I, readGepaCandidatePopulationArtifact as J, recoverTruncatedJson as K, assertSearchHistoryMatchesReplay as L, renderSurfaceDiff as M, surfaceContentHash as N, optimizationTokenUsageFromSummary as O, surfaceHash as P, redTeamReport as Q, createSearchHistoryReceipt as R, paretoFrontierWithCrowding as S, combineComparisonCosts as T, compareRankKeys as U, campaignBreakdown as V, buildReflectionPrompt as W, DEFAULT_RED_TEAM_CORPUS as X, defaultProductionGate as Y, redTeamDataset as Z, labelTrustRank as _, buildLoopProvenanceRecord as a, tangleTracesRoot as at, dominates as b, emitLoopProvenance as c, summarizeBackendIntegrity as ct, provenanceRecordPath as d, campaignScenarioIdentity as dt, runCanaries as et, provenanceSpansPath as f, campaignSplitDigest as ft, isProposedCandidate as g, computeManifestHash as gt, runOptimization as h, cellCachePath as ht, transientDispatchFailure as i, resolveRunDir as it, componentSurfaceIdentityMaterial as j, assertCodeSurfaceIdentity as k, loopProvenanceArgsFromResult as l, assertCampaignDesign as lt, runImprovementLoop as m, readCachedCell as mt, JudgeParseError as n, runCampaign as nt, campaignMeasurementDigest as o, BackendIntegrityError as ot, verifyLoopProvenanceRecord as p, campaignSplitDigestFromIdentities as pt, assertGepaCandidatePopulationSummary as q, isTransientTransportFailure as r, planCampaignRun as rt, canonicalDigest as s, assertRealBackend as st, llmJudge as t, runEval as tt, loopProvenanceSpans as u, assertCampaignSplitIdentity as ut, SearchRecorder as v, assertOptimizationResult as w, paretoFrontier as x, recordCandidatePopulationSearch as y, searchHistoryCoverageRow as z };
|
|
5119
6177
|
|
|
5120
|
-
//# sourceMappingURL=llm-judge-
|
|
6178
|
+
//# sourceMappingURL=llm-judge-BhasIPFT.js.map
|