@tangle-network/agent-eval 0.183.0 → 0.185.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 +28 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/{agent-profile-cell-s__adRnK.d.ts → agent-profile-cell-BHcB-mZX.d.ts} +8 -9
- package/dist/{agent-profile-cell-s__adRnK.d.ts.map → agent-profile-cell-BHcB-mZX.d.ts.map} +1 -1
- package/dist/{agent-profile-cell-Cv6UA-W_.js → agent-profile-cell-DcFW4vOc.js} +16 -15
- package/dist/agent-profile-cell-DcFW4vOc.js.map +1 -0
- package/dist/{agent-profile-CivaSsSy.d.ts → agent-profile-uAIQK3Nr.d.ts} +3 -3
- package/dist/{agent-profile-CivaSsSy.d.ts.map → agent-profile-uAIQK3Nr.d.ts.map} +1 -1
- package/dist/analyst/index.d.ts +11 -336
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +10 -8
- package/dist/analyst/index.js.map +1 -1
- package/dist/analyze-runs-CrYhqXop.d.ts +75 -0
- package/dist/analyze-runs-CrYhqXop.d.ts.map +1 -0
- package/dist/{define-agent-eval-CneiWyuA.js → analyze-runs-sTygaDyD.js} +6 -813
- package/dist/analyze-runs-sTygaDyD.js.map +1 -0
- package/dist/{benchmark-DQKzykkO.js → benchmark-BeQJyrRC.js} +3 -3
- package/dist/{benchmark-DQKzykkO.js.map → benchmark-BeQJyrRC.js.map} +1 -1
- package/dist/{benchmark-command-NBrqNwgy.js → benchmark-command-kvq7yFY4.js} +17 -54
- package/dist/benchmark-command-kvq7yFY4.js.map +1 -0
- package/dist/benchmarks/index.d.ts +4 -4
- package/dist/benchmarks/index.js +3 -3
- package/dist/builder-eval/index.js +1 -1
- package/dist/campaign/index.d.ts +6 -5
- package/dist/campaign/index.js +10 -9
- package/dist/{campaign-BwcEBC91.js → campaign-eJgtRs-W.js} +16 -15
- package/dist/{campaign-BwcEBC91.js.map → campaign-eJgtRs-W.js.map} +1 -1
- package/dist/{campaign-evidence-PYPUftRy.js → campaign-evidence-BsrCmBSE.js} +7 -258
- package/dist/campaign-evidence-BsrCmBSE.js.map +1 -0
- package/dist/{canonical-DPyQ_rpt.js → canonical-BsZVgBhW.js} +2 -4
- package/dist/canonical-BsZVgBhW.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{client-kh2jOjTK.d.ts → client-Bc8LANCG.d.ts} +4 -4
- package/dist/{client-kh2jOjTK.d.ts.map → client-Bc8LANCG.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +10 -10
- package/dist/contract/index.js +15 -284
- package/dist/contract/index.js.map +1 -1
- package/dist/{default-registry-BwDSWVzg.d.ts → default-registry-CXv9kHMt.d.ts} +6 -6
- package/dist/{default-registry-BwDSWVzg.d.ts.map → default-registry-CXv9kHMt.d.ts.map} +1 -1
- package/dist/{default-registry-C0-N4PkG.js → default-registry-xiHrldW8.js} +6 -4
- package/dist/{default-registry-C0-N4PkG.js.map → default-registry-xiHrldW8.js.map} +1 -1
- package/dist/define-agent-eval-D4uumjl3.js +813 -0
- package/dist/define-agent-eval-D4uumjl3.js.map +1 -0
- package/dist/{define-agent-eval-CwOWWQt_.d.ts → define-agent-eval-DE67ECH1.d.ts} +7 -7
- package/dist/{define-agent-eval-CwOWWQt_.d.ts.map → define-agent-eval-DE67ECH1.d.ts.map} +1 -1
- package/dist/diagnosis/index.d.ts +319 -0
- package/dist/diagnosis/index.d.ts.map +1 -0
- package/dist/diagnosis/index.js +1328 -0
- package/dist/diagnosis/index.js.map +1 -0
- package/dist/{dspy-rlm-engine-8pgBSiy7.js → dspy-rlm-engine-BE9lCzzL.js} +3 -3
- package/dist/{dspy-rlm-engine-8pgBSiy7.js.map → dspy-rlm-engine-BE9lCzzL.js.map} +1 -1
- package/dist/{engine-DS1cysJy.d.ts → engine-cXUK-WHS.d.ts} +5 -77
- package/dist/engine-cXUK-WHS.d.ts.map +1 -0
- package/dist/equal-terms-Blx9Zk5I.js +25 -0
- package/dist/equal-terms-Blx9Zk5I.js.map +1 -0
- package/dist/{eval-campaign-CCEkwzoH.js → eval-campaign-XFHEpN86.js} +4 -4
- package/dist/{eval-campaign-CCEkwzoH.js.map → eval-campaign-XFHEpN86.js.map} +1 -1
- package/dist/evaluation.d.ts +75 -0
- package/dist/evaluation.d.ts.map +1 -0
- package/dist/evaluation.js +137 -0
- package/dist/evaluation.js.map +1 -0
- package/dist/{exact-types-BZDe0W2D.d.ts → exact-types-BEHN7tnq.d.ts} +2 -2
- package/dist/{exact-types-BZDe0W2D.d.ts.map → exact-types-BEHN7tnq.d.ts.map} +1 -1
- package/dist/experiment/index.d.ts +2 -2
- package/dist/experiment/index.js +6 -5
- package/dist/experiment/index.js.map +1 -1
- package/dist/{experiment-tracker-C7PfnF4b.d.ts → experiment-tracker-URRGP9ek.d.ts} +2 -2
- package/dist/{experiment-tracker-C7PfnF4b.d.ts.map → experiment-tracker-URRGP9ek.d.ts.map} +1 -1
- package/dist/{external-optimizer-process-DIB4YWEe.js → external-optimizer-process-BbhvXTFx.js} +4 -4
- package/dist/{external-optimizer-process-DIB4YWEe.js.map → external-optimizer-process-BbhvXTFx.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-CjguXN2e.js → external-optimizer-subprocess-DMgmqTB6.js} +3 -3
- package/dist/{external-optimizer-subprocess-CjguXN2e.js.map → external-optimizer-subprocess-DMgmqTB6.js.map} +1 -1
- package/dist/{feedback-trajectory-CXmtITBo.d.ts → feedback-trajectory-CytTR7u4.d.ts} +3 -3
- package/dist/{feedback-trajectory-CXmtITBo.d.ts.map → feedback-trajectory-CytTR7u4.d.ts.map} +1 -1
- package/dist/hosted/index.d.ts +2 -2
- package/dist/{index-DoykkxW0.d.ts → index-BQWfAFeH.d.ts} +11 -11
- package/dist/{index-DoykkxW0.d.ts.map → index-BQWfAFeH.d.ts.map} +1 -1
- package/dist/{index-DbG8QbH9.d.ts → index-C8_iU8KL.d.ts} +6 -6
- package/dist/{index-DbG8QbH9.d.ts.map → index-C8_iU8KL.d.ts.map} +1 -1
- package/dist/{index--_8_Nlpn.d.ts → index-CKZa_rnt.d.ts} +4 -121
- package/dist/index-CKZa_rnt.d.ts.map +1 -0
- package/dist/{index-Bp_6sj3x.d.ts → index-ww8736Am.d.ts} +20 -315
- package/dist/index-ww8736Am.d.ts.map +1 -0
- package/dist/index.d.ts +24 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -24
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-D1qa0HWs.d.ts → insight-report-C3Bfl762.d.ts} +3 -3
- package/dist/{insight-report-D1qa0HWs.d.ts.map → insight-report-C3Bfl762.d.ts.map} +1 -1
- package/dist/jev-protocol.d.ts +74 -0
- package/dist/jev-protocol.d.ts.map +1 -0
- package/dist/jev-protocol.js +91 -0
- package/dist/jev-protocol.js.map +1 -0
- package/dist/jev.d.ts +131 -0
- package/dist/jev.d.ts.map +1 -0
- package/dist/jev.js +312 -0
- package/dist/jev.js.map +1 -0
- package/dist/{journal-Cs9f7385.js → journal-BuRLm6ho.js} +2 -2
- package/dist/{journal-Cs9f7385.js.map → journal-BuRLm6ho.js.map} +1 -1
- package/dist/{kind-factory-DxTzg32u.js → kind-factory-V79Hw0AU.js} +7 -84
- package/dist/kind-factory-V79Hw0AU.js.map +1 -0
- package/dist/ledger-core/index.js +2 -2
- package/dist/{llm-judge-FfaRgz9X.js → llm-judge-FWWhEb31.js} +11 -9
- package/dist/{llm-judge-FfaRgz9X.js.map → llm-judge-FWWhEb31.js.map} +1 -1
- package/dist/{matrix-CyhW-vgJ.d.ts → matrix-CPKsRY8Y.d.ts} +2 -2
- package/dist/{matrix-CyhW-vgJ.d.ts.map → matrix-CPKsRY8Y.d.ts.map} +1 -1
- package/dist/meta-eval/index.d.ts +54 -2
- package/dist/meta-eval/index.d.ts.map +1 -1
- package/dist/meta-eval/index.js +52 -3
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/{mint-ySIIkKlV.js → mint-B4zgSAJW.js} +63 -14
- package/dist/mint-B4zgSAJW.js.map +1 -0
- package/dist/mint-BI14xehJ.d.ts +285 -0
- package/dist/mint-BI14xehJ.d.ts.map +1 -0
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/otel-spans-CQY1pNiN.js +275 -0
- package/dist/otel-spans-CQY1pNiN.js.map +1 -0
- package/dist/otlp-attributes-BpC_blLF.js +83 -0
- package/dist/otlp-attributes-BpC_blLF.js.map +1 -0
- package/dist/{run-record-DPa2PeHx.js → paired-promotion-decision-ClJh_9nK.js} +2 -215
- package/dist/paired-promotion-decision-ClJh_9nK.js.map +1 -0
- package/dist/pipelines/index.js +2 -2
- package/dist/prime-bridge-transport-Z3cpKGoV.js +43 -0
- package/dist/prime-bridge-transport-Z3cpKGoV.js.map +1 -0
- package/dist/prime-protocol-CDBcL9NM.d.ts +331 -0
- package/dist/prime-protocol-CDBcL9NM.d.ts.map +1 -0
- package/dist/{prime-protocol-6tZTVsWm.js → prime-protocol-DcAK9pC8.js} +2 -23
- package/dist/prime-protocol-DcAK9pC8.js.map +1 -0
- package/dist/{produced-state-CGoVInrl.js → produced-state-CmB02tr2.js} +23 -19
- package/dist/{produced-state-CGoVInrl.js.map → produced-state-CmB02tr2.js.map} +1 -1
- package/dist/profile-cell.d.ts +1 -1
- package/dist/profile-cell.js +1 -1
- package/dist/{promotion-policy-BKFrl7CC.js → promotion-policy-DdrYWHDh.js} +3 -3
- package/dist/{promotion-policy-BKFrl7CC.js.map → promotion-policy-DdrYWHDh.js.map} +1 -1
- package/dist/{query-D1nLIKt7.js → query-DlV0pdx4.js} +2 -2
- package/dist/{query-D1nLIKt7.js.map → query-DlV0pdx4.js.map} +1 -1
- package/dist/{registry-BRbB6Y0v.d.ts → registry-D5Ly3GRV.d.ts} +3 -3
- package/dist/{registry-BRbB6Y0v.d.ts.map → registry-D5Ly3GRV.d.ts.map} +1 -1
- package/dist/{release-confidence-BcqeQTHW.d.ts → release-confidence-DsETiO4f.d.ts} +3 -3
- package/dist/{release-confidence-BcqeQTHW.d.ts.map → release-confidence-DsETiO4f.d.ts.map} +1 -1
- package/dist/{release-confidence-DMg8n18l.js → release-confidence-RanRUXRW.js} +2 -2
- package/dist/{release-confidence-DMg8n18l.js.map → release-confidence-RanRUXRW.js.map} +1 -1
- package/dist/reporting.d.ts +3 -3
- package/dist/reporting.js +2 -2
- package/dist/{researcher-64T49THL.d.ts → researcher-CJkH-6Ty.d.ts} +4 -4
- package/dist/{researcher-64T49THL.d.ts.map → researcher-CJkH-6Ty.d.ts.map} +1 -1
- package/dist/{reward-hacking-uzO_ihep.d.ts → reward-hacking-BIQ2BWLG.d.ts} +2 -2
- package/dist/{reward-hacking-uzO_ihep.d.ts.map → reward-hacking-BIQ2BWLG.d.ts.map} +1 -1
- package/dist/rl.d.ts +10 -6
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +22 -7
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +2 -2
- package/dist/rollout/index.js +2 -2
- package/dist/{rollout-D_54FZVu.js → rollout-C0Ifk3vK.js} +2 -2
- package/dist/{rollout-D_54FZVu.js.map → rollout-C0Ifk3vK.js.map} +1 -1
- package/dist/{rubric-predictive-validity-Bmj2_cll.d.ts → rubric-predictive-validity-CTU8y8Cv.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-Bmj2_cll.d.ts.map → rubric-predictive-validity-CTU8y8Cv.d.ts.map} +1 -1
- package/dist/run-record-CNNzWGpB.js +216 -0
- package/dist/run-record-CNNzWGpB.js.map +1 -0
- package/dist/{run-record-BiTWauyO.d.ts → run-record-D9wS35fK.d.ts} +2 -2
- package/dist/{run-record-BiTWauyO.d.ts.map → run-record-D9wS35fK.d.ts.map} +1 -1
- package/dist/{run-record-DualPTn2.js → run-record-tg_5H2IK.js} +2 -2
- package/dist/{run-record-DualPTn2.js.map → run-record-tg_5H2IK.js.map} +1 -1
- package/dist/search-ledger-types-D7KDVg-o.d.ts +302 -0
- package/dist/search-ledger-types-D7KDVg-o.d.ts.map +1 -0
- package/dist/{semantic-concept-judge-_3Fp6Q_3.js → semantic-concept-judge-Cnt0TWp0.js} +4 -4
- package/dist/{semantic-concept-judge-_3Fp6Q_3.js.map → semantic-concept-judge-Cnt0TWp0.js.map} +1 -1
- package/dist/{sequential-D_xHrBZe.js → sequential-PgLEqcTJ.js} +3 -3
- package/dist/{sequential-D_xHrBZe.js.map → sequential-PgLEqcTJ.js.map} +1 -1
- package/dist/{server-BZQR1f0C.js → server-DmpcFiVK.js} +2 -2
- package/dist/{server-BZQR1f0C.js.map → server-DmpcFiVK.js.map} +1 -1
- package/dist/{skillopt-optimization-method-DY1aQ-aL.js → skillopt-optimization-method-FSk8b5FQ.js} +8 -7
- package/dist/{skillopt-optimization-method-DY1aQ-aL.js.map → skillopt-optimization-method-FSk8b5FQ.js.map} +1 -1
- package/dist/{statistical-heldout-CpVd6FmY.d.ts → statistical-heldout-Bu4oNOJh.d.ts} +3 -3
- package/dist/{statistical-heldout-CpVd6FmY.d.ts.map → statistical-heldout-Bu4oNOJh.d.ts.map} +1 -1
- package/dist/statistical-heldout-CeWT_W7y.js +256 -0
- package/dist/statistical-heldout-CeWT_W7y.js.map +1 -0
- package/dist/{store-otlp-DAaEbMLf.js → store-otlp-2gYCy-v0.js} +2 -2
- package/dist/{store-otlp-DAaEbMLf.js.map → store-otlp-2gYCy-v0.js.map} +1 -1
- package/dist/{store-tool-spans-BZ8MPKFe.js → store-tool-spans-B1e6Auc2.js} +69 -6
- package/dist/store-tool-spans-B1e6Auc2.js.map +1 -0
- package/dist/{store-tool-spans-Dt-YdAuE.d.ts → store-tool-spans-BrdfPaVh.d.ts} +54 -6
- package/dist/store-tool-spans-BrdfPaVh.d.ts.map +1 -0
- package/dist/{summary-report-IGAOtgPd.js → summary-report-BMvou2oZ.js} +2 -2
- package/dist/{summary-report-IGAOtgPd.js.map → summary-report-BMvou2oZ.js.map} +1 -1
- package/dist/{summary-report-D1h4dlrK.d.ts → summary-report-BzFS5UhZ.d.ts} +2 -2
- package/dist/{summary-report-D1h4dlrK.d.ts.map → summary-report-BzFS5UhZ.d.ts.map} +1 -1
- package/dist/{task-failure-attributes-B_JjrOVo.js → task-failure-attributes-B34TiMBe.js} +2 -2
- package/dist/{task-failure-attributes-B_JjrOVo.js.map → task-failure-attributes-B34TiMBe.js.map} +1 -1
- package/dist/{tool-groups-B2bSNaJB.d.ts → tool-groups-eOOgYGaM.d.ts} +3 -3
- package/dist/tool-groups-eOOgYGaM.d.ts.map +1 -0
- package/dist/{tool-waste-C7MU9u1e.js → tool-waste-nbHPAxei.js} +2 -2
- package/dist/{tool-waste-C7MU9u1e.js.map → tool-waste-nbHPAxei.js.map} +1 -1
- package/dist/trace-repair/index.d.ts +2 -2
- package/dist/trace-repair/index.js +5 -4
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +5 -5
- package/dist/traces.js +8 -7
- package/dist/traces.js.map +1 -1
- package/dist/trajectory-replay/index.js +1 -1
- package/dist/{types-CS0qk_Yp.d.ts → types-BTRcIqFr.d.ts} +3 -3
- package/dist/{types-CS0qk_Yp.d.ts.map → types-BTRcIqFr.d.ts.map} +1 -1
- package/dist/{types-D7gEdPoQ.d.ts → types-BjB2wZM9.d.ts} +2 -2
- package/dist/{types-D7gEdPoQ.d.ts.map → types-BjB2wZM9.d.ts.map} +1 -1
- package/dist/types-C8VBbiw6.js +91 -0
- package/dist/types-C8VBbiw6.js.map +1 -0
- package/dist/{types-BvZoPTGa.d.ts → types-c3ZRTbw9.d.ts} +3 -3
- package/dist/{types-BvZoPTGa.d.ts.map → types-c3ZRTbw9.d.ts.map} +1 -1
- package/dist/{types-DQ0e2E7y.js → usage-receipt-Cx3xNeyB.js} +2 -89
- package/dist/usage-receipt-Cx3xNeyB.js.map +1 -0
- package/dist/{verdict-BQ3pCFf8.js → verdict-DhPoXApk.js} +2 -2
- package/dist/{verdict-BQ3pCFf8.js.map → verdict-DhPoXApk.js.map} +1 -1
- package/dist/{verdict-cache-B3eCVQtY.js → verdict-cache-BQEsVy9n.js} +2 -2
- package/dist/{verdict-cache-B3eCVQtY.js.map → verdict-cache-BQEsVy9n.js.map} +1 -1
- package/dist/wire/index.d.ts +1 -1
- package/dist/wire/index.js +1 -1
- package/docs/changes/evaluation-definition-identity.md +27 -0
- package/docs/changes/jev-evidence-review.md +18 -0
- package/docs/changes/jev-product-adoption.md +18 -0
- package/docs/changes/probability-policy-audit.md +81 -0
- package/docs/diagnosis.md +42 -0
- package/docs/jev-behavior-review.md +174 -0
- package/docs/jev-integrations.md +50 -0
- package/docs/jev.md +140 -0
- package/docs/produced-state.md +13 -0
- package/docs/profile-json-identity.md +33 -0
- package/package.json +22 -1
- package/dist/agent-profile-cell-Cv6UA-W_.js.map +0 -1
- package/dist/benchmark-command-NBrqNwgy.js.map +0 -1
- package/dist/campaign-evidence-PYPUftRy.js.map +0 -1
- package/dist/canonical-DPyQ_rpt.js.map +0 -1
- package/dist/define-agent-eval-CneiWyuA.js.map +0 -1
- package/dist/engine-DS1cysJy.d.ts.map +0 -1
- package/dist/exporters-D98GPi1n.d.ts +0 -161
- package/dist/exporters-D98GPi1n.d.ts.map +0 -1
- package/dist/index--_8_Nlpn.d.ts.map +0 -1
- package/dist/index-Bp_6sj3x.d.ts.map +0 -1
- package/dist/kind-factory-DxTzg32u.js.map +0 -1
- package/dist/mint-ySIIkKlV.js.map +0 -1
- package/dist/prime-protocol-6tZTVsWm.js.map +0 -1
- package/dist/run-record-DPa2PeHx.js.map +0 -1
- package/dist/store-tool-spans-BZ8MPKFe.js.map +0 -1
- package/dist/store-tool-spans-Dt-YdAuE.d.ts.map +0 -1
- package/dist/tool-groups-B2bSNaJB.d.ts.map +0 -1
- package/dist/types-DQ0e2E7y.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["SEVERITIES"],"sources":["../../src/diagnosis/secret-filter.ts","../../src/diagnosis/spans.ts","../../src/diagnosis/deterministic.ts","../../src/diagnosis/findings.ts","../../src/diagnosis/model-pass.ts","../../src/diagnosis/engine.ts"],"sourcesContent":["/**\n * The secret filter every diagnosis input passes through before any model or\n * report reads it.\n *\n * Two layers:\n * - `secret-assignment` is the line-anchored credential-assignment pattern\n * trace-archive uses to keep plaintext-secret files out of the archive\n * (`holds_secret` in tangle-tools trace-archive/archive.py). It is ported\n * here verbatim so both the archive and the miner refuse the same lines.\n * That pattern is line-anchored on purpose, so a secret quoted inside a\n * JSON record or a prose line passes it;\n * - the token-shape rules close that gap: they match the credential itself\n * wherever it appears (`sk-`, `sk-ant-`, GitHub, Slack, AWS, Google, JWT,\n * bearer headers, URL passwords, PEM blocks, and JSON `\"...key\": \"...\"`).\n *\n * A redacted value becomes `[REDACTED:<rule id>]`, so a report can state what\n * was removed by class without carrying any of it. The filter never throws on\n * input shape: non-string leaves pass through unchanged.\n */\n\nexport interface SecretRule {\n id: string\n pattern: RegExp\n /** Rebuilds the match with the secret replaced; receives the regex groups. */\n replace: (match: string, ...groups: string[]) => string\n}\n\nexport interface SecretFilterReport {\n redactionCount: number\n byRule: Record<string, number>\n}\n\nconst marker = (id: string) => `[REDACTED:${id}]`\nconst whole = (id: string) => () => marker(id)\n\n/**\n * The trace-archive `SECRET_ASSIGNMENT` pattern (tangle-tools\n * trace-archive/archive.py), with the prefix captured so the key name survives\n * and only the value is replaced.\n */\nexport const SECRET_ASSIGNMENT_PATTERN =\n /^([ \\t]*(?:export[ \\t]+)?[\"']?(?:[A-Za-z_][A-Za-z0-9_.-]*)?(?:key|token|secret|password|passwd|passphrase|credentials?)[A-Za-z0-9_]*[\"']?[ \\t]*[=:][ \\t]*[\"']?)(?!encrypted:)(?![$`])(?=[^\\s\"'#,]*[0-9])(?=[^\\s\"'#,]*[A-Za-z])[^\\s\"'#,]{16,}([\"']?[ \\t]*,?[ \\t]*(?:#.*)?\\r?)$/gim\n\nexport const DIAGNOSIS_SECRET_RULES: readonly SecretRule[] = [\n {\n id: 'pem-block',\n pattern:\n /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\\s\\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY-----|$)/g,\n replace: whole('pem-block'),\n },\n {\n id: 'secret-assignment',\n pattern: SECRET_ASSIGNMENT_PATTERN,\n replace: (_match, prefix, suffix) => `${prefix}${marker('secret-assignment')}${suffix}`,\n },\n {\n id: 'json-secret',\n pattern:\n /(\"[A-Za-z0-9_.-]*(?:key|token|secret|password|passwd|passphrase|credentials?)[A-Za-z0-9_]*\"[ \\t]*:[ \\t]*\")(?!encrypted:)(?![$`])(?=[^\"\\s]*[0-9])(?=[^\"\\s]*[A-Za-z])[^\"\\s]{16,}(\")/gi,\n replace: (_match, prefix, suffix) => `${prefix}${marker('json-secret')}${suffix}`,\n },\n {\n // The same key vocabulary anywhere in a line (`cd x && GH_TOKEN=... gh pr`,\n // `--api-key=...`), which the line-anchored pattern lets through.\n id: 'inline-assignment',\n pattern:\n /\\b([A-Za-z0-9_.-]*(?:key|token|secret|password|passwd|passphrase|credentials?)[A-Za-z0-9_]*[\"']?[ \\t]*[=:][ \\t]*[\"']?)(?!encrypted:)(?![$`[])(?=[^\\s\"'#,&;]*[0-9])(?=[^\\s\"'#,&;]*[A-Za-z])[^\\s\"'#,&;]{16,}/gi,\n replace: (_match, prefix) => `${prefix}${marker('inline-assignment')}`,\n },\n { id: 'anthropic-key', pattern: /\\bsk-ant-[A-Za-z0-9_-]{20,}/g, replace: whole('anthropic-key') },\n { id: 'openai-key', pattern: /\\bsk-[A-Za-z0-9_-]{20,}/g, replace: whole('openai-key') },\n {\n id: 'github-token',\n pattern: /\\b(?:gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{30,})/g,\n replace: whole('github-token'),\n },\n {\n id: 'slack-token',\n pattern: /\\bxox[abeoprs]-[A-Za-z0-9-]{10,}/g,\n replace: whole('slack-token'),\n },\n {\n id: 'aws-access-key',\n pattern: /\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g,\n replace: whole('aws-access-key'),\n },\n { id: 'google-api-key', pattern: /\\bAIza[0-9A-Za-z_-]{35}/g, replace: whole('google-api-key') },\n {\n id: 'jwt',\n pattern: /\\beyJ[A-Za-z0-9_-]{8,}\\.eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}/g,\n replace: whole('jwt'),\n },\n {\n id: 'bearer',\n pattern: /\\b(Bearer)[ \\t]+[A-Za-z0-9._~+/=-]{16,}/gi,\n replace: (_match, word) => `${word} ${marker('bearer')}`,\n },\n {\n id: 'url-credentials',\n pattern: /\\b([a-z][a-z0-9+.-]*:\\/\\/[^\\s:/@]+:)[^\\s@/]+@/gi,\n replace: (_match, prefix) => `${prefix}${marker('url-credentials')}@`,\n },\n]\n\n/** Redact one string, adding the per-rule counts to `report`. */\nexport function redactSecrets(\n input: string,\n report: SecretFilterReport = emptySecretFilterReport(),\n rules: readonly SecretRule[] = DIAGNOSIS_SECRET_RULES,\n): string {\n let output = input\n for (const rule of rules) {\n let hits = 0\n rule.pattern.lastIndex = 0\n output = output.replace(rule.pattern, (match: string, ...rest: unknown[]) => {\n hits += 1\n // `replace` passes the groups first, then the offset and the whole\n // string; an unmatched optional group arrives as undefined and becomes ''.\n const captured = rest\n .slice(0, countGroups(rule.pattern))\n .map((value) => (typeof value === 'string' ? value : ''))\n return rule.replace(match, ...captured)\n })\n if (hits > 0) {\n report.redactionCount += hits\n report.byRule[rule.id] = (report.byRule[rule.id] ?? 0) + hits\n }\n }\n return output\n}\n\n/** Whether any rule matches: the miner's equivalent of trace-archive `holds_secret`. */\nexport function holdsSecret(\n input: string,\n rules: readonly SecretRule[] = DIAGNOSIS_SECRET_RULES,\n): boolean {\n return rules.some((rule) => {\n rule.pattern.lastIndex = 0\n const found = rule.pattern.test(input)\n rule.pattern.lastIndex = 0\n return found\n })\n}\n\n/** Redact every string leaf of a JSON-like value. Keys are kept; values are filtered. */\nexport function redactSecretsDeep(value: unknown, report: SecretFilterReport): unknown {\n if (typeof value === 'string') return redactSecrets(value, report)\n if (Array.isArray(value)) return value.map((item) => redactSecretsDeep(item, report))\n if (value !== null && typeof value === 'object') {\n const next: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n next[key] = redactSecretsDeep(item, report)\n }\n return next\n }\n return value\n}\n\nexport function emptySecretFilterReport(): SecretFilterReport {\n return { redactionCount: 0, byRule: {} }\n}\n\nconst groupCounts = new WeakMap<RegExp, number>()\n\nfunction countGroups(pattern: RegExp): number {\n const cached = groupCounts.get(pattern)\n if (cached !== undefined) return cached\n // An alternation with the empty string always matches, so exec reports the\n // pattern's capture-group count as match.length - 1.\n const count = (new RegExp(`${pattern.source}|`).exec('')?.length ?? 1) - 1\n groupCounts.set(pattern, count)\n return count\n}\n","/**\n * Ingest for the diagnosis engine: flat spans in, filtered and normalized spans\n * out. Nothing downstream of this file sees an unfiltered value.\n *\n * Input is the flat-span shape trace-adapters and the traces CLI emit, one\n * object per span: `{trace_id, span_id, parent_span_id, name, kind,\n * start_time, end_time, status | status_code, status_message, attributes,\n * resource?}`. Times may be OTLP nanosecond strings, epoch milliseconds, or\n * ISO-8601; the generic OTLP line reader treats every digit string as\n * milliseconds, so time parsing is owned here.\n */\n\nimport { createHmac, randomBytes } from 'node:crypto'\nimport {\n type ContractSpan,\n MODEL_ATTR_KEYS,\n resolveSpanKind,\n SPAN_KINDS,\n type SpanKind,\n TOOL_NAME_ATTR_KEYS,\n} from '@tangle-network/agent-trace-contract'\nimport { redactSecrets, redactSecretsDeep, type SecretFilterReport } from './secret-filter'\n\nexport type DiagnosisSpanStatus = 'OK' | 'ERROR' | 'UNSET'\n\nexport interface DiagnosisSpan {\n traceId: string\n spanId: string\n parentSpanId: string | null\n name: string\n kind: SpanKind\n startMs: number | null\n endMs: number | null\n status: DiagnosisSpanStatus\n statusMessage: string | null\n toolName: string | null\n model: string | null\n /**\n * Keyed fingerprint of the tool call's input, taken before redaction so calls\n * that differ only in secret material stay distinct. The key is random per\n * ingest, so the fingerprint cannot be matched against a guessed payload or\n * joined across diagnoses. Null when the span carries no input.\n */\n inputDigest: string | null\n attributes: Record<string, unknown>\n}\n\nexport interface IngestReport {\n received: number\n accepted: number\n /** Lines without a trace id or span id, which no evidence could ever cite. */\n unreadable: number\n /** Identical (trace id, span id) pairs seen again; the first occurrence is kept. */\n duplicateSpans: number\n /** Span ids that occur in more than one trace, which evidence cannot cite unambiguously. */\n ambiguousSpanIds: string[]\n secrets: SecretFilterReport\n /** Attribute keys removed because content was not included. */\n droppedAttributes: string[]\n}\n\n/**\n * Attributes that carry prompt, response, or tool payload text. When content is\n * not included they are removed before anything reads the span, rather than\n * trusting pattern redaction over free-form prose.\n */\nconst CONTENT_ATTRIBUTE =\n /^(?:input\\.value|output\\.value|input|output|result|prompt|completion|text|thinking|message|messages|tool\\.(?:input|output|arguments|result)|tool_input|tool_output|arguments|gen_ai\\.(?:prompt|completion|input\\.messages|output\\.messages|system_instructions|tool\\.call\\.(?:arguments|result))(?:\\..*)?|llm\\.(?:input|output)_messages(?:\\..*)?|llm\\.prompts?(?:\\..*)?|content|body|request|response|command)$|\\.content$/\n\nconst INPUT_ATTRIBUTE_KEYS = [\n 'input.value',\n 'input',\n 'tool.input',\n 'tool.arguments',\n 'tool_input',\n 'arguments',\n 'gen_ai.tool.call.arguments',\n]\n\nexport function isContentAttribute(key: string): boolean {\n return CONTENT_ATTRIBUTE.test(key)\n}\n\n/**\n * Filter secrets from every string, drop content attributes unless content is\n * included, and normalize each span. Order matters: the input fingerprint is\n * keyed and taken before redaction and the content drop, so repeated-call\n * detection works on metadata-only runs without the payload itself surviving.\n */\nexport function ingestSpans(\n raw: readonly unknown[],\n options: { contentIncluded: boolean },\n): { spans: DiagnosisSpan[]; report: IngestReport } {\n const secrets: SecretFilterReport = { redactionCount: 0, byRule: {} }\n const dropped = new Set<string>()\n const seen = new Set<string>()\n const spans: DiagnosisSpan[] = []\n let unreadable = 0\n let duplicateSpans = 0\n const traceOfSpan = new Map<string, string>()\n const ambiguous = new Set<string>()\n const digestKey = randomBytes(32)\n for (const line of raw) {\n if (line === null || typeof line !== 'object' || Array.isArray(line)) {\n unreadable += 1\n continue\n }\n const record = line as Record<string, unknown>\n const traceId = idField(record, 'trace_id', 'traceId')\n const spanId = idField(record, 'span_id', 'spanId')\n if (!traceId || !spanId) {\n unreadable += 1\n continue\n }\n const key = `${traceId}\\u0000${spanId}`\n if (seen.has(key)) {\n duplicateSpans += 1\n continue\n }\n seen.add(key)\n const firstTrace = traceOfSpan.get(spanId)\n if (firstTrace === undefined) traceOfSpan.set(spanId, traceId)\n else if (firstTrace !== traceId) ambiguous.add(spanId)\n const merged = mergedAttributes(record)\n const inputDigest = digestInput(merged, digestKey)\n const attributes = redactSecretsDeep(merged, secrets) as Record<string, unknown>\n if (!options.contentIncluded) {\n for (const key of Object.keys(attributes)) {\n if (isContentAttribute(key)) {\n delete attributes[key]\n dropped.add(key)\n }\n }\n }\n const status = readStatus(record)\n const statusMessage = status.message === null ? null : redactSecrets(status.message, secrets)\n const toolName = firstString(attributes, TOOL_NAME_ATTR_KEYS)\n const model = firstString(attributes, MODEL_ATTR_KEYS)\n const name = redactSecrets(stringOr(record.name, 'unknown'), secrets)\n spans.push({\n traceId,\n spanId,\n parentSpanId: idField(record, 'parent_span_id', 'parentSpanId') ?? null,\n name,\n kind: resolveKind(record.kind, name, attributes),\n startMs: epochMillis(record.start_time ?? record.startTime ?? record.startTimeUnixNano),\n endMs: epochMillis(record.end_time ?? record.endTime ?? record.endTimeUnixNano),\n status: status.code,\n statusMessage: options.contentIncluded ? statusMessage : truncate(statusMessage, 160),\n toolName,\n model,\n inputDigest,\n attributes,\n })\n }\n return {\n spans,\n report: {\n received: raw.length,\n accepted: spans.length,\n unreadable,\n duplicateSpans,\n ambiguousSpanIds: [...ambiguous].sort(),\n secrets,\n droppedAttributes: [...dropped].sort(),\n },\n }\n}\n\n/** The contract shape `validateTraceSpans` reads. */\nexport function toContractSpan(span: DiagnosisSpan): ContractSpan {\n return {\n trace_id: span.traceId,\n span_id: span.spanId,\n parent_span_id: span.parentSpanId,\n name: span.name,\n ...(span.kind === 'UNKNOWN' ? {} : { kind: span.kind }),\n start_time: isoOrEmpty(span.startMs),\n end_time: isoOrEmpty(span.endMs),\n status: {\n code:\n span.status === 'ERROR'\n ? 'STATUS_CODE_ERROR'\n : span.status === 'OK'\n ? 'STATUS_CODE_OK'\n : 'STATUS_CODE_UNSET',\n ...(span.statusMessage ? { message: span.statusMessage } : {}),\n },\n attributes: span.attributes,\n }\n}\n\nexport function durationMs(span: DiagnosisSpan): number | null {\n return span.startMs !== null && span.endMs !== null\n ? Math.max(0, span.endMs - span.startMs)\n : null\n}\n\n/**\n * Epoch milliseconds from OTLP nanoseconds, epoch milliseconds, epoch seconds,\n * or ISO-8601. Digit strings are classified by length: 17 or more digits are\n * nanoseconds, 15-16 microseconds, 12-14 milliseconds, and fewer are seconds.\n */\nexport function epochMillis(value: unknown): number | null {\n if (typeof value === 'number')\n return Number.isFinite(value) ? scaleEpoch(value, String(Math.trunc(value)).length) : null\n if (typeof value !== 'string' || value.length === 0) return null\n if (/^\\d+$/.test(value)) {\n if (value.length >= 17) return Number(BigInt(value) / 1_000_000n)\n return scaleEpoch(Number(value), value.length)\n }\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? null : parsed\n}\n\nfunction scaleEpoch(value: number, digits: number): number {\n if (digits >= 17) return Math.trunc(value / 1_000_000)\n if (digits >= 15) return Math.trunc(value / 1_000)\n if (digits >= 12) return value\n return value * 1000\n}\n\nfunction isoOrEmpty(ms: number | null): string {\n return ms === null ? '' : new Date(ms).toISOString()\n}\n\nfunction mergedAttributes(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const resource = record.resource\n if (resource && typeof resource === 'object' && !Array.isArray(resource)) {\n const attrs = (resource as Record<string, unknown>).attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n }\n const attrs = record.attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n if (typeof record.scope_name === 'string' && out['otel.scope.name'] === undefined) {\n out['otel.scope.name'] = record.scope_name\n }\n return out\n}\n\nfunction readStatus(record: Record<string, unknown>): {\n code: DiagnosisSpanStatus\n message: string | null\n} {\n let code: unknown = record.status_code\n let message: unknown = record.status_message\n const status = record.status\n if (status && typeof status === 'object' && !Array.isArray(status)) {\n const object = status as Record<string, unknown>\n code = object.code ?? code\n message = object.message ?? message\n }\n const text = typeof code === 'string' ? code.toUpperCase() : code\n const normalized: DiagnosisSpanStatus =\n text === 2 || text === 'STATUS_CODE_ERROR' || text === 'ERROR' || text === '2'\n ? 'ERROR'\n : text === 1 || text === 'STATUS_CODE_OK' || text === 'OK' || text === '1'\n ? 'OK'\n : 'UNSET'\n return {\n code: normalized,\n message: typeof message === 'string' && message.length > 0 ? message : null,\n }\n}\n\n/**\n * The contract's classifier decides the kind, so the capability table and the\n * findings count the same tool and LLM spans. A top-level `kind` counts as a\n * declaration only when it is a contract kind; OTLP words such as\n * SPAN_KIND_INTERNAL fall through to the attribute and name signals.\n */\nfunction resolveKind(kind: unknown, name: string, attributes: Record<string, unknown>): SpanKind {\n const declared =\n typeof kind === 'string' && (SPAN_KINDS as readonly string[]).includes(kind.toUpperCase())\n ? kind.toUpperCase()\n : undefined\n return resolveSpanKind({ ...(declared ? { kind: declared } : {}), name, attributes })\n}\n\nfunction digestInput(attributes: Record<string, unknown>, key: Buffer): string | null {\n for (const name of INPUT_ATTRIBUTE_KEYS) {\n const value = attributes[name]\n if (value === undefined || value === null || value === '') continue\n const text = typeof value === 'string' ? value : JSON.stringify(value)\n return createHmac('sha256', key).update(text).digest('hex').slice(0, 16)\n }\n return null\n}\n\nfunction idField(\n record: Record<string, unknown>,\n snake: string,\n camel: string,\n): string | undefined {\n const value = record[snake] ?? record[camel]\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction firstString(attributes: Record<string, unknown>, keys: readonly string[]): string | null {\n for (const key of keys) {\n const value = attributes[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return null\n}\n\nfunction stringOr(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.length > 0 ? value : fallback\n}\n\nfunction truncate(value: string | null, max: number): string | null {\n if (value === null || value.length <= max) return value\n return `${value.slice(0, max)}…`\n}\n","/**\n * The deterministic pass: everything the engine can say without a model.\n *\n * It produces the capability table (the trace contract's own validator, so the\n * reasons are the trace's reasons), execution facts with token and cost\n * accounting (agent-eval's `fromOtelSpans` + `summarizeExecution`), and\n * `observed` findings computed directly from span data. Every observed finding\n * carries a measure with its denominator and cites the spans it counted.\n */\n\nimport { createHash } from 'node:crypto'\nimport { type TraceValidation, validateTraceSpans } from '@tangle-network/agent-trace-contract'\nimport { type ExecutionReport, summarizeExecution } from '../contract/analyze-runs'\nimport { fromOtelSpans } from '../contract/intake/otel-spans'\nimport type { TraceSpanEvent } from '../hosted/types'\nimport type {\n DiagnosisCapability,\n DiagnosisFinding,\n DiagnosisSeverity,\n DiagnosisSkippedAnalysis,\n} from './findings'\nimport { type DiagnosisSpan, durationMs, toContractSpan } from './spans'\n\n/** Evidence ids cited per finding; the measure carries the full count. */\nexport const MAX_EVIDENCE_PER_FINDING = 8\n/**\n * Identical tool calls with no different tool call between them that count as\n * a repeated-call run. Model turns between the calls do not break the run: an\n * agent that calls, reads, and calls again with the same input is the waste\n * this detects.\n */\nexport const REPEAT_RUN_LENGTH = 3\n/** A tool is reported only once it has at least this many calls. */\nexport const MIN_TOOL_CALLS = 3\n\n/** The analysis each capability gates, as the report names it. */\nconst CAPABILITY_ANALYSES: Record<string, string> = {\n 'token-accounting': 'token accounting',\n 'cost-attribution': 'cost attribution',\n 'tool-usage': 'tool failure rates and repeated-call detection',\n 'loop-convergence': 'loop convergence (did round N+1 improve on round N)',\n 'tree-comparison': 'arm-vs-arm comparison across branches of one run',\n 'steering-chain': 'steering chain (which verdict caused which retry)',\n 'latency-analysis': 'latency distribution',\n}\n\n/** Capabilities the engine reports but has no analysis for yet. */\nconst NOT_BUILT = new Map([\n ['loop-convergence', 'the engine has no round-over-round convergence analysis yet'],\n ['tree-comparison', 'the engine has no arm-vs-arm comparison yet'],\n ['steering-chain', 'the engine has no steering-chain analysis yet'],\n])\n\nexport interface ExecutionFacts {\n runs: number\n spans: number\n spansByKind: Record<string, number>\n errorSpans: number\n toolCalls: number\n models: string[]\n /** agent-eval execution summary; null with a reason when it could not be computed. */\n execution: ExecutionReport | null\n executionError?: string\n}\n\nexport interface DeterministicResult {\n validation: TraceValidation\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n facts: ExecutionFacts\n findings: DiagnosisFinding[]\n window: string\n}\n\nexport function runDeterministicPass(spans: readonly DiagnosisSpan[]): DeterministicResult {\n const validation = validateTraceSpans(spans.map(toContractSpan))\n const capabilities: Record<string, DiagnosisCapability> = {}\n const skipped: DiagnosisSkippedAnalysis[] = []\n for (const capability of validation.capabilities) {\n capabilities[capability.name] = capability.available\n ? { available: true }\n : {\n available: false,\n reason: capability.reason ?? 'the trace contract validator gave no reason',\n }\n const analysis = CAPABILITY_ANALYSES[capability.name] ?? capability.name\n if (!capability.available) {\n skipped.push({ analysis, reason: capability.reason ?? 'capability unavailable' })\n } else if (NOT_BUILT.has(capability.name)) {\n skipped.push({ analysis, reason: NOT_BUILT.get(capability.name)! })\n }\n }\n\n const traces = groupByTrace(spans)\n const findings: DiagnosisFinding[] = []\n const tools = spans.filter((span) => span.kind === 'TOOL')\n if (tools.length > 0) {\n findings.push(...toolFailureFindings(tools))\n const withDigest = tools.filter((span) => span.inputDigest !== null).length\n if (withDigest > 0) findings.push(...repeatedCallFindings(traces))\n else\n skipped.push({\n analysis: 'repeated identical tool calls',\n reason: `none of ${tools.length} tool spans carries its input, so identical calls cannot be told apart`,\n })\n } else {\n skipped.push({ analysis: 'tool failure rates', reason: 'no span resolves to kind TOOL' })\n }\n findings.push(...failedRunFindings(traces))\n\n const facts = executionFacts(spans, traces.size)\n return { validation, capabilities, skipped, facts, findings, window: timeWindow(spans) }\n}\n\nexport function groupByTrace(spans: readonly DiagnosisSpan[]): Map<string, DiagnosisSpan[]> {\n const traces = new Map<string, DiagnosisSpan[]>()\n for (const span of spans) {\n const list = traces.get(span.traceId)\n if (list) list.push(span)\n else traces.set(span.traceId, [span])\n }\n for (const list of traces.values()) list.sort(byStart)\n return traces\n}\n\nfunction toolFailureFindings(tools: readonly DiagnosisSpan[]): DiagnosisFinding[] {\n const byTool = new Map<string, DiagnosisSpan[]>()\n for (const span of tools) {\n const name = span.toolName ?? span.name\n const list = byTool.get(name)\n if (list) list.push(span)\n else byTool.set(name, [span])\n }\n const findings: DiagnosisFinding[] = []\n for (const [tool, calls] of byTool) {\n const failed = calls.filter((span) => span.status === 'ERROR')\n if (calls.length < MIN_TOOL_CALLS || failed.length < 2) continue\n const rate = failed.length / calls.length\n const severity: DiagnosisSeverity =\n rate >= 0.5 && failed.length >= 5 ? 'high' : rate >= 0.2 ? 'medium' : 'low'\n findings.push({\n id: stableId('tool-failures', tool),\n severity,\n claim: `${failed.length} of ${calls.length} calls to the ${tool} tool failed.`,\n consequence: `Each failed call spends a model turn noticing the error and retrying, so ${pct(rate)} of this tool's calls bought no progress.`,\n measure: {\n name: `${tool} tool failure rate`,\n value: round(rate * 100),\n unit: '%',\n denominator: `${calls.length} calls to ${tool}`,\n },\n evidence: failed.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation: `Read the failed ${tool} calls' status messages and fix the most common cause, or give the agent the precondition it keeps missing.`,\n })\n }\n return findings.sort((a, b) => (b.measure?.value ?? 0) - (a.measure?.value ?? 0)).slice(0, 10)\n}\n\nfunction repeatedCallFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const runs: DiagnosisSpan[][] = []\n let digestCalls = 0\n for (const spans of traces.values()) {\n let current: DiagnosisSpan[] = []\n for (const span of spans) {\n if (span.kind !== 'TOOL' || span.inputDigest === null) continue\n digestCalls += 1\n const last = current[current.length - 1]\n if (\n last &&\n last.inputDigest === span.inputDigest &&\n (last.toolName ?? last.name) === (span.toolName ?? span.name)\n ) {\n current.push(span)\n } else {\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n current = [span]\n }\n }\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n }\n if (runs.length === 0) return []\n const wasted = runs.reduce((sum, run) => sum + run.length - 1, 0)\n const tracesAffected = new Set(runs.map((run) => run[0]!.traceId)).size\n runs.sort((a, b) => b.length - a.length)\n const evidence = runs\n .flatMap((run) => run.slice(0, 2).map((span) => span.spanId))\n .slice(0, MAX_EVIDENCE_PER_FINDING)\n const rate = wasted / digestCalls\n return [\n {\n id: stableId('repeated-calls', String(runs.length)),\n severity: rate >= 0.1 ? 'high' : rate >= 0.03 ? 'medium' : 'low',\n claim: `The agent made the same tool call with the same input ${REPEAT_RUN_LENGTH} or more times with no other tool call in between, ${runs.length} times across ${tracesAffected} runs; the longest streak was ${runs[0]!.length} calls.`,\n consequence: `${wasted} calls repeated the previous tool call with the same input, which is work the agent paid for twice without new information.`,\n measure: {\n name: 'repeated identical tool calls',\n value: wasted,\n unit: 'calls',\n denominator: `${digestCalls} tool calls with recorded input`,\n },\n evidence,\n confidence: 'observed',\n recommendation:\n 'Detect a repeated identical call in the harness and stop or change strategy after the second attempt.',\n },\n ]\n}\n\nfunction failedRunFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const failedRoots: DiagnosisSpan[] = []\n for (const spans of traces.values()) {\n const ids = new Set(spans.map((span) => span.spanId))\n const root = spans.find((span) => span.parentSpanId === null || !ids.has(span.parentSpanId))\n if (root?.status === 'ERROR') failedRoots.push(root)\n }\n if (failedRoots.length === 0) return []\n const rate = failedRoots.length / traces.size\n return [\n {\n id: stableId('failed-runs', String(traces.size)),\n severity: rate >= 0.25 ? 'critical' : rate >= 0.1 ? 'high' : 'medium',\n claim: `${failedRoots.length} of ${traces.size} runs ended with an error on their root span.`,\n consequence:\n 'A run that ends in an error delivered nothing its caller can use, and any tokens it spent are lost.',\n measure: {\n name: 'failed runs',\n value: round(rate * 100),\n unit: '%',\n denominator: `${traces.size} runs`,\n },\n evidence: failedRoots.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation:\n 'Group the failed runs by their root status message and fix the largest group first.',\n },\n ]\n}\n\nfunction executionFacts(spans: readonly DiagnosisSpan[], runs: number): ExecutionFacts {\n const spansByKind: Record<string, number> = {}\n const models = new Set<string>()\n let errorSpans = 0\n let toolCalls = 0\n for (const span of spans) {\n spansByKind[span.kind] = (spansByKind[span.kind] ?? 0) + 1\n if (span.status === 'ERROR') errorSpans += 1\n if (span.kind === 'TOOL') toolCalls += 1\n if (span.model) models.add(span.model)\n }\n const facts: ExecutionFacts = {\n runs,\n spans: spans.length,\n spansByKind,\n errorSpans,\n toolCalls,\n models: [...models].sort(),\n execution: null,\n }\n try {\n facts.execution = summarizeExecution({\n runs: fromOtelSpans({ spans: spans.map(toTraceSpanEvent) }),\n })\n } catch (error) {\n facts.executionError = error instanceof Error ? error.message : String(error)\n }\n return facts\n}\n\nfunction toTraceSpanEvent(span: DiagnosisSpan): TraceSpanEvent {\n const attributes: Record<string, string | number | boolean> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (typeof value === 'string' || typeof value === 'boolean') attributes[key] = value\n else if (typeof value === 'number' && Number.isFinite(value)) attributes[key] = value\n }\n if (span.kind !== 'UNKNOWN' && attributes['openinference.span.kind'] === undefined) {\n attributes['openinference.span.kind'] = span.kind\n }\n const start = span.startMs ?? 0\n const end = span.endMs ?? start\n return {\n traceId: span.traceId,\n spanId: span.spanId,\n ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),\n name: span.name,\n startTimeUnixNano: `${BigInt(Math.trunc(start)) * 1_000_000n}`,\n endTimeUnixNano: `${BigInt(Math.trunc(end)) * 1_000_000n}`,\n attributes,\n status: { code: span.status, ...(span.statusMessage ? { message: span.statusMessage } : {}) },\n }\n}\n\nfunction timeWindow(spans: readonly DiagnosisSpan[]): string {\n let first = Number.POSITIVE_INFINITY\n let last = Number.NEGATIVE_INFINITY\n for (const span of spans) {\n if (span.startMs !== null) first = Math.min(first, span.startMs)\n const end = span.endMs ?? span.startMs\n if (end !== null) last = Math.max(last, end)\n }\n if (!Number.isFinite(first) || !Number.isFinite(last)) return 'unknown'\n return `${new Date(first).toISOString()}/${new Date(last).toISOString()}`\n}\n\nfunction byStart(a: DiagnosisSpan, b: DiagnosisSpan): number {\n return (a.startMs ?? 0) - (b.startMs ?? 0) || (durationMs(b) ?? 0) - (durationMs(a) ?? 0)\n}\n\nexport function stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}-${createHash('sha256').update(parts.join('\\u0000')).digest('hex').slice(0, 12)}`\n}\n\nfunction pct(rate: number): string {\n return `${round(rate * 100)}%`\n}\n\nfunction round(value: number): number {\n return Math.round(value * 10) / 10\n}\n","/**\n * The diagnosis findings document: what the engine returns and what the\n * diagnosis report renders. It mirrors the kit's JSON Schema\n * (`https://tangle.tools/schemas/diagnosis-findings-v1.json`, owned by the\n * traces repository's diagnosis kit) field for field, including its closed\n * objects, so a document that passes {@link validateDiagnosisFindings} passes\n * that schema.\n */\n\nexport const DIAGNOSIS_FINDINGS_SCHEMA_ID =\n 'https://tangle.tools/schemas/diagnosis-findings-v1.json'\n\nexport type DiagnosisSeverity = 'critical' | 'high' | 'medium' | 'low'\n\n/** `observed` is read directly off the trace; `inferred` is a model's reading of it. */\nexport type DiagnosisConfidence = 'observed' | 'inferred'\n\nexport interface DiagnosisMeasure {\n name: string\n value: number\n unit: string\n /** What the value is out of. The engine always sets it; a rate without one is not reportable. */\n denominator: string\n}\n\nexport interface DiagnosisFinding {\n id: string\n severity: DiagnosisSeverity\n claim: string\n consequence: string\n measure?: DiagnosisMeasure\n /** Verbatim span ids from the input. Never empty. */\n evidence: string[]\n reproduce?: string\n confidence: DiagnosisConfidence\n recommendation?: string\n}\n\nexport interface DiagnosisCapability {\n available: boolean\n reason?: string\n}\n\nexport interface DiagnosisSkippedAnalysis {\n analysis: string\n reason: string\n}\n\nexport interface DiagnosisRedaction {\n redactionCount: number\n byRule: Record<string, number>\n droppedAttributes: string[]\n}\n\nexport interface DiagnosisFindingsDocument {\n schemaVersion: 1\n subject: {\n label: string\n runCount: number\n window: string\n contentIncluded?: boolean\n }\n coverage: {\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n redaction?: DiagnosisRedaction\n }\n findings: DiagnosisFinding[]\n}\n\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\nexport const SEVERITY_RANK: Record<DiagnosisSeverity, number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n}\n\n/**\n * Structural check against the v1 schema plus the two rules the schema states\n * in prose: an unavailable capability carries a reason, and a measure carries a\n * denominator. When `spanIds` is given, every evidence id must resolve to it.\n * Returns the list of defects; empty means valid.\n */\nexport function validateDiagnosisFindings(\n document: unknown,\n options: { spanIds?: ReadonlySet<string> } = {},\n): string[] {\n const errors: string[] = []\n if (!isObject(document)) return ['document is not an object']\n closed(document, ['schemaVersion', 'subject', 'coverage', 'findings'], '', errors)\n if (document.schemaVersion !== 1) errors.push('schemaVersion must be 1')\n\n const subject = document.subject\n if (!isObject(subject)) errors.push('subject must be an object')\n else {\n closed(subject, ['label', 'runCount', 'window', 'contentIncluded'], 'subject', errors)\n if (typeof subject.label !== 'string') errors.push('subject.label must be a string')\n if (!Number.isInteger(subject.runCount) || (subject.runCount as number) < 0)\n errors.push('subject.runCount must be a non-negative integer')\n if (typeof subject.window !== 'string') errors.push('subject.window must be a string')\n if (subject.contentIncluded !== undefined && typeof subject.contentIncluded !== 'boolean')\n errors.push('subject.contentIncluded must be a boolean')\n }\n\n const coverage = document.coverage\n if (!isObject(coverage)) errors.push('coverage must be an object')\n else {\n closed(coverage, ['capabilities', 'skipped', 'redaction'], 'coverage', errors)\n if (!isObject(coverage.capabilities)) errors.push('coverage.capabilities must be an object')\n else {\n for (const [name, capability] of Object.entries(coverage.capabilities)) {\n if (!isObject(capability) || typeof capability.available !== 'boolean') {\n errors.push(`coverage.capabilities.${name}.available must be a boolean`)\n } else if (\n !capability.available &&\n !(typeof capability.reason === 'string' && capability.reason)\n ) {\n errors.push(`coverage.capabilities.${name} is unavailable without a reason`)\n }\n }\n }\n if (!Array.isArray(coverage.skipped)) errors.push('coverage.skipped must be an array')\n else\n coverage.skipped.forEach((entry, index) => {\n if (\n !isObject(entry) ||\n typeof entry.analysis !== 'string' ||\n typeof entry.reason !== 'string'\n )\n errors.push(`coverage.skipped[${index}] needs analysis and reason strings`)\n })\n if (coverage.redaction !== undefined) {\n const redaction = coverage.redaction\n if (!isObject(redaction)) errors.push('coverage.redaction must be an object')\n else {\n if (!Number.isInteger(redaction.redactionCount) || (redaction.redactionCount as number) < 0)\n errors.push('coverage.redaction.redactionCount must be a non-negative integer')\n if (redaction.byRule !== undefined && !isObject(redaction.byRule))\n errors.push('coverage.redaction.byRule must be an object')\n if (\n redaction.droppedAttributes !== undefined &&\n !Array.isArray(redaction.droppedAttributes)\n )\n errors.push('coverage.redaction.droppedAttributes must be an array')\n }\n }\n }\n\n if (!Array.isArray(document.findings)) errors.push('findings must be an array')\n else\n document.findings.forEach((finding, index) => {\n const at = `findings[${index}]`\n if (!isObject(finding)) {\n errors.push(`${at} must be an object`)\n return\n }\n closed(\n finding,\n [\n 'id',\n 'severity',\n 'claim',\n 'consequence',\n 'measure',\n 'evidence',\n 'reproduce',\n 'confidence',\n 'recommendation',\n ],\n at,\n errors,\n )\n for (const key of ['id', 'claim', 'consequence'] as const) {\n if (typeof finding[key] !== 'string' || !(finding[key] as string))\n errors.push(`${at}.${key} must be a non-empty string`)\n }\n if (!SEVERITIES.has(finding.severity as string)) errors.push(`${at}.severity is invalid`)\n if (finding.confidence !== 'observed' && finding.confidence !== 'inferred')\n errors.push(`${at}.confidence must be observed or inferred`)\n if (!Array.isArray(finding.evidence) || finding.evidence.length === 0)\n errors.push(`${at}.evidence must be a non-empty array`)\n else\n for (const id of finding.evidence) {\n if (typeof id !== 'string') errors.push(`${at}.evidence holds a non-string`)\n else if (options.spanIds && !options.spanIds.has(id))\n errors.push(`${at}.evidence ${id} does not resolve`)\n }\n if (finding.measure !== undefined) {\n const measure = finding.measure\n if (\n !isObject(measure) ||\n typeof measure.name !== 'string' ||\n typeof measure.value !== 'number' ||\n !Number.isFinite(measure.value) ||\n typeof measure.unit !== 'string'\n ) {\n errors.push(`${at}.measure needs name, finite value and unit`)\n } else if (!(typeof measure.denominator === 'string' && measure.denominator)) {\n errors.push(`${at}.measure has no denominator`)\n }\n }\n for (const key of ['reproduce', 'recommendation'] as const) {\n if (finding[key] !== undefined && typeof finding[key] !== 'string')\n errors.push(`${at}.${key} must be a string`)\n }\n })\n return errors\n}\n\nfunction closed(\n value: Record<string, unknown>,\n allowed: readonly string[],\n at: string,\n errors: string[],\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) errors.push(`${at ? `${at}.` : ''}${key} is not allowed`)\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n","/**\n * The model pass: one prime-protocol exchange per selected run.\n *\n * The run's filtered spans are inlined into the prompt (prime has no trace\n * tools), the reply is one fenced JSON block of short rows, and each row that\n * claims a defect must cite span ids from that run. A row citing an id the run\n * does not hold, or an id that several runs share, is rejected with the reason\n * recorded, never repaired by guessing. Every accepted finding is `inferred`:\n * it is the model's reading, and the report keeps it apart from what the\n * deterministic pass observed.\n */\n\nimport type { PrimeBridgeTransport } from '../analyst/prime-bridge-transport'\nimport {\n buildPrimePrompt,\n type PrimeRawUsage,\n type PrimeReplyContract,\n primeProtocolSha256,\n runPrimeExchange,\n} from '../analyst/prime-protocol'\nimport { stableId } from './deterministic'\nimport type { DiagnosisFinding, DiagnosisSeverity } from './findings'\nimport { type DiagnosisSpan, durationMs } from './spans'\n\nexport interface DiagnosisModelOptions {\n /** One POST-shaped call to an OpenAI-compatible chat endpoint, or an equivalent local runner. */\n transport: PrimeBridgeTransport\n /** Endpoint the transport receives, e.g. `http://127.0.0.1:4181/v1/chat/completions`. */\n url: string\n /** Model id as the endpoint names it, e.g. `deepseek/deepseek-v4.1-flash`. */\n model: string\n /** Runs read by the model per diagnosis. Default 6. */\n maxTraces?: number\n /** Deadline for one exchange turn. Default 10 minutes. */\n timeoutMs?: number\n /** Inline budget for one rendered run. Default 400,000 characters. */\n maxInlineChars?: number\n /** Per-attribute character cap for the rendering. Default 600. */\n attributeChars?: number\n /** Segments of one long run the model reads, most errors first. Default 3. */\n maxSegmentsPerRun?: number\n /** Exact token rates; without them cost stays uncaptured. */\n pricing?: { inputUsdPerMillion: number; outputUsdPerMillion: number }\n}\n\nexport interface ModelRowNote {\n kind: 'operator' | 'topology'\n text: string\n evidence: string[]\n traceId?: string\n project?: string\n}\n\nexport interface ModelQuestion {\n question: string\n project?: string\n traceId?: string\n}\n\nexport interface ModelRejection {\n traceId?: string\n reason: string\n}\n\nexport interface ModelRunRecord {\n traceId: string\n ok: boolean\n failure?: string\n delivery?: { segment: number; segments: number; renderedChars: number }\n usage: PrimeRawUsage\n rows: number\n}\n\nexport interface ModelPassResult {\n findings: DiagnosisFinding[]\n questions: ModelQuestion[]\n notes: ModelRowNote[]\n summaries: Array<{ traceId: string; answer: string }>\n rejected: ModelRejection[]\n /** Runs the model read only in part, with which segments it read. */\n uncovered: ModelRejection[]\n runs: ModelRunRecord[]\n promptSha256: string\n}\n\nexport interface ModelPassInput {\n subject: 'internal' | 'customer'\n focus?: string\n projects?: readonly string[]\n contentIncluded: boolean\n}\n\ninterface RawRow {\n kind: 'finding' | 'question' | 'operator' | 'topology'\n severity?: DiagnosisSeverity\n claim?: string\n consequence?: string\n recommendation?: string\n question?: string\n project?: string\n evidence: string[]\n}\n\nconst MAX_ROWS = 12\nconst MAX_STRING = 400\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\n\nexport function modelQuestion(input: ModelPassInput): string {\n const focus = input.focus ? ` The owner's question: ${input.focus}` : ''\n const projects =\n input.projects && input.projects.length > 0\n ? ` The runs belong to these projects: ${input.projects.join(', ')}; set \"project\" on a row to one of these names when the run shows which one it concerns.`\n : ''\n const withheld = input.contentIncluded\n ? ''\n : \" Prompt, response and tool payload content was withheld at the owner's choice; do not report its absence as a defect, and reason from span names, kinds, order, timing, status and the remaining attributes.\"\n return input.subject === 'internal'\n ? `Diagnose this coding-agent session from our own fleet: find concrete agent failures, wasted work, unsupported claims of success, and where the human operator's instructions caused trouble.${withheld}${projects}${focus}`\n : `Diagnose this agent run: find concrete failures, wasted work, and unsupported claims of success that cost the owner money, time, or correct results.${withheld}${projects}${focus}`\n}\n\nexport function modelContractLines(subject: 'internal' | 'customer'): string[] {\n const kinds =\n subject === 'internal' ? '\"finding\" | \"question\" | \"operator\"' : '\"finding\" | \"question\"'\n return [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) summarising what went wrong in this run, or that nothing did.',\n ` \"rows\": an array of at most ${MAX_ROWS} objects, each with \"kind\": ${kinds}.`,\n 'A \"finding\" row: {\"kind\":\"finding\",\"severity\":\"critical|high|medium|low\",\"claim\":\"one sentence stating the defect\",\"consequence\":\"what it cost in money, time, failed work or escalations\",\"recommendation\":\"the fix\",\"evidence\":[\"<span_id>\", ...]}.',\n 'A \"question\" row: {\"kind\":\"question\",\"question\":\"a concrete question the owner should answer\",\"evidence\":[]}.',\n ...(subject === 'internal'\n ? [\n 'An \"operator\" row: {\"kind\":\"operator\",\"claim\":\"one sentence critiquing how the human operator instructed or steered the agent\",\"evidence\":[\"<span_id>\", ...]}.',\n ]\n : []),\n 'Add \"project\": \"<repo or project name>\" to any row when the run shows which project it belongs to.',\n 'Every \"finding\" and \"operator\" row cites 1-8 span ids copied VERBATIM from the \"id\" fields of the trajectory. Rows citing ids that are not in the trajectory are discarded.',\n 'Keep every string under 400 characters. Report only what the trajectory shows; an empty rows array is a valid answer.',\n ]\n}\n\nexport async function runModelPass(\n traces: ReadonlyArray<{ traceId: string; spans: readonly DiagnosisSpan[] }>,\n ambiguousSpanIds: ReadonlySet<string>,\n input: ModelPassInput,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<ModelPassResult> {\n const question = modelQuestion(input)\n const contractLines = modelContractLines(input.subject)\n const promptSha256 = primeProtocolSha256({\n question,\n contractLines,\n repairContractLines: contractLines,\n limits: { maxRows: MAX_ROWS, maxString: MAX_STRING },\n })\n const result: ModelPassResult = {\n findings: [],\n questions: [],\n notes: [],\n summaries: [],\n rejected: [],\n uncovered: [],\n runs: [],\n promptSha256,\n }\n const maxInlineChars = options.maxInlineChars ?? 400_000\n const attributeChars = options.attributeChars ?? 600\n\n const maxSegments = options.maxSegmentsPerRun ?? 3\n for (const { traceId, spans } of traces) {\n const segments = segmentRun(spans, attributeChars, input.contentIncluded, maxInlineChars)\n const chosen = segments\n .map((segment, index) => ({ ...segment, index }))\n .sort((a, b) => b.errors - a.errors || a.index - b.index)\n .slice(0, maxSegments)\n .sort((a, b) => a.index - b.index)\n if (segments.length > chosen.length) {\n result.uncovered.push({\n traceId,\n reason: `the run renders to ${segments.length} segments of at most ${maxInlineChars} characters; the model read the ${chosen.length} with the most errors (${chosen.map((segment) => segment.index + 1).join(', ')})`,\n })\n }\n for (const segment of chosen) {\n const label =\n segments.length > 1 ? `${traceId} segment ${segment.index + 1}/${segments.length}` : traceId\n const ids = new Set(segment.spans.map((span) => span.spanId))\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, input.subject),\n } satisfies PrimeReplyContract<RawRow>,\n prompt: buildPrimePrompt({\n question,\n contractLines,\n trajectoryHeader: `TRAJECTORY (run ${label}; ${segment.spans.length} of the run's ${spans.length} spans, in start order; secrets redacted as [REDACTED:<kind>]):`,\n renderedTrajectory: segment.rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const delivery = {\n segment: segment.index + 1,\n segments: segments.length,\n renderedChars: segment.rendered.length,\n }\n if (!outcome.ok) {\n result.runs.push({\n traceId,\n ok: false,\n failure: `${label}: ${outcome.failure.kind}: ${outcome.failure.message}`,\n delivery,\n usage: outcome.usage,\n rows: 0,\n })\n continue\n }\n for (const rejection of outcome.rejected) {\n result.rejected.push({ traceId, reason: `row ${rejection.index}: ${rejection.reason}` })\n }\n if (outcome.overflow > 0) {\n result.rejected.push({\n traceId,\n reason: `${outcome.overflow} valid rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (outcome.answer)\n result.summaries.push({ traceId, answer: outcome.answer.slice(0, MAX_STRING) })\n acceptRows(result, outcome.rows, traceId, ids, ambiguousSpanIds)\n result.runs.push({\n traceId,\n ok: true,\n delivery,\n usage: outcome.usage,\n rows: outcome.rows.length,\n })\n }\n }\n return result\n}\n\n/** The topology reading: one exchange over the caller's run-graph summary, internal runs only. */\nexport async function runTopologyPass(\n topology: unknown,\n runIds: ReadonlySet<string>,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<{\n notes: ModelRowNote[]\n questions: ModelQuestion[]\n rejected: ModelRejection[]\n run: ModelRunRecord\n}> {\n const contractLines = [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) on how the agent fleet was organised today.',\n ` \"rows\": at most ${MAX_ROWS} objects, each either {\"kind\":\"topology\",\"claim\":\"one sentence on a spawn, messaging, hand-off or resume pattern that helped or hurt\",\"evidence\":[\"<run id>\", ...],\"project\":\"<optional>\"} or {\"kind\":\"question\",\"question\":\"...\",\"project\":\"<optional>\",\"evidence\":[]}.`,\n 'Every \"topology\" row cites 1-8 run ids copied VERBATIM from the graph. Keep every string under 400 characters.',\n ]\n const rendered = JSON.stringify(topology)\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, 'topology'),\n },\n prompt: buildPrimePrompt({\n question:\n \"Analyse the topology of this agent fleet's runs: who spawned whom, who messaged whom, hand-offs and resumes. Name patterns that wasted work or lost context, and what to change.\",\n contractLines,\n trajectoryHeader: `RUN GRAPH (${runIds.size} runs):`,\n renderedTrajectory:\n rendered.length > (options.maxInlineChars ?? 400_000)\n ? rendered.slice(0, options.maxInlineChars ?? 400_000)\n : rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const notes: ModelRowNote[] = []\n const questions: ModelQuestion[] = []\n const rejected: ModelRejection[] = []\n if (outcome.ok && outcome.overflow > 0) {\n rejected.push({\n reason: `${outcome.overflow} valid topology rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (!outcome.ok) {\n return {\n notes,\n questions,\n rejected,\n run: {\n traceId: 'topology',\n ok: false,\n failure: `${outcome.failure.kind}: ${outcome.failure.message}`,\n usage: outcome.usage,\n rows: 0,\n },\n }\n }\n for (const row of outcome.rows) {\n if (row.kind === 'question') {\n questions.push({ question: row.question!, ...(row.project ? { project: row.project } : {}) })\n continue\n }\n const cited = row.evidence.filter((id) => runIds.has(id))\n if (cited.length === 0) {\n rejected.push({\n reason: `topology row \"${(row.claim ?? '').slice(0, 80)}\" cites no run id from the graph`,\n })\n continue\n }\n notes.push({\n kind: 'topology',\n text: row.claim!,\n evidence: cited,\n ...(row.project ? { project: row.project } : {}),\n })\n }\n if (outcome.answer)\n notes.unshift({ kind: 'topology', text: outcome.answer.slice(0, MAX_STRING), evidence: [] })\n return {\n notes,\n questions,\n rejected,\n run: { traceId: 'topology', ok: true, usage: outcome.usage, rows: outcome.rows.length },\n }\n}\n\nfunction acceptRows(\n result: ModelPassResult,\n rows: readonly RawRow[],\n traceId: string,\n ids: ReadonlySet<string>,\n ambiguousSpanIds: ReadonlySet<string>,\n): void {\n for (const row of rows) {\n const unresolved = row.evidence.filter((id) => !ids.has(id))\n const ambiguous = row.evidence.filter((id) => ambiguousSpanIds.has(id))\n const cited = row.evidence.filter((id) => ids.has(id) && !ambiguousSpanIds.has(id))\n if (unresolved.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids not in the segment it read: ${unresolved.slice(0, 5).join(', ')}`,\n })\n if (ambiguous.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids shared by several runs: ${ambiguous.slice(0, 5).join(', ')}`,\n })\n if (row.kind === 'question') {\n result.questions.push({\n question: row.question!,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n // A claim that leaned on an invalid id is not supported by the valid ones\n // left over, so the whole row goes rather than a trimmed version of it.\n if (unresolved.length > 0 || ambiguous.length > 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" discarded: it cites invalid evidence`,\n })\n continue\n }\n if (cited.length === 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" has no resolvable evidence`,\n })\n continue\n }\n if (row.kind === 'operator') {\n result.notes.push({\n kind: 'operator',\n text: row.claim!,\n evidence: cited,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n result.findings.push({\n id: stableId('inferred', traceId, row.claim!),\n severity: row.severity!,\n claim: row.claim!,\n consequence: row.consequence!,\n evidence: cited,\n confidence: 'inferred',\n ...(row.recommendation ? { recommendation: row.recommendation } : {}),\n })\n }\n}\n\ninterface RunSegment {\n spans: DiagnosisSpan[]\n rendered: string\n errors: number\n}\n\n/**\n * Split a run, in start order, into contiguous segments that each render\n * within the inline budget. Inline is prime's only delivery, so a long run is\n * read as whole segments rather than silently truncated; which segments were\n * read and which were not is recorded by the caller.\n */\nexport function segmentRun(\n spans: readonly DiagnosisSpan[],\n attributeChars: number,\n contentIncluded: boolean,\n maxInlineChars: number,\n): RunSegment[] {\n const segments: RunSegment[] = []\n let current: DiagnosisSpan[] = []\n let parts: string[] = []\n let size = 2\n let errors = 0\n const flush = () => {\n if (current.length === 0) return\n segments.push({ spans: current, rendered: `[${parts.join(',')}]`, errors })\n current = []\n parts = []\n size = 2\n errors = 0\n }\n for (const span of spans) {\n let part = JSON.stringify(renderSpan(span, attributeChars, contentIncluded))\n if (part.length + 2 > maxInlineChars)\n part = JSON.stringify(renderSpan(span, 120, contentIncluded))\n if (size + part.length + 1 > maxInlineChars) flush()\n current.push(span)\n parts.push(part)\n size += part.length + 1\n if (span.status === 'ERROR') errors += 1\n }\n flush()\n return segments\n}\n\nfunction decodeRow(\n row: unknown,\n mode: 'internal' | 'customer' | 'topology',\n): { ok: true; row: RawRow } | { ok: false; reason: string } {\n if (row === null || typeof row !== 'object' || Array.isArray(row))\n return { ok: false, reason: 'row is not an object' }\n const value = row as Record<string, unknown>\n const kind = value.kind\n const allowed =\n mode === 'internal'\n ? ['finding', 'question', 'operator']\n : mode === 'customer'\n ? ['finding', 'question']\n : ['topology', 'question']\n if (typeof kind !== 'string' || !allowed.includes(kind))\n return { ok: false, reason: `kind ${String(kind)} is not allowed here` }\n const evidence = Array.isArray(value.evidence)\n ? value.evidence\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .slice(0, 8)\n : []\n const project = shortString(value.project)\n if (kind === 'question') {\n const question = shortString(value.question)\n if (!question) return { ok: false, reason: 'question row has no question' }\n return { ok: true, row: { kind, question, evidence, ...(project ? { project } : {}) } }\n }\n const claim = shortString(value.claim)\n if (!claim) return { ok: false, reason: `${kind} row has no claim` }\n if (kind !== 'finding')\n return {\n ok: true,\n row: { kind: kind as RawRow['kind'], claim, evidence, ...(project ? { project } : {}) },\n }\n const severity = value.severity\n if (typeof severity !== 'string' || !SEVERITIES.has(severity))\n return { ok: false, reason: `severity ${String(severity)} is invalid` }\n const consequence = shortString(value.consequence)\n if (!consequence) return { ok: false, reason: 'finding row has no consequence' }\n const recommendation = shortString(value.recommendation)\n return {\n ok: true,\n row: {\n kind: 'finding',\n severity: severity as DiagnosisSeverity,\n claim,\n consequence,\n evidence,\n ...(recommendation ? { recommendation } : {}),\n ...(project ? { project } : {}),\n },\n }\n}\n\n/** One span as the model reads it: the pivots, then the attributes that remain after filtering. */\nfunction renderSpan(\n span: DiagnosisSpan,\n attributeChars: number,\n contentIncluded: boolean,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {\n id: span.spanId,\n parent: span.parentSpanId,\n kind: span.kind,\n name: span.name,\n }\n if (span.toolName) out.tool = span.toolName\n if (span.model) out.model = span.model\n if (span.status !== 'UNSET') out.status = span.status\n if (span.statusMessage) out.status_message = clip(span.statusMessage, attributeChars)\n const duration = durationMs(span)\n if (duration !== null) out.ms = duration\n const attrs: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (SKIP_ATTRIBUTES.has(key)) continue\n if (typeof value === 'string') attrs[key] = clip(value, attributeChars)\n else if (typeof value === 'number' || typeof value === 'boolean') attrs[key] = value\n else if (value !== null && value !== undefined)\n attrs[key] = clip(JSON.stringify(value), attributeChars)\n }\n if (Object.keys(attrs).length > 0) out.attrs = attrs\n if (!contentIncluded) out.content = 'withheld'\n return out\n}\n\n/** Pivots already rendered above, and resource noise that repeats on every span. */\nconst SKIP_ATTRIBUTES = new Set([\n 'openinference.span.kind',\n 'tool.name',\n 'gen_ai.tool.name',\n 'llm.model_name',\n 'gen_ai.request.model',\n 'service.name',\n 'agent.name',\n 'source_file',\n 'otel.scope.name',\n 'telemetry.sdk.name',\n 'telemetry.sdk.language',\n 'telemetry.sdk.version',\n])\n\nfunction clip(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max)}…[+${value.length - max} chars]`\n}\n\nfunction shortString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n if (!trimmed) return undefined\n return trimmed.length <= MAX_STRING ? trimmed : `${trimmed.slice(0, MAX_STRING)}…`\n}\n","/**\n * The agent-failure diagnosis engine: flat spans plus context in, a findings\n * document out.\n *\n * It is a plain function. Its only side effect is the model call made through\n * the caller's transport, and in deterministic mode it makes none. It keeps no\n * storage, files no issues, and retains nothing: where the spans came from and\n * where the findings go belong to the caller. That is what lets one engine\n * serve both the internal daily mining run and a customer diagnosis while their\n * data paths stay separate.\n *\n * Order of operations, each step reading only the previous step's output:\n * 1. secret filter and content drop over every input (spans, focus, topology);\n * 2. the deterministic pass: capability table, execution facts, observed findings;\n * 3. in model mode, the prime-protocol pass over the highest-signal runs;\n * 4. evidence resolution: every cited id must be a span id of the input that\n * no other run shares; findings left without evidence are rejected.\n */\n\nimport { packageVersion } from '../package-version'\nimport { type DeterministicResult, groupByTrace, runDeterministicPass } from './deterministic'\nimport {\n type DiagnosisFinding,\n type DiagnosisFindingsDocument,\n SEVERITY_RANK,\n validateDiagnosisFindings,\n} from './findings'\nimport {\n type DiagnosisModelOptions,\n type ModelQuestion,\n type ModelRejection,\n type ModelRowNote,\n type ModelRunRecord,\n runModelPass,\n runTopologyPass,\n} from './model-pass'\nimport { redactSecrets, redactSecretsDeep } from './secret-filter'\nimport { type IngestReport, ingestSpans } from './spans'\n\nexport interface DiagnosisContext {\n /** Whose traces these are. Operator critique and topology run only for `internal`. */\n subject: 'internal' | 'customer'\n /** What was analysed, in the owner's words. Never an internal id for a customer. */\n label: string\n /** The owner's question, e.g. from the intake form. */\n focus?: string\n /**\n * Whether prompt, response and tool payload attributes may be read. Default\n * false: they are dropped before anything reads the spans.\n */\n contentIncluded?: boolean\n /** Project or repository names the runs belong to, for grouping questions. */\n projects?: string[]\n /** A run-graph summary (internal only), e.g. from the lineage graph. */\n topology?: { runs: Array<{ id: string } & Record<string, unknown>> } & Record<string, unknown>\n}\n\nexport type DiagnosisOptions =\n | { mode: 'deterministic'; reason?: string; signal?: AbortSignal }\n | { mode: 'model'; model: DiagnosisModelOptions; signal?: AbortSignal }\n\nexport interface DiagnosisUsage {\n exchanges: number\n inputTokens: number | null\n outputTokens: number | null\n usd: number | null\n}\n\nexport interface DiagnosisResult {\n /** Validates against diagnosis-findings-v1. The only part a customer report renders. */\n document: DiagnosisFindingsDocument\n /** Questions for the owner, grouped later by project. */\n questions: ModelQuestion[]\n /** Operator critique and topology notes; internal runs only. */\n notes: ModelRowNote[]\n /** The model's one-paragraph reading of each run it read. */\n summaries: Array<{ traceId: string; answer: string }>\n facts: DeterministicResult['facts']\n conformance: DeterministicResult['validation']['findings']\n ingest: IngestReport\n /** Model rows and findings dropped, each with why. */\n rejected: ModelRejection[]\n model: {\n used: boolean\n model: string | null\n runs: ModelRunRecord[]\n promptSha256: string | null\n usage: DiagnosisUsage\n }\n engine: { name: 'agent-eval/diagnosis'; version: string }\n}\n\nexport const DEFAULT_MAX_MODEL_TRACES = 6\n/** Runs with fewer spans carry too little for the model to read. */\nexport const MIN_MODEL_SPANS = 3\n\nexport async function diagnoseSpans(\n spans: readonly unknown[],\n context: DiagnosisContext,\n options: DiagnosisOptions,\n): Promise<DiagnosisResult> {\n if (context.subject !== 'internal' && context.subject !== 'customer') {\n throw new TypeError(\n `diagnoseSpans: subject must be internal or customer, got ${String(context.subject)}`,\n )\n }\n if (context.subject === 'customer' && context.topology !== undefined) {\n throw new TypeError(\n 'diagnoseSpans: topology analysis is internal only; a customer context must not carry one',\n )\n }\n const contentIncluded = context.contentIncluded === true\n const { spans: filtered, report: ingest } = ingestSpans(spans, { contentIncluded })\n const focus =\n context.focus === undefined ? undefined : redactSecrets(context.focus, ingest.secrets)\n const deterministic = runDeterministicPass(filtered)\n const skipped = [...deterministic.skipped]\n const ambiguous = new Set(ingest.ambiguousSpanIds)\n const rejected: ModelRejection[] = []\n const questions: ModelQuestion[] = []\n const notes: ModelRowNote[] = []\n const summaries: Array<{ traceId: string; answer: string }> = []\n const runs: ModelRunRecord[] = []\n let promptSha256: string | null = null\n let modelFindings: DiagnosisFinding[] = []\n\n const traces = groupByTrace(filtered)\n if (options.mode === 'deterministic') {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: options.reason ?? 'deterministic mode: no model call was made',\n })\n } else {\n const maxTraces = options.model.maxTraces ?? DEFAULT_MAX_MODEL_TRACES\n const ranked = rankTraces(traces)\n const selected = ranked.slice(0, maxTraces)\n const short = traces.size - ranked.length\n if (ranked.length === 0) {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: `no run has the ${MIN_MODEL_SPANS} spans the model needs to read it; ${traces.size} runs were too short`,\n })\n } else if (short > 0) {\n skipped.push({\n analysis: `model reading of ${short} of ${traces.size} runs`,\n reason: `those runs have fewer than ${MIN_MODEL_SPANS} spans, too few for the model to read`,\n })\n }\n if (ranked.length > selected.length) {\n skipped.push({\n analysis: `model reading of ${ranked.length - selected.length} of ${ranked.length} runs`,\n reason: `the model reads at most ${maxTraces} runs per diagnosis, chosen by error count then size`,\n })\n }\n const pass = await runModelPass(\n selected,\n ambiguous,\n {\n subject: context.subject,\n contentIncluded,\n ...(focus ? { focus } : {}),\n ...(context.projects ? { projects: context.projects } : {}),\n },\n options.model,\n options.signal,\n )\n promptSha256 = pass.promptSha256\n modelFindings = pass.findings\n questions.push(...pass.questions)\n notes.push(...(context.subject === 'internal' ? pass.notes : []))\n summaries.push(...pass.summaries)\n rejected.push(...pass.rejected)\n runs.push(...pass.runs)\n for (const gap of pass.uncovered) {\n skipped.push({ analysis: `model reading of part of run ${gap.traceId}`, reason: gap.reason })\n }\n for (const run of pass.runs) {\n if (!run.ok)\n skipped.push({\n analysis: `model reading of run ${run.traceId}`,\n reason: run.failure ?? 'failed',\n })\n }\n if (context.subject === 'internal' && context.topology) {\n const topology = redactSecretsDeep(context.topology, ingest.secrets) as NonNullable<\n DiagnosisContext['topology']\n >\n const runIds = new Set(\n (topology.runs ?? [])\n .map((run) => run.id)\n .filter((id): id is string => typeof id === 'string'),\n )\n const reading = await runTopologyPass(topology, runIds, options.model, options.signal)\n notes.push(...reading.notes)\n questions.push(...reading.questions)\n rejected.push(...reading.rejected)\n runs.push(reading.run)\n if (!reading.run.ok)\n skipped.push({ analysis: 'topology reading', reason: reading.run.failure ?? 'failed' })\n }\n }\n\n const spanIds = new Set(filtered.map((span) => span.spanId))\n const findings = resolveEvidence(\n [...deterministic.findings, ...modelFindings],\n spanIds,\n ambiguous,\n rejected,\n ).sort(\n (a, b) =>\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] ||\n (a.confidence === b.confidence ? 0 : a.confidence === 'observed' ? -1 : 1),\n )\n\n const document: DiagnosisFindingsDocument = {\n schemaVersion: 1,\n subject: {\n label: redactSecrets(context.label, ingest.secrets),\n runCount: traces.size,\n window: deterministic.window,\n contentIncluded,\n },\n coverage: {\n capabilities: deterministic.capabilities,\n skipped,\n redaction: {\n redactionCount: ingest.secrets.redactionCount,\n byRule: { ...ingest.secrets.byRule },\n droppedAttributes: ingest.droppedAttributes,\n },\n },\n findings,\n }\n const defects = validateDiagnosisFindings(document, { spanIds })\n if (defects.length > 0) {\n throw new Error(\n `diagnoseSpans produced an invalid findings document: ${defects.slice(0, 5).join('; ')}`,\n )\n }\n const pricing = options.mode === 'model' ? options.model.pricing : undefined\n return {\n document,\n questions,\n notes,\n summaries,\n facts: deterministic.facts,\n conformance: deterministic.validation.findings,\n ingest,\n rejected,\n model: {\n used: options.mode === 'model',\n model: options.mode === 'model' ? options.model.model : null,\n runs,\n promptSha256,\n usage: totalUsage(runs, pricing),\n },\n engine: { name: 'agent-eval/diagnosis', version: packageVersion() },\n }\n}\n\n/** Runs with more errors first, then larger runs; runs under MIN_MODEL_SPANS are left out. */\nfunction rankTraces(traces: ReadonlyMap<string, import('./spans').DiagnosisSpan[]>) {\n return [...traces.entries()]\n .filter(([, spans]) => spans.length >= MIN_MODEL_SPANS)\n .map(([traceId, spans]) => ({\n traceId,\n spans,\n errors: spans.filter((span) => span.status === 'ERROR').length,\n }))\n .sort(\n (a, b) =>\n b.errors - a.errors ||\n b.spans.length - a.spans.length ||\n a.traceId.localeCompare(b.traceId),\n )\n}\n\nfunction resolveEvidence(\n findings: DiagnosisFinding[],\n spanIds: ReadonlySet<string>,\n ambiguous: ReadonlySet<string>,\n rejected: ModelRejection[],\n): DiagnosisFinding[] {\n const kept: DiagnosisFinding[] = []\n for (const finding of findings) {\n const evidence = finding.evidence.filter((id) => spanIds.has(id) && !ambiguous.has(id))\n if (evidence.length === 0) {\n rejected.push({\n reason: `finding ${finding.id} lost all evidence: its span ids are missing or shared by several runs`,\n })\n continue\n }\n kept.push({ ...finding, evidence })\n }\n return kept\n}\n\n/**\n * Token and cost totals over the model exchanges. No exchange attempted is a\n * measured zero. An exchange that failed without reporting usage may still\n * have been billed, so it makes the totals unknown (null) rather than zero.\n */\nfunction totalUsage(\n runs: readonly ModelRunRecord[],\n pricing: DiagnosisModelOptions['pricing'],\n): DiagnosisUsage {\n let inputTokens: number | null = 0\n let outputTokens: number | null = 0\n let exchanges = 0\n for (const run of runs) {\n exchanges += 1\n inputTokens =\n inputTokens === null || run.usage.inputTokens === null\n ? null\n : inputTokens + run.usage.inputTokens\n outputTokens =\n outputTokens === null || run.usage.outputTokens === null\n ? null\n : outputTokens + run.usage.outputTokens\n }\n const usd =\n exchanges === 0\n ? 0\n : pricing && inputTokens !== null && outputTokens !== null\n ? (inputTokens * pricing.inputUsdPerMillion + outputTokens * pricing.outputUsdPerMillion) /\n 1_000_000\n : null\n return { exchanges, inputTokens, outputTokens, usd }\n}\n"],"mappings":";;;;;;;;AAgCA,MAAM,UAAU,OAAe,aAAa,GAAG;AAC/C,MAAM,SAAS,aAAqB,OAAO,EAAE;;;;;;AAO7C,MAAa,4BACX;AAEF,MAAa,yBAAgD;CAC3D;EACE,IAAI;EACJ,SACE;EACF,SAAS,MAAM,WAAW;CAC5B;CACA;EACE,IAAI;EACJ,SAAS;EACT,UAAU,QAAQ,QAAQ,WAAW,GAAG,SAAS,OAAO,mBAAmB,IAAI;CACjF;CACA;EACE,IAAI;EACJ,SACE;EACF,UAAU,QAAQ,QAAQ,WAAW,GAAG,SAAS,OAAO,aAAa,IAAI;CAC3E;CACA;EAGE,IAAI;EACJ,SACE;EACF,UAAU,QAAQ,WAAW,GAAG,SAAS,OAAO,mBAAmB;CACrE;CACA;EAAE,IAAI;EAAiB,SAAS;EAAgC,SAAS,MAAM,eAAe;CAAE;CAChG;EAAE,IAAI;EAAc,SAAS;EAA4B,SAAS,MAAM,YAAY;CAAE;CACtF;EACE,IAAI;EACJ,SAAS;EACT,SAAS,MAAM,cAAc;CAC/B;CACA;EACE,IAAI;EACJ,SAAS;EACT,SAAS,MAAM,aAAa;CAC9B;CACA;EACE,IAAI;EACJ,SAAS;EACT,SAAS,MAAM,gBAAgB;CACjC;CACA;EAAE,IAAI;EAAkB,SAAS;EAA4B,SAAS,MAAM,gBAAgB;CAAE;CAC9F;EACE,IAAI;EACJ,SAAS;EACT,SAAS,MAAM,KAAK;CACtB;CACA;EACE,IAAI;EACJ,SAAS;EACT,UAAU,QAAQ,SAAS,GAAG,KAAK,GAAG,OAAO,QAAQ;CACvD;CACA;EACE,IAAI;EACJ,SAAS;EACT,UAAU,QAAQ,WAAW,GAAG,SAAS,OAAO,iBAAiB,EAAE;CACrE;AACF;;AAGA,SAAgB,cACd,OACA,SAA6B,wBAAwB,GACrD,QAA+B,wBACvB;CACR,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,OAAO;EACX,KAAK,QAAQ,YAAY;EACzB,SAAS,OAAO,QAAQ,KAAK,UAAU,OAAe,GAAG,SAAoB;GAC3E,QAAQ;GAGR,MAAM,WAAW,KACd,MAAM,GAAG,YAAY,KAAK,OAAO,CAAC,CAAC,CACnC,KAAK,UAAW,OAAO,UAAU,WAAW,QAAQ,EAAG;GAC1D,OAAO,KAAK,QAAQ,OAAO,GAAG,QAAQ;EACxC,CAAC;EACD,IAAI,OAAO,GAAG;GACZ,OAAO,kBAAkB;GACzB,OAAO,OAAO,KAAK,OAAO,OAAO,OAAO,KAAK,OAAO,KAAK;EAC3D;CACF;CACA,OAAO;AACT;;AAGA,SAAgB,YACd,OACA,QAA+B,wBACtB;CACT,OAAO,MAAM,MAAM,SAAS;EAC1B,KAAK,QAAQ,YAAY;EACzB,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK;EACrC,KAAK,QAAQ,YAAY;EACzB,OAAO;CACT,CAAC;AACH;;AAGA,SAAgB,kBAAkB,OAAgB,QAAqC;CACrF,IAAI,OAAO,UAAU,UAAU,OAAO,cAAc,OAAO,MAAM;CACjE,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,SAAS,kBAAkB,MAAM,MAAM,CAAC;CACpF,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,MAAM,OAAgC,CAAC;EACvC,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAgC,GACvE,KAAK,OAAO,kBAAkB,MAAM,MAAM;EAE5C,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,0BAA8C;CAC5D,OAAO;EAAE,gBAAgB;EAAG,QAAQ,CAAC;CAAE;AACzC;AAEA,MAAM,8BAAc,IAAI,QAAwB;AAEhD,SAAS,YAAY,SAAyB;CAC5C,MAAM,SAAS,YAAY,IAAI,OAAO;CACtC,IAAI,WAAW,KAAA,GAAW,OAAO;CAGjC,MAAM,SAAS,IAAI,OAAO,GAAG,QAAQ,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,KAAK;CACzE,YAAY,IAAI,SAAS,KAAK;CAC9B,OAAO;AACT;;;;;;;;;;;;;;;;;;;AC1GA,MAAM,oBACJ;AAEF,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,mBAAmB,KAAsB;CACvD,OAAO,kBAAkB,KAAK,GAAG;AACnC;;;;;;;AAQA,SAAgB,YACd,KACA,SACkD;CAClD,MAAM,UAA8B;EAAE,gBAAgB;EAAG,QAAQ,CAAC;CAAE;CACpE,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,QAAyB,CAAC;CAChC,IAAI,aAAa;CACjB,IAAI,iBAAiB;CACrB,MAAM,8BAAc,IAAI,IAAoB;CAC5C,MAAM,4BAAY,IAAI,IAAY;CAClC,MAAM,YAAY,YAAY,EAAE;CAChC,KAAK,MAAM,QAAQ,KAAK;EACtB,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GAAG;GACpE,cAAc;GACd;EACF;EACA,MAAM,SAAS;EACf,MAAM,UAAU,QAAQ,QAAQ,YAAY,SAAS;EACrD,MAAM,SAAS,QAAQ,QAAQ,WAAW,QAAQ;EAClD,IAAI,CAAC,WAAW,CAAC,QAAQ;GACvB,cAAc;GACd;EACF;EACA,MAAM,MAAM,GAAG,QAAQ,QAAQ;EAC/B,IAAI,KAAK,IAAI,GAAG,GAAG;GACjB,kBAAkB;GAClB;EACF;EACA,KAAK,IAAI,GAAG;EACZ,MAAM,aAAa,YAAY,IAAI,MAAM;EACzC,IAAI,eAAe,KAAA,GAAW,YAAY,IAAI,QAAQ,OAAO;OACxD,IAAI,eAAe,SAAS,UAAU,IAAI,MAAM;EACrD,MAAM,SAAS,iBAAiB,MAAM;EACtC,MAAM,cAAc,YAAY,QAAQ,SAAS;EACjD,MAAM,aAAa,kBAAkB,QAAQ,OAAO;EACpD,IAAI,CAAC,QAAQ,iBACN;QAAA,MAAM,OAAO,OAAO,KAAK,UAAU,GACtC,IAAI,mBAAmB,GAAG,GAAG;IAC3B,OAAO,WAAW;IAClB,QAAQ,IAAI,GAAG;GACjB;;EAGJ,MAAM,SAAS,WAAW,MAAM;EAChC,MAAM,gBAAgB,OAAO,YAAY,OAAO,OAAO,cAAc,OAAO,SAAS,OAAO;EAC5F,MAAM,WAAW,YAAY,YAAY,mBAAmB;EAC5D,MAAM,QAAQ,YAAY,YAAY,eAAe;EACrD,MAAM,OAAO,cAAc,SAAS,OAAO,MAAM,SAAS,GAAG,OAAO;EACpE,MAAM,KAAK;GACT;GACA;GACA,cAAc,QAAQ,QAAQ,kBAAkB,cAAc,KAAK;GACnE;GACA,MAAM,YAAY,OAAO,MAAM,MAAM,UAAU;GAC/C,SAAS,YAAY,OAAO,cAAc,OAAO,aAAa,OAAO,iBAAiB;GACtF,OAAO,YAAY,OAAO,YAAY,OAAO,WAAW,OAAO,eAAe;GAC9E,QAAQ,OAAO;GACf,eAAe,QAAQ,kBAAkB,gBAAgB,SAAS,eAAe,GAAG;GACpF;GACA;GACA;GACA;EACF,CAAC;CACH;CACA,OAAO;EACL;EACA,QAAQ;GACN,UAAU,IAAI;GACd,UAAU,MAAM;GAChB;GACA;GACA,kBAAkB,CAAC,GAAG,SAAS,CAAC,CAAC,KAAK;GACtC;GACA,mBAAmB,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK;EACvC;CACF;AACF;;AAGA,SAAgB,eAAe,MAAmC;CAChE,OAAO;EACL,UAAU,KAAK;EACf,SAAS,KAAK;EACd,gBAAgB,KAAK;EACrB,MAAM,KAAK;EACX,GAAI,KAAK,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;EACrD,YAAY,WAAW,KAAK,OAAO;EACnC,UAAU,WAAW,KAAK,KAAK;EAC/B,QAAQ;GACN,MACE,KAAK,WAAW,UACZ,sBACA,KAAK,WAAW,OACd,mBACA;GACR,GAAI,KAAK,gBAAgB,EAAE,SAAS,KAAK,cAAc,IAAI,CAAC;EAC9D;EACA,YAAY,KAAK;CACnB;AACF;AAEA,SAAgB,WAAW,MAAoC;CAC7D,OAAO,KAAK,YAAY,QAAQ,KAAK,UAAU,OAC3C,KAAK,IAAI,GAAG,KAAK,QAAQ,KAAK,OAAO,IACrC;AACN;;;;;;AAOA,SAAgB,YAAY,OAA+B;CACzD,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,SAAS,KAAK,IAAI,WAAW,OAAO,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI;CACxF,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG,OAAO;CAC5D,IAAI,QAAQ,KAAK,KAAK,GAAG;EACvB,IAAI,MAAM,UAAU,IAAI,OAAO,OAAO,OAAO,KAAK,IAAI,QAAU;EAChE,OAAO,WAAW,OAAO,KAAK,GAAG,MAAM,MAAM;CAC/C;CACA,MAAM,SAAS,KAAK,MAAM,KAAK;CAC/B,OAAO,OAAO,MAAM,MAAM,IAAI,OAAO;AACvC;AAEA,SAAS,WAAW,OAAe,QAAwB;CACzD,IAAI,UAAU,IAAI,OAAO,KAAK,MAAM,QAAQ,GAAS;CACrD,IAAI,UAAU,IAAI,OAAO,KAAK,MAAM,QAAQ,GAAK;CACjD,IAAI,UAAU,IAAI,OAAO;CACzB,OAAO,QAAQ;AACjB;AAEA,SAAS,WAAW,IAA2B;CAC7C,OAAO,OAAO,OAAO,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC,YAAY;AACrD;AAEA,SAAS,iBAAiB,QAA0D;CAClF,MAAM,MAA+B,CAAC;CACtC,MAAM,WAAW,OAAO;CACxB,IAAI,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,QAAQ,GAAG;EACxE,MAAM,QAAS,SAAqC;EACpD,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,OAAO,KAAK,KAAK;CAC3F;CACA,MAAM,QAAQ,OAAO;CACrB,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,OAAO,KAAK,KAAK;CACzF,IAAI,OAAO,OAAO,eAAe,YAAY,IAAI,uBAAuB,KAAA,GACtE,IAAI,qBAAqB,OAAO;CAElC,OAAO;AACT;AAEA,SAAS,WAAW,QAGlB;CACA,IAAI,OAAgB,OAAO;CAC3B,IAAI,UAAmB,OAAO;CAC9B,MAAM,SAAS,OAAO;CACtB,IAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;EAClE,MAAM,SAAS;EACf,OAAO,OAAO,QAAQ;EACtB,UAAU,OAAO,WAAW;CAC9B;CACA,MAAM,OAAO,OAAO,SAAS,WAAW,KAAK,YAAY,IAAI;CAO7D,OAAO;EACL,MANA,SAAS,KAAK,SAAS,uBAAuB,SAAS,WAAW,SAAS,MACvE,UACA,SAAS,KAAK,SAAS,oBAAoB,SAAS,QAAQ,SAAS,MACnE,OACA;EAGN,SAAS,OAAO,YAAY,YAAY,QAAQ,SAAS,IAAI,UAAU;CACzE;AACF;;;;;;;AAQA,SAAS,YAAY,MAAe,MAAc,YAA+C;CAC/F,MAAM,WACJ,OAAO,SAAS,YAAa,WAAiC,SAAS,KAAK,YAAY,CAAC,IACrF,KAAK,YAAY,IACjB,KAAA;CACN,OAAO,gBAAgB;EAAE,GAAI,WAAW,EAAE,MAAM,SAAS,IAAI,CAAC;EAAI;EAAM;CAAW,CAAC;AACtF;AAEA,SAAS,YAAY,YAAqC,KAA4B;CACpF,KAAK,MAAM,QAAQ,sBAAsB;EACvC,MAAM,QAAQ,WAAW;EACzB,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,IAAI;EAC3D,MAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;EACrE,OAAO,WAAW,UAAU,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;CACzE;CACA,OAAO;AACT;AAEA,SAAS,QACP,QACA,OACA,OACoB;CACpB,MAAM,QAAQ,OAAO,UAAU,OAAO;CACtC,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ,KAAA;AACjE;AAEA,SAAS,YAAY,YAAqC,MAAwC;CAChG,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,WAAW;EACzB,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAG,OAAO;CAC5D;CACA,OAAO;AACT;AAEA,SAAS,SAAS,OAAgB,UAA0B;CAC1D,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,SAAS,OAAsB,KAA4B;CAClE,IAAI,UAAU,QAAQ,MAAM,UAAU,KAAK,OAAO;CAClD,OAAO,GAAG,MAAM,MAAM,GAAG,GAAG,EAAE;AAChC;;ACtRA,MAAM,sBAA8C;CAClD,oBAAoB;CACpB,oBAAoB;CACpB,cAAc;CACd,oBAAoB;CACpB,mBAAmB;CACnB,kBAAkB;CAClB,oBAAoB;AACtB;;AAGA,MAAM,4BAAY,IAAI,IAAI;CACxB,CAAC,oBAAoB,6DAA6D;CAClF,CAAC,mBAAmB,6CAA6C;CACjE,CAAC,kBAAkB,+CAA+C;AACpE,CAAC;AAuBD,SAAgB,qBAAqB,OAAsD;CACzF,MAAM,aAAa,mBAAmB,MAAM,IAAI,cAAc,CAAC;CAC/D,MAAM,eAAoD,CAAC;CAC3D,MAAM,UAAsC,CAAC;CAC7C,KAAK,MAAM,cAAc,WAAW,cAAc;EAChD,aAAa,WAAW,QAAQ,WAAW,YACvC,EAAE,WAAW,KAAK,IAClB;GACE,WAAW;GACX,QAAQ,WAAW,UAAU;EAC/B;EACJ,MAAM,WAAW,oBAAoB,WAAW,SAAS,WAAW;EACpE,IAAI,CAAC,WAAW,WACd,QAAQ,KAAK;GAAE;GAAU,QAAQ,WAAW,UAAU;EAAyB,CAAC;OAC3E,IAAI,UAAU,IAAI,WAAW,IAAI,GACtC,QAAQ,KAAK;GAAE;GAAU,QAAQ,UAAU,IAAI,WAAW,IAAI;EAAG,CAAC;CAEtE;CAEA,MAAM,SAAS,aAAa,KAAK;CACjC,MAAM,WAA+B,CAAC;CACtC,MAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,SAAS,MAAM;CACzD,IAAI,MAAM,SAAS,GAAG;EACpB,SAAS,KAAK,GAAG,oBAAoB,KAAK,CAAC;EAE3C,IADmB,MAAM,QAAQ,SAAS,KAAK,gBAAgB,IAAI,CAAC,CAAC,SACpD,GAAG,SAAS,KAAK,GAAG,qBAAqB,MAAM,CAAC;OAE/D,QAAQ,KAAK;GACX,UAAU;GACV,QAAQ,WAAW,MAAM,OAAO;EAClC,CAAC;CACL,OACE,QAAQ,KAAK;EAAE,UAAU;EAAsB,QAAQ;CAAgC,CAAC;CAE1F,SAAS,KAAK,GAAG,kBAAkB,MAAM,CAAC;CAG1C,OAAO;EAAE;EAAY;EAAc;EAAS,OAD9B,eAAe,OAAO,OAAO,IACK;EAAG;EAAU,QAAQ,WAAW,KAAK;CAAE;AACzF;AAEA,SAAgB,aAAa,OAA+D;CAC1F,MAAM,yBAAS,IAAI,IAA6B;CAChD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,IAAI,KAAK,OAAO;EACpC,IAAI,MAAM,KAAK,KAAK,IAAI;OACnB,OAAO,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC;CACtC;CACA,KAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,KAAK,KAAK,OAAO;CACrD,OAAO;AACT;AAEA,SAAS,oBAAoB,OAAqD;CAChF,MAAM,yBAAS,IAAI,IAA6B;CAChD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,YAAY,KAAK;EACnC,MAAM,OAAO,OAAO,IAAI,IAAI;EAC5B,IAAI,MAAM,KAAK,KAAK,IAAI;OACnB,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC;CAC9B;CACA,MAAM,WAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,MAAM,UAAU,QAAQ;EAClC,MAAM,SAAS,MAAM,QAAQ,SAAS,KAAK,WAAW,OAAO;EAC7D,IAAI,MAAM,SAAA,KAA2B,OAAO,SAAS,GAAG;EACxD,MAAM,OAAO,OAAO,SAAS,MAAM;EACnC,MAAM,WACJ,QAAQ,MAAO,OAAO,UAAU,IAAI,SAAS,QAAQ,KAAM,WAAW;EACxE,SAAS,KAAK;GACZ,IAAI,SAAS,iBAAiB,IAAI;GAClC;GACA,OAAO,GAAG,OAAO,OAAO,MAAM,MAAM,OAAO,gBAAgB,KAAK;GAChE,aAAa,4EAA4E,IAAI,IAAI,EAAE;GACnG,SAAS;IACP,MAAM,GAAG,KAAK;IACd,OAAO,MAAM,OAAO,GAAG;IACvB,MAAM;IACN,aAAa,GAAG,MAAM,OAAO,YAAY;GAC3C;GACA,UAAU,OAAO,MAAM,GAAA,CAA2B,CAAC,CAAC,KAAK,SAAS,KAAK,MAAM;GAC7E,YAAY;GACZ,gBAAgB,mBAAmB,KAAK;EAC1C,CAAC;CACH;CACA,OAAO,SAAS,MAAM,GAAG,OAAO,EAAE,SAAS,SAAS,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE;AAC/F;AAEA,SAAS,qBAAqB,QAAkE;CAC9F,MAAM,OAA0B,CAAC;CACjC,IAAI,cAAc;CAClB,KAAK,MAAM,SAAS,OAAO,OAAO,GAAG;EACnC,IAAI,UAA2B,CAAC;EAChC,KAAK,MAAM,QAAQ,OAAO;GACxB,IAAI,KAAK,SAAS,UAAU,KAAK,gBAAgB,MAAM;GACvD,eAAe;GACf,MAAM,OAAO,QAAQ,QAAQ,SAAS;GACtC,IACE,QACA,KAAK,gBAAgB,KAAK,gBACzB,KAAK,YAAY,KAAK,WAAW,KAAK,YAAY,KAAK,OAExD,QAAQ,KAAK,IAAI;QACZ;IACL,IAAI,QAAQ,UAAA,GAA6B,KAAK,KAAK,OAAO;IAC1D,UAAU,CAAC,IAAI;GACjB;EACF;EACA,IAAI,QAAQ,UAAA,GAA6B,KAAK,KAAK,OAAO;CAC5D;CACA,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;CAC/B,MAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,MAAM,IAAI,SAAS,GAAG,CAAC;CAChE,MAAM,iBAAiB,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,EAAE,CAAE,OAAO,CAAC,CAAC,CAAC;CACnE,KAAK,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;CACvC,MAAM,WAAW,KACd,SAAS,QAAQ,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC,CAC5D,MAAM,GAAA,CAA2B;CACpC,MAAM,OAAO,SAAS;CACtB,OAAO,CACL;EACE,IAAI,SAAS,kBAAkB,OAAO,KAAK,MAAM,CAAC;EAClD,UAAU,QAAQ,KAAM,SAAS,QAAQ,MAAO,WAAW;EAC3D,OAAO,6GAAgI,KAAK,OAAO,gBAAgB,eAAe,gCAAgC,KAAK,EAAE,CAAE,OAAO;EAClO,aAAa,GAAG,OAAO;EACvB,SAAS;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,aAAa,GAAG,YAAY;EAC9B;EACA;EACA,YAAY;EACZ,gBACE;CACJ,CACF;AACF;AAEA,SAAS,kBAAkB,QAAkE;CAC3F,MAAM,cAA+B,CAAC;CACtC,KAAK,MAAM,SAAS,OAAO,OAAO,GAAG;EACnC,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC;EACpD,MAAM,OAAO,MAAM,MAAM,SAAS,KAAK,iBAAiB,QAAQ,CAAC,IAAI,IAAI,KAAK,YAAY,CAAC;EAC3F,IAAI,MAAM,WAAW,SAAS,YAAY,KAAK,IAAI;CACrD;CACA,IAAI,YAAY,WAAW,GAAG,OAAO,CAAC;CACtC,MAAM,OAAO,YAAY,SAAS,OAAO;CACzC,OAAO,CACL;EACE,IAAI,SAAS,eAAe,OAAO,OAAO,IAAI,CAAC;EAC/C,UAAU,QAAQ,MAAO,aAAa,QAAQ,KAAM,SAAS;EAC7D,OAAO,GAAG,YAAY,OAAO,MAAM,OAAO,KAAK;EAC/C,aACE;EACF,SAAS;GACP,MAAM;GACN,OAAO,MAAM,OAAO,GAAG;GACvB,MAAM;GACN,aAAa,GAAG,OAAO,KAAK;EAC9B;EACA,UAAU,YAAY,MAAM,GAAA,CAA2B,CAAC,CAAC,KAAK,SAAS,KAAK,MAAM;EAClF,YAAY;EACZ,gBACE;CACJ,CACF;AACF;AAEA,SAAS,eAAe,OAAiC,MAA8B;CACrF,MAAM,cAAsC,CAAC;CAC7C,MAAM,yBAAS,IAAI,IAAY;CAC/B,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,KAAK,MAAM,QAAQ,OAAO;EACxB,YAAY,KAAK,SAAS,YAAY,KAAK,SAAS,KAAK;EACzD,IAAI,KAAK,WAAW,SAAS,cAAc;EAC3C,IAAI,KAAK,SAAS,QAAQ,aAAa;EACvC,IAAI,KAAK,OAAO,OAAO,IAAI,KAAK,KAAK;CACvC;CACA,MAAM,QAAwB;EAC5B;EACA,OAAO,MAAM;EACb;EACA;EACA;EACA,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK;EACzB,WAAW;CACb;CACA,IAAI;EACF,MAAM,YAAY,mBAAmB,EACnC,MAAM,cAAc,EAAE,OAAO,MAAM,IAAI,gBAAgB,EAAE,CAAC,EAC5D,CAAC;CACH,SAAS,OAAO;EACd,MAAM,iBAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAC9E;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,MAAqC;CAC7D,MAAM,aAAwD,CAAC;CAC/D,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,UAAU,GACvD,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,WAAW,OAAO;MAC1E,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG,WAAW,OAAO;CAElF,IAAI,KAAK,SAAS,aAAa,WAAW,+BAA+B,KAAA,GACvE,WAAW,6BAA6B,KAAK;CAE/C,MAAM,QAAQ,KAAK,WAAW;CAC9B,MAAM,MAAM,KAAK,SAAS;CAC1B,OAAO;EACL,SAAS,KAAK;EACd,QAAQ,KAAK;EACb,GAAI,KAAK,eAAe,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;EAC/D,MAAM,KAAK;EACX,mBAAmB,GAAG,OAAO,KAAK,MAAM,KAAK,CAAC,IAAI;EAClD,iBAAiB,GAAG,OAAO,KAAK,MAAM,GAAG,CAAC,IAAI;EAC9C;EACA,QAAQ;GAAE,MAAM,KAAK;GAAQ,GAAI,KAAK,gBAAgB,EAAE,SAAS,KAAK,cAAc,IAAI,CAAC;EAAG;CAC9F;AACF;AAEA,SAAS,WAAW,OAAyC;CAC3D,IAAI,QAAQ,OAAO;CACnB,IAAI,OAAO,OAAO;CAClB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,KAAK,YAAY,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,OAAO;EAC/D,MAAM,MAAM,KAAK,SAAS,KAAK;EAC/B,IAAI,QAAQ,MAAM,OAAO,KAAK,IAAI,MAAM,GAAG;CAC7C;CACA,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;CAC9D,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,YAAY,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,YAAY;AACxE;AAEA,SAAS,QAAQ,GAAkB,GAA0B;CAC3D,QAAQ,EAAE,WAAW,MAAM,EAAE,WAAW,OAAO,WAAW,CAAC,KAAK,MAAM,WAAW,CAAC,KAAK;AACzF;AAEA,SAAgB,SAAS,QAAgB,GAAG,OAAyB;CACnE,OAAO,GAAG,OAAO,GAAG,WAAW,QAAQ,CAAC,CAAC,OAAO,MAAM,KAAK,IAAQ,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;AACjG;AAEA,SAAS,IAAI,MAAsB;CACjC,OAAO,GAAG,MAAM,OAAO,GAAG,EAAE;AAC9B;AAEA,SAAS,MAAM,OAAuB;CACpC,OAAO,KAAK,MAAM,QAAQ,EAAE,IAAI;AAClC;;;;;;;;;;;ACrTA,MAAa,+BACX;AA4DF,MAAMA,+BAAa,IAAI,IAAI;CAAC;CAAY;CAAQ;CAAU;AAAK,CAAC;AAChE,MAAa,gBAAmD;CAC9D,UAAU;CACV,MAAM;CACN,QAAQ;CACR,KAAK;AACP;;;;;;;AAQA,SAAgB,0BACd,UACA,UAA6C,CAAC,GACpC;CACV,MAAM,SAAmB,CAAC;CAC1B,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO,CAAC,2BAA2B;CAC5D,OAAO,UAAU;EAAC;EAAiB;EAAW;EAAY;CAAU,GAAG,IAAI,MAAM;CACjF,IAAI,SAAS,kBAAkB,GAAG,OAAO,KAAK,yBAAyB;CAEvE,MAAM,UAAU,SAAS;CACzB,IAAI,CAAC,SAAS,OAAO,GAAG,OAAO,KAAK,2BAA2B;MAC1D;EACH,OAAO,SAAS;GAAC;GAAS;GAAY;GAAU;EAAiB,GAAG,WAAW,MAAM;EACrF,IAAI,OAAO,QAAQ,UAAU,UAAU,OAAO,KAAK,gCAAgC;EACnF,IAAI,CAAC,OAAO,UAAU,QAAQ,QAAQ,KAAM,QAAQ,WAAsB,GACxE,OAAO,KAAK,iDAAiD;EAC/D,IAAI,OAAO,QAAQ,WAAW,UAAU,OAAO,KAAK,iCAAiC;EACrF,IAAI,QAAQ,oBAAoB,KAAA,KAAa,OAAO,QAAQ,oBAAoB,WAC9E,OAAO,KAAK,2CAA2C;CAC3D;CAEA,MAAM,WAAW,SAAS;CAC1B,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO,KAAK,4BAA4B;MAC5D;EACH,OAAO,UAAU;GAAC;GAAgB;GAAW;EAAW,GAAG,YAAY,MAAM;EAC7E,IAAI,CAAC,SAAS,SAAS,YAAY,GAAG,OAAO,KAAK,yCAAyC;OAEzF,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,SAAS,YAAY,GACnE,IAAI,CAAC,SAAS,UAAU,KAAK,OAAO,WAAW,cAAc,WAC3D,OAAO,KAAK,yBAAyB,KAAK,6BAA6B;OAClE,IACL,CAAC,WAAW,aACZ,EAAE,OAAO,WAAW,WAAW,YAAY,WAAW,SAEtD,OAAO,KAAK,yBAAyB,KAAK,iCAAiC;EAIjF,IAAI,CAAC,MAAM,QAAQ,SAAS,OAAO,GAAG,OAAO,KAAK,mCAAmC;OAEnF,SAAS,QAAQ,SAAS,OAAO,UAAU;GACzC,IACE,CAAC,SAAS,KAAK,KACf,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,WAAW,UAExB,OAAO,KAAK,oBAAoB,MAAM,oCAAoC;EAC9E,CAAC;EACH,IAAI,SAAS,cAAc,KAAA,GAAW;GACpC,MAAM,YAAY,SAAS;GAC3B,IAAI,CAAC,SAAS,SAAS,GAAG,OAAO,KAAK,sCAAsC;QACvE;IACH,IAAI,CAAC,OAAO,UAAU,UAAU,cAAc,KAAM,UAAU,iBAA4B,GACxF,OAAO,KAAK,kEAAkE;IAChF,IAAI,UAAU,WAAW,KAAA,KAAa,CAAC,SAAS,UAAU,MAAM,GAC9D,OAAO,KAAK,6CAA6C;IAC3D,IACE,UAAU,sBAAsB,KAAA,KAChC,CAAC,MAAM,QAAQ,UAAU,iBAAiB,GAE1C,OAAO,KAAK,uDAAuD;GACvE;EACF;CACF;CAEA,IAAI,CAAC,MAAM,QAAQ,SAAS,QAAQ,GAAG,OAAO,KAAK,2BAA2B;MAE5E,SAAS,SAAS,SAAS,SAAS,UAAU;EAC5C,MAAM,KAAK,YAAY,MAAM;EAC7B,IAAI,CAAC,SAAS,OAAO,GAAG;GACtB,OAAO,KAAK,GAAG,GAAG,mBAAmB;GACrC;EACF;EACA,OACE,SACA;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,IACA,MACF;EACA,KAAK,MAAM,OAAO;GAAC;GAAM;GAAS;EAAa,GAC7C,IAAI,OAAO,QAAQ,SAAS,YAAY,CAAE,QAAQ,MAChD,OAAO,KAAK,GAAG,GAAG,GAAG,IAAI,4BAA4B;EAEzD,IAAI,CAACA,aAAW,IAAI,QAAQ,QAAkB,GAAG,OAAO,KAAK,GAAG,GAAG,qBAAqB;EACxF,IAAI,QAAQ,eAAe,cAAc,QAAQ,eAAe,YAC9D,OAAO,KAAK,GAAG,GAAG,yCAAyC;EAC7D,IAAI,CAAC,MAAM,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,SAAS,WAAW,GAClE,OAAO,KAAK,GAAG,GAAG,oCAAoC;OAEtD,KAAK,MAAM,MAAM,QAAQ,UACvB,IAAI,OAAO,OAAO,UAAU,OAAO,KAAK,GAAG,GAAG,6BAA6B;OACtE,IAAI,QAAQ,WAAW,CAAC,QAAQ,QAAQ,IAAI,EAAE,GACjD,OAAO,KAAK,GAAG,GAAG,YAAY,GAAG,kBAAkB;EAEzD,IAAI,QAAQ,YAAY,KAAA,GAAW;GACjC,MAAM,UAAU,QAAQ;GACxB,IACE,CAAC,SAAS,OAAO,KACjB,OAAO,QAAQ,SAAS,YACxB,OAAO,QAAQ,UAAU,YACzB,CAAC,OAAO,SAAS,QAAQ,KAAK,KAC9B,OAAO,QAAQ,SAAS,UAExB,OAAO,KAAK,GAAG,GAAG,2CAA2C;QACxD,IAAI,EAAE,OAAO,QAAQ,gBAAgB,YAAY,QAAQ,cAC9D,OAAO,KAAK,GAAG,GAAG,4BAA4B;EAElD;EACA,KAAK,MAAM,OAAO,CAAC,aAAa,gBAAgB,GAC9C,IAAI,QAAQ,SAAS,KAAA,KAAa,OAAO,QAAQ,SAAS,UACxD,OAAO,KAAK,GAAG,GAAG,GAAG,IAAI,kBAAkB;CAEjD,CAAC;CACH,OAAO;AACT;AAEA,SAAS,OACP,OACA,SACA,IACA,QACM;CACN,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GACjC,IAAI,CAAC,QAAQ,SAAS,GAAG,GAAG,OAAO,KAAK,GAAG,KAAK,GAAG,GAAG,KAAK,KAAK,IAAI,gBAAgB;AAExF;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ACxHA,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAM,6BAAa,IAAI,IAAI;CAAC;CAAY;CAAQ;CAAU;AAAK,CAAC;AAEhE,SAAgB,cAAc,OAA+B;CAC3D,MAAM,QAAQ,MAAM,QAAQ,0BAA0B,MAAM,UAAU;CACtE,MAAM,WACJ,MAAM,YAAY,MAAM,SAAS,SAAS,IACtC,uCAAuC,MAAM,SAAS,KAAK,IAAI,EAAE,4FACjE;CACN,MAAM,WAAW,MAAM,kBACnB,KACA;CACJ,OAAO,MAAM,YAAY,aACrB,+LAA+L,WAAW,WAAW,UACrN,uJAAuJ,WAAW,WAAW;AACnL;AAEA,SAAgB,mBAAmB,SAA4C;CAG7E,OAAO;EACL;EACA;EACA,iCAAiC,SAAS,8BAJ1C,YAAY,aAAa,8CAAwC,6BAIa;EAC9E;EACA;EACA,GAAI,YAAY,aACZ,CACE,8KACF,IACA,CAAC;EACL;EACA;EACA;CACF;AACF;AAEA,eAAsB,aACpB,QACA,kBACA,OACA,SACA,QAC0B;CAC1B,MAAM,WAAW,cAAc,KAAK;CACpC,MAAM,gBAAgB,mBAAmB,MAAM,OAAO;CAOtD,MAAM,SAA0B;EAC9B,UAAU,CAAC;EACX,WAAW,CAAC;EACZ,OAAO,CAAC;EACR,WAAW,CAAC;EACZ,UAAU,CAAC;EACX,WAAW,CAAC;EACZ,MAAM,CAAC;EACP,cAdmB,oBAAoB;GACvC;GACA;GACA,qBAAqB;GACrB,QAAQ;IAAE,SAAS;IAAU,WAAW;GAAW;EACrD,CASa;CACb;CACA,MAAM,iBAAiB,QAAQ,kBAAkB;CACjD,MAAM,iBAAiB,QAAQ,kBAAkB;CAEjD,MAAM,cAAc,QAAQ,qBAAqB;CACjD,KAAK,MAAM,EAAE,SAAS,WAAW,QAAQ;EACvC,MAAM,WAAW,WAAW,OAAO,gBAAgB,MAAM,iBAAiB,cAAc;EACxF,MAAM,SAAS,SACZ,KAAK,SAAS,WAAW;GAAE,GAAG;GAAS;EAAM,EAAE,CAAC,CAChD,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,CACxD,MAAM,GAAG,WAAW,CAAC,CACrB,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;EACnC,IAAI,SAAS,SAAS,OAAO,QAC3B,OAAO,UAAU,KAAK;GACpB;GACA,QAAQ,sBAAsB,SAAS,OAAO,uBAAuB,eAAe,kCAAkC,OAAO,OAAO,yBAAyB,OAAO,KAAK,YAAY,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;EACrN,CAAC;EAEH,KAAK,MAAM,WAAW,QAAQ;GAC5B,MAAM,QACJ,SAAS,SAAS,IAAI,GAAG,QAAQ,WAAW,QAAQ,QAAQ,EAAE,GAAG,SAAS,WAAW;GACvF,MAAM,MAAM,IAAI,IAAI,QAAQ,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC;GAC5D,MAAM,UAAU,MAAM,iBAAiB;IACrC,UAAU;KACR,WAAW;KACX;KACA,qBAAqB;KACrB,SAAS;KACT,YAAY,QAAQ,UAAU,KAAK,MAAM,OAAO;IAClD;IACA,QAAQ,iBAAiB;KACvB;KACA;KACA,kBAAkB,mBAAmB,MAAM,IAAI,QAAQ,MAAM,OAAO,gBAAgB,MAAM,OAAO;KACjG,oBAAoB,QAAQ;IAC9B,CAAC;IACD,WAAW,QAAQ;IACnB,KAAK,QAAQ;IACb,OAAO,QAAQ;IACf,WAAW,QAAQ,aAAa;IAChC,QAAQ;IACR,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;GAC7B,CAAC;GACD,MAAM,WAAW;IACf,SAAS,QAAQ,QAAQ;IACzB,UAAU,SAAS;IACnB,eAAe,QAAQ,SAAS;GAClC;GACA,IAAI,CAAC,QAAQ,IAAI;IACf,OAAO,KAAK,KAAK;KACf;KACA,IAAI;KACJ,SAAS,GAAG,MAAM,IAAI,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ;KAC/D;KACA,OAAO,QAAQ;KACf,MAAM;IACR,CAAC;IACD;GACF;GACA,KAAK,MAAM,aAAa,QAAQ,UAC9B,OAAO,SAAS,KAAK;IAAE;IAAS,QAAQ,OAAO,UAAU,MAAM,IAAI,UAAU;GAAS,CAAC;GAEzF,IAAI,QAAQ,WAAW,GACrB,OAAO,SAAS,KAAK;IACnB;IACA,QAAQ,GAAG,QAAQ,SAAS,yBAAyB,SAAS;GAChE,CAAC;GAEH,IAAI,QAAQ,QACV,OAAO,UAAU,KAAK;IAAE;IAAS,QAAQ,QAAQ,OAAO,MAAM,GAAG,UAAU;GAAE,CAAC;GAChF,WAAW,QAAQ,QAAQ,MAAM,SAAS,KAAK,gBAAgB;GAC/D,OAAO,KAAK,KAAK;IACf;IACA,IAAI;IACJ;IACA,OAAO,QAAQ;IACf,MAAM,QAAQ,KAAK;GACrB,CAAC;EACH;CACF;CACA,OAAO;AACT;;AAGA,eAAsB,gBACpB,UACA,QACA,SACA,QAMC;CACD,MAAM,gBAAgB;EACpB;EACA;EACA,qBAAqB,SAAS;EAC9B;CACF;CACA,MAAM,WAAW,KAAK,UAAU,QAAQ;CACxC,MAAM,UAAU,MAAM,iBAAiB;EACrC,UAAU;GACR,WAAW;GACX;GACA,qBAAqB;GACrB,SAAS;GACT,YAAY,QAAQ,UAAU,KAAK,UAAU;EAC/C;EACA,QAAQ,iBAAiB;GACvB,UACE;GACF;GACA,kBAAkB,cAAc,OAAO,KAAK;GAC5C,oBACE,SAAS,UAAU,QAAQ,kBAAkB,OACzC,SAAS,MAAM,GAAG,QAAQ,kBAAkB,GAAO,IACnD;EACR,CAAC;EACD,WAAW,QAAQ;EACnB,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,WAAW,QAAQ,aAAa;EAChC,QAAQ;EACR,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;CAC7B,CAAC;CACD,MAAM,QAAwB,CAAC;CAC/B,MAAM,YAA6B,CAAC;CACpC,MAAM,WAA6B,CAAC;CACpC,IAAI,QAAQ,MAAM,QAAQ,WAAW,GACnC,SAAS,KAAK,EACZ,QAAQ,GAAG,QAAQ,SAAS,kCAAkC,SAAS,uBACzE,CAAC;CAEH,IAAI,CAAC,QAAQ,IACX,OAAO;EACL;EACA;EACA;EACA,KAAK;GACH,SAAS;GACT,IAAI;GACJ,SAAS,GAAG,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ;GACrD,OAAO,QAAQ;GACf,MAAM;EACR;CACF;CAEF,KAAK,MAAM,OAAO,QAAQ,MAAM;EAC9B,IAAI,IAAI,SAAS,YAAY;GAC3B,UAAU,KAAK;IAAE,UAAU,IAAI;IAAW,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;GAAG,CAAC;GAC5F;EACF;EACA,MAAM,QAAQ,IAAI,SAAS,QAAQ,OAAO,OAAO,IAAI,EAAE,CAAC;EACxD,IAAI,MAAM,WAAW,GAAG;GACtB,SAAS,KAAK,EACZ,QAAQ,kBAAkB,IAAI,SAAS,GAAA,CAAI,MAAM,GAAG,EAAE,EAAE,kCAC1D,CAAC;GACD;EACF;EACA,MAAM,KAAK;GACT,MAAM;GACN,MAAM,IAAI;GACV,UAAU;GACV,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;EAChD,CAAC;CACH;CACA,IAAI,QAAQ,QACV,MAAM,QAAQ;EAAE,MAAM;EAAY,MAAM,QAAQ,OAAO,MAAM,GAAG,UAAU;EAAG,UAAU,CAAC;CAAE,CAAC;CAC7F,OAAO;EACL;EACA;EACA;EACA,KAAK;GAAE,SAAS;GAAY,IAAI;GAAM,OAAO,QAAQ;GAAO,MAAM,QAAQ,KAAK;EAAO;CACxF;AACF;AAEA,SAAS,WACP,QACA,MACA,SACA,KACA,kBACM;CACN,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,aAAa,IAAI,SAAS,QAAQ,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;EAC3D,MAAM,YAAY,IAAI,SAAS,QAAQ,OAAO,iBAAiB,IAAI,EAAE,CAAC;EACtE,MAAM,QAAQ,IAAI,SAAS,QAAQ,OAAO,IAAI,IAAI,EAAE,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC;EAClF,IAAI,WAAW,SAAS,GACtB,OAAO,SAAS,KAAK;GACnB;GACA,QAAQ,GAAG,IAAI,KAAK,6CAA6C,WAAW,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;EACnG,CAAC;EACH,IAAI,UAAU,SAAS,GACrB,OAAO,SAAS,KAAK;GACnB;GACA,QAAQ,GAAG,IAAI,KAAK,yCAAyC,UAAU,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;EAC9F,CAAC;EACH,IAAI,IAAI,SAAS,YAAY;GAC3B,OAAO,UAAU,KAAK;IACpB,UAAU,IAAI;IACd;IACA,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;GAChD,CAAC;GACD;EACF;EAGA,IAAI,WAAW,SAAS,KAAK,UAAU,SAAS,GAAG;GACjD,OAAO,SAAS,KAAK;IACnB;IACA,QAAQ,GAAG,IAAI,KAAK,SAAS,IAAI,SAAS,GAAA,CAAI,MAAM,GAAG,EAAE,EAAE;GAC7D,CAAC;GACD;EACF;EACA,IAAI,MAAM,WAAW,GAAG;GACtB,OAAO,SAAS,KAAK;IACnB;IACA,QAAQ,GAAG,IAAI,KAAK,SAAS,IAAI,SAAS,GAAA,CAAI,MAAM,GAAG,EAAE,EAAE;GAC7D,CAAC;GACD;EACF;EACA,IAAI,IAAI,SAAS,YAAY;GAC3B,OAAO,MAAM,KAAK;IAChB,MAAM;IACN,MAAM,IAAI;IACV,UAAU;IACV;IACA,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;GAChD,CAAC;GACD;EACF;EACA,OAAO,SAAS,KAAK;GACnB,IAAI,SAAS,YAAY,SAAS,IAAI,KAAM;GAC5C,UAAU,IAAI;GACd,OAAO,IAAI;GACX,aAAa,IAAI;GACjB,UAAU;GACV,YAAY;GACZ,GAAI,IAAI,iBAAiB,EAAE,gBAAgB,IAAI,eAAe,IAAI,CAAC;EACrE,CAAC;CACH;AACF;;;;;;;AAcA,SAAgB,WACd,OACA,gBACA,iBACA,gBACc;CACd,MAAM,WAAyB,CAAC;CAChC,IAAI,UAA2B,CAAC;CAChC,IAAI,QAAkB,CAAC;CACvB,IAAI,OAAO;CACX,IAAI,SAAS;CACb,MAAM,cAAc;EAClB,IAAI,QAAQ,WAAW,GAAG;EAC1B,SAAS,KAAK;GAAE,OAAO;GAAS,UAAU,IAAI,MAAM,KAAK,GAAG,EAAE;GAAI;EAAO,CAAC;EAC1E,UAAU,CAAC;EACX,QAAQ,CAAC;EACT,OAAO;EACP,SAAS;CACX;CACA,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,OAAO,KAAK,UAAU,WAAW,MAAM,gBAAgB,eAAe,CAAC;EAC3E,IAAI,KAAK,SAAS,IAAI,gBACpB,OAAO,KAAK,UAAU,WAAW,MAAM,KAAK,eAAe,CAAC;EAC9D,IAAI,OAAO,KAAK,SAAS,IAAI,gBAAgB,MAAM;EACnD,QAAQ,KAAK,IAAI;EACjB,MAAM,KAAK,IAAI;EACf,QAAQ,KAAK,SAAS;EACtB,IAAI,KAAK,WAAW,SAAS,UAAU;CACzC;CACA,MAAM;CACN,OAAO;AACT;AAEA,SAAS,UACP,KACA,MAC2D;CAC3D,IAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAC9D,OAAO;EAAE,IAAI;EAAO,QAAQ;CAAuB;CACrD,MAAM,QAAQ;CACd,MAAM,OAAO,MAAM;CAOnB,IAAI,OAAO,SAAS,YAAY,EAL9B,SAAS,aACL;EAAC;EAAW;EAAY;CAAU,IAClC,SAAS,aACP,CAAC,WAAW,UAAU,IACtB,CAAC,YAAY,UAAU,EAAA,CACU,SAAS,IAAI,GACpD,OAAO;EAAE,IAAI;EAAO,QAAQ,QAAQ,OAAO,IAAI,EAAE;CAAsB;CACzE,MAAM,WAAW,MAAM,QAAQ,MAAM,QAAQ,IACzC,MAAM,SACH,QAAQ,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC,CAAC,CACrE,MAAM,GAAG,CAAC,IACb,CAAC;CACL,MAAM,UAAU,YAAY,MAAM,OAAO;CACzC,IAAI,SAAS,YAAY;EACvB,MAAM,WAAW,YAAY,MAAM,QAAQ;EAC3C,IAAI,CAAC,UAAU,OAAO;GAAE,IAAI;GAAO,QAAQ;EAA+B;EAC1E,OAAO;GAAE,IAAI;GAAM,KAAK;IAAE;IAAM;IAAU;IAAU,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAAG;EAAE;CACxF;CACA,MAAM,QAAQ,YAAY,MAAM,KAAK;CACrC,IAAI,CAAC,OAAO,OAAO;EAAE,IAAI;EAAO,QAAQ,GAAG,KAAK;CAAmB;CACnE,IAAI,SAAS,WACX,OAAO;EACL,IAAI;EACJ,KAAK;GAAQ;GAAwB;GAAO;GAAU,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAAG;CACxF;CACF,MAAM,WAAW,MAAM;CACvB,IAAI,OAAO,aAAa,YAAY,CAAC,WAAW,IAAI,QAAQ,GAC1D,OAAO;EAAE,IAAI;EAAO,QAAQ,YAAY,OAAO,QAAQ,EAAE;CAAa;CACxE,MAAM,cAAc,YAAY,MAAM,WAAW;CACjD,IAAI,CAAC,aAAa,OAAO;EAAE,IAAI;EAAO,QAAQ;CAAiC;CAC/E,MAAM,iBAAiB,YAAY,MAAM,cAAc;CACvD,OAAO;EACL,IAAI;EACJ,KAAK;GACH,MAAM;GACI;GACV;GACA;GACA;GACA,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC3C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC/B;CACF;AACF;;AAGA,SAAS,WACP,MACA,gBACA,iBACyB;CACzB,MAAM,MAA+B;EACnC,IAAI,KAAK;EACT,QAAQ,KAAK;EACb,MAAM,KAAK;EACX,MAAM,KAAK;CACb;CACA,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK;CACnC,IAAI,KAAK,OAAO,IAAI,QAAQ,KAAK;CACjC,IAAI,KAAK,WAAW,SAAS,IAAI,SAAS,KAAK;CAC/C,IAAI,KAAK,eAAe,IAAI,iBAAiB,KAAK,KAAK,eAAe,cAAc;CACpF,MAAM,WAAW,WAAW,IAAI;CAChC,IAAI,aAAa,MAAM,IAAI,KAAK;CAChC,MAAM,QAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,UAAU,GAAG;EAC1D,IAAI,gBAAgB,IAAI,GAAG,GAAG;EAC9B,IAAI,OAAO,UAAU,UAAU,MAAM,OAAO,KAAK,OAAO,cAAc;OACjE,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,MAAM,OAAO;OAC1E,IAAI,UAAU,QAAQ,UAAU,KAAA,GACnC,MAAM,OAAO,KAAK,KAAK,UAAU,KAAK,GAAG,cAAc;CAC3D;CACA,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,QAAQ;CAC/C,IAAI,CAAC,iBAAiB,IAAI,UAAU;CACpC,OAAO;AACT;;AAGA,MAAM,kCAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,KAAK,OAAe,KAAqB;CAChD,OAAO,MAAM,UAAU,MAAM,QAAQ,GAAG,MAAM,MAAM,GAAG,GAAG,EAAE,KAAK,MAAM,SAAS,IAAI;AACtF;AAEA,SAAS,YAAY,OAAoC;CACvD,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;CACtC,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,CAAC,SAAS,OAAO,KAAA;CACrB,OAAO,QAAQ,UAAU,aAAa,UAAU,GAAG,QAAQ,MAAM,GAAG,UAAU,EAAE;AAClF;;;;;;;;;;;;;;;;;;;;;ACzdA,MAAa,2BAA2B;AAIxC,eAAsB,cACpB,OACA,SACA,SAC0B;CAC1B,IAAI,QAAQ,YAAY,cAAc,QAAQ,YAAY,YACxD,MAAM,IAAI,UACR,4DAA4D,OAAO,QAAQ,OAAO,GACpF;CAEF,IAAI,QAAQ,YAAY,cAAc,QAAQ,aAAa,KAAA,GACzD,MAAM,IAAI,UACR,0FACF;CAEF,MAAM,kBAAkB,QAAQ,oBAAoB;CACpD,MAAM,EAAE,OAAO,UAAU,QAAQ,WAAW,YAAY,OAAO,EAAE,gBAAgB,CAAC;CAClF,MAAM,QACJ,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAY,cAAc,QAAQ,OAAO,OAAO,OAAO;CACvF,MAAM,gBAAgB,qBAAqB,QAAQ;CACnD,MAAM,UAAU,CAAC,GAAG,cAAc,OAAO;CACzC,MAAM,YAAY,IAAI,IAAI,OAAO,gBAAgB;CACjD,MAAM,WAA6B,CAAC;CACpC,MAAM,YAA6B,CAAC;CACpC,MAAM,QAAwB,CAAC;CAC/B,MAAM,YAAwD,CAAC;CAC/D,MAAM,OAAyB,CAAC;CAChC,IAAI,eAA8B;CAClC,IAAI,gBAAoC,CAAC;CAEzC,MAAM,SAAS,aAAa,QAAQ;CACpC,IAAI,QAAQ,SAAS,iBACnB,QAAQ,KAAK;EACX,UAAU;EACV,QAAQ,QAAQ,UAAU;CAC5B,CAAC;MACI;EACL,MAAM,YAAY,QAAQ,MAAM,aAAA;EAChC,MAAM,SAAS,WAAW,MAAM;EAChC,MAAM,WAAW,OAAO,MAAM,GAAG,SAAS;EAC1C,MAAM,QAAQ,OAAO,OAAO,OAAO;EACnC,IAAI,OAAO,WAAW,GACpB,QAAQ,KAAK;GACX,UAAU;GACV,QAAQ,sDAAuE,OAAO,KAAK;EAC7F,CAAC;OACI,IAAI,QAAQ,GACjB,QAAQ,KAAK;GACX,UAAU,oBAAoB,MAAM,MAAM,OAAO,KAAK;GACtD,QAAQ;EACV,CAAC;EAEH,IAAI,OAAO,SAAS,SAAS,QAC3B,QAAQ,KAAK;GACX,UAAU,oBAAoB,OAAO,SAAS,SAAS,OAAO,MAAM,OAAO,OAAO;GAClF,QAAQ,2BAA2B,UAAU;EAC/C,CAAC;EAEH,MAAM,OAAO,MAAM,aACjB,UACA,WACA;GACE,SAAS,QAAQ;GACjB;GACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GACzB,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;EAC3D,GACA,QAAQ,OACR,QAAQ,MACV;EACA,eAAe,KAAK;EACpB,gBAAgB,KAAK;EACrB,UAAU,KAAK,GAAG,KAAK,SAAS;EAChC,MAAM,KAAK,GAAI,QAAQ,YAAY,aAAa,KAAK,QAAQ,CAAC,CAAE;EAChE,UAAU,KAAK,GAAG,KAAK,SAAS;EAChC,SAAS,KAAK,GAAG,KAAK,QAAQ;EAC9B,KAAK,KAAK,GAAG,KAAK,IAAI;EACtB,KAAK,MAAM,OAAO,KAAK,WACrB,QAAQ,KAAK;GAAE,UAAU,gCAAgC,IAAI;GAAW,QAAQ,IAAI;EAAO,CAAC;EAE9F,KAAK,MAAM,OAAO,KAAK,MACrB,IAAI,CAAC,IAAI,IACP,QAAQ,KAAK;GACX,UAAU,wBAAwB,IAAI;GACtC,QAAQ,IAAI,WAAW;EACzB,CAAC;EAEL,IAAI,QAAQ,YAAY,cAAc,QAAQ,UAAU;GACtD,MAAM,WAAW,kBAAkB,QAAQ,UAAU,OAAO,OAAO;GAQnE,MAAM,UAAU,MAAM,gBAAgB,UAAU,IAL7B,KAChB,SAAS,QAAQ,CAAC,EAAA,CAChB,KAAK,QAAQ,IAAI,EAAE,CAAC,CACpB,QAAQ,OAAqB,OAAO,OAAO,QAAQ,CAEH,GAAG,QAAQ,OAAO,QAAQ,MAAM;GACrF,MAAM,KAAK,GAAG,QAAQ,KAAK;GAC3B,UAAU,KAAK,GAAG,QAAQ,SAAS;GACnC,SAAS,KAAK,GAAG,QAAQ,QAAQ;GACjC,KAAK,KAAK,QAAQ,GAAG;GACrB,IAAI,CAAC,QAAQ,IAAI,IACf,QAAQ,KAAK;IAAE,UAAU;IAAoB,QAAQ,QAAQ,IAAI,WAAW;GAAS,CAAC;EAC1F;CACF;CAEA,MAAM,UAAU,IAAI,IAAI,SAAS,KAAK,SAAS,KAAK,MAAM,CAAC;CAC3D,MAAM,WAAW,gBACf,CAAC,GAAG,cAAc,UAAU,GAAG,aAAa,GAC5C,SACA,WACA,QACF,CAAC,CAAC,MACC,GAAG,MACF,cAAc,EAAE,YAAY,cAAc,EAAE,cAC3C,EAAE,eAAe,EAAE,aAAa,IAAI,EAAE,eAAe,aAAa,KAAK,EAC5E;CAEA,MAAM,WAAsC;EAC1C,eAAe;EACf,SAAS;GACP,OAAO,cAAc,QAAQ,OAAO,OAAO,OAAO;GAClD,UAAU,OAAO;GACjB,QAAQ,cAAc;GACtB;EACF;EACA,UAAU;GACR,cAAc,cAAc;GAC5B;GACA,WAAW;IACT,gBAAgB,OAAO,QAAQ;IAC/B,QAAQ,EAAE,GAAG,OAAO,QAAQ,OAAO;IACnC,mBAAmB,OAAO;GAC5B;EACF;EACA;CACF;CACA,MAAM,UAAU,0BAA0B,UAAU,EAAE,QAAQ,CAAC;CAC/D,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MACR,wDAAwD,QAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,GACvF;CAEF,MAAM,UAAU,QAAQ,SAAS,UAAU,QAAQ,MAAM,UAAU,KAAA;CACnE,OAAO;EACL;EACA;EACA;EACA;EACA,OAAO,cAAc;EACrB,aAAa,cAAc,WAAW;EACtC;EACA;EACA,OAAO;GACL,MAAM,QAAQ,SAAS;GACvB,OAAO,QAAQ,SAAS,UAAU,QAAQ,MAAM,QAAQ;GACxD;GACA;GACA,OAAO,WAAW,MAAM,OAAO;EACjC;EACA,QAAQ;GAAE,MAAM;GAAwB,SAAS,eAAe;EAAE;CACpE;AACF;;AAGA,SAAS,WAAW,QAAgE;CAClF,OAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CACzB,QAAQ,GAAG,WAAW,MAAM,UAAA,CAAyB,CAAC,CACtD,KAAK,CAAC,SAAS,YAAY;EAC1B;EACA;EACA,QAAQ,MAAM,QAAQ,SAAS,KAAK,WAAW,OAAO,CAAC,CAAC;CAC1D,EAAE,CAAC,CACF,MACE,GAAG,MACF,EAAE,SAAS,EAAE,UACb,EAAE,MAAM,SAAS,EAAE,MAAM,UACzB,EAAE,QAAQ,cAAc,EAAE,OAAO,CACrC;AACJ;AAEA,SAAS,gBACP,UACA,SACA,WACA,UACoB;CACpB,MAAM,OAA2B,CAAC;CAClC,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,WAAW,QAAQ,SAAS,QAAQ,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;EACtF,IAAI,SAAS,WAAW,GAAG;GACzB,SAAS,KAAK,EACZ,QAAQ,WAAW,QAAQ,GAAG,wEAChC,CAAC;GACD;EACF;EACA,KAAK,KAAK;GAAE,GAAG;GAAS;EAAS,CAAC;CACpC;CACA,OAAO;AACT;;;;;;AAOA,SAAS,WACP,MACA,SACgB;CAChB,IAAI,cAA6B;CACjC,IAAI,eAA8B;CAClC,IAAI,YAAY;CAChB,KAAK,MAAM,OAAO,MAAM;EACtB,aAAa;EACb,cACE,gBAAgB,QAAQ,IAAI,MAAM,gBAAgB,OAC9C,OACA,cAAc,IAAI,MAAM;EAC9B,eACE,iBAAiB,QAAQ,IAAI,MAAM,iBAAiB,OAChD,OACA,eAAe,IAAI,MAAM;CACjC;CACA,MAAM,MACJ,cAAc,IACV,IACA,WAAW,gBAAgB,QAAQ,iBAAiB,QACjD,cAAc,QAAQ,qBAAqB,eAAe,QAAQ,uBACnE,MACA;CACR,OAAO;EAAE;EAAW;EAAa;EAAc;CAAI;AACrD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as resolveModelPricing } from "./metrics-DOMpkoeb.js";
|
|
2
|
-
import { _ as removeCredentialEnvironment, a as closeServer, c as waitForActiveHandlers, d as assertExternalOptimizerModelBudget, i as startExternalOptimizerModelProxy, o as listenLocal, r as runWithCleanup, s as sendJsonIfOpen, t as runExternalOptimizerProcess, v as resolveExternalOptimizerCallbackLimits, y as resolveExternalOptimizerProcessLimits } from "./external-optimizer-subprocess-
|
|
3
|
-
import { F as coerceJson, M as RawAnalystFindingSchema, V as parseFindingSubject } from "./kind-factory-
|
|
2
|
+
import { _ as removeCredentialEnvironment, a as closeServer, c as waitForActiveHandlers, d as assertExternalOptimizerModelBudget, i as startExternalOptimizerModelProxy, o as listenLocal, r as runWithCleanup, s as sendJsonIfOpen, t as runExternalOptimizerProcess, v as resolveExternalOptimizerCallbackLimits, y as resolveExternalOptimizerProcessLimits } from "./external-optimizer-subprocess-DMgmqTB6.js";
|
|
3
|
+
import { F as coerceJson, M as RawAnalystFindingSchema, V as parseFindingSubject } from "./kind-factory-V79Hw0AU.js";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { createServer } from "node:http";
|
|
6
6
|
/**
|
|
@@ -462,4 +462,4 @@ function isRecord(value) {
|
|
|
462
462
|
//#endregion
|
|
463
463
|
export { decodeRawFindingArray as n, createDspyRlmTraceEngine as t };
|
|
464
464
|
|
|
465
|
-
//# sourceMappingURL=dspy-rlm-engine-
|
|
465
|
+
//# sourceMappingURL=dspy-rlm-engine-BE9lCzzL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dspy-rlm-engine-8pgBSiy7.js","names":["isRecord"],"sources":["../src/analyst/finding-codec.ts","../src/analyst/trace-tool-callback.ts","../src/analyst/dspy-rlm-engine.ts"],"sourcesContent":["/**\n * The raw-finding wire contract — one decoder for both sides of the process\n * boundary.\n *\n * A finding array crosses a process boundary twice: an optimizer bridge writes\n * it in Python, TypeScript reads it back. Two decoders written independently\n * accept different shapes, so Python could report a completed investigation\n * whose rows TypeScript then dropped — the paid work disappearing between two\n * \"successes\". This module is the TypeScript half; `finding_contract.json`\n * carries the same rules to the Python half, generated from the schema here.\n *\n * Decoding never invents an empty result. A value that is not an array of rows\n * fails with the exact type it was, and a malformed row is reported with its\n * index and path while its valid siblings survive.\n */\n\nimport { type RawAnalystFinding, RawAnalystFindingSchema } from './finding-signature'\nimport { parseFindingSubject } from './finding-subject'\nimport { coerceJson } from './parse-tolerant'\n\n/**\n * Version of the wire contract both languages implement. Bump when the\n * accepted row shape changes; the Python package pins the same value, and the\n * emitted contract carries it so a mismatched pair is visible.\n */\nexport const FINDING_WIRE_CONTRACT_VERSION = 1\n\n/** Why one row was refused. Stable across languages: Python reports the same codes. */\nexport type FindingRejectionCode = 'not-an-object' | 'schema' | 'invalid-subject' | 'row-limit'\n\n/** A refused row, named precisely enough to repair or report. */\nexport interface RejectedFindingRow {\n /** Position in the submitted array. */\n readonly index: number\n /** Dotted path to the offending field, `''` for the row itself. */\n readonly path: string\n readonly code: FindingRejectionCode\n readonly message: string\n}\n\nexport interface DecodedFindingArray {\n readonly accepted: RawAnalystFinding[]\n readonly rejected: RejectedFindingRow[]\n /**\n * Set when the value was not a finding array at all — the array itself is\n * the failure, so `accepted` and `rejected` are both empty and a caller must\n * not read the result as \"no findings\".\n */\n readonly topLevelError?: string\n}\n\n/**\n * Rows past this count are refused rather than validated. A model that emits\n * thousands of rows has lost the plot, and the diagnostics for them would\n * dwarf the answer they came with.\n */\nexport const MAX_FINDING_ROWS = 500\n\n/**\n * Decode a submitted findings value into accepted rows plus per-row\n * diagnostics.\n *\n * Accepts an array of rows, or a string carrying one (a JSON array, possibly\n * fenced). Anything else — an object, a number, null, undefined — sets\n * `topLevelError` naming the type received: a caller that asked for findings\n * and got a number has a defect to report, not an empty result to record.\n */\nexport function decodeRawFindingArray(value: unknown): DecodedFindingArray {\n const rows = findingRows(value)\n if (typeof rows === 'string') return { accepted: [], rejected: [], topLevelError: rows }\n\n const accepted: RawAnalystFinding[] = []\n const rejected: RejectedFindingRow[] = []\n for (const [index, row] of rows.entries()) {\n if (index >= MAX_FINDING_ROWS) {\n rejected.push({\n index,\n path: '',\n code: 'row-limit',\n message: `findings array exceeds ${MAX_FINDING_ROWS} rows`,\n })\n continue\n }\n const decoded = decodeRow(row, index)\n if ('finding' in decoded) accepted.push(decoded.finding)\n else rejected.push(decoded.rejection)\n }\n return { accepted, rejected }\n}\n\nfunction decodeRow(\n row: unknown,\n index: number,\n): { finding: RawAnalystFinding } | { rejection: RejectedFindingRow } {\n if (row === null || typeof row !== 'object' || Array.isArray(row)) {\n return {\n rejection: {\n index,\n path: '',\n code: 'not-an-object',\n message: `finding row must be an object, received ${describe(row)}`,\n },\n }\n }\n const parsed = RawAnalystFindingSchema.safeParse(row)\n if (!parsed.success) {\n const issue = parsed.error.issues[0]\n const path = (issue?.path ?? []).join('.')\n // The schema refines `subject` against the grammar; name that refusal\n // separately so a repair turn can be told which rule the row broke.\n const code: FindingRejectionCode =\n path === 'subject' && parseFindingSubject((row as { subject?: string }).subject) === null\n ? 'invalid-subject'\n : 'schema'\n return {\n rejection: { index, path, code, message: issue?.message ?? 'row does not match the schema' },\n }\n }\n return { finding: parsed.data }\n}\n\n/**\n * Narrow a submitted value to candidate rows, or return the message naming why\n * it is not a findings array at all.\n */\nfunction findingRows(value: unknown): unknown[] | string {\n if (Array.isArray(value)) return value\n if (typeof value === 'string') {\n const parsed = coerceJson(value)\n if (parsed === undefined) {\n return 'findings must be a JSON array; the string received is not JSON'\n }\n if (Array.isArray(parsed)) return parsed\n const unwrapped = findingsProperty(parsed)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be a JSON array, received ${describe(parsed)}`\n }\n const unwrapped = findingsProperty(value)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be an array, received ${describe(value)}`\n}\n\n/** `{ findings: [...] }` is the one wrapper models emit often enough to unwrap. */\nfunction findingsProperty(value: unknown): unknown[] | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\n const inner = (value as Record<string, unknown>).findings\n return Array.isArray(inner) ? inner : undefined\n}\n\nfunction describe(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'an array'\n return `a ${typeof value}`\n}\n\n/** One line per refused row, for a repair prompt or an error message. */\nexport function describeRejectedRows(rejected: readonly RejectedFindingRow[]): string {\n return rejected\n .map((row) => `row ${row.index}${row.path ? ` field '${row.path}'` : ''}: ${row.message}`)\n .join('\\n')\n}\n","import { randomBytes } from 'node:crypto'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport {\n type ExternalOptimizerCallbackLimits,\n resolveExternalOptimizerCallbackLimits,\n} from '../campaign/external-optimizer-contracts'\nimport {\n closeServer,\n listenLocal,\n sendJsonIfOpen,\n waitForActiveHandlers,\n} from '../campaign/external-optimizer-http'\nimport type { TraceAnalysisToolDescriptor } from '../trace-analyst/tools'\n\nexport interface TraceToolCallback {\n url: string\n token: string\n calls: () => number\n close: () => Promise<void>\n}\n\nexport type TraceToolCallbackLimits = ExternalOptimizerCallbackLimits\n\n/** Expose one bounded trace-tool set only on an authenticated loopback socket. */\nexport async function startTraceToolCallback(args: {\n tools: readonly TraceAnalysisToolDescriptor[]\n maxCalls: number\n /** Trace-tool request/response byte limits. Omitted fields use finite defaults. */\n limits?: Partial<TraceToolCallbackLimits>\n signal?: AbortSignal\n}): Promise<TraceToolCallback> {\n if (!Number.isSafeInteger(args.maxCalls) || args.maxCalls <= 0) {\n throw new TypeError('trace tool callback maxCalls must be a positive safe integer')\n }\n const limits = resolveExternalOptimizerCallbackLimits(args.limits, 'trace tool callback limits')\n args.signal?.throwIfAborted()\n const byName = new Map(args.tools.map((tool) => [tool.name, tool]))\n if (byName.size !== args.tools.length) {\n throw new Error('trace tool callback received duplicate tool names')\n }\n\n const token = randomBytes(32).toString('hex')\n let calls = 0\n let accepting = true\n let closePromise: Promise<void> | undefined\n const activeControllers = new Set<AbortController>()\n const activeHandlers = new Set<Promise<void>>()\n const server = createServer((request, response) => {\n if (!accepting) {\n sendJsonIfOpen(response, 503, { error: 'trace tool callback is closing' })\n return\n }\n const controller = new AbortController()\n const abortRequest = (): void => {\n request.destroy()\n response.destroy()\n }\n activeControllers.add(controller)\n controller.signal.addEventListener('abort', abortRequest, { once: true })\n\n let handler!: Promise<void>\n handler = handleRequest(request, response, controller.signal).finally(() => {\n controller.signal.removeEventListener('abort', abortRequest)\n activeControllers.delete(controller)\n activeHandlers.delete(handler)\n })\n activeHandlers.add(handler)\n void handler.catch(() => undefined)\n })\n const port = await listenLocal(server)\n const close = (): Promise<void> => {\n closePromise ??= closeCallback()\n return closePromise\n }\n const onAbort = (): void => {\n void close().catch(() => undefined)\n }\n args.signal?.addEventListener('abort', onAbort, { once: true })\n if (args.signal?.aborted) onAbort()\n\n return {\n url: `http://127.0.0.1:${port}/call`,\n token,\n calls: () => calls,\n close,\n }\n\n async function handleRequest(\n request: IncomingMessage,\n response: ServerResponse,\n signal: AbortSignal,\n ): Promise<void> {\n try {\n if (request.method !== 'POST' || request.url !== '/call') {\n sendJsonIfOpen(response, 404, { error: 'not found' })\n return\n }\n if (request.headers.authorization !== `Bearer ${token}`) {\n sendJsonIfOpen(response, 401, { error: 'unauthorized' })\n return\n }\n if (calls >= args.maxCalls) {\n sendJsonIfOpen(response, 429, { error: 'trace tool call limit reached' })\n return\n }\n const body = await readJson(request, limits.maxRequestBytes)\n if (!isRecord(body) || typeof body.name !== 'string' || !('args' in body)) {\n sendJsonIfOpen(response, 400, { error: 'name and args are required' })\n return\n }\n const tool = byName.get(body.name)\n if (!tool) {\n sendJsonIfOpen(response, 404, { error: `unknown trace tool '${body.name}'` })\n return\n }\n calls += 1\n const result = await tool.handler(body.args, { signal })\n const encoded = JSON.stringify({ result })\n if (Buffer.byteLength(encoded) > limits.maxResponseBytes) {\n sendJsonIfOpen(response, 413, { error: 'trace tool response too large' })\n return\n }\n response.writeHead(200, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': String(Buffer.byteLength(encoded)),\n })\n response.end(encoded)\n } catch (error) {\n sendJsonIfOpen(response, signal.aborted ? 499 : 400, {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n async function closeCallback(): Promise<void> {\n args.signal?.removeEventListener('abort', onAbort)\n accepting = false\n const closingServer = closeServer(server)\n server.closeIdleConnections?.()\n for (const controller of activeControllers) controller.abort()\n const [serverResult] = await Promise.allSettled([\n closingServer,\n waitForActiveHandlers(activeHandlers),\n ])\n if (activeControllers.size !== 0 || activeHandlers.size !== 0) {\n throw new Error('trace tool callback closed with active requests')\n }\n if (serverResult?.status === 'rejected') throw serverResult.reason\n }\n}\n\nfunction readJson(request: IncomingMessage, maxRequestBytes: number): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let size = 0\n const chunks: Buffer[] = []\n request.on('data', (chunk: Buffer) => {\n size += chunk.length\n if (size > maxRequestBytes) {\n reject(new Error('trace tool request too large'))\n request.destroy()\n return\n }\n chunks.push(chunk)\n })\n request.on('error', reject)\n request.on('end', () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')))\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import {\n assertExternalOptimizerModelBudget,\n type ExternalOptimizerModelCall,\n type ExternalOptimizerModelExecutionObservation,\n type ExternalOptimizerModelProxy,\n type ExternalOptimizerRunnerCommand,\n removeCredentialEnvironment,\n resolveExternalOptimizerCallbackLimits,\n resolveExternalOptimizerProcessLimits,\n} from '../campaign/external-optimizer-contracts'\nimport { startExternalOptimizerModelProxy } from '../campaign/external-optimizer-model-proxy'\nimport { runWithCleanup } from '../campaign/external-optimizer-resources'\nimport { runExternalOptimizerProcess } from '../campaign/external-optimizer-subprocess'\nimport type { CustomTokenPricing } from '../cost-ledger'\nimport { resolveModelPricing } from '../metrics'\nimport {\n DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS,\n type TraceAnalysisEngine,\n type TraceAnalysisEngineResult,\n} from './engine'\nimport { decodeRawFindingArray } from './finding-codec'\nimport { startTraceToolCallback, type TraceToolCallbackLimits } from './trace-tool-callback'\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000\nconst DEFAULT_MAX_COST_USD = 1\nconst DEFAULT_MAX_MODEL_REQUEST_BYTES = 16 * 1024 * 1024\nconst DEFAULT_MAX_MODEL_RESPONSE_BYTES = 4 * 1024 * 1024\nconst DEFAULT_TRACE_TOOL_TIMEOUT_MS = 60_000\nconst MAX_TIMER_DELAY_MS = 2_147_483_647\nconst BRIDGE_MODULE = 'agent_eval_rpc.dspy_rlm_bridge'\n/** Bumped whenever this engine's execution behavior changes. */\nconst DSPY_RLM_ENGINE_VERSION = '1.0.0'\n\nexport interface DspyRlmTraceEngineOptions {\n /** Caller-owned execution path. Agent Eval never receives provider credentials. */\n call: ExternalOptimizerModelCall\n /** Stable public identity for the caller-owned path, such as an AgentProfile digest. */\n callRef: string\n /** Persist the finite execution record returned for every admitted call. */\n recordExecution: (observation: ExternalOptimizerModelExecutionObservation) => void\n model: string\n /** Exact provider rates. Required when the model is absent from the pricing table. */\n pricing?: CustomTokenPricing\n /** Maximum provider spend for one investigation. Default: 1 USD. */\n maxCostUsd?: number\n /** Controller response cap. Default: {@link DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS}. */\n maxOutputTokens?: number\n /**\n * Thinking tokens one controller turn may bill on top of its completion.\n * A reasoning model bills these beyond `maxOutputTokens`, so the cost\n * reservation must cover them. Default: four times the completion cap.\n */\n maxReasoningTokens?: number\n /** Maximum caller-owned model invocations. Default derives from the analysis limits. */\n maxModelRequests?: number\n /** Maximum model request bytes. Default: 16 MiB. */\n maxModelRequestBytes?: number\n /** Maximum model response bytes. Default: 4 MiB. */\n maxModelResponseBytes?: number\n /** Deadline for one caller-owned model invocation. Default: the whole analysis deadline. */\n modelRequestTimeoutMs?: number\n /** Trace-tool loopback request/response byte limits. */\n traceToolLimits?: Partial<TraceToolCallbackLimits>\n /** Deadline for one Python-to-Node trace-tool call. Default: 60 seconds. */\n traceToolTimeoutMs?: number\n /**\n * How the controller's reasoning and code fields are obtained.\n *\n * `tolerant` parses marker output strictly first, then recovers the fields\n * deterministically from prose plus a fenced code block — the shape coding\n * models naturally emit — at no extra model cost. `two-step` extracts with a\n * second call per turn. `chat` accepts marker output only. Default:\n * `tolerant`.\n */\n controlAdapter?: 'chat' | 'two-step' | 'tolerant'\n /** Python command used to load agent-eval-rpc[dspy]. Default: python. */\n runner?: ExternalOptimizerRunnerCommand\n /** Whole investigation deadline. Default: 10 minutes. */\n timeoutMs?: number\n}\n\n/** Use the official DSPy RLM as a bounded recursive trace-analysis engine. */\nexport function createDspyRlmTraceEngine(options: DspyRlmTraceEngineOptions): TraceAnalysisEngine {\n assertOptions(options)\n const maxOutputTokens = options.maxOutputTokens ?? DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS\n if (!Number.isSafeInteger(maxOutputTokens) || maxOutputTokens <= 0) {\n throw new TypeError('DSPy RLM maxOutputTokens must be a positive safe integer')\n }\n const controlAdapter = options.controlAdapter ?? 'tolerant'\n const maxReasoningTokens = options.maxReasoningTokens ?? maxOutputTokens * 4\n if (!Number.isSafeInteger(maxReasoningTokens) || maxReasoningTokens < 0) {\n throw new TypeError('DSPy RLM maxReasoningTokens must be a non-negative safe integer')\n }\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n assertTimerDelay(timeoutMs, 'timeoutMs')\n const maxCostUsd = options.maxCostUsd ?? DEFAULT_MAX_COST_USD\n if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {\n throw new TypeError('DSPy RLM maxCostUsd must be positive and finite')\n }\n const pricing = options.pricing ?? pricingForModel(options.model)\n const maxModelRequestBytes = options.maxModelRequestBytes ?? DEFAULT_MAX_MODEL_REQUEST_BYTES\n const maxModelResponseBytes = options.maxModelResponseBytes ?? DEFAULT_MAX_MODEL_RESPONSE_BYTES\n const modelRequestTimeoutMs = options.modelRequestTimeoutMs ?? timeoutMs\n const traceToolTimeoutMs = options.traceToolTimeoutMs ?? DEFAULT_TRACE_TOOL_TIMEOUT_MS\n assertExternalOptimizerModelBudget(\n {\n maxCostUsd,\n maxRequests: options.maxModelRequests ?? 1,\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n pricing,\n requestTimeoutMs: modelRequestTimeoutMs,\n },\n 'DSPy RLM model limits',\n )\n resolveExternalOptimizerCallbackLimits(options.traceToolLimits, 'DSPy RLM trace tool limits')\n assertTimerDelay(traceToolTimeoutMs, 'traceToolTimeoutMs')\n\n const runner = sanitizedRunner(options.runner)\n const processLimits = resolveExternalOptimizerProcessLimits(runner?.limits)\n return {\n id: 'dspy-rlm',\n description: 'Official DSPy RLM with bounded trace tools and metered model calls.',\n model: options.model,\n version: DSPY_RLM_ENGINE_VERSION,\n executionConfig: {\n bridge_module: BRIDGE_MODULE,\n call_ref: options.callRef,\n model: options.model,\n pricing: { ...pricing },\n max_cost_usd: maxCostUsd,\n max_output_tokens: maxOutputTokens,\n max_reasoning_tokens: maxReasoningTokens,\n control_adapter: controlAdapter,\n timeout_ms: timeoutMs,\n max_model_requests: options.maxModelRequests ?? null,\n max_request_bytes: maxModelRequestBytes,\n max_response_bytes: maxModelResponseBytes,\n model_request_timeout_ms: modelRequestTimeoutMs,\n trace_tool_limits: options.traceToolLimits ?? null,\n trace_tool_timeout_ms: traceToolTimeoutMs,\n process_limits: processLimits,\n runner: runner ? 'caller-supplied' : 'default',\n runner_command: runner?.command ?? null,\n },\n async analyze(request) {\n const callback = await startTraceToolCallback({\n tools: request.tools,\n maxCalls: request.limits.maxToolCalls,\n ...(options.traceToolLimits ? { limits: options.traceToolLimits } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n let modelProxy: ExternalOptimizerModelProxy | undefined\n const modelExecutions: ExternalOptimizerModelExecutionObservation[] = []\n const result = await runWithCleanup({\n label: 'DSPy RLM trace-analysis resources',\n run: async () => {\n modelProxy = await startExternalOptimizerModelProxy({\n call: options.call,\n callRef: options.callRef,\n recordExecution: (observation) => {\n modelExecutions.push(structuredClone(observation))\n options.recordExecution(observation)\n },\n model: options.model,\n budget: {\n maxCostUsd,\n maxRequests: resolveMaxModelRequests(options.maxModelRequests, request.limits),\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n requestTimeoutMs: modelRequestTimeoutMs,\n pricing,\n },\n costLedger: request.costLedger,\n channel: 'analyst',\n phase: request.costPhase,\n actor: request.analystId,\n ...(request.costTags ? { tags: request.costTags } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n request.log?.('trace analyst engine started', {\n engine: 'dspy-rlm',\n model: options.model,\n tools: request.tools.map((tool) => tool.name),\n limits: request.limits,\n })\n const raw = await runExternalOptimizerProcess<unknown>({\n label: 'DSPy RLM trace analysis',\n tempPrefix: 'agent-eval-dspy-rlm-',\n module: BRIDGE_MODULE,\n input: {\n operation: 'analyze',\n question: request.question,\n instructions: request.instructions,\n modelProxy: {\n baseUrl: modelProxy.baseUrl,\n apiKey: modelProxy.apiKey,\n model: options.model,\n maxOutputTokens,\n },\n toolCallback: {\n url: callback.url,\n token: callback.token,\n timeoutMs: traceToolTimeoutMs,\n },\n toolSpecs: request.tools.map(({ name, description, parameters }) => ({\n name,\n description,\n parameters,\n })),\n controlAdapter,\n limits: {\n maxIterations: request.limits.maxIterations,\n maxLlmCalls: request.limits.maxLlmCalls,\n maxOutputChars: request.limits.maxOutputChars,\n },\n // Omitted entirely when the caller supplied none, so a request\n // without structured inputs sends the payload it always sent.\n ...(request.taskInputs ? { taskInputs: request.taskInputs } : {}),\n },\n ...(runner ? { runner } : {}),\n additionalArgs: ['--max-input-bytes', String(processLimits.maxInputBytes)],\n timeoutMs,\n ...(request.signal ? { signal: request.signal } : {}),\n })\n const parsed = parseBridgeOutput(raw, (index, reason) => {\n request.log?.('finding rejected: bridge row failed schema validation', {\n engine: 'dspy-rlm',\n index,\n reason,\n })\n })\n const successfulCompletions = modelProxy.successfulCompletions()\n const requestAttempts = modelProxy.requestAttempts()\n if (parsed.modelCalls !== successfulCompletions) {\n throw new Error(\n `DSPy RLM reported ${parsed.modelCalls} model calls, but the provider proxy recorded ${successfulCompletions}`,\n )\n }\n modelProxy.assertExecutionComplete()\n return {\n ...parsed,\n toolCalls: callback.calls(),\n runtime: {\n ...parsed.runtime,\n modelRequestAttempts: requestAttempts,\n modelSuccessfulCompletions: successfulCompletions,\n modelExecutions,\n },\n } satisfies TraceAnalysisEngineResult\n },\n cleanup: async () => {\n const results = await Promise.allSettled([\n ...(modelProxy ? [modelProxy.close()] : []),\n callback.close(),\n ])\n const errors = results.flatMap((entry) =>\n entry.status === 'rejected' ? [entry.reason] : [],\n )\n if (errors.length > 0) {\n throw new AggregateError(errors, 'DSPy RLM resource cleanup failed')\n }\n },\n })\n request.log?.('trace analyst engine completed', {\n engine: 'dspy-rlm',\n model_calls: result.modelCalls,\n model_request_attempts: result.runtime.modelRequestAttempts,\n tool_calls: result.toolCalls,\n findings: result.findings.length,\n })\n return result\n },\n }\n}\n\nfunction parseBridgeOutput(\n value: unknown,\n onRejectedFinding: (index: number, reason: string) => void,\n): Omit<TraceAnalysisEngineResult, 'toolCalls'> {\n if (!isRecord(value)) throw new Error('DSPy RLM bridge output must be an object')\n if (typeof value.answer !== 'string' || !value.answer.trim()) {\n throw new Error('DSPy RLM bridge returned no answer')\n }\n // Findings are model output: one malformed row is model noise, not a bridge\n // fault, and the rest of the paid investigation must survive it. The codec\n // is the same decoder the Python side runs, so a row this bridge accepts is\n // a row the optimizer could report, and vice versa.\n const decoded = decodeRawFindingArray(value.findings)\n if (decoded.topLevelError !== undefined) {\n throw new Error(`DSPy RLM bridge findings must be an array: ${decoded.topLevelError}`)\n }\n const findings = decoded.accepted\n const rejectedFindings = decoded.rejected.length\n for (const rejection of decoded.rejected) {\n onRejectedFinding(\n rejection.index,\n `${rejection.code}${rejection.path ? ` at ${rejection.path}` : ''}: ${rejection.message}`,\n )\n }\n if (!Array.isArray(value.trajectory)) {\n throw new Error('DSPy RLM bridge trajectory must be an array')\n }\n if (!Number.isSafeInteger(value.modelCalls) || (value.modelCalls as number) <= 0) {\n throw new Error('DSPy RLM bridge modelCalls must be a positive safe integer')\n }\n if (!isRecord(value.runtime)) {\n throw new Error('DSPy RLM bridge runtime must be an object')\n }\n return {\n answer: value.answer,\n findings,\n trajectory: value.trajectory,\n modelCalls: value.modelCalls as number,\n runtime: { ...value.runtime, rejectedFindings },\n }\n}\n\nfunction assertOptions(options: DspyRlmTraceEngineOptions): void {\n for (const [name, value] of [\n ['callRef', options.callRef],\n ['model', options.model],\n ] as const) {\n if (typeof value !== 'string' || !value.trim() || value !== value.trim()) {\n throw new TypeError(`DSPy RLM ${name} must be a trimmed non-empty string`)\n }\n }\n if (typeof options.call !== 'function') {\n throw new TypeError('DSPy RLM call must be a function')\n }\n if (typeof options.recordExecution !== 'function') {\n throw new TypeError('DSPy RLM recordExecution must be a function')\n }\n if (\n options.maxModelRequests !== undefined &&\n (!Number.isSafeInteger(options.maxModelRequests) || options.maxModelRequests <= 0)\n ) {\n throw new TypeError('DSPy RLM maxModelRequests must be a positive safe integer')\n }\n}\n\nfunction resolveMaxModelRequests(\n configured: number | undefined,\n limits: { maxIterations: number; maxLlmCalls: number },\n): number {\n if (configured !== undefined) return configured\n const derived = limits.maxIterations + limits.maxLlmCalls + 1\n if (!Number.isSafeInteger(derived) || derived <= 0) {\n throw new Error('DSPy RLM analysis limits produce an invalid model request limit')\n }\n return derived\n}\n\nfunction assertTimerDelay(value: number, field: string): void {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_TIMER_DELAY_MS) {\n throw new TypeError(`DSPy RLM ${field} must be between 1 and ${MAX_TIMER_DELAY_MS}`)\n }\n}\n\nfunction pricingForModel(model: string): CustomTokenPricing {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n throw new Error(\n `no pricing is configured for '${model}'; provide DspyRlmTraceEngineOptions.pricing`,\n )\n }\n return {\n inputUsdPerMillion: pricing.input * 1_000,\n outputUsdPerMillion: pricing.output * 1_000,\n }\n}\n\nfunction sanitizedRunner(\n runner: ExternalOptimizerRunnerCommand | undefined,\n): ExternalOptimizerRunnerCommand | undefined {\n if (!runner) return undefined\n return {\n ...(runner.command ? { command: runner.command } : {}),\n ...(runner.args ? { args: runner.args } : {}),\n ...(runner.env ? { env: removeCredentialEnvironment(runner.env) } : {}),\n ...(runner.limits ? { limits: { ...runner.limits } } : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dspy-rlm-engine-BE9lCzzL.js","names":["isRecord"],"sources":["../src/analyst/finding-codec.ts","../src/analyst/trace-tool-callback.ts","../src/analyst/dspy-rlm-engine.ts"],"sourcesContent":["/**\n * The raw-finding wire contract — one decoder for both sides of the process\n * boundary.\n *\n * A finding array crosses a process boundary twice: an optimizer bridge writes\n * it in Python, TypeScript reads it back. Two decoders written independently\n * accept different shapes, so Python could report a completed investigation\n * whose rows TypeScript then dropped — the paid work disappearing between two\n * \"successes\". This module is the TypeScript half; `finding_contract.json`\n * carries the same rules to the Python half, generated from the schema here.\n *\n * Decoding never invents an empty result. A value that is not an array of rows\n * fails with the exact type it was, and a malformed row is reported with its\n * index and path while its valid siblings survive.\n */\n\nimport { type RawAnalystFinding, RawAnalystFindingSchema } from './finding-signature'\nimport { parseFindingSubject } from './finding-subject'\nimport { coerceJson } from './parse-tolerant'\n\n/**\n * Version of the wire contract both languages implement. Bump when the\n * accepted row shape changes; the Python package pins the same value, and the\n * emitted contract carries it so a mismatched pair is visible.\n */\nexport const FINDING_WIRE_CONTRACT_VERSION = 1\n\n/** Why one row was refused. Stable across languages: Python reports the same codes. */\nexport type FindingRejectionCode = 'not-an-object' | 'schema' | 'invalid-subject' | 'row-limit'\n\n/** A refused row, named precisely enough to repair or report. */\nexport interface RejectedFindingRow {\n /** Position in the submitted array. */\n readonly index: number\n /** Dotted path to the offending field, `''` for the row itself. */\n readonly path: string\n readonly code: FindingRejectionCode\n readonly message: string\n}\n\nexport interface DecodedFindingArray {\n readonly accepted: RawAnalystFinding[]\n readonly rejected: RejectedFindingRow[]\n /**\n * Set when the value was not a finding array at all — the array itself is\n * the failure, so `accepted` and `rejected` are both empty and a caller must\n * not read the result as \"no findings\".\n */\n readonly topLevelError?: string\n}\n\n/**\n * Rows past this count are refused rather than validated. A model that emits\n * thousands of rows has lost the plot, and the diagnostics for them would\n * dwarf the answer they came with.\n */\nexport const MAX_FINDING_ROWS = 500\n\n/**\n * Decode a submitted findings value into accepted rows plus per-row\n * diagnostics.\n *\n * Accepts an array of rows, or a string carrying one (a JSON array, possibly\n * fenced). Anything else — an object, a number, null, undefined — sets\n * `topLevelError` naming the type received: a caller that asked for findings\n * and got a number has a defect to report, not an empty result to record.\n */\nexport function decodeRawFindingArray(value: unknown): DecodedFindingArray {\n const rows = findingRows(value)\n if (typeof rows === 'string') return { accepted: [], rejected: [], topLevelError: rows }\n\n const accepted: RawAnalystFinding[] = []\n const rejected: RejectedFindingRow[] = []\n for (const [index, row] of rows.entries()) {\n if (index >= MAX_FINDING_ROWS) {\n rejected.push({\n index,\n path: '',\n code: 'row-limit',\n message: `findings array exceeds ${MAX_FINDING_ROWS} rows`,\n })\n continue\n }\n const decoded = decodeRow(row, index)\n if ('finding' in decoded) accepted.push(decoded.finding)\n else rejected.push(decoded.rejection)\n }\n return { accepted, rejected }\n}\n\nfunction decodeRow(\n row: unknown,\n index: number,\n): { finding: RawAnalystFinding } | { rejection: RejectedFindingRow } {\n if (row === null || typeof row !== 'object' || Array.isArray(row)) {\n return {\n rejection: {\n index,\n path: '',\n code: 'not-an-object',\n message: `finding row must be an object, received ${describe(row)}`,\n },\n }\n }\n const parsed = RawAnalystFindingSchema.safeParse(row)\n if (!parsed.success) {\n const issue = parsed.error.issues[0]\n const path = (issue?.path ?? []).join('.')\n // The schema refines `subject` against the grammar; name that refusal\n // separately so a repair turn can be told which rule the row broke.\n const code: FindingRejectionCode =\n path === 'subject' && parseFindingSubject((row as { subject?: string }).subject) === null\n ? 'invalid-subject'\n : 'schema'\n return {\n rejection: { index, path, code, message: issue?.message ?? 'row does not match the schema' },\n }\n }\n return { finding: parsed.data }\n}\n\n/**\n * Narrow a submitted value to candidate rows, or return the message naming why\n * it is not a findings array at all.\n */\nfunction findingRows(value: unknown): unknown[] | string {\n if (Array.isArray(value)) return value\n if (typeof value === 'string') {\n const parsed = coerceJson(value)\n if (parsed === undefined) {\n return 'findings must be a JSON array; the string received is not JSON'\n }\n if (Array.isArray(parsed)) return parsed\n const unwrapped = findingsProperty(parsed)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be a JSON array, received ${describe(parsed)}`\n }\n const unwrapped = findingsProperty(value)\n if (unwrapped !== undefined) return unwrapped\n return `findings must be an array, received ${describe(value)}`\n}\n\n/** `{ findings: [...] }` is the one wrapper models emit often enough to unwrap. */\nfunction findingsProperty(value: unknown): unknown[] | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\n const inner = (value as Record<string, unknown>).findings\n return Array.isArray(inner) ? inner : undefined\n}\n\nfunction describe(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'an array'\n return `a ${typeof value}`\n}\n\n/** One line per refused row, for a repair prompt or an error message. */\nexport function describeRejectedRows(rejected: readonly RejectedFindingRow[]): string {\n return rejected\n .map((row) => `row ${row.index}${row.path ? ` field '${row.path}'` : ''}: ${row.message}`)\n .join('\\n')\n}\n","import { randomBytes } from 'node:crypto'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport {\n type ExternalOptimizerCallbackLimits,\n resolveExternalOptimizerCallbackLimits,\n} from '../campaign/external-optimizer-contracts'\nimport {\n closeServer,\n listenLocal,\n sendJsonIfOpen,\n waitForActiveHandlers,\n} from '../campaign/external-optimizer-http'\nimport type { TraceAnalysisToolDescriptor } from '../trace-analyst/tools'\n\nexport interface TraceToolCallback {\n url: string\n token: string\n calls: () => number\n close: () => Promise<void>\n}\n\nexport type TraceToolCallbackLimits = ExternalOptimizerCallbackLimits\n\n/** Expose one bounded trace-tool set only on an authenticated loopback socket. */\nexport async function startTraceToolCallback(args: {\n tools: readonly TraceAnalysisToolDescriptor[]\n maxCalls: number\n /** Trace-tool request/response byte limits. Omitted fields use finite defaults. */\n limits?: Partial<TraceToolCallbackLimits>\n signal?: AbortSignal\n}): Promise<TraceToolCallback> {\n if (!Number.isSafeInteger(args.maxCalls) || args.maxCalls <= 0) {\n throw new TypeError('trace tool callback maxCalls must be a positive safe integer')\n }\n const limits = resolveExternalOptimizerCallbackLimits(args.limits, 'trace tool callback limits')\n args.signal?.throwIfAborted()\n const byName = new Map(args.tools.map((tool) => [tool.name, tool]))\n if (byName.size !== args.tools.length) {\n throw new Error('trace tool callback received duplicate tool names')\n }\n\n const token = randomBytes(32).toString('hex')\n let calls = 0\n let accepting = true\n let closePromise: Promise<void> | undefined\n const activeControllers = new Set<AbortController>()\n const activeHandlers = new Set<Promise<void>>()\n const server = createServer((request, response) => {\n if (!accepting) {\n sendJsonIfOpen(response, 503, { error: 'trace tool callback is closing' })\n return\n }\n const controller = new AbortController()\n const abortRequest = (): void => {\n request.destroy()\n response.destroy()\n }\n activeControllers.add(controller)\n controller.signal.addEventListener('abort', abortRequest, { once: true })\n\n let handler!: Promise<void>\n handler = handleRequest(request, response, controller.signal).finally(() => {\n controller.signal.removeEventListener('abort', abortRequest)\n activeControllers.delete(controller)\n activeHandlers.delete(handler)\n })\n activeHandlers.add(handler)\n void handler.catch(() => undefined)\n })\n const port = await listenLocal(server)\n const close = (): Promise<void> => {\n closePromise ??= closeCallback()\n return closePromise\n }\n const onAbort = (): void => {\n void close().catch(() => undefined)\n }\n args.signal?.addEventListener('abort', onAbort, { once: true })\n if (args.signal?.aborted) onAbort()\n\n return {\n url: `http://127.0.0.1:${port}/call`,\n token,\n calls: () => calls,\n close,\n }\n\n async function handleRequest(\n request: IncomingMessage,\n response: ServerResponse,\n signal: AbortSignal,\n ): Promise<void> {\n try {\n if (request.method !== 'POST' || request.url !== '/call') {\n sendJsonIfOpen(response, 404, { error: 'not found' })\n return\n }\n if (request.headers.authorization !== `Bearer ${token}`) {\n sendJsonIfOpen(response, 401, { error: 'unauthorized' })\n return\n }\n if (calls >= args.maxCalls) {\n sendJsonIfOpen(response, 429, { error: 'trace tool call limit reached' })\n return\n }\n const body = await readJson(request, limits.maxRequestBytes)\n if (!isRecord(body) || typeof body.name !== 'string' || !('args' in body)) {\n sendJsonIfOpen(response, 400, { error: 'name and args are required' })\n return\n }\n const tool = byName.get(body.name)\n if (!tool) {\n sendJsonIfOpen(response, 404, { error: `unknown trace tool '${body.name}'` })\n return\n }\n calls += 1\n const result = await tool.handler(body.args, { signal })\n const encoded = JSON.stringify({ result })\n if (Buffer.byteLength(encoded) > limits.maxResponseBytes) {\n sendJsonIfOpen(response, 413, { error: 'trace tool response too large' })\n return\n }\n response.writeHead(200, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': String(Buffer.byteLength(encoded)),\n })\n response.end(encoded)\n } catch (error) {\n sendJsonIfOpen(response, signal.aborted ? 499 : 400, {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n async function closeCallback(): Promise<void> {\n args.signal?.removeEventListener('abort', onAbort)\n accepting = false\n const closingServer = closeServer(server)\n server.closeIdleConnections?.()\n for (const controller of activeControllers) controller.abort()\n const [serverResult] = await Promise.allSettled([\n closingServer,\n waitForActiveHandlers(activeHandlers),\n ])\n if (activeControllers.size !== 0 || activeHandlers.size !== 0) {\n throw new Error('trace tool callback closed with active requests')\n }\n if (serverResult?.status === 'rejected') throw serverResult.reason\n }\n}\n\nfunction readJson(request: IncomingMessage, maxRequestBytes: number): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let size = 0\n const chunks: Buffer[] = []\n request.on('data', (chunk: Buffer) => {\n size += chunk.length\n if (size > maxRequestBytes) {\n reject(new Error('trace tool request too large'))\n request.destroy()\n return\n }\n chunks.push(chunk)\n })\n request.on('error', reject)\n request.on('end', () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')))\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import {\n assertExternalOptimizerModelBudget,\n type ExternalOptimizerModelCall,\n type ExternalOptimizerModelExecutionObservation,\n type ExternalOptimizerModelProxy,\n type ExternalOptimizerRunnerCommand,\n removeCredentialEnvironment,\n resolveExternalOptimizerCallbackLimits,\n resolveExternalOptimizerProcessLimits,\n} from '../campaign/external-optimizer-contracts'\nimport { startExternalOptimizerModelProxy } from '../campaign/external-optimizer-model-proxy'\nimport { runWithCleanup } from '../campaign/external-optimizer-resources'\nimport { runExternalOptimizerProcess } from '../campaign/external-optimizer-subprocess'\nimport type { CustomTokenPricing } from '../cost-ledger'\nimport { resolveModelPricing } from '../metrics'\nimport {\n DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS,\n type TraceAnalysisEngine,\n type TraceAnalysisEngineResult,\n} from './engine'\nimport { decodeRawFindingArray } from './finding-codec'\nimport { startTraceToolCallback, type TraceToolCallbackLimits } from './trace-tool-callback'\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000\nconst DEFAULT_MAX_COST_USD = 1\nconst DEFAULT_MAX_MODEL_REQUEST_BYTES = 16 * 1024 * 1024\nconst DEFAULT_MAX_MODEL_RESPONSE_BYTES = 4 * 1024 * 1024\nconst DEFAULT_TRACE_TOOL_TIMEOUT_MS = 60_000\nconst MAX_TIMER_DELAY_MS = 2_147_483_647\nconst BRIDGE_MODULE = 'agent_eval_rpc.dspy_rlm_bridge'\n/** Bumped whenever this engine's execution behavior changes. */\nconst DSPY_RLM_ENGINE_VERSION = '1.0.0'\n\nexport interface DspyRlmTraceEngineOptions {\n /** Caller-owned execution path. Agent Eval never receives provider credentials. */\n call: ExternalOptimizerModelCall\n /** Stable public identity for the caller-owned path, such as an AgentProfile digest. */\n callRef: string\n /** Persist the finite execution record returned for every admitted call. */\n recordExecution: (observation: ExternalOptimizerModelExecutionObservation) => void\n model: string\n /** Exact provider rates. Required when the model is absent from the pricing table. */\n pricing?: CustomTokenPricing\n /** Maximum provider spend for one investigation. Default: 1 USD. */\n maxCostUsd?: number\n /** Controller response cap. Default: {@link DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS}. */\n maxOutputTokens?: number\n /**\n * Thinking tokens one controller turn may bill on top of its completion.\n * A reasoning model bills these beyond `maxOutputTokens`, so the cost\n * reservation must cover them. Default: four times the completion cap.\n */\n maxReasoningTokens?: number\n /** Maximum caller-owned model invocations. Default derives from the analysis limits. */\n maxModelRequests?: number\n /** Maximum model request bytes. Default: 16 MiB. */\n maxModelRequestBytes?: number\n /** Maximum model response bytes. Default: 4 MiB. */\n maxModelResponseBytes?: number\n /** Deadline for one caller-owned model invocation. Default: the whole analysis deadline. */\n modelRequestTimeoutMs?: number\n /** Trace-tool loopback request/response byte limits. */\n traceToolLimits?: Partial<TraceToolCallbackLimits>\n /** Deadline for one Python-to-Node trace-tool call. Default: 60 seconds. */\n traceToolTimeoutMs?: number\n /**\n * How the controller's reasoning and code fields are obtained.\n *\n * `tolerant` parses marker output strictly first, then recovers the fields\n * deterministically from prose plus a fenced code block — the shape coding\n * models naturally emit — at no extra model cost. `two-step` extracts with a\n * second call per turn. `chat` accepts marker output only. Default:\n * `tolerant`.\n */\n controlAdapter?: 'chat' | 'two-step' | 'tolerant'\n /** Python command used to load agent-eval-rpc[dspy]. Default: python. */\n runner?: ExternalOptimizerRunnerCommand\n /** Whole investigation deadline. Default: 10 minutes. */\n timeoutMs?: number\n}\n\n/** Use the official DSPy RLM as a bounded recursive trace-analysis engine. */\nexport function createDspyRlmTraceEngine(options: DspyRlmTraceEngineOptions): TraceAnalysisEngine {\n assertOptions(options)\n const maxOutputTokens = options.maxOutputTokens ?? DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS\n if (!Number.isSafeInteger(maxOutputTokens) || maxOutputTokens <= 0) {\n throw new TypeError('DSPy RLM maxOutputTokens must be a positive safe integer')\n }\n const controlAdapter = options.controlAdapter ?? 'tolerant'\n const maxReasoningTokens = options.maxReasoningTokens ?? maxOutputTokens * 4\n if (!Number.isSafeInteger(maxReasoningTokens) || maxReasoningTokens < 0) {\n throw new TypeError('DSPy RLM maxReasoningTokens must be a non-negative safe integer')\n }\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n assertTimerDelay(timeoutMs, 'timeoutMs')\n const maxCostUsd = options.maxCostUsd ?? DEFAULT_MAX_COST_USD\n if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {\n throw new TypeError('DSPy RLM maxCostUsd must be positive and finite')\n }\n const pricing = options.pricing ?? pricingForModel(options.model)\n const maxModelRequestBytes = options.maxModelRequestBytes ?? DEFAULT_MAX_MODEL_REQUEST_BYTES\n const maxModelResponseBytes = options.maxModelResponseBytes ?? DEFAULT_MAX_MODEL_RESPONSE_BYTES\n const modelRequestTimeoutMs = options.modelRequestTimeoutMs ?? timeoutMs\n const traceToolTimeoutMs = options.traceToolTimeoutMs ?? DEFAULT_TRACE_TOOL_TIMEOUT_MS\n assertExternalOptimizerModelBudget(\n {\n maxCostUsd,\n maxRequests: options.maxModelRequests ?? 1,\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n pricing,\n requestTimeoutMs: modelRequestTimeoutMs,\n },\n 'DSPy RLM model limits',\n )\n resolveExternalOptimizerCallbackLimits(options.traceToolLimits, 'DSPy RLM trace tool limits')\n assertTimerDelay(traceToolTimeoutMs, 'traceToolTimeoutMs')\n\n const runner = sanitizedRunner(options.runner)\n const processLimits = resolveExternalOptimizerProcessLimits(runner?.limits)\n return {\n id: 'dspy-rlm',\n description: 'Official DSPy RLM with bounded trace tools and metered model calls.',\n model: options.model,\n version: DSPY_RLM_ENGINE_VERSION,\n executionConfig: {\n bridge_module: BRIDGE_MODULE,\n call_ref: options.callRef,\n model: options.model,\n pricing: { ...pricing },\n max_cost_usd: maxCostUsd,\n max_output_tokens: maxOutputTokens,\n max_reasoning_tokens: maxReasoningTokens,\n control_adapter: controlAdapter,\n timeout_ms: timeoutMs,\n max_model_requests: options.maxModelRequests ?? null,\n max_request_bytes: maxModelRequestBytes,\n max_response_bytes: maxModelResponseBytes,\n model_request_timeout_ms: modelRequestTimeoutMs,\n trace_tool_limits: options.traceToolLimits ?? null,\n trace_tool_timeout_ms: traceToolTimeoutMs,\n process_limits: processLimits,\n runner: runner ? 'caller-supplied' : 'default',\n runner_command: runner?.command ?? null,\n },\n async analyze(request) {\n const callback = await startTraceToolCallback({\n tools: request.tools,\n maxCalls: request.limits.maxToolCalls,\n ...(options.traceToolLimits ? { limits: options.traceToolLimits } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n let modelProxy: ExternalOptimizerModelProxy | undefined\n const modelExecutions: ExternalOptimizerModelExecutionObservation[] = []\n const result = await runWithCleanup({\n label: 'DSPy RLM trace-analysis resources',\n run: async () => {\n modelProxy = await startExternalOptimizerModelProxy({\n call: options.call,\n callRef: options.callRef,\n recordExecution: (observation) => {\n modelExecutions.push(structuredClone(observation))\n options.recordExecution(observation)\n },\n model: options.model,\n budget: {\n maxCostUsd,\n maxRequests: resolveMaxModelRequests(options.maxModelRequests, request.limits),\n maxRequestBytes: maxModelRequestBytes,\n maxResponseBytes: maxModelResponseBytes,\n maxOutputTokensPerRequest: maxOutputTokens,\n maxReasoningTokensPerRequest: maxReasoningTokens,\n requestTimeoutMs: modelRequestTimeoutMs,\n pricing,\n },\n costLedger: request.costLedger,\n channel: 'analyst',\n phase: request.costPhase,\n actor: request.analystId,\n ...(request.costTags ? { tags: request.costTags } : {}),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n request.log?.('trace analyst engine started', {\n engine: 'dspy-rlm',\n model: options.model,\n tools: request.tools.map((tool) => tool.name),\n limits: request.limits,\n })\n const raw = await runExternalOptimizerProcess<unknown>({\n label: 'DSPy RLM trace analysis',\n tempPrefix: 'agent-eval-dspy-rlm-',\n module: BRIDGE_MODULE,\n input: {\n operation: 'analyze',\n question: request.question,\n instructions: request.instructions,\n modelProxy: {\n baseUrl: modelProxy.baseUrl,\n apiKey: modelProxy.apiKey,\n model: options.model,\n maxOutputTokens,\n },\n toolCallback: {\n url: callback.url,\n token: callback.token,\n timeoutMs: traceToolTimeoutMs,\n },\n toolSpecs: request.tools.map(({ name, description, parameters }) => ({\n name,\n description,\n parameters,\n })),\n controlAdapter,\n limits: {\n maxIterations: request.limits.maxIterations,\n maxLlmCalls: request.limits.maxLlmCalls,\n maxOutputChars: request.limits.maxOutputChars,\n },\n // Omitted entirely when the caller supplied none, so a request\n // without structured inputs sends the payload it always sent.\n ...(request.taskInputs ? { taskInputs: request.taskInputs } : {}),\n },\n ...(runner ? { runner } : {}),\n additionalArgs: ['--max-input-bytes', String(processLimits.maxInputBytes)],\n timeoutMs,\n ...(request.signal ? { signal: request.signal } : {}),\n })\n const parsed = parseBridgeOutput(raw, (index, reason) => {\n request.log?.('finding rejected: bridge row failed schema validation', {\n engine: 'dspy-rlm',\n index,\n reason,\n })\n })\n const successfulCompletions = modelProxy.successfulCompletions()\n const requestAttempts = modelProxy.requestAttempts()\n if (parsed.modelCalls !== successfulCompletions) {\n throw new Error(\n `DSPy RLM reported ${parsed.modelCalls} model calls, but the provider proxy recorded ${successfulCompletions}`,\n )\n }\n modelProxy.assertExecutionComplete()\n return {\n ...parsed,\n toolCalls: callback.calls(),\n runtime: {\n ...parsed.runtime,\n modelRequestAttempts: requestAttempts,\n modelSuccessfulCompletions: successfulCompletions,\n modelExecutions,\n },\n } satisfies TraceAnalysisEngineResult\n },\n cleanup: async () => {\n const results = await Promise.allSettled([\n ...(modelProxy ? [modelProxy.close()] : []),\n callback.close(),\n ])\n const errors = results.flatMap((entry) =>\n entry.status === 'rejected' ? [entry.reason] : [],\n )\n if (errors.length > 0) {\n throw new AggregateError(errors, 'DSPy RLM resource cleanup failed')\n }\n },\n })\n request.log?.('trace analyst engine completed', {\n engine: 'dspy-rlm',\n model_calls: result.modelCalls,\n model_request_attempts: result.runtime.modelRequestAttempts,\n tool_calls: result.toolCalls,\n findings: result.findings.length,\n })\n return result\n },\n }\n}\n\nfunction parseBridgeOutput(\n value: unknown,\n onRejectedFinding: (index: number, reason: string) => void,\n): Omit<TraceAnalysisEngineResult, 'toolCalls'> {\n if (!isRecord(value)) throw new Error('DSPy RLM bridge output must be an object')\n if (typeof value.answer !== 'string' || !value.answer.trim()) {\n throw new Error('DSPy RLM bridge returned no answer')\n }\n // Findings are model output: one malformed row is model noise, not a bridge\n // fault, and the rest of the paid investigation must survive it. The codec\n // is the same decoder the Python side runs, so a row this bridge accepts is\n // a row the optimizer could report, and vice versa.\n const decoded = decodeRawFindingArray(value.findings)\n if (decoded.topLevelError !== undefined) {\n throw new Error(`DSPy RLM bridge findings must be an array: ${decoded.topLevelError}`)\n }\n const findings = decoded.accepted\n const rejectedFindings = decoded.rejected.length\n for (const rejection of decoded.rejected) {\n onRejectedFinding(\n rejection.index,\n `${rejection.code}${rejection.path ? ` at ${rejection.path}` : ''}: ${rejection.message}`,\n )\n }\n if (!Array.isArray(value.trajectory)) {\n throw new Error('DSPy RLM bridge trajectory must be an array')\n }\n if (!Number.isSafeInteger(value.modelCalls) || (value.modelCalls as number) <= 0) {\n throw new Error('DSPy RLM bridge modelCalls must be a positive safe integer')\n }\n if (!isRecord(value.runtime)) {\n throw new Error('DSPy RLM bridge runtime must be an object')\n }\n return {\n answer: value.answer,\n findings,\n trajectory: value.trajectory,\n modelCalls: value.modelCalls as number,\n runtime: { ...value.runtime, rejectedFindings },\n }\n}\n\nfunction assertOptions(options: DspyRlmTraceEngineOptions): void {\n for (const [name, value] of [\n ['callRef', options.callRef],\n ['model', options.model],\n ] as const) {\n if (typeof value !== 'string' || !value.trim() || value !== value.trim()) {\n throw new TypeError(`DSPy RLM ${name} must be a trimmed non-empty string`)\n }\n }\n if (typeof options.call !== 'function') {\n throw new TypeError('DSPy RLM call must be a function')\n }\n if (typeof options.recordExecution !== 'function') {\n throw new TypeError('DSPy RLM recordExecution must be a function')\n }\n if (\n options.maxModelRequests !== undefined &&\n (!Number.isSafeInteger(options.maxModelRequests) || options.maxModelRequests <= 0)\n ) {\n throw new TypeError('DSPy RLM maxModelRequests must be a positive safe integer')\n }\n}\n\nfunction resolveMaxModelRequests(\n configured: number | undefined,\n limits: { maxIterations: number; maxLlmCalls: number },\n): number {\n if (configured !== undefined) return configured\n const derived = limits.maxIterations + limits.maxLlmCalls + 1\n if (!Number.isSafeInteger(derived) || derived <= 0) {\n throw new Error('DSPy RLM analysis limits produce an invalid model request limit')\n }\n return derived\n}\n\nfunction assertTimerDelay(value: number, field: string): void {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_TIMER_DELAY_MS) {\n throw new TypeError(`DSPy RLM ${field} must be between 1 and ${MAX_TIMER_DELAY_MS}`)\n }\n}\n\nfunction pricingForModel(model: string): CustomTokenPricing {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n throw new Error(\n `no pricing is configured for '${model}'; provide DspyRlmTraceEngineOptions.pricing`,\n )\n }\n return {\n inputUsdPerMillion: pricing.input * 1_000,\n outputUsdPerMillion: pricing.output * 1_000,\n }\n}\n\nfunction sanitizedRunner(\n runner: ExternalOptimizerRunnerCommand | undefined,\n): ExternalOptimizerRunnerCommand | undefined {\n if (!runner) return undefined\n return {\n ...(runner.command ? { command: runner.command } : {}),\n ...(runner.args ? { args: runner.args } : {}),\n ...(runner.env ? { env: removeCredentialEnvironment(runner.env) } : {}),\n ...(runner.limits ? { limits: { ...runner.limits } } : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n"],"mappings":"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"}
|
|
@@ -1,80 +1,8 @@
|
|
|
1
1
|
import { c as CostLedgerHandle } from "./cost-ledger-DbQdN3nO.js";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import "./
|
|
5
|
-
import { r as DatasetScenario } from "./dataset-DQqhOCPt.js";
|
|
6
|
-
import "./summary-report-D1h4dlrK.js";
|
|
7
|
-
import { o as InsightReport, r as ExecutionInsight, t as CostProvenanceSummary } from "./insight-report-D1qa0HWs.js";
|
|
8
|
-
import { n as AnalystRegistry } from "./registry-BRbB6Y0v.js";
|
|
2
|
+
import { D as TraceAnalysisStore, S as BoundedTraceAnalysisStoreOptions, p as EvidenceRef } from "./types-BjB2wZM9.js";
|
|
3
|
+
import "./types-BTRcIqFr.js";
|
|
4
|
+
import "./analyze-runs-CrYhqXop.js";
|
|
9
5
|
import { z } from "zod";
|
|
10
|
-
//#region src/contract/analyze-runs.d.ts
|
|
11
|
-
interface AnalyzeRunsOptions {
|
|
12
|
-
/** The runs to analyze. */
|
|
13
|
-
runs: RunRecord[];
|
|
14
|
-
/** Which split to score against when reading composite from RunOutcome.
|
|
15
|
-
* Default: holdout when ANY run has a `holdoutScore`, else search. */
|
|
16
|
-
split?: 'search' | 'holdout' | 'auto';
|
|
17
|
-
/** Pairwise analysis configuration. When both `baselineCandidateId` and
|
|
18
|
-
* `candidateCandidateId` are present, lift is computed on paired
|
|
19
|
-
* (experimentId, scenarioId, seed) identities shared between the two sides.
|
|
20
|
-
* Unmatched rows remain visible in the lift result. */
|
|
21
|
-
baselineCandidateId?: string;
|
|
22
|
-
candidateCandidateId?: string;
|
|
23
|
-
/** Average matched run scores within these units before estimating lift.
|
|
24
|
-
* Raw run distributions and unmatched-run counts remain unchanged. */
|
|
25
|
-
independentUnitByScenarioId?: ReadonlyMap<string, string>;
|
|
26
|
-
/** Canary scenarios — checked against every run's raw output for
|
|
27
|
-
* holdout contamination. */
|
|
28
|
-
canaryScenarios?: DatasetScenario[];
|
|
29
|
-
/** Analyst registry for failure clustering. When omitted, the
|
|
30
|
-
* `failureClusters` section is left undefined. */
|
|
31
|
-
analyst?: AnalystRegistry;
|
|
32
|
-
/** Downstream outcome metric per run (e.g. engagement rate, approval
|
|
33
|
-
* rate, downstream pass rate). When present, the report includes
|
|
34
|
-
* `outcomeCorrelation` + a simple linear reward model fit. */
|
|
35
|
-
outcomeSignal?: {
|
|
36
|
-
metric: string;
|
|
37
|
-
valueByRunId: Record<string, number>;
|
|
38
|
-
};
|
|
39
|
-
/** Multi-rater feedback for inter-rater agreement. Each entry is one
|
|
40
|
-
* rater's score for one run. Two or more raters → kappa + disagreement
|
|
41
|
-
* triage list. */
|
|
42
|
-
raterScores?: Array<{
|
|
43
|
-
runId: string;
|
|
44
|
-
rater: string;
|
|
45
|
-
score: number;
|
|
46
|
-
}>;
|
|
47
|
-
/** Number of histogram bins for distributional summaries. Default 12. */
|
|
48
|
-
histogramBins?: number;
|
|
49
|
-
/** Decision threshold — the smallest composite lift the caller cares
|
|
50
|
-
* about. Used by the recommendations engine to call ship vs hold.
|
|
51
|
-
* Default 0.02. */
|
|
52
|
-
decisionThreshold?: number;
|
|
53
|
-
/** Optional prior-period runs. When set, the report includes
|
|
54
|
-
* `priorPeriodComparison` with per-metric Welch-CI deltas and
|
|
55
|
-
* recommendations fire on statistically significant regressions.
|
|
56
|
-
* The two windows do NOT have to share scenarios — the comparison
|
|
57
|
-
* is two-sample unpaired (the substrate's `lift` field uses paired
|
|
58
|
-
* bootstrap on shared (experimentId, scenarioId, seed) identities; this is the
|
|
59
|
-
* shape for "this week vs last week" rather than "candidate vs
|
|
60
|
-
* baseline within a campaign"). */
|
|
61
|
-
baselineRuns?: RunRecord[];
|
|
62
|
-
/** Human-readable label for the baseline window, e.g. "vs prior 7
|
|
63
|
-
* days", "vs v3.1 release". Surfaces in recommendations + UI. */
|
|
64
|
-
baselineLabel?: string;
|
|
65
|
-
}
|
|
66
|
-
interface SummarizeExecutionOptions {
|
|
67
|
-
runs: RunRecord[];
|
|
68
|
-
histogramBins?: number;
|
|
69
|
-
}
|
|
70
|
-
interface ExecutionReport {
|
|
71
|
-
execution: ExecutionInsight;
|
|
72
|
-
costProvenance: CostProvenanceSummary;
|
|
73
|
-
}
|
|
74
|
-
/** Summarize runtime facts without interpreting task quality or promotion readiness. */
|
|
75
|
-
declare function summarizeExecution(opts: SummarizeExecutionOptions): ExecutionReport;
|
|
76
|
-
declare function analyzeRuns(opts: AnalyzeRunsOptions): Promise<InsightReport>;
|
|
77
|
-
//#endregion
|
|
78
6
|
//#region src/eval-tools.d.ts
|
|
79
7
|
/** One agent-callable tool. `parameters` is a JSON Schema (draft-07+) object. */
|
|
80
8
|
interface EvalToolDef {
|
|
@@ -229,5 +157,5 @@ interface TraceAnalysisEngine {
|
|
|
229
157
|
}
|
|
230
158
|
declare function resolveTraceAnalystLimits(limits: Partial<TraceAnalystLimits> | undefined): TraceAnalystLimits;
|
|
231
159
|
//#endregion
|
|
232
|
-
export {
|
|
233
|
-
//# sourceMappingURL=engine-
|
|
160
|
+
export { traceAnalystFunctionGroup as _, TraceAnalystLimits as a, RawAnalystEvidence as c, evidenceRefsFromRawFinding as d, parseRawFinding as f, buildTraceAnalysisToolDescriptors as g, TraceAnalysisToolDescriptor as h, TraceAnalysisEngineResult as i, RawAnalystFinding as l, TRACE_ANALYST_TOOL_NAMESPACE as m, TraceAnalysisEngine as n, resolveTraceAnalystLimits as o, BuildTraceAnalysisToolsOptions as p, TraceAnalysisEngineRequest as r, RAW_FINDING_SCHEMA_PROMPT as s, DEFAULT_TRACE_ANALYST_OUTPUT_TOKENS as t, RawAnalystFindingSchema as u };
|
|
161
|
+
//# sourceMappingURL=engine-cXUK-WHS.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-cXUK-WHS.d.ts","names":[],"sources":["../src/eval-tools.ts","../src/trace-analyst/tools.ts","../src/analyst/finding-signature.ts","../src/analyst/engine.ts"],"mappings":";;;;;;;UA4BiB;EACf;EACA;EACA,YAAY;EACZ,UAAU,eAAe;IAAQ,SAAS;QAAkB;;;;cClBjD;UAEI,uCAAuC;EACtD,OAAO;;UAGQ,oCAAoC;EACnD,kBAAkB;;;iBAIJ,kCACd,SAAS,iCACR;iBAoIa,0BAA0B,SAAS;EACjD;EACA;EACA;EACA;EACA,WAAW;;;;cCxJP,0BAAwB,EAAA;;;GAKnB,EAAA,KAAA;KAEC,qBAAqB,EAAE,aAAa;cAiBnC,yBAAuB,EAAA;;;;;;;;;;;;;;;;;GAKzB,EAAA,KAAA;KAEC,oBAAoB,EAAE,aAAa;;;;;;cAOlC;;iBAYG,2BAA2B,SAAS,oBAAoB;iBAQxD,gBACd,cACA,OAAO,aAAa,SAAS,mCAC5B;;;;UCpEc;;EAEf;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;;;;cAwBW;UAEI;EACf;EACA;EACA;EACA,gBAAgB;;;;;;;;;;;EAWhB,aAAa,SAAS;EACtB,QAAQ;EACR,YAAY;EACZ;EACA,WAAW;EACX,SAAS;EACT,OAAO,iBAAiB,SAAS;;;UAIlB;EACf;EACA,UAAU;;EAEV;;;;;EAKA;;EAEA;EACA,SAAS;;;;;;;;;UAUM;WACN;WACA;WACA;;WAEA;;;;;;;;WAQA,iBAAiB,SAAS;EACnC,QAAQ,SAAS,6BAA6B,QAAQ;;iBAGxC,0BACd,QAAQ,QAAQ,kCACf"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { s as ValidationError } from "./errors-Dngq5h35.js";
|
|
2
|
+
//#region src/analyst/equal-terms.ts
|
|
3
|
+
/**
|
|
4
|
+
* Refuses a comparison whose arms are not on equal terms: an empty set, a
|
|
5
|
+
* duplicated id, or unequal repair turns — a retry is a second sample the
|
|
6
|
+
* other arms never got. `noun` names the arm kind in every message so a
|
|
7
|
+
* refusal reads in the caller's vocabulary.
|
|
8
|
+
*/
|
|
9
|
+
function assertEqualDeclarativeTerms(noun, terms) {
|
|
10
|
+
if (terms.length === 0) throw new ValidationError(`a ${noun} comparison needs at least one ${noun}`);
|
|
11
|
+
const ids = terms.map((term) => term.id);
|
|
12
|
+
const duplicate = ids.find((id, index) => ids.indexOf(id) !== index);
|
|
13
|
+
if (duplicate !== void 0) throw new ValidationError(`${noun} '${duplicate}' is declared twice`);
|
|
14
|
+
const repairTurns = terms[0].repairTurns;
|
|
15
|
+
const unequal = terms.find((term) => term.repairTurns !== repairTurns);
|
|
16
|
+
if (unequal) throw new ValidationError(`${noun} '${unequal.id}' gets ${unequal.repairTurns} bounded repair turns and ${noun} '${terms[0].id}' gets ${repairTurns}; a retry is a second sample the other arms never got`);
|
|
17
|
+
return {
|
|
18
|
+
ids,
|
|
19
|
+
repairTurns
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { assertEqualDeclarativeTerms as t };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=equal-terms-Blx9Zk5I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"equal-terms-Blx9Zk5I.js","names":[],"sources":["../src/analyst/equal-terms.ts"],"sourcesContent":["import { ValidationError } from '../errors'\n\n/**\n * The terms every declarative-arm comparison must hold equal before any\n * per-kind check runs. Arm kinds (analyst definitions, repair arms) extend\n * the comparison with their own fields; the refusals here are the floor.\n */\nexport interface DeclarativeArmTerms {\n readonly id: string\n /** Bounded repair turns the arm earns on a malformed reply. */\n readonly repairTurns: number\n}\n\nexport interface EqualDeclarativeTerms {\n readonly ids: readonly string[]\n readonly repairTurns: number\n}\n\n/**\n * Refuses a comparison whose arms are not on equal terms: an empty set, a\n * duplicated id, or unequal repair turns — a retry is a second sample the\n * other arms never got. `noun` names the arm kind in every message so a\n * refusal reads in the caller's vocabulary.\n */\nexport function assertEqualDeclarativeTerms(\n noun: string,\n terms: ReadonlyArray<DeclarativeArmTerms>,\n): EqualDeclarativeTerms {\n if (terms.length === 0) {\n throw new ValidationError(`a ${noun} comparison needs at least one ${noun}`)\n }\n const ids = terms.map((term) => term.id)\n const duplicate = ids.find((id, index) => ids.indexOf(id) !== index)\n if (duplicate !== undefined) {\n throw new ValidationError(`${noun} '${duplicate}' is declared twice`)\n }\n const repairTurns = terms[0]!.repairTurns\n const unequal = terms.find((term) => term.repairTurns !== repairTurns)\n if (unequal) {\n throw new ValidationError(\n `${noun} '${unequal.id}' gets ${unequal.repairTurns} bounded repair turns and ` +\n `${noun} '${terms[0]!.id}' gets ${repairTurns}; a retry is a second sample ` +\n 'the other arms never got',\n )\n }\n return { ids, repairTurns }\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,4BACd,MACA,OACuB;CACvB,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,gBAAgB,KAAK,KAAK,iCAAiC,MAAM;CAE7E,MAAM,MAAM,MAAM,KAAK,SAAS,KAAK,EAAE;CACvC,MAAM,YAAY,IAAI,MAAM,IAAI,UAAU,IAAI,QAAQ,EAAE,MAAM,KAAK;CACnE,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,gBAAgB,GAAG,KAAK,IAAI,UAAU,oBAAoB;CAEtE,MAAM,cAAc,MAAM,EAAE,CAAE;CAC9B,MAAM,UAAU,MAAM,MAAM,SAAS,KAAK,gBAAgB,WAAW;CACrE,IAAI,SACF,MAAM,IAAI,gBACR,GAAG,KAAK,IAAI,QAAQ,GAAG,SAAS,QAAQ,YAAY,4BAC/C,KAAK,IAAI,MAAM,EAAE,CAAE,GAAG,SAAS,YAAY,sDAElD;CAEF,OAAO;EAAE;EAAK;CAAY;AAC5B"}
|