@tangle-network/agent-eval 0.129.0 → 0.130.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +1 -0
- package/dist/active-curriculum-C4mk67HP.js +214 -0
- package/dist/active-curriculum-C4mk67HP.js.map +1 -0
- package/dist/adversarial-smnADNFS.d.ts +21 -0
- package/dist/adversarial-smnADNFS.d.ts.map +1 -0
- package/dist/analyst/index.d.ts +81 -2872
- package/dist/analyst/index.d.ts.map +1 -0
- package/dist/analyst/index.js +319 -360
- package/dist/analyst/index.js.map +1 -1
- package/dist/analyst-BkTS3C58.d.ts +89 -0
- package/dist/analyst-BkTS3C58.d.ts.map +1 -0
- package/dist/analyst-LsnNpSkm.js +152 -0
- package/dist/analyst-LsnNpSkm.js.map +1 -0
- package/dist/analyze-runs-C1CavBMk.js +1067 -0
- package/dist/analyze-runs-C1CavBMk.js.map +1 -0
- package/dist/analyze-runs-FsgYCinh.d.ts +72 -0
- package/dist/analyze-runs-FsgYCinh.d.ts.map +1 -0
- package/dist/attribute-vocabulary-DLJ6303h.d.ts +54 -0
- package/dist/attribute-vocabulary-DLJ6303h.d.ts.map +1 -0
- package/dist/authenticity/index.d.ts +81 -79
- package/dist/authenticity/index.d.ts.map +1 -0
- package/dist/authenticity/index.js +209 -193
- package/dist/authenticity/index.js.map +1 -1
- package/dist/baseline-HsBvw_dk.js +550 -0
- package/dist/baseline-HsBvw_dk.js.map +1 -0
- package/dist/baseline-hG3K85h4.d.ts +125 -0
- package/dist/baseline-hG3K85h4.d.ts.map +1 -0
- package/dist/belief-state/index.d.ts +448 -1188
- package/dist/belief-state/index.d.ts.map +1 -0
- package/dist/belief-state/index.js +1617 -1709
- package/dist/belief-state/index.js.map +1 -1
- package/dist/benchmarks/index.d.ts +2 -891
- package/dist/benchmarks/index.js +2 -60
- package/dist/benchmarks-DviOvUNr.js +754 -0
- package/dist/benchmarks-DviOvUNr.js.map +1 -0
- package/dist/builder-eval/index.d.ts +150 -662
- package/dist/builder-eval/index.d.ts.map +1 -0
- package/dist/builder-eval/index.js +356 -345
- package/dist/builder-eval/index.js.map +1 -1
- package/dist/calibration-CNWWA6K8.js +94 -0
- package/dist/calibration-CNWWA6K8.js.map +1 -0
- package/dist/campaign/index.d.ts +5 -6381
- package/dist/campaign/index.js +3 -213
- package/dist/campaign-CBKZvQ1H.js +3885 -0
- package/dist/campaign-CBKZvQ1H.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +164 -175
- package/dist/cli.js.map +1 -1
- package/dist/client-C97NMzqi.d.ts +581 -0
- package/dist/client-C97NMzqi.d.ts.map +1 -0
- package/dist/client-CYzbdJOZ.js +637 -0
- package/dist/client-CYzbdJOZ.js.map +1 -0
- package/dist/code-agent-session-BjkMTQ7H.js +1390 -0
- package/dist/code-agent-session-BjkMTQ7H.js.map +1 -0
- package/dist/code-agent-session-DqqgOJaz.d.ts +143 -0
- package/dist/code-agent-session-DqqgOJaz.d.ts.map +1 -0
- package/dist/concurrency-DIxRZF_J.js +85 -0
- package/dist/concurrency-DIxRZF_J.js.map +1 -0
- package/dist/contract/index.d.ts +645 -5565
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +1730 -1938
- package/dist/contract/index.js.map +1 -1
- package/dist/control.d.ts +3 -1030
- package/dist/control.js +2 -33
- package/dist/cost-ledger-DIgQUFZZ.js +801 -0
- package/dist/cost-ledger-DIgQUFZZ.js.map +1 -0
- package/dist/cost-ledger-Dye6jCgg.d.ts +236 -0
- package/dist/cost-ledger-Dye6jCgg.d.ts.map +1 -0
- package/dist/dataset-BvtnC8Dc.d.ts +115 -0
- package/dist/dataset-BvtnC8Dc.d.ts.map +1 -0
- package/dist/default-registry-C-vFCSEc.js +2579 -0
- package/dist/default-registry-C-vFCSEc.js.map +1 -0
- package/dist/default-registry-CNPo-Vsb.d.ts +540 -0
- package/dist/default-registry-CNPo-Vsb.d.ts.map +1 -0
- package/dist/emitter-CPBAhxum.js +266 -0
- package/dist/emitter-CPBAhxum.js.map +1 -0
- package/dist/emitter-DGQGoLyj.d.ts +113 -0
- package/dist/emitter-DGQGoLyj.d.ts.map +1 -0
- package/dist/errors-8YnH8WlF.js +64 -0
- package/dist/errors-8YnH8WlF.js.map +1 -0
- package/dist/errors-CEk209JS.d.ts +76 -0
- package/dist/errors-CEk209JS.d.ts.map +1 -0
- package/dist/eval-campaign-DEm6c8ru.js +349 -0
- package/dist/eval-campaign-DEm6c8ru.js.map +1 -0
- package/dist/execution-tracks-CpgFPpS5.js +93 -0
- package/dist/execution-tracks-CpgFPpS5.js.map +1 -0
- package/dist/exporters-q9iL-2Jf.js +148 -0
- package/dist/exporters-q9iL-2Jf.js.map +1 -0
- package/dist/extract-usage-BrQ8mCLX.js +155 -0
- package/dist/extract-usage-BrQ8mCLX.js.map +1 -0
- package/dist/failure-cluster-CqcvCcdR.d.ts +59 -0
- package/dist/failure-cluster-CqcvCcdR.d.ts.map +1 -0
- package/dist/feedback-trajectory-CVaeREXV.d.ts +340 -0
- package/dist/feedback-trajectory-CVaeREXV.d.ts.map +1 -0
- package/dist/fuzz.d.ts +320 -646
- package/dist/fuzz.d.ts.map +1 -0
- package/dist/fuzz.js +670 -618
- package/dist/fuzz.js.map +1 -1
- package/dist/hf-dataset-DBJXXoY1.js +763 -0
- package/dist/hf-dataset-DBJXXoY1.js.map +1 -0
- package/dist/hosted/index.d.ts +11 -831
- package/dist/hosted/index.d.ts.map +1 -0
- package/dist/hosted/index.js +2 -37
- package/dist/index-2JJSA6-r2.d.ts +926 -0
- package/dist/index-2JJSA6-r2.d.ts.map +1 -0
- package/dist/index-6N0aYmpW.d.ts +217 -0
- package/dist/index-6N0aYmpW.d.ts.map +1 -0
- package/dist/index-BAvgST_9.d.ts +131 -0
- package/dist/index-BAvgST_9.d.ts.map +1 -0
- package/dist/index-BvnJuTGD.d.ts +68 -0
- package/dist/index-BvnJuTGD.d.ts.map +1 -0
- package/dist/index-C61Wi7yg.d.ts +547 -0
- package/dist/index-C61Wi7yg.d.ts.map +1 -0
- package/dist/index-CAPUUKaM.d.ts +335 -0
- package/dist/index-CAPUUKaM.d.ts.map +1 -0
- package/dist/index-DE5fb3EC.d.ts +2244 -0
- package/dist/index-DE5fb3EC.d.ts.map +1 -0
- package/dist/index-DSC51roc.d.ts +102 -0
- package/dist/index-DSC51roc.d.ts.map +1 -0
- package/dist/index.d.ts +3755 -15555
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11182 -11216
- package/dist/index.js.map +1 -1
- package/dist/integrity-BzRbCHzi.js +424 -0
- package/dist/integrity-BzRbCHzi.js.map +1 -0
- package/dist/integrity-rmVhXWA7.d.ts +61 -0
- package/dist/integrity-rmVhXWA7.d.ts.map +1 -0
- package/dist/judge-calibration-DFtEMlde.d.ts +146 -0
- package/dist/judge-calibration-DFtEMlde.d.ts.map +1 -0
- package/dist/ledger-core/index.d.ts +2 -0
- package/dist/ledger-core/index.js +2 -0
- package/dist/ledger-core-DtZz1RG0.js +388 -0
- package/dist/ledger-core-DtZz1RG0.js.map +1 -0
- package/dist/llm-client--GR4JbZE.js +687 -0
- package/dist/llm-client--GR4JbZE.js.map +1 -0
- package/dist/llm-client-B_nIBlYo.d.ts +290 -0
- package/dist/llm-client-B_nIBlYo.d.ts.map +1 -0
- package/dist/matrix/index.d.ts +3 -155
- package/dist/matrix/index.js +2 -8
- package/dist/matrix-BzQnu2S6.js +270 -0
- package/dist/matrix-BzQnu2S6.js.map +1 -0
- package/dist/meta-eval/index.d.ts +4 -1027
- package/dist/meta-eval/index.js +393 -390
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/metrics-C9YY1OcL.js +239 -0
- package/dist/metrics-C9YY1OcL.js.map +1 -0
- package/dist/mint-yN2M2eh0.js +201 -0
- package/dist/mint-yN2M2eh0.js.map +1 -0
- package/dist/multi-layer-verifier-BHY1gWAc.d.ts +138 -0
- package/dist/multi-layer-verifier-BHY1gWAc.d.ts.map +1 -0
- package/dist/multishot/index.d.ts +273 -480
- package/dist/multishot/index.d.ts.map +1 -0
- package/dist/multishot/index.js +595 -548
- package/dist/multishot/index.js.map +1 -1
- package/dist/off-policy-DvgzvtIx.js +220 -0
- package/dist/off-policy-DvgzvtIx.js.map +1 -0
- package/dist/off-policy-mskQw8Mb.d.ts +153 -0
- package/dist/off-policy-mskQw8Mb.d.ts.map +1 -0
- package/dist/openapi.json +1 -1
- package/dist/opencode-sqlite-BGrHeDu3.js +318 -0
- package/dist/opencode-sqlite-BGrHeDu3.js.map +1 -0
- package/dist/outcome-store-BYHIuO0e.d.ts +65 -0
- package/dist/outcome-store-BYHIuO0e.d.ts.map +1 -0
- package/dist/outcome-store-ChBKlTd_.js +75 -0
- package/dist/outcome-store-ChBKlTd_.js.map +1 -0
- package/dist/paired-arms-D9D0wXj2.js +260 -0
- package/dist/paired-arms-D9D0wXj2.js.map +1 -0
- package/dist/pipelines/index.d.ts +95 -532
- package/dist/pipelines/index.d.ts.map +1 -0
- package/dist/pipelines/index.js +497 -478
- package/dist/pipelines/index.js.map +1 -1
- package/dist/pre-registration-DakwTRXk.js +96 -0
- package/dist/pre-registration-DakwTRXk.js.map +1 -0
- package/dist/propose-review-control-LhIWGzHl.js +1458 -0
- package/dist/propose-review-control-LhIWGzHl.js.map +1 -0
- package/dist/query-CJ_DX8vl.d.ts +28 -0
- package/dist/query-CJ_DX8vl.d.ts.map +1 -0
- package/dist/query-Di7eEQ79.js +83 -0
- package/dist/query-Di7eEQ79.js.map +1 -0
- package/dist/raw-provider-sink-BQd7mzyT.js +201 -0
- package/dist/raw-provider-sink-BQd7mzyT.js.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/redact-7Aq1ukl-.js +107 -0
- package/dist/redact-7Aq1ukl-.js.map +1 -0
- package/dist/release-report-Cz9NKH39.js +603 -0
- package/dist/release-report-Cz9NKH39.js.map +1 -0
- package/dist/release-report-mvB2G4_J.d.ts +244 -0
- package/dist/release-report-mvB2G4_J.d.ts.map +1 -0
- package/dist/replay-GnyotH0J.js +1741 -0
- package/dist/replay-GnyotH0J.js.map +1 -0
- package/dist/replay-OoidtG1E.d.ts +749 -0
- package/dist/replay-OoidtG1E.d.ts.map +1 -0
- package/dist/reporting.d.ts +6 -1312
- package/dist/reporting.js +6 -51
- package/dist/researcher-CwTdwXG1.d.ts +314 -0
- package/dist/researcher-CwTdwXG1.d.ts.map +1 -0
- package/dist/reward-hacking-eAnOsynk.d.ts +224 -0
- package/dist/reward-hacking-eAnOsynk.d.ts.map +1 -0
- package/dist/reward-hacking-qipEpKvY.js +596 -0
- package/dist/reward-hacking-qipEpKvY.js.map +1 -0
- package/dist/reward-nw2xZGZG.js +137 -0
- package/dist/reward-nw2xZGZG.js.map +1 -0
- package/dist/rl.d.ts +760 -4010
- package/dist/rl.d.ts.map +1 -0
- package/dist/rl.js +2325 -1958
- package/dist/rl.js.map +1 -1
- package/dist/rolldown-runtime-8H4AJuhK.js +14 -0
- package/dist/rollout/index.d.ts +3 -2087
- package/dist/rollout/index.js +8 -168
- package/dist/rollout-BOYjemfR.js +624 -0
- package/dist/rollout-BOYjemfR.js.map +1 -0
- package/dist/rubric-predictive-validity-B3xmbmS1.js +141 -0
- package/dist/rubric-predictive-validity-B3xmbmS1.js.map +1 -0
- package/dist/rubric-predictive-validity-Ku_clp_1.d.ts +74 -0
- package/dist/rubric-predictive-validity-Ku_clp_1.d.ts.map +1 -0
- package/dist/run-evidence-ClRX_8A9.d.ts +225 -0
- package/dist/run-evidence-ClRX_8A9.d.ts.map +1 -0
- package/dist/run-record-BuoE80Dq.js +467 -0
- package/dist/{chunk-56TAVBOK.js.map → run-record-BuoE80Dq.js.map} +1 -1
- package/dist/run-record-CnZu_gjl.d.ts +357 -0
- package/dist/run-record-CnZu_gjl.d.ts.map +1 -0
- package/dist/run-score-iEEAWiBY.js +41 -0
- package/dist/run-score-iEEAWiBY.js.map +1 -0
- package/dist/runtime-trajectory-1gyaTOoC.js +93 -0
- package/dist/runtime-trajectory-1gyaTOoC.js.map +1 -0
- package/dist/runtime-trajectory-BvSZcCHD.d.ts +50 -0
- package/dist/runtime-trajectory-BvSZcCHD.d.ts.map +1 -0
- package/dist/schema-BtVldJ3T.d.ts +206 -0
- package/dist/schema-BtVldJ3T.d.ts.map +1 -0
- package/dist/schema-C6DW4ZHR.js +821 -0
- package/dist/schema-C6DW4ZHR.js.map +1 -0
- package/dist/schema-CRhEY1SO.js +69 -0
- package/dist/schema-CRhEY1SO.js.map +1 -0
- package/dist/schema-Cef2cFmb.d.ts +408 -0
- package/dist/schema-Cef2cFmb.d.ts.map +1 -0
- package/dist/semantic-concept-judge-B6cWNJ2K.js +725 -0
- package/dist/semantic-concept-judge-B6cWNJ2K.js.map +1 -0
- package/dist/sequential-Br0mAPHA.js +148 -0
- package/dist/sequential-Br0mAPHA.js.map +1 -0
- package/dist/sequential-CYwq6Ff_.d.ts +141 -0
- package/dist/sequential-CYwq6Ff_.d.ts.map +1 -0
- package/dist/series-convergence-CjO2QdRW.js +43 -0
- package/dist/series-convergence-CjO2QdRW.js.map +1 -0
- package/dist/series-convergence-ofsqPWhs.d.ts +35 -0
- package/dist/series-convergence-ofsqPWhs.d.ts.map +1 -0
- package/dist/server-m5D9cvnG.js +1040 -0
- package/dist/server-m5D9cvnG.js.map +1 -0
- package/dist/skill-usage-C_pXm7lP.d.ts +534 -0
- package/dist/skill-usage-C_pXm7lP.d.ts.map +1 -0
- package/dist/skillopt-optimization-method-B7wX7XkF.d.ts +1739 -0
- package/dist/skillopt-optimization-method-B7wX7XkF.d.ts.map +1 -0
- package/dist/skillopt-optimization-method-D4ODwFVV.js +7712 -0
- package/dist/skillopt-optimization-method-D4ODwFVV.js.map +1 -0
- package/dist/statistics-Cmj6nynr.d.ts +514 -0
- package/dist/statistics-Cmj6nynr.d.ts.map +1 -0
- package/dist/statistics-CnnxdpOg.js +1437 -0
- package/dist/statistics-CnnxdpOg.js.map +1 -0
- package/dist/store-CT9YIIve.d.ts +117 -0
- package/dist/store-CT9YIIve.d.ts.map +1 -0
- package/dist/store-CxJry_cs.d.ts +229 -0
- package/dist/store-CxJry_cs.d.ts.map +1 -0
- package/dist/storyboard/index.d.ts +84 -203
- package/dist/storyboard/index.d.ts.map +1 -0
- package/dist/storyboard/index.js +609 -542
- package/dist/storyboard/index.js.map +1 -1
- package/dist/summary-report-BNs5nmXI.js +862 -0
- package/dist/summary-report-BNs5nmXI.js.map +1 -0
- package/dist/summary-report-Cj9gdw4i.d.ts +407 -0
- package/dist/summary-report-Cj9gdw4i.d.ts.map +1 -0
- package/dist/supervisor-run/index.d.ts +2 -959
- package/dist/supervisor-run/index.js +2 -65
- package/dist/supervisor-run-_lnTLM3z.js +1679 -0
- package/dist/supervisor-run-_lnTLM3z.js.map +1 -0
- package/dist/task-failure-attributes-CQZlB3et.js +311 -0
- package/dist/task-failure-attributes-CQZlB3et.js.map +1 -0
- package/dist/test-graded-scenario-BsqWLmPt.js +318 -0
- package/dist/test-graded-scenario-BsqWLmPt.js.map +1 -0
- package/dist/test-graded-scenario-D1TaI2va.d.ts +141 -0
- package/dist/test-graded-scenario-D1TaI2va.d.ts.map +1 -0
- package/dist/tools-BmuN627J.js +1085 -0
- package/dist/tools-BmuN627J.js.map +1 -0
- package/dist/trace-attributes.d.ts +2 -52
- package/dist/trace-attributes.js +131 -61
- package/dist/trace-attributes.js.map +1 -1
- package/dist/traces.d.ts +12 -2365
- package/dist/traces.js +12 -252
- package/dist/trajectory-D_7rLrvE.js +56 -0
- package/dist/trajectory-D_7rLrvE.js.map +1 -0
- package/dist/types-DGsxbAEd.d.ts +387 -0
- package/dist/types-DGsxbAEd.d.ts.map +1 -0
- package/dist/types-k9tZGKUg.d.ts +640 -0
- package/dist/types-k9tZGKUg.d.ts.map +1 -0
- package/dist/verdict-Dps8_okt.d.ts +37 -0
- package/dist/verdict-Dps8_okt.d.ts.map +1 -0
- package/dist/wire/index.d.ts +702 -1173
- package/dist/wire/index.d.ts.map +1 -0
- package/dist/wire/index.js +2 -81
- package/package.json +17 -9
- package/dist/benchmarks/index.js.map +0 -1
- package/dist/campaign/index.js.map +0 -1
- package/dist/chunk-2QU3YOPR.js +0 -7374
- package/dist/chunk-2QU3YOPR.js.map +0 -1
- package/dist/chunk-3OCR4R5I.js +0 -728
- package/dist/chunk-3OCR4R5I.js.map +0 -1
- package/dist/chunk-3RF76KTD.js +0 -84
- package/dist/chunk-3RF76KTD.js.map +0 -1
- package/dist/chunk-56TAVBOK.js +0 -698
- package/dist/chunk-5DTSBUL2.js +0 -159
- package/dist/chunk-5DTSBUL2.js.map +0 -1
- package/dist/chunk-7FO3TNPI.js +0 -232
- package/dist/chunk-7FO3TNPI.js.map +0 -1
- package/dist/chunk-7ZZMD7UK.js +0 -386
- package/dist/chunk-7ZZMD7UK.js.map +0 -1
- package/dist/chunk-BOD4O7OF.js +0 -40
- package/dist/chunk-BOD4O7OF.js.map +0 -1
- package/dist/chunk-BSO5JDQH.js +0 -2335
- package/dist/chunk-BSO5JDQH.js.map +0 -1
- package/dist/chunk-C6LXANRU.js +0 -1550
- package/dist/chunk-C6LXANRU.js.map +0 -1
- package/dist/chunk-DODXQREJ.js +0 -752
- package/dist/chunk-DODXQREJ.js.map +0 -1
- package/dist/chunk-DRYIUNWY.js +0 -622
- package/dist/chunk-DRYIUNWY.js.map +0 -1
- package/dist/chunk-E7QXT7SX.js +0 -183
- package/dist/chunk-E7QXT7SX.js.map +0 -1
- package/dist/chunk-EG66UGL4.js +0 -341
- package/dist/chunk-EG66UGL4.js.map +0 -1
- package/dist/chunk-FXTVJPYD.js +0 -576
- package/dist/chunk-FXTVJPYD.js.map +0 -1
- package/dist/chunk-G7MGMCZD.js +0 -153
- package/dist/chunk-G7MGMCZD.js.map +0 -1
- package/dist/chunk-GGE4NNQT.js +0 -65
- package/dist/chunk-GGE4NNQT.js.map +0 -1
- package/dist/chunk-H23X7XKK.js +0 -181
- package/dist/chunk-H23X7XKK.js.map +0 -1
- package/dist/chunk-HHWE3POT.js +0 -94
- package/dist/chunk-HHWE3POT.js.map +0 -1
- package/dist/chunk-HPWUNB47.js +0 -289
- package/dist/chunk-HPWUNB47.js.map +0 -1
- package/dist/chunk-IYCLP2N2.js +0 -766
- package/dist/chunk-IYCLP2N2.js.map +0 -1
- package/dist/chunk-JHCHEVET.js +0 -274
- package/dist/chunk-JHCHEVET.js.map +0 -1
- package/dist/chunk-JQSF5DQT.js +0 -701
- package/dist/chunk-JQSF5DQT.js.map +0 -1
- package/dist/chunk-K4DBDHLK.js +0 -158
- package/dist/chunk-K4DBDHLK.js.map +0 -1
- package/dist/chunk-K6N6XJJX.js +0 -306
- package/dist/chunk-K6N6XJJX.js.map +0 -1
- package/dist/chunk-M4YBQKIJ.js +0 -1040
- package/dist/chunk-M4YBQKIJ.js.map +0 -1
- package/dist/chunk-MA6HLL3S.js +0 -65
- package/dist/chunk-MA6HLL3S.js.map +0 -1
- package/dist/chunk-MAZ26DC7.js +0 -99
- package/dist/chunk-MAZ26DC7.js.map +0 -1
- package/dist/chunk-NPCTHQIO.js +0 -91
- package/dist/chunk-NPCTHQIO.js.map +0 -1
- package/dist/chunk-NY44NC4A.js +0 -1056
- package/dist/chunk-NY44NC4A.js.map +0 -1
- package/dist/chunk-OIUOT4QD.js +0 -44
- package/dist/chunk-OIUOT4QD.js.map +0 -1
- package/dist/chunk-ONWEPEDO.js +0 -57
- package/dist/chunk-ONWEPEDO.js.map +0 -1
- package/dist/chunk-OWN5NPMC.js +0 -152
- package/dist/chunk-OWN5NPMC.js.map +0 -1
- package/dist/chunk-P6FYH6K4.js +0 -1161
- package/dist/chunk-P6FYH6K4.js.map +0 -1
- package/dist/chunk-PC4UYEBM.js +0 -166
- package/dist/chunk-PC4UYEBM.js.map +0 -1
- package/dist/chunk-PC5DOSM7.js +0 -579
- package/dist/chunk-PC5DOSM7.js.map +0 -1
- package/dist/chunk-PXE2VKMX.js +0 -140
- package/dist/chunk-PXE2VKMX.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-QB6BDBP2.js +0 -4464
- package/dist/chunk-QB6BDBP2.js.map +0 -1
- package/dist/chunk-RXHCETDZ.js +0 -536
- package/dist/chunk-RXHCETDZ.js.map +0 -1
- package/dist/chunk-RZTMDUO7.js +0 -49
- package/dist/chunk-RZTMDUO7.js.map +0 -1
- package/dist/chunk-SFLLL76A.js +0 -669
- package/dist/chunk-SFLLL76A.js.map +0 -1
- package/dist/chunk-SZLVEKMJ.js +0 -1446
- package/dist/chunk-SZLVEKMJ.js.map +0 -1
- package/dist/chunk-T4SQEITX.js +0 -95
- package/dist/chunk-T4SQEITX.js.map +0 -1
- package/dist/chunk-T6RLYGAD.js +0 -158
- package/dist/chunk-T6RLYGAD.js.map +0 -1
- package/dist/chunk-TJVT4QFF.js +0 -911
- package/dist/chunk-TJVT4QFF.js.map +0 -1
- package/dist/chunk-TQ7LNKZ3.js +0 -136
- package/dist/chunk-TQ7LNKZ3.js.map +0 -1
- package/dist/chunk-U4L7JRPZ.js +0 -1706
- package/dist/chunk-U4L7JRPZ.js.map +0 -1
- package/dist/chunk-U4PHLT2N.js +0 -419
- package/dist/chunk-U4PHLT2N.js.map +0 -1
- package/dist/chunk-VCZ5FQYW.js +0 -928
- package/dist/chunk-VCZ5FQYW.js.map +0 -1
- package/dist/chunk-VI2UW6B6.js +0 -162
- package/dist/chunk-VI2UW6B6.js.map +0 -1
- package/dist/chunk-VQMK5FMP.js +0 -247
- package/dist/chunk-VQMK5FMP.js.map +0 -1
- package/dist/chunk-WGXIEX7P.js +0 -116
- package/dist/chunk-WGXIEX7P.js.map +0 -1
- package/dist/chunk-WVATSFCP.js +0 -1553
- package/dist/chunk-WVATSFCP.js.map +0 -1
- package/dist/chunk-X4YIBDER.js +0 -1662
- package/dist/chunk-X4YIBDER.js.map +0 -1
- package/dist/chunk-YQN4ICPP.js +0 -355
- package/dist/chunk-YQN4ICPP.js.map +0 -1
- package/dist/chunk-ZET2UAYW.js +0 -89
- package/dist/chunk-ZET2UAYW.js.map +0 -1
- package/dist/chunk-ZHTZ4EYI.js +0 -1212
- package/dist/chunk-ZHTZ4EYI.js.map +0 -1
- package/dist/control.js.map +0 -1
- package/dist/hosted/index.js.map +0 -1
- package/dist/matrix/index.js.map +0 -1
- package/dist/reporting.js.map +0 -1
- package/dist/rollout/index.js.map +0 -1
- package/dist/run-campaign-OJJ7CZF4.js +0 -18
- package/dist/run-campaign-OJJ7CZF4.js.map +0 -1
- package/dist/supervisor-run/index.js.map +0 -1
- package/dist/traces.js.map +0 -1
- package/dist/wire/index.js.map +0 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import { n as CaptureIntegrityError } from "./errors-8YnH8WlF.js";
|
|
2
|
+
//#region src/trace/store.ts
|
|
3
|
+
var InMemoryTraceStore = class {
|
|
4
|
+
runs = /* @__PURE__ */ new Map();
|
|
5
|
+
allSpans = [];
|
|
6
|
+
allEvents = [];
|
|
7
|
+
allArtifacts = [];
|
|
8
|
+
allBudget = [];
|
|
9
|
+
async appendRun(run) {
|
|
10
|
+
if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`);
|
|
11
|
+
this.runs.set(run.runId, { ...run });
|
|
12
|
+
}
|
|
13
|
+
async updateRun(runId, patch) {
|
|
14
|
+
const existing = this.runs.get(runId);
|
|
15
|
+
if (!existing) throw new Error(`run ${runId} not found`);
|
|
16
|
+
this.runs.set(runId, {
|
|
17
|
+
...existing,
|
|
18
|
+
...patch
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async appendSpan(span) {
|
|
22
|
+
this.allSpans.push({ ...span });
|
|
23
|
+
}
|
|
24
|
+
async updateSpan(spanId, patch) {
|
|
25
|
+
const idx = this.allSpans.findIndex((s) => s.spanId === spanId);
|
|
26
|
+
if (idx < 0) throw new Error(`span ${spanId} not found`);
|
|
27
|
+
this.allSpans[idx] = {
|
|
28
|
+
...this.allSpans[idx],
|
|
29
|
+
...patch
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async appendEvent(event) {
|
|
33
|
+
this.allEvents.push({ ...event });
|
|
34
|
+
}
|
|
35
|
+
async appendArtifact(artifact) {
|
|
36
|
+
this.allArtifacts.push({ ...artifact });
|
|
37
|
+
}
|
|
38
|
+
async appendBudgetEntry(entry) {
|
|
39
|
+
this.allBudget.push({ ...entry });
|
|
40
|
+
}
|
|
41
|
+
async getRun(runId) {
|
|
42
|
+
const r = this.runs.get(runId);
|
|
43
|
+
return r ? { ...r } : void 0;
|
|
44
|
+
}
|
|
45
|
+
async listRuns(filter = {}) {
|
|
46
|
+
return [...this.runs.values()].filter((r) => matchesRun(r, filter));
|
|
47
|
+
}
|
|
48
|
+
async spans(filter = {}) {
|
|
49
|
+
return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }));
|
|
50
|
+
}
|
|
51
|
+
async events(filter = {}) {
|
|
52
|
+
return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }));
|
|
53
|
+
}
|
|
54
|
+
async budget(runId) {
|
|
55
|
+
return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }));
|
|
56
|
+
}
|
|
57
|
+
async artifacts(runId) {
|
|
58
|
+
return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }));
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function matchesRun(r, f) {
|
|
62
|
+
if (f.scenarioId && r.scenarioId !== f.scenarioId) return false;
|
|
63
|
+
if (f.variantId && r.variantId !== f.variantId) return false;
|
|
64
|
+
if (f.status && r.status !== f.status) return false;
|
|
65
|
+
if (f.since !== void 0 && r.startedAt < f.since) return false;
|
|
66
|
+
if (f.until !== void 0 && r.startedAt > f.until) return false;
|
|
67
|
+
if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false;
|
|
68
|
+
if (f.parentRunId && r.parentRunId !== f.parentRunId) return false;
|
|
69
|
+
if (f.projectId && r.projectId !== f.projectId) return false;
|
|
70
|
+
if (f.chatId && r.chatId !== f.chatId) return false;
|
|
71
|
+
if (f.layer && r.layer !== f.layer) return false;
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
function matchesSpan(s, f) {
|
|
75
|
+
if (f.runId && s.runId !== f.runId) return false;
|
|
76
|
+
if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false;
|
|
77
|
+
if (f.kind && s.kind !== f.kind) return false;
|
|
78
|
+
if (f.name && s.name !== f.name) return false;
|
|
79
|
+
if (f.toolName && (s.kind !== "tool" || s.toolName !== f.toolName)) return false;
|
|
80
|
+
if (f.judgeId && (s.kind !== "judge" || s.judgeId !== f.judgeId)) return false;
|
|
81
|
+
if (f.since !== void 0 && s.startedAt < f.since) return false;
|
|
82
|
+
if (f.until !== void 0 && s.startedAt > f.until) return false;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
function matchesEvent(e, f) {
|
|
86
|
+
if (f.runId && e.runId !== f.runId) return false;
|
|
87
|
+
if (f.spanId && e.spanId !== f.spanId) return false;
|
|
88
|
+
if (f.kind && e.kind !== f.kind) return false;
|
|
89
|
+
if (f.since !== void 0 && e.timestamp < f.since) return false;
|
|
90
|
+
if (f.until !== void 0 && e.timestamp > f.until) return false;
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
var FileSystemTraceStore = class {
|
|
94
|
+
dir;
|
|
95
|
+
maxBytes;
|
|
96
|
+
/** Lazy in-memory index for queries — populated on first read. */
|
|
97
|
+
index;
|
|
98
|
+
/** Memoized index build — concurrent first reads share one build, and an
|
|
99
|
+
* append racing an in-flight load awaits this so its row isn't lost. */
|
|
100
|
+
indexPromise;
|
|
101
|
+
/** Strictly-increasing rollover stamp. Date.now() alone collides when two
|
|
102
|
+
* rollovers land in the same millisecond, overwriting a rolled file. */
|
|
103
|
+
lastRolloverStamp = 0;
|
|
104
|
+
/**
|
|
105
|
+
* Per-file append serialization. stat → conditional-rename → appendFile is a
|
|
106
|
+
* read-modify-write on the active file; without a lock two concurrent appends
|
|
107
|
+
* to the same `name` can both pass the size check (exceeding maxBytes) or one
|
|
108
|
+
* can append to a file the other just renamed away. Each entry chains the
|
|
109
|
+
* next append behind the prior one for that file.
|
|
110
|
+
*/
|
|
111
|
+
appendLocks = /* @__PURE__ */ new Map();
|
|
112
|
+
constructor(options) {
|
|
113
|
+
this.dir = options.dir;
|
|
114
|
+
this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024;
|
|
115
|
+
}
|
|
116
|
+
async ensureDir() {
|
|
117
|
+
await (await import("node:fs/promises")).mkdir(this.dir, { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
async append(name, record) {
|
|
120
|
+
if (this.indexPromise) await this.indexPromise;
|
|
121
|
+
const result = (this.appendLocks.get(name) ?? Promise.resolve()).then(() => this.appendLocked(name, record));
|
|
122
|
+
const tail = result.then(() => {}, () => {});
|
|
123
|
+
this.appendLocks.set(name, tail);
|
|
124
|
+
try {
|
|
125
|
+
await result;
|
|
126
|
+
} finally {
|
|
127
|
+
if (this.appendLocks.get(name) === tail) this.appendLocks.delete(name);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async appendLocked(name, record) {
|
|
131
|
+
await this.ensureDir();
|
|
132
|
+
const fs = await import("node:fs/promises");
|
|
133
|
+
const path = await import("node:path");
|
|
134
|
+
const active = path.join(this.dir, `${name}.ndjson`);
|
|
135
|
+
try {
|
|
136
|
+
if ((await fs.stat(active)).size >= this.maxBytes) {
|
|
137
|
+
const stamp = Math.max(Date.now(), this.lastRolloverStamp + 1);
|
|
138
|
+
this.lastRolloverStamp = stamp;
|
|
139
|
+
const rolled = path.join(this.dir, `${name}.${stamp}.ndjson`);
|
|
140
|
+
await fs.rename(active, rolled);
|
|
141
|
+
}
|
|
142
|
+
} catch {}
|
|
143
|
+
await fs.appendFile(active, `${JSON.stringify(record)}\n`, "utf8");
|
|
144
|
+
if (this.index && !record?._update) await this.insertInto(name, record);
|
|
145
|
+
}
|
|
146
|
+
async insertInto(name, record) {
|
|
147
|
+
if (!this.index) return;
|
|
148
|
+
switch (name) {
|
|
149
|
+
case "runs":
|
|
150
|
+
await this.index.appendRun(record);
|
|
151
|
+
break;
|
|
152
|
+
case "spans":
|
|
153
|
+
await this.index.appendSpan(record);
|
|
154
|
+
break;
|
|
155
|
+
case "events":
|
|
156
|
+
await this.index.appendEvent(record);
|
|
157
|
+
break;
|
|
158
|
+
case "artifacts":
|
|
159
|
+
await this.index.appendArtifact(record);
|
|
160
|
+
break;
|
|
161
|
+
case "budget":
|
|
162
|
+
await this.index.appendBudgetEntry(record);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
load() {
|
|
167
|
+
this.indexPromise ??= this.buildIndex();
|
|
168
|
+
return this.indexPromise;
|
|
169
|
+
}
|
|
170
|
+
async buildIndex() {
|
|
171
|
+
const fs = await import("node:fs/promises");
|
|
172
|
+
const path = await import("node:path");
|
|
173
|
+
const store = new InMemoryTraceStore();
|
|
174
|
+
let entries;
|
|
175
|
+
try {
|
|
176
|
+
entries = await fs.readdir(this.dir);
|
|
177
|
+
} catch {
|
|
178
|
+
this.index = store;
|
|
179
|
+
return store;
|
|
180
|
+
}
|
|
181
|
+
entries.sort((a, b) => {
|
|
182
|
+
const baseA = a.split(".")[0];
|
|
183
|
+
const baseB = b.split(".")[0];
|
|
184
|
+
if (baseA !== baseB) return baseA < baseB ? -1 : 1;
|
|
185
|
+
const ta = a.match(/^[^.]+\.(\d+)\.ndjson$/);
|
|
186
|
+
const tb = b.match(/^[^.]+\.(\d+)\.ndjson$/);
|
|
187
|
+
return (ta ? Number(ta[1]) : Number.POSITIVE_INFINITY) - (tb ? Number(tb[1]) : Number.POSITIVE_INFINITY);
|
|
188
|
+
});
|
|
189
|
+
{
|
|
190
|
+
const runUpdates = [];
|
|
191
|
+
const spanUpdates = [];
|
|
192
|
+
for (const file of entries) {
|
|
193
|
+
if (!file.endsWith(".ndjson")) continue;
|
|
194
|
+
const full = path.join(this.dir, file);
|
|
195
|
+
const content = await fs.readFile(full, "utf8");
|
|
196
|
+
const base = file.split(".")[0];
|
|
197
|
+
const lines = content.split("\n");
|
|
198
|
+
for (let ln = 0; ln < lines.length; ln++) {
|
|
199
|
+
const line = lines[ln];
|
|
200
|
+
if (!line.trim()) continue;
|
|
201
|
+
let record;
|
|
202
|
+
try {
|
|
203
|
+
record = JSON.parse(line);
|
|
204
|
+
} catch (err) {
|
|
205
|
+
throw new Error(`FileSystemTraceStore: corrupt NDJSON in ${file} line ${ln + 1}: ${err instanceof Error ? err.message : String(err)} — ${line.slice(0, 120)}`);
|
|
206
|
+
}
|
|
207
|
+
if (base === "runs") {
|
|
208
|
+
if (record?._update) {
|
|
209
|
+
runUpdates.push(record);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
await store.appendRun(record);
|
|
214
|
+
} catch {
|
|
215
|
+
await store.updateRun(record.runId, record);
|
|
216
|
+
}
|
|
217
|
+
} else if (base === "spans") {
|
|
218
|
+
if (record?._update) {
|
|
219
|
+
spanUpdates.push(record);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
await store.appendSpan(record);
|
|
223
|
+
} else if (base === "events") await store.appendEvent(record);
|
|
224
|
+
else if (base === "artifacts") await store.appendArtifact(record);
|
|
225
|
+
else if (base === "budget") await store.appendBudgetEntry(record);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
for (const record of runUpdates) await store.updateRun(record.runId, record);
|
|
229
|
+
for (const record of spanUpdates) await store.updateSpan(record.spanId, record);
|
|
230
|
+
}
|
|
231
|
+
this.index = store;
|
|
232
|
+
return store;
|
|
233
|
+
}
|
|
234
|
+
async appendRun(run) {
|
|
235
|
+
await this.append("runs", run);
|
|
236
|
+
}
|
|
237
|
+
async updateRun(runId, patch) {
|
|
238
|
+
await this.append("runs", {
|
|
239
|
+
runId,
|
|
240
|
+
...patch,
|
|
241
|
+
_update: true
|
|
242
|
+
});
|
|
243
|
+
if (this.index) await this.index.updateRun(runId, patch);
|
|
244
|
+
}
|
|
245
|
+
async appendSpan(span) {
|
|
246
|
+
await this.append("spans", span);
|
|
247
|
+
}
|
|
248
|
+
async updateSpan(spanId, patch) {
|
|
249
|
+
await this.append("spans", {
|
|
250
|
+
spanId,
|
|
251
|
+
...patch,
|
|
252
|
+
_update: true
|
|
253
|
+
});
|
|
254
|
+
if (this.index) await this.index.updateSpan(spanId, patch);
|
|
255
|
+
}
|
|
256
|
+
async appendEvent(event) {
|
|
257
|
+
await this.append("events", event);
|
|
258
|
+
}
|
|
259
|
+
async appendArtifact(artifact) {
|
|
260
|
+
await this.append("artifacts", artifact);
|
|
261
|
+
}
|
|
262
|
+
async appendBudgetEntry(entry) {
|
|
263
|
+
await this.append("budget", entry);
|
|
264
|
+
}
|
|
265
|
+
async getRun(runId) {
|
|
266
|
+
return (await this.load()).getRun(runId);
|
|
267
|
+
}
|
|
268
|
+
async listRuns(filter) {
|
|
269
|
+
return (await this.load()).listRuns(filter);
|
|
270
|
+
}
|
|
271
|
+
async spans(filter) {
|
|
272
|
+
return (await this.load()).spans(filter);
|
|
273
|
+
}
|
|
274
|
+
async events(filter) {
|
|
275
|
+
return (await this.load()).events(filter);
|
|
276
|
+
}
|
|
277
|
+
async budget(runId) {
|
|
278
|
+
return (await this.load()).budget(runId);
|
|
279
|
+
}
|
|
280
|
+
async artifacts(runId) {
|
|
281
|
+
return (await this.load()).artifacts(runId);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/trace/integrity.ts
|
|
286
|
+
/**
|
|
287
|
+
* Run-completion integrity check — at end of run, verify the expected event
|
|
288
|
+
* types were actually captured. The point is the launch-review failure mode:
|
|
289
|
+
* a run *appears* successful but the raw provider events were never written,
|
|
290
|
+
* so a downstream reviewer can't reconstruct what happened.
|
|
291
|
+
*
|
|
292
|
+
* Pattern:
|
|
293
|
+
*
|
|
294
|
+
* const report = await assertRunCaptured(store, runId, {
|
|
295
|
+
* llmSpansMin: 1,
|
|
296
|
+
* judgeSpansMin: 1,
|
|
297
|
+
* rawSink: providerSink, // must have ≥ 1 event for this run
|
|
298
|
+
* requireRawCoverageOfLlmSpans: true, // every llm span has matching raw events
|
|
299
|
+
* })
|
|
300
|
+
* if (!report.ok) throwIfRunIncomplete(report) // or mark run failed and continue
|
|
301
|
+
*
|
|
302
|
+
* The function is read-only on the store and returns a structured report;
|
|
303
|
+
* the caller chooses the failure mode (throw, mark run failed, log warning).
|
|
304
|
+
* `throwIfRunIncomplete` is the convenient strict mode.
|
|
305
|
+
*/
|
|
306
|
+
var RunIntegrityError = class extends CaptureIntegrityError {
|
|
307
|
+
report;
|
|
308
|
+
constructor(report) {
|
|
309
|
+
super(`Run ${report.runId} failed integrity check: ${report.issues.map((i) => i.code).join(", ")}`);
|
|
310
|
+
this.report = report;
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
async function assertRunCaptured(store, runId, expectations = {}) {
|
|
314
|
+
const issues = [];
|
|
315
|
+
const run = await store.getRun(runId);
|
|
316
|
+
if (!run) return {
|
|
317
|
+
ok: false,
|
|
318
|
+
runId,
|
|
319
|
+
llmSpanCount: 0,
|
|
320
|
+
judgeSpanCount: 0,
|
|
321
|
+
toolSpanCount: 0,
|
|
322
|
+
rawProviderEventCount: 0,
|
|
323
|
+
rawSpanCoverage: {
|
|
324
|
+
covered: 0,
|
|
325
|
+
total: 0
|
|
326
|
+
},
|
|
327
|
+
issues: [{
|
|
328
|
+
code: "no_run",
|
|
329
|
+
message: `Run ${runId} not found in store.`
|
|
330
|
+
}]
|
|
331
|
+
};
|
|
332
|
+
const spans = await store.spans({ runId });
|
|
333
|
+
const llmSpans = spans.filter((s) => s.kind === "llm");
|
|
334
|
+
const judgeSpans = spans.filter((s) => s.kind === "judge");
|
|
335
|
+
const toolSpans = spans.filter((s) => s.kind === "tool");
|
|
336
|
+
const llmMin = expectations.llmSpansMin ?? 0;
|
|
337
|
+
const judgeMin = expectations.judgeSpansMin ?? 0;
|
|
338
|
+
const toolMin = expectations.toolSpansMin ?? 0;
|
|
339
|
+
if (llmSpans.length < llmMin) issues.push({
|
|
340
|
+
code: "missing_llm_spans",
|
|
341
|
+
message: `Expected ≥ ${llmMin} LLM spans, found ${llmSpans.length}.`,
|
|
342
|
+
detail: {
|
|
343
|
+
expected: llmMin,
|
|
344
|
+
found: llmSpans.length
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
if (judgeSpans.length < judgeMin) issues.push({
|
|
348
|
+
code: "missing_judge_spans",
|
|
349
|
+
message: `Expected ≥ ${judgeMin} judge spans, found ${judgeSpans.length}.`,
|
|
350
|
+
detail: {
|
|
351
|
+
expected: judgeMin,
|
|
352
|
+
found: judgeSpans.length
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
if (toolSpans.length < toolMin) issues.push({
|
|
356
|
+
code: "missing_tool_spans",
|
|
357
|
+
message: `Expected ≥ ${toolMin} tool spans, found ${toolSpans.length}.`,
|
|
358
|
+
detail: {
|
|
359
|
+
expected: toolMin,
|
|
360
|
+
found: toolSpans.length
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
let rawEventCount = 0;
|
|
364
|
+
let coverage = {
|
|
365
|
+
covered: 0,
|
|
366
|
+
total: llmSpans.length
|
|
367
|
+
};
|
|
368
|
+
if (expectations.rawSink) if (!expectations.rawSink.list) issues.push({
|
|
369
|
+
code: "no_raw_sink",
|
|
370
|
+
message: "Provided rawSink does not implement list(); cannot verify capture."
|
|
371
|
+
});
|
|
372
|
+
else {
|
|
373
|
+
const events = await expectations.rawSink.list({ runId });
|
|
374
|
+
rawEventCount = events.length;
|
|
375
|
+
const rawMin = expectations.rawProviderEventsMin ?? 1;
|
|
376
|
+
if (rawEventCount < rawMin) issues.push({
|
|
377
|
+
code: "missing_raw_events",
|
|
378
|
+
message: `Expected ≥ ${rawMin} raw provider events, found ${rawEventCount}.`,
|
|
379
|
+
detail: {
|
|
380
|
+
expected: rawMin,
|
|
381
|
+
found: rawEventCount
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
if (expectations.requireRawCoverageOfLlmSpans) {
|
|
385
|
+
const requestEventsBySpan = new Set(events.filter((e) => e.direction === "request" && e.spanId).map((e) => e.spanId));
|
|
386
|
+
const orphaned = llmSpans.filter((s) => !requestEventsBySpan.has(s.spanId));
|
|
387
|
+
coverage = {
|
|
388
|
+
covered: llmSpans.length - orphaned.length,
|
|
389
|
+
total: llmSpans.length
|
|
390
|
+
};
|
|
391
|
+
if (orphaned.length > 0) issues.push({
|
|
392
|
+
code: "orphan_llm_span",
|
|
393
|
+
message: `${orphaned.length} LLM span(s) have no matching raw provider request event.`,
|
|
394
|
+
detail: { orphanedSpanIds: orphaned.map((s) => s.spanId) }
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
else if (expectations.requireRawCoverageOfLlmSpans || expectations.rawProviderEventsMin) issues.push({
|
|
399
|
+
code: "no_raw_sink",
|
|
400
|
+
message: "Raw coverage required but no rawSink supplied to the integrity check."
|
|
401
|
+
});
|
|
402
|
+
if (expectations.requireOutcome && (run.outcome === void 0 || run.outcome === null)) issues.push({
|
|
403
|
+
code: "missing_outcome",
|
|
404
|
+
message: `Run ${runId} has no outcome recorded.`
|
|
405
|
+
});
|
|
406
|
+
return {
|
|
407
|
+
ok: issues.length === 0,
|
|
408
|
+
runId,
|
|
409
|
+
llmSpanCount: llmSpans.length,
|
|
410
|
+
judgeSpanCount: judgeSpans.length,
|
|
411
|
+
toolSpanCount: toolSpans.length,
|
|
412
|
+
rawProviderEventCount: rawEventCount,
|
|
413
|
+
rawSpanCoverage: coverage,
|
|
414
|
+
issues
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
/** Strict mode: throws `RunIntegrityError` when the report isn't ok. */
|
|
418
|
+
function throwIfRunIncomplete(report) {
|
|
419
|
+
if (!report.ok) throw new RunIntegrityError(report);
|
|
420
|
+
}
|
|
421
|
+
//#endregion
|
|
422
|
+
export { InMemoryTraceStore as a, FileSystemTraceStore as i, assertRunCaptured as n, throwIfRunIncomplete as r, RunIntegrityError as t };
|
|
423
|
+
|
|
424
|
+
//# sourceMappingURL=integrity-BzRbCHzi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity-BzRbCHzi.js","names":[],"sources":["../src/trace/store.ts","../src/trace/integrity.ts"],"sourcesContent":["/**\n * TraceStore — persistence + query over the TraceSchema v1 corpus.\n *\n * Two implementations ship in the core:\n * - InMemoryTraceStore: dev + tests, fully in-process\n * - FileSystemTraceStore: NDJSON append-only files per entity, suitable\n * for long-running CI jobs; rolled over at 32MB\n *\n * Downstream adapters (DuckDB, Langfuse, R2 parquet) implement this same\n * interface — the rest of the framework is storage-agnostic.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n Run,\n RunStatus,\n Span,\n SpanKind,\n TraceEvent,\n} from './schema'\n\nexport interface RunFilter {\n scenarioId?: string\n variantId?: string\n status?: RunStatus\n since?: number\n until?: number\n tag?: { key: string; value: string }\n parentRunId?: string\n projectId?: string\n chatId?: string\n layer?: import('./schema').RunLayer\n}\n\nexport interface SpanFilter {\n runId?: string\n parentSpanId?: string\n kind?: SpanKind\n name?: string\n toolName?: string\n judgeId?: string\n since?: number\n until?: number\n}\n\nexport interface EventFilter {\n runId?: string\n spanId?: string\n kind?: EventKind\n since?: number\n until?: number\n}\n\nexport interface TraceStore {\n appendRun(run: Run): Promise<void>\n updateRun(runId: string, patch: Partial<Run>): Promise<void>\n appendSpan(span: Span): Promise<void>\n updateSpan(spanId: string, patch: Partial<Span>): Promise<void>\n appendEvent(event: TraceEvent): Promise<void>\n appendArtifact(artifact: Artifact): Promise<void>\n appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void>\n\n getRun(runId: string): Promise<Run | undefined>\n listRuns(filter?: RunFilter): Promise<Run[]>\n spans(filter?: SpanFilter): Promise<Span[]>\n events(filter?: EventFilter): Promise<TraceEvent[]>\n budget(runId: string): Promise<BudgetLedgerEntry[]>\n artifacts(runId: string): Promise<Artifact[]>\n}\n\n// ── In-memory ────────────────────────────────────────────────────────\n\nexport class InMemoryTraceStore implements TraceStore {\n private runs = new Map<string, Run>()\n private allSpans: Span[] = []\n private allEvents: TraceEvent[] = []\n private allArtifacts: Artifact[] = []\n private allBudget: BudgetLedgerEntry[] = []\n\n async appendRun(run: Run): Promise<void> {\n if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`)\n this.runs.set(run.runId, { ...run })\n }\n\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n const existing = this.runs.get(runId)\n if (!existing) throw new Error(`run ${runId} not found`)\n this.runs.set(runId, { ...existing, ...patch })\n }\n\n async appendSpan(span: Span): Promise<void> {\n this.allSpans.push({ ...span })\n }\n\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n const idx = this.allSpans.findIndex((s) => s.spanId === spanId)\n if (idx < 0) throw new Error(`span ${spanId} not found`)\n this.allSpans[idx] = { ...this.allSpans[idx], ...patch } as Span\n }\n\n async appendEvent(event: TraceEvent): Promise<void> {\n this.allEvents.push({ ...event })\n }\n\n async appendArtifact(artifact: Artifact): Promise<void> {\n this.allArtifacts.push({ ...artifact })\n }\n\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n this.allBudget.push({ ...entry })\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n const r = this.runs.get(runId)\n return r ? { ...r } : undefined\n }\n\n async listRuns(filter: RunFilter = {}): Promise<Run[]> {\n return [...this.runs.values()].filter((r) => matchesRun(r, filter))\n }\n\n async spans(filter: SpanFilter = {}): Promise<Span[]> {\n return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }))\n }\n\n async events(filter: EventFilter = {}): Promise<TraceEvent[]> {\n return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }))\n }\n\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }))\n }\n\n async artifacts(runId: string): Promise<Artifact[]> {\n return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }))\n }\n}\n\nfunction matchesRun(r: Run, f: RunFilter): boolean {\n if (f.scenarioId && r.scenarioId !== f.scenarioId) return false\n if (f.variantId && r.variantId !== f.variantId) return false\n if (f.status && r.status !== f.status) return false\n if (f.since !== undefined && r.startedAt < f.since) return false\n if (f.until !== undefined && r.startedAt > f.until) return false\n if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false\n if (f.parentRunId && r.parentRunId !== f.parentRunId) return false\n if (f.projectId && r.projectId !== f.projectId) return false\n if (f.chatId && r.chatId !== f.chatId) return false\n if (f.layer && r.layer !== f.layer) return false\n return true\n}\n\nfunction matchesSpan(s: Span, f: SpanFilter): boolean {\n if (f.runId && s.runId !== f.runId) return false\n if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false\n if (f.kind && s.kind !== f.kind) return false\n if (f.name && s.name !== f.name) return false\n if (f.toolName && (s.kind !== 'tool' || s.toolName !== f.toolName)) return false\n if (f.judgeId && (s.kind !== 'judge' || s.judgeId !== f.judgeId)) return false\n if (f.since !== undefined && s.startedAt < f.since) return false\n if (f.until !== undefined && s.startedAt > f.until) return false\n return true\n}\n\nfunction matchesEvent(e: TraceEvent, f: EventFilter): boolean {\n if (f.runId && e.runId !== f.runId) return false\n if (f.spanId && e.spanId !== f.spanId) return false\n if (f.kind && e.kind !== f.kind) return false\n if (f.since !== undefined && e.timestamp < f.since) return false\n if (f.until !== undefined && e.timestamp > f.until) return false\n return true\n}\n\n// ── Filesystem (NDJSON append-only, one file per entity) ─────────────\n\nexport interface FileSystemTraceStoreOptions {\n dir: string\n /** Roll over NDJSON files when they exceed this size in bytes. Default 32 MB. */\n maxBytes?: number\n}\n\nexport class FileSystemTraceStore implements TraceStore {\n private dir: string\n private maxBytes: number\n /** Lazy in-memory index for queries — populated on first read. */\n private index?: InMemoryTraceStore\n /** Memoized index build — concurrent first reads share one build, and an\n * append racing an in-flight load awaits this so its row isn't lost. */\n private indexPromise?: Promise<InMemoryTraceStore>\n /** Strictly-increasing rollover stamp. Date.now() alone collides when two\n * rollovers land in the same millisecond, overwriting a rolled file. */\n private lastRolloverStamp = 0\n /**\n * Per-file append serialization. stat → conditional-rename → appendFile is a\n * read-modify-write on the active file; without a lock two concurrent appends\n * to the same `name` can both pass the size check (exceeding maxBytes) or one\n * can append to a file the other just renamed away. Each entry chains the\n * next append behind the prior one for that file.\n */\n private appendLocks = new Map<string, Promise<void>>()\n\n constructor(options: FileSystemTraceStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: string, record: unknown): Promise<void> {\n // If an index load is in flight, wait for it. The row must hit disk AFTER\n // the load finished reading, so it lands in the completed index via the\n // mirror below — never lost in the gap before `this.index` is assigned.\n if (this.indexPromise) await this.indexPromise\n // Chain this append behind any in-flight append for the same file. The tail\n // promise never rejects (errors are isolated to each caller's `result`), so\n // one failed append can't break the lock chain for the next one.\n const prior = this.appendLocks.get(name) ?? Promise.resolve()\n const result = prior.then(() => this.appendLocked(name, record))\n const tail = result.then(\n () => {},\n () => {},\n )\n this.appendLocks.set(name, tail)\n try {\n await result\n } finally {\n // Drop the slot once this append is the current tail, so the map doesn't\n // grow without bound across many appends to the same file.\n if (this.appendLocks.get(name) === tail) this.appendLocks.delete(name)\n }\n }\n\n private async appendLocked(name: string, record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n // Strictly-increasing, collision-free even within one millisecond — a\n // bare Date.now() would let two same-ms rollovers overwrite each other.\n const stamp = Math.max(Date.now(), this.lastRolloverStamp + 1)\n this.lastRolloverStamp = stamp\n const rolled = path.join(this.dir, `${name}.${stamp}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n // Mirror genuinely-new rows into the lazy index. Update rows (marked\n // with `_update: true` by updateRun/updateSpan) are applied by those\n // methods directly via the index's update* APIs — re-inserting them\n // here triggers a duplicate-id error once the first read populates\n // the index. Await the mirror: a fire-and-forget would let an index\n // rejection go unhandled and let disk + index diverge silently.\n if (this.index && !(record as { _update?: boolean })?._update) {\n await this.insertInto(name, record)\n }\n }\n\n private async insertInto(name: string, record: unknown): Promise<void> {\n if (!this.index) return\n switch (name) {\n case 'runs':\n await this.index.appendRun(record as Run)\n break\n case 'spans':\n await this.index.appendSpan(record as Span)\n break\n case 'events':\n await this.index.appendEvent(record as TraceEvent)\n break\n case 'artifacts':\n await this.index.appendArtifact(record as Artifact)\n break\n case 'budget':\n await this.index.appendBudgetEntry(record as BudgetLedgerEntry)\n break\n }\n }\n\n private load(): Promise<InMemoryTraceStore> {\n // Memoize: concurrent first reads share one build, and an append racing an\n // in-flight load awaits this same promise (see append()).\n this.indexPromise ??= this.buildIndex()\n return this.indexPromise\n }\n\n private async buildIndex(): Promise<InMemoryTraceStore> {\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryTraceStore()\n let entries: string[]\n try {\n entries = await fs.readdir(this.dir)\n } catch {\n // No dir yet (first run / empty corpus). Anything past this point — parse\n // errors, missing patch bases — is real corruption and must fail loud.\n this.index = store\n return store\n }\n // Replay files in write order. For one entity, rolled files\n // (`name.<ts>.ndjson`) are older than the active bare file (`name.ndjson`),\n // and readdir order is not chronological — so without this sort a patch in\n // an older rolled file could be applied AFTER (overwrite) a newer patch in\n // the active file, silently restoring a stale field. Sort: per entity,\n // rolled ascending by timestamp, then the bare active file last.\n entries.sort((a, b) => {\n // Group by the same entity base the loop uses (`split('.')[0]`); within an\n // entity, real rollover files (`<base>.<ms>.ndjson`) sort by timestamp\n // ascending and the bare active file (no numeric segment) sorts last.\n // Non-rollover names tie (Infinity) and a stable sort preserves their\n // readdir order.\n const baseA = a.split('.')[0]!\n const baseB = b.split('.')[0]!\n if (baseA !== baseB) return baseA < baseB ? -1 : 1\n const ta = a.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tb = b.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tsA = ta ? Number(ta[1]) : Number.POSITIVE_INFINITY\n const tsB = tb ? Number(tb[1]) : Number.POSITIVE_INFINITY\n return tsA - tsB\n })\n {\n // Two-pass load. Pass 1 indexes all full (base) rows; pass 2 replays the\n // `_update` patch rows that updateRun/updateSpan append. readdir order is\n // not deterministic and rollover splits a stream across files, so a patch\n // can be read before its base. Applying patches in a separate pass — after\n // every base row is indexed — means a patch always finds its target.\n // Doing it in one pass let a patch hit the catch and append a runId-less\n // fragment, corrupting span/run counts cross-instance.\n const runUpdates: Array<Record<string, unknown>> = []\n const spanUpdates: Array<Record<string, unknown>> = []\n for (const file of entries) {\n if (!file.endsWith('.ndjson')) continue\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n const lines = content.split('\\n')\n for (let ln = 0; ln < lines.length; ln++) {\n const line = lines[ln]!\n if (!line.trim()) continue\n let record: ReturnType<typeof JSON.parse>\n try {\n record = JSON.parse(line)\n } catch (err) {\n // Fail loud WITH context — a bare SyntaxError loses which file/line\n // is corrupt and which valid rows surround it.\n throw new Error(\n `FileSystemTraceStore: corrupt NDJSON in ${file} line ${ln + 1}: ${\n err instanceof Error ? err.message : String(err)\n } — ${line.slice(0, 120)}`,\n )\n }\n if (base === 'runs') {\n if (record?._update) {\n runUpdates.push(record)\n continue\n }\n // A duplicate full row (same dir loaded twice into one stream) is\n // collapsed last-write-wins rather than thrown.\n try {\n await store.appendRun(record)\n } catch {\n await store.updateRun(record.runId, record)\n }\n } else if (base === 'spans') {\n // `updateSpan` appends an `_update: true` patch row instead of\n // rewriting the original span. Deferred to pass 2 so it collapses\n // onto the original span — otherwise a fresh FileSystemTraceStore\n // reading the same dir reports duplicate spans (one full, one\n // fragment with no runId/kind/name), which breaks any downstream\n // consumer that re-opens the store cross-process (e.g. the OTLP\n // converter).\n if (record?._update) {\n spanUpdates.push(record)\n continue\n }\n await store.appendSpan(record)\n } else if (base === 'events') {\n await store.appendEvent(record)\n } else if (base === 'artifacts') {\n await store.appendArtifact(record)\n } else if (base === 'budget') {\n await store.appendBudgetEntry(record)\n }\n }\n }\n // Pass 2: every base row is now indexed. A patch whose base is genuinely\n // absent (truncated/partial corpus) throws inside update* — we let it\n // propagate rather than silently appending a fragment, so a corrupt\n // corpus fails loud instead of polluting counts.\n for (const record of runUpdates) {\n await store.updateRun(record.runId as string, record as Partial<Run>)\n }\n for (const record of spanUpdates) {\n await store.updateSpan(record.spanId as string, record as Partial<Span>)\n }\n }\n this.index = store\n return store\n }\n\n async appendRun(run: Run): Promise<void> {\n await this.append('runs', run)\n }\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n // NDJSON is append-only; record updates as new rows with the same runId —\n // readers collapse by last-write-wins on load.\n await this.append('runs', { runId, ...patch, _update: true })\n if (this.index) await this.index.updateRun(runId, patch)\n }\n async appendSpan(span: Span): Promise<void> {\n await this.append('spans', span)\n }\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n await this.append('spans', { spanId, ...patch, _update: true })\n if (this.index) await this.index.updateSpan(spanId, patch)\n }\n async appendEvent(event: TraceEvent): Promise<void> {\n await this.append('events', event)\n }\n async appendArtifact(artifact: Artifact): Promise<void> {\n await this.append('artifacts', artifact)\n }\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n await this.append('budget', entry)\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n return (await this.load()).getRun(runId)\n }\n async listRuns(filter?: RunFilter): Promise<Run[]> {\n return (await this.load()).listRuns(filter)\n }\n async spans(filter?: SpanFilter): Promise<Span[]> {\n return (await this.load()).spans(filter)\n }\n async events(filter?: EventFilter): Promise<TraceEvent[]> {\n return (await this.load()).events(filter)\n }\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return (await this.load()).budget(runId)\n }\n async artifacts(runId: string): Promise<Artifact[]> {\n return (await this.load()).artifacts(runId)\n }\n}\n","/**\n * Run-completion integrity check — at end of run, verify the expected event\n * types were actually captured. The point is the launch-review failure mode:\n * a run *appears* successful but the raw provider events were never written,\n * so a downstream reviewer can't reconstruct what happened.\n *\n * Pattern:\n *\n * const report = await assertRunCaptured(store, runId, {\n * llmSpansMin: 1,\n * judgeSpansMin: 1,\n * rawSink: providerSink, // must have ≥ 1 event for this run\n * requireRawCoverageOfLlmSpans: true, // every llm span has matching raw events\n * })\n * if (!report.ok) throwIfRunIncomplete(report) // or mark run failed and continue\n *\n * The function is read-only on the store and returns a structured report;\n * the caller chooses the failure mode (throw, mark run failed, log warning).\n * `throwIfRunIncomplete` is the convenient strict mode.\n */\n\nimport { CaptureIntegrityError } from '../errors'\nimport type { RawProviderSink } from './raw-provider-sink'\nimport type { TraceStore } from './store'\n\nexport interface RunIntegrityExpectations {\n /** Minimum LLM span count. Default 0 (no requirement). */\n llmSpansMin?: number\n /** Minimum judge span count. Default 0. */\n judgeSpansMin?: number\n /** Minimum tool span count. Default 0. */\n toolSpansMin?: number\n /**\n * Raw provider sink to consult for capture verification. When present,\n * the check requires at least one raw event for the run.\n */\n rawSink?: RawProviderSink\n /** Minimum raw provider event count. Default 0; ignored when `rawSink` absent. */\n rawProviderEventsMin?: number\n /**\n * Every LLM span must have at least one matching raw `request` event\n * (matched by spanId). Catches the common bug where the structured span\n * was emitted but the raw HTTP capture was wired to a different sink.\n */\n requireRawCoverageOfLlmSpans?: boolean\n /** Run outcome must be set (not null/undefined). Default false. */\n requireOutcome?: boolean\n}\n\nexport type RunIntegrityIssueCode =\n | 'no_run'\n | 'missing_llm_spans'\n | 'missing_judge_spans'\n | 'missing_tool_spans'\n | 'missing_raw_events'\n | 'no_raw_sink'\n | 'orphan_llm_span'\n | 'missing_outcome'\n\nexport interface RunIntegrityIssue {\n code: RunIntegrityIssueCode\n message: string\n detail?: Record<string, unknown>\n}\n\nexport interface RunIntegrityReport {\n ok: boolean\n runId: string\n llmSpanCount: number\n judgeSpanCount: number\n toolSpanCount: number\n rawProviderEventCount: number\n /**\n * Coverage of LLM spans by raw provider events keyed on spanId.\n * `total` is the number of LLM spans; `covered` is the count with at\n * least one matching `request` raw event.\n */\n rawSpanCoverage: { covered: number; total: number }\n issues: RunIntegrityIssue[]\n}\n\nexport class RunIntegrityError extends CaptureIntegrityError {\n constructor(public readonly report: RunIntegrityReport) {\n super(\n `Run ${report.runId} failed integrity check: ${report.issues.map((i) => i.code).join(', ')}`,\n )\n }\n}\n\nexport async function assertRunCaptured(\n store: TraceStore,\n runId: string,\n expectations: RunIntegrityExpectations = {},\n): Promise<RunIntegrityReport> {\n const issues: RunIntegrityIssue[] = []\n const run = await store.getRun(runId)\n if (!run) {\n return {\n ok: false,\n runId,\n llmSpanCount: 0,\n judgeSpanCount: 0,\n toolSpanCount: 0,\n rawProviderEventCount: 0,\n rawSpanCoverage: { covered: 0, total: 0 },\n issues: [{ code: 'no_run', message: `Run ${runId} not found in store.` }],\n }\n }\n\n const spans = await store.spans({ runId })\n const llmSpans = spans.filter((s) => s.kind === 'llm')\n const judgeSpans = spans.filter((s) => s.kind === 'judge')\n const toolSpans = spans.filter((s) => s.kind === 'tool')\n\n const llmMin = expectations.llmSpansMin ?? 0\n const judgeMin = expectations.judgeSpansMin ?? 0\n const toolMin = expectations.toolSpansMin ?? 0\n\n if (llmSpans.length < llmMin) {\n issues.push({\n code: 'missing_llm_spans',\n message: `Expected ≥ ${llmMin} LLM spans, found ${llmSpans.length}.`,\n detail: { expected: llmMin, found: llmSpans.length },\n })\n }\n if (judgeSpans.length < judgeMin) {\n issues.push({\n code: 'missing_judge_spans',\n message: `Expected ≥ ${judgeMin} judge spans, found ${judgeSpans.length}.`,\n detail: { expected: judgeMin, found: judgeSpans.length },\n })\n }\n if (toolSpans.length < toolMin) {\n issues.push({\n code: 'missing_tool_spans',\n message: `Expected ≥ ${toolMin} tool spans, found ${toolSpans.length}.`,\n detail: { expected: toolMin, found: toolSpans.length },\n })\n }\n\n let rawEventCount = 0\n let coverage = { covered: 0, total: llmSpans.length }\n\n if (expectations.rawSink) {\n if (!expectations.rawSink.list) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Provided rawSink does not implement list(); cannot verify capture.',\n })\n } else {\n const events = await expectations.rawSink.list({ runId })\n rawEventCount = events.length\n const rawMin = expectations.rawProviderEventsMin ?? 1\n if (rawEventCount < rawMin) {\n issues.push({\n code: 'missing_raw_events',\n message: `Expected ≥ ${rawMin} raw provider events, found ${rawEventCount}.`,\n detail: { expected: rawMin, found: rawEventCount },\n })\n }\n if (expectations.requireRawCoverageOfLlmSpans) {\n const requestEventsBySpan = new Set(\n events.filter((e) => e.direction === 'request' && e.spanId).map((e) => e.spanId!),\n )\n const orphaned = llmSpans.filter((s) => !requestEventsBySpan.has(s.spanId))\n coverage = { covered: llmSpans.length - orphaned.length, total: llmSpans.length }\n if (orphaned.length > 0) {\n issues.push({\n code: 'orphan_llm_span',\n message: `${orphaned.length} LLM span(s) have no matching raw provider request event.`,\n detail: { orphanedSpanIds: orphaned.map((s) => s.spanId) },\n })\n }\n }\n }\n } else if (expectations.requireRawCoverageOfLlmSpans || expectations.rawProviderEventsMin) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Raw coverage required but no rawSink supplied to the integrity check.',\n })\n }\n\n if (expectations.requireOutcome && (run.outcome === undefined || run.outcome === null)) {\n issues.push({\n code: 'missing_outcome',\n message: `Run ${runId} has no outcome recorded.`,\n })\n }\n\n return {\n ok: issues.length === 0,\n runId,\n llmSpanCount: llmSpans.length,\n judgeSpanCount: judgeSpans.length,\n toolSpanCount: toolSpans.length,\n rawProviderEventCount: rawEventCount,\n rawSpanCoverage: coverage,\n issues,\n }\n}\n\n/** Strict mode: throws `RunIntegrityError` when the report isn't ok. */\nexport function throwIfRunIncomplete(report: RunIntegrityReport): void {\n if (!report.ok) throw new RunIntegrityError(report)\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { r as CaptureIntegrityError } from "./errors-CEk209JS.js";
|
|
2
|
+
import { l as RawProviderSink } from "./raw-provider-sink-BU29Sh8h.js";
|
|
3
|
+
import { s as TraceStore } from "./store-CT9YIIve.js";
|
|
4
|
+
//#region src/trace/integrity.d.ts
|
|
5
|
+
interface RunIntegrityExpectations {
|
|
6
|
+
/** Minimum LLM span count. Default 0 (no requirement). */
|
|
7
|
+
llmSpansMin?: number;
|
|
8
|
+
/** Minimum judge span count. Default 0. */
|
|
9
|
+
judgeSpansMin?: number;
|
|
10
|
+
/** Minimum tool span count. Default 0. */
|
|
11
|
+
toolSpansMin?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Raw provider sink to consult for capture verification. When present,
|
|
14
|
+
* the check requires at least one raw event for the run.
|
|
15
|
+
*/
|
|
16
|
+
rawSink?: RawProviderSink;
|
|
17
|
+
/** Minimum raw provider event count. Default 0; ignored when `rawSink` absent. */
|
|
18
|
+
rawProviderEventsMin?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Every LLM span must have at least one matching raw `request` event
|
|
21
|
+
* (matched by spanId). Catches the common bug where the structured span
|
|
22
|
+
* was emitted but the raw HTTP capture was wired to a different sink.
|
|
23
|
+
*/
|
|
24
|
+
requireRawCoverageOfLlmSpans?: boolean;
|
|
25
|
+
/** Run outcome must be set (not null/undefined). Default false. */
|
|
26
|
+
requireOutcome?: boolean;
|
|
27
|
+
}
|
|
28
|
+
type RunIntegrityIssueCode = 'no_run' | 'missing_llm_spans' | 'missing_judge_spans' | 'missing_tool_spans' | 'missing_raw_events' | 'no_raw_sink' | 'orphan_llm_span' | 'missing_outcome';
|
|
29
|
+
interface RunIntegrityIssue {
|
|
30
|
+
code: RunIntegrityIssueCode;
|
|
31
|
+
message: string;
|
|
32
|
+
detail?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
interface RunIntegrityReport {
|
|
35
|
+
ok: boolean;
|
|
36
|
+
runId: string;
|
|
37
|
+
llmSpanCount: number;
|
|
38
|
+
judgeSpanCount: number;
|
|
39
|
+
toolSpanCount: number;
|
|
40
|
+
rawProviderEventCount: number;
|
|
41
|
+
/**
|
|
42
|
+
* Coverage of LLM spans by raw provider events keyed on spanId.
|
|
43
|
+
* `total` is the number of LLM spans; `covered` is the count with at
|
|
44
|
+
* least one matching `request` raw event.
|
|
45
|
+
*/
|
|
46
|
+
rawSpanCoverage: {
|
|
47
|
+
covered: number;
|
|
48
|
+
total: number;
|
|
49
|
+
};
|
|
50
|
+
issues: RunIntegrityIssue[];
|
|
51
|
+
}
|
|
52
|
+
declare class RunIntegrityError extends CaptureIntegrityError {
|
|
53
|
+
readonly report: RunIntegrityReport;
|
|
54
|
+
constructor(report: RunIntegrityReport);
|
|
55
|
+
}
|
|
56
|
+
declare function assertRunCaptured(store: TraceStore, runId: string, expectations?: RunIntegrityExpectations): Promise<RunIntegrityReport>;
|
|
57
|
+
/** Strict mode: throws `RunIntegrityError` when the report isn't ok. */
|
|
58
|
+
declare function throwIfRunIncomplete(report: RunIntegrityReport): void;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { RunIntegrityReport as a, RunIntegrityIssueCode as i, RunIntegrityExpectations as n, assertRunCaptured as o, RunIntegrityIssue as r, throwIfRunIncomplete as s, RunIntegrityError as t };
|
|
61
|
+
//# sourceMappingURL=integrity-rmVhXWA7.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity-rmVhXWA7.d.ts","names":[],"sources":["../src/trace/integrity.ts"],"mappings":";;;;UAyBiB;;EAEf;;EAEA;;EAEA;;;;;EAKA,UAAU;;EAEV;;;;;;EAMA;;EAEA;;KAGU;UAUK;EACf,MAAM;EACN;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA;IAAmB;IAAiB;;EACpC,QAAQ;;cAGG,0BAA0B;WACT,QAAQ;EAApC,YAA4B,QAAQ;;iBAOhB,kBACpB,OAAO,YACP,eACA,eAAc,2BACb,QAAQ;;iBA6GK,qBAAqB,QAAQ"}
|