@tangle-network/agent-eval 0.132.0 → 0.133.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +1 -1
  3. package/dist/agent-profile-cell-OhuTee9n.js +335 -0
  4. package/dist/agent-profile-cell-OhuTee9n.js.map +1 -0
  5. package/dist/analyst/index.js +3 -3
  6. package/dist/{analyze-runs-BjPn_fOS.js → analyze-runs-B-afTpCv.js} +6 -19
  7. package/dist/analyze-runs-B-afTpCv.js.map +1 -0
  8. package/dist/{analyze-runs-AFDI5RI0.d.ts → analyze-runs-DZr7JW-m.d.ts} +2 -2
  9. package/dist/{analyze-runs-AFDI5RI0.d.ts.map → analyze-runs-DZr7JW-m.d.ts.map} +1 -1
  10. package/dist/{baseline-HsBvw_dk.js → baseline-DcX5hQDv.js} +2 -70
  11. package/dist/{baseline-HsBvw_dk.js.map → baseline-DcX5hQDv.js.map} +1 -1
  12. package/dist/baseline-hG3K85h4.d.ts.map +1 -1
  13. package/dist/benchmarks/index.d.ts +1 -1
  14. package/dist/benchmarks/index.js +1 -1
  15. package/dist/{benchmarks-DTrT3UH-.js → benchmarks-BU7P6PCW.js} +3 -3
  16. package/dist/{benchmarks-DTrT3UH-.js.map → benchmarks-BU7P6PCW.js.map} +1 -1
  17. package/dist/builder-eval/index.js +1 -1
  18. package/dist/campaign/index.d.ts +3 -3
  19. package/dist/campaign/index.js +2 -2
  20. package/dist/{campaign-Cx6CfMR4.js → campaign-CnzHQndg.js} +21 -15
  21. package/dist/{campaign-Cx6CfMR4.js.map → campaign-CnzHQndg.js.map} +1 -1
  22. package/dist/cli.js +1 -1
  23. package/dist/{client-aZDHJiKO.d.ts → client-D4F9hdzR.d.ts} +2 -2
  24. package/dist/{client-aZDHJiKO.d.ts.map → client-D4F9hdzR.d.ts.map} +1 -1
  25. package/dist/contract/index.d.ts +145 -6
  26. package/dist/contract/index.d.ts.map +1 -1
  27. package/dist/contract/index.js +1395 -11
  28. package/dist/contract/index.js.map +1 -1
  29. package/dist/control.js +1 -1
  30. package/dist/{cost-ledger-ZAa_P4r0.js → cost-ledger-BrJxbrMy.js} +238 -3
  31. package/dist/cost-ledger-BrJxbrMy.js.map +1 -0
  32. package/dist/{default-registry-B1JcpnRv.js → default-registry-D3T9XbuY.js} +3 -3
  33. package/dist/{default-registry-B1JcpnRv.js.map → default-registry-D3T9XbuY.js.map} +1 -1
  34. package/dist/{eval-campaign-mDKhkdUq.js → eval-campaign-DXhpZghy.js} +5 -6
  35. package/dist/{eval-campaign-mDKhkdUq.js.map → eval-campaign-DXhpZghy.js.map} +1 -1
  36. package/dist/{task-failure-attributes-CQZlB3et.js → extract-usage-2j25whHw.js} +154 -2
  37. package/dist/extract-usage-2j25whHw.js.map +1 -0
  38. package/dist/fuzz.js +1 -1
  39. package/dist/hosted/index.d.ts +1 -1
  40. package/dist/{index-3cdlURSk2.d.ts → index-3cdlURSk.d.ts} +1 -1
  41. package/dist/index-3cdlURSk.d.ts.map +1 -0
  42. package/dist/{index-FpfWFsKm.d.ts → index-Ba636PKl.d.ts} +29 -6
  43. package/dist/{index-FpfWFsKm.d.ts.map → index-Ba636PKl.d.ts.map} +1 -1
  44. package/dist/{index-p2TR_iWJ.d.ts → index-Wek5mU0y.d.ts} +3 -3
  45. package/dist/{index-p2TR_iWJ.d.ts.map → index-Wek5mU0y.d.ts.map} +1 -1
  46. package/dist/{index-BAvgST_9.d.ts → index-nhIYz9hn.d.ts} +67 -9
  47. package/dist/index-nhIYz9hn.d.ts.map +1 -0
  48. package/dist/index.d.ts +55 -9
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +111 -24
  51. package/dist/index.js.map +1 -1
  52. package/dist/ledger-core/index.d.ts +2 -2
  53. package/dist/ledger-core/index.js +2 -2
  54. package/dist/ledger-core-CPZfcrC2.js +620 -0
  55. package/dist/ledger-core-CPZfcrC2.js.map +1 -0
  56. package/dist/{llm-client-BNcP4v08.js → llm-client-ClPW-dWB.js} +2 -2
  57. package/dist/{llm-client-BNcP4v08.js.map → llm-client-ClPW-dWB.js.map} +1 -1
  58. package/dist/meta-eval/index.d.ts +215 -2
  59. package/dist/{index-CXs7QlR5.d.ts.map → meta-eval/index.d.ts.map} +1 -1
  60. package/dist/meta-eval/index.js +93 -3
  61. package/dist/meta-eval/index.js.map +1 -1
  62. package/dist/{mint-D5_87M5L.js → mint-BvkwcYZU.js} +2 -2
  63. package/dist/{mint-D5_87M5L.js.map → mint-BvkwcYZU.js.map} +1 -1
  64. package/dist/openapi.json +1 -1
  65. package/dist/{paired-arms-D9D0wXj2.js → paired-arms-6XItKzd1.js} +2 -2
  66. package/dist/{paired-arms-D9D0wXj2.js.map → paired-arms-6XItKzd1.js.map} +1 -1
  67. package/dist/pipelines/index.js +2 -2
  68. package/dist/profile-cell.js +1 -242
  69. package/dist/{propose-review-control-Bqb7daEJ.js → propose-review-control-SQ-n9-We.js} +2 -2
  70. package/dist/{propose-review-control-Bqb7daEJ.js.map → propose-review-control-SQ-n9-We.js.map} +1 -1
  71. package/dist/{release-report-oWt9f2k-.js → release-report-wuilQkvK.js} +3 -3
  72. package/dist/{release-report-oWt9f2k-.js.map → release-report-wuilQkvK.js.map} +1 -1
  73. package/dist/{replay-D18-pBAA.js → replay-CJfGLdx4.js} +4 -5
  74. package/dist/{replay-D18-pBAA.js.map → replay-CJfGLdx4.js.map} +1 -1
  75. package/dist/reporting.d.ts +1 -1
  76. package/dist/reporting.js +4 -4
  77. package/dist/{reward-hacking-BEvjdUtD.js → reward-hacking-Dl2UBzej.js} +3 -3
  78. package/dist/{reward-hacking-BEvjdUtD.js.map → reward-hacking-Dl2UBzej.js.map} +1 -1
  79. package/dist/rl.d.ts +153 -3
  80. package/dist/rl.d.ts.map +1 -1
  81. package/dist/rl.js +222 -7
  82. package/dist/rl.js.map +1 -1
  83. package/dist/rollout/index.d.ts +1 -1
  84. package/dist/rollout/index.js +2 -2
  85. package/dist/{rollout-VEo41J0N.js → rollout-CeTlDrf6.js} +2 -2
  86. package/dist/{rollout-VEo41J0N.js.map → rollout-CeTlDrf6.js.map} +1 -1
  87. package/dist/{rubric-predictive-validity-B3xmbmS1.js → rubric-predictive-validity-QG7ydk0s.js} +2 -2
  88. package/dist/{rubric-predictive-validity-B3xmbmS1.js.map → rubric-predictive-validity-QG7ydk0s.js.map} +1 -1
  89. package/dist/{run-record-CN8Zd21B.js → run-record-BIwU2wdV.js} +2 -2
  90. package/dist/{run-record-CN8Zd21B.js.map → run-record-BIwU2wdV.js.map} +1 -1
  91. package/dist/{semantic-concept-judge-DKCtoOz8.js → semantic-concept-judge-BypLt6Fw.js} +4 -4
  92. package/dist/{semantic-concept-judge-DKCtoOz8.js.map → semantic-concept-judge-BypLt6Fw.js.map} +1 -1
  93. package/dist/{server-Dc_lsOYd.js → server-BPqlDBWK.js} +3 -3
  94. package/dist/{server-Dc_lsOYd.js.map → server-BPqlDBWK.js.map} +1 -1
  95. package/dist/{skillopt-optimization-method-CQlz8GQM.js → skillopt-optimization-method-BoIzh7Dl.js} +6 -6
  96. package/dist/{skillopt-optimization-method-CQlz8GQM.js.map → skillopt-optimization-method-BoIzh7Dl.js.map} +1 -1
  97. package/dist/{skillopt-optimization-method-C9M_lxdo.d.ts → skillopt-optimization-method-CAASpcS3.d.ts} +3 -3
  98. package/dist/{skillopt-optimization-method-C9M_lxdo.d.ts.map → skillopt-optimization-method-CAASpcS3.d.ts.map} +1 -1
  99. package/dist/{statistics-CnnxdpOg.js → statistics-DWM_AyLe.js} +90 -76
  100. package/dist/statistics-DWM_AyLe.js.map +1 -0
  101. package/dist/statistics-DbvkkDPa.d.ts.map +1 -1
  102. package/dist/{summary-report-BNs5nmXI.js → summary-report-Ci17nIdU.js} +4 -4
  103. package/dist/{summary-report-BNs5nmXI.js.map → summary-report-Ci17nIdU.js.map} +1 -1
  104. package/dist/traces.js +2 -2
  105. package/dist/wire/index.js +1 -1
  106. package/package.json +2 -7
  107. package/dist/analyze-runs-BjPn_fOS.js.map +0 -1
  108. package/dist/belief-state/index.d.ts +0 -622
  109. package/dist/belief-state/index.d.ts.map +0 -1
  110. package/dist/belief-state/index.js +0 -1819
  111. package/dist/belief-state/index.js.map +0 -1
  112. package/dist/calibration-CNWWA6K8.js +0 -94
  113. package/dist/calibration-CNWWA6K8.js.map +0 -1
  114. package/dist/code-agent-session-BjkMTQ7H.js +0 -1390
  115. package/dist/code-agent-session-BjkMTQ7H.js.map +0 -1
  116. package/dist/code-agent-session-D5URqc3_.d.ts +0 -143
  117. package/dist/code-agent-session-D5URqc3_.d.ts.map +0 -1
  118. package/dist/cost-ledger-ZAa_P4r0.js.map +0 -1
  119. package/dist/extract-usage-BrQ8mCLX.js +0 -155
  120. package/dist/extract-usage-BrQ8mCLX.js.map +0 -1
  121. package/dist/index-3cdlURSk2.d.ts.map +0 -1
  122. package/dist/index-BAvgST_9.d.ts.map +0 -1
  123. package/dist/index-CXs7QlR5.d.ts +0 -217
  124. package/dist/ledger-core-eqaI3PCD.js +0 -388
  125. package/dist/ledger-core-eqaI3PCD.js.map +0 -1
  126. package/dist/metrics-C9YY1OcL.js +0 -239
  127. package/dist/metrics-C9YY1OcL.js.map +0 -1
  128. package/dist/off-policy-DvgzvtIx.js +0 -220
  129. package/dist/off-policy-DvgzvtIx.js.map +0 -1
  130. package/dist/off-policy-mskQw8Mb.d.ts +0 -153
  131. package/dist/off-policy-mskQw8Mb.d.ts.map +0 -1
  132. package/dist/pre-registration-DakwTRXk.js +0 -96
  133. package/dist/pre-registration-DakwTRXk.js.map +0 -1
  134. package/dist/profile-cell.js.map +0 -1
  135. package/dist/runtime-trajectory-1gyaTOoC.js +0 -93
  136. package/dist/runtime-trajectory-1gyaTOoC.js.map +0 -1
  137. package/dist/runtime-trajectory-BW9Wszb-.d.ts +0 -50
  138. package/dist/runtime-trajectory-BW9Wszb-.d.ts.map +0 -1
  139. package/dist/statistics-CnnxdpOg.js.map +0 -1
  140. package/dist/task-failure-attributes-CQZlB3et.js.map +0 -1
@@ -1,10 +1,9 @@
1
- import { r as hashJson, t as canonicalize } from "./pre-registration-DakwTRXk.js";
2
- import { buildAgentProfileCell, verifyAgentProfileCell } from "./profile-cell.js";
1
+ import { f as verifyAgentProfileCell, h as hashJson, p as canonicalize, s as buildAgentProfileCell } from "./agent-profile-cell-OhuTee9n.js";
3
2
  import { t as FileSystemRawProviderSink } from "./raw-provider-sink-BQd7mzyT.js";
4
- import { a as assertLlmRoute } from "./llm-client-BNcP4v08.js";
3
+ import { a as assertLlmRoute } from "./llm-client-ClPW-dWB.js";
5
4
  import { t as TraceEmitter } from "./emitter-CPBAhxum.js";
6
- import { s as validateRunRecord } from "./run-record-CN8Zd21B.js";
7
- import { i as researchReport } from "./summary-report-BNs5nmXI.js";
5
+ import { s as validateRunRecord } from "./run-record-BIwU2wdV.js";
6
+ import { i as researchReport } from "./summary-report-Ci17nIdU.js";
8
7
  import { n as assertRunCaptured, t as RunIntegrityError } from "./integrity-BzRbCHzi.js";
9
8
  //#region src/eval-campaign.ts
10
9
  /**
@@ -347,4 +346,4 @@ function defaultRunId(params) {
347
346
  //#endregion
348
347
  export { runEvalCampaign as t };
349
348
 
350
- //# sourceMappingURL=eval-campaign-mDKhkdUq.js.map
349
+ //# sourceMappingURL=eval-campaign-DXhpZghy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval-campaign-mDKhkdUq.js","names":[],"sources":["../src/eval-campaign.ts"],"sourcesContent":["/**\n * EvalCampaign — opinionated matrix runner that wires the four\n * capture-integrity directives by construction.\n *\n * The canonical benchmark shape — matrix runner → for each\n * (variant, scenario, seed) → start a TraceEmitter → call LLMs → end the\n * run → analyze — has a bug class at the integration boundary: raw\n * events not captured, route silently wrong, integrity not asserted,\n * analyst never run. The directives in `SKILL.md § Capture integrity`\n * are the mitigations.\n *\n * `EvalCampaign` is the structural fix — consumers don't wire the\n * integrity surface themselves; the campaign owns it. Specifically:\n *\n * - calls `assertLlmRoute` once at preflight before any work runs\n * - constructs a per-run `TraceStore` and `RawProviderSink` via factories\n * - constructs the `TraceEmitter` with `onRunComplete: [analyst hook]`\n * - hands the runner an `LlmClientOptions` pre-wired with the sink and\n * trace context — the runner can't accidentally call an LLM without\n * capturing the raw HTTP envelope\n * - calls `assertRunCaptured` after every `endRun` and routes failures\n * through a configurable policy (`throw` / `mark_failed` / `log`)\n * - assembles per-run `RunRecord`s and runs `researchReport` at the end\n * so the campaign artifact is launch-decision-grade by default\n * - embeds the campaign fingerprint (a SHA-256 over the canonicalised\n * run set) and optional `preregistrationHash` in the report\n *\n * The runner contract is intentionally narrow: produce a `CampaignRunOutcome`\n * given a fully-wired `CampaignRunContext`. Everything orchestration-shaped\n * lives in the campaign. This is the inversion-of-control point — consumers\n * stop writing matrix runners and start writing scenario-runners.\n *\n * Out of scope for v1 (tracked in `docs/research-report-methodology.md`):\n *\n * - Distributed/cluster execution (concurrency is local async)\n * - Adaptive sampling / sequential interim looks\n * - Resume from partial state across crashes\n * - LLM-call retry beyond what `LlmClient` already does\n */\n\nimport {\n type AgentProfileCell,\n type AgentProfileCellInput,\n buildAgentProfileCell,\n verifyAgentProfileCell,\n} from './agent-profile-cell'\nimport { assertLlmRoute, type LlmClientOptions, type LlmRouteRequirements } from './llm-client'\nimport { canonicalize, hashJson } from './pre-registration'\nimport type {\n JudgeScoresRecord,\n RunCostProvenance,\n RunJudgeMetadata,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTaskFailure,\n RunTokenUsage,\n} from './run-record'\nimport { validateRunRecord } from './run-record'\nimport { type ResearchReport, type ResearchReportOptions, researchReport } from './summary-report'\nimport type { RunCompleteHook } from './trace/emitter'\nimport { TraceEmitter } from './trace/emitter'\nimport {\n assertRunCaptured,\n RunIntegrityError,\n type RunIntegrityExpectations,\n type RunIntegrityReport,\n} from './trace/integrity'\nimport { FileSystemRawProviderSink, type RawProviderSink } from './trace/raw-provider-sink'\nimport type { TraceStore } from './trace/store'\n\n// ── Public types ─────────────────────────────────────────────────────────\n\nexport interface CampaignVariant<V> {\n id: string\n payload: V\n}\n\nexport interface CampaignScenario {\n scenarioId: string\n /** Free-form metadata propagated to runs and reports. */\n tags?: Record<string, string>\n}\n\nexport interface CampaignRunContext<V> {\n /** Stable run id. The campaign generates this; the runner does not. */\n runId: string\n /** Logical experiment id (campaignId by default; overridable per-run via opts). */\n experimentId: string\n variant: V\n variantId: string\n scenarioId: string\n scenarioTags: Record<string, string>\n seed: number\n splitTag: RunSplitTag\n /**\n * The TraceEmitter for this run, with `onRunComplete` hooks pre-wired\n * (analyst auto-execution if configured, plus integrity check). The\n * runner MUST call `emitter.startRun` before doing any work and either\n * `emitter.endRun` or `emitter.abortRun` before returning.\n */\n emitter: TraceEmitter\n store: TraceStore\n rawSink: RawProviderSink\n /**\n * Pre-wired LLM client options — `rawSink` and `traceContext` are populated\n * so any `callLlm(req, ctx.llmOpts)` automatically captures raw HTTP. The\n * runner can spread additional fields if needed.\n */\n llmOpts: LlmClientOptions\n}\n\ninterface CampaignRunOutcomeFields {\n /** Did the run pass? Mirrors `RunOutcome.pass` semantics. */\n pass: boolean\n /** Score for the run on its split. Maps to `searchScore` or `holdoutScore`. */\n score: number\n /** Cost in USD, or null when the runner could not capture it. */\n costUsd: number | null\n /** Source of the cost amount. */\n costProvenance: RunCostProvenance\n tokenUsage: RunTokenUsage\n /** Snapshot model id (e.g. `claude-sonnet-4-6@2025-04-15`). */\n model: string\n /** sha256 of the effective prompt sent to the model. */\n promptHash: string\n /** sha256 of the effective config (model, temperature, tools, judges, splits). */\n configHash: string\n /** Optional extra numeric metrics to land in `outcome.raw`. */\n raw?: Record<string, number>\n /** Optional judge metadata when a judge was used. */\n judgeMetadata?: RunJudgeMetadata\n /**\n * Optional per-judge / per-dim breakdown for ensemble-judged runs.\n * Propagated to `outcome.judgeScores` on the resulting `RunRecord`.\n * Single-judge or scalar-only runs leave this unset.\n */\n judgeScores?: JudgeScoresRecord\n /**\n * Agent profile cell observed by the runner. When supplied, it overrides\n * `EvalCampaignOptions.agentProfile` for this run and must match the\n * outcome's `model` and `promptHash`.\n */\n agentProfile?: AgentProfileCell | AgentProfileCellInput\n}\n\n/** Campaign result with the same task-failure invariant as `RunRecord`. */\nexport type CampaignRunOutcome = CampaignRunOutcomeFields & RunTaskFailure\n\nexport type CampaignRunner<V> = (ctx: CampaignRunContext<V>) => Promise<CampaignRunOutcome>\n\nexport type CampaignIntegrityPolicy = 'throw' | 'mark_failed' | 'log'\n\nexport interface EvalCampaignOptions<V> {\n /**\n * Stable id for the campaign. Used as the default `experimentId` on\n * every run, and folded into the campaign fingerprint.\n */\n campaignId: string\n variants: CampaignVariant<V>[]\n scenarios: CampaignScenario[]\n /** Default `[0, 1, 2]`. */\n seeds?: number[]\n /** Default `'holdout'` — the split that anchors a launch decision. */\n splitTag?: RunSplitTag\n /** Git SHA the campaign is run against. Mandatory; `RunRecord` rejects unset. */\n commitSha: string\n /**\n * LLM client config. Augmented per-run with `rawSink` and `traceContext`\n * before being passed to the runner. The campaign asserts this config\n * matches `routeRequirements` once at preflight.\n */\n llmOpts: LlmClientOptions\n /**\n * Default `{ requireExplicitBaseUrl: true, requireAuth: true }` — fail\n * loud if the campaign would silently fall back to the public router or\n * run unauthenticated. Override with an empty object to disable.\n */\n routeRequirements?: LlmRouteRequirements\n /**\n * Per-run TraceStore factory. Common shape: a fresh store per run keyed\n * on `runId`. Implementations that share a store across the campaign\n * are valid — the campaign only writes through `emitter`.\n */\n storeFactory: (params: CampaignFactoryParams) => TraceStore\n /**\n * Per-run RawProviderSink factory. Defaults to `FileSystemRawProviderSink`\n * rooted at `${workDir}/raw-events/${runId}` if `workDir` is supplied;\n * otherwise required. Forensic capture is non-negotiable in a campaign\n * run — pass `NoopRawProviderSink` explicitly if you want to opt out.\n */\n rawSinkFactory?: (params: CampaignFactoryParams) => RawProviderSink\n /**\n * Filesystem root for default `rawSinkFactory`. Ignored if\n * `rawSinkFactory` is supplied.\n */\n workDir?: string\n /**\n * Extra `onRunComplete` hooks the campaign appends (after its own\n * integrity-check hook). Pass `traceAnalystOnRunComplete(...)` here.\n */\n onRunComplete?: RunCompleteHook[]\n /**\n * Per-run integrity expectations. Defaults to:\n * `{ llmSpansMin: 1, requireRawCoverageOfLlmSpans: true, requireOutcome: true }`.\n * Override (e.g. `{ llmSpansMin: 0 }`) for runs that don't call LLMs.\n */\n integrity?: RunIntegrityExpectations\n /** Behaviour when integrity fails. Default `'mark_failed'`. */\n onIntegrityFailure?: CampaignIntegrityPolicy\n /**\n * Per-run runner. Receives a fully-wired context; produces an outcome\n * the campaign converts into a `RunRecord`.\n */\n runner: CampaignRunner<V>\n /**\n * If set, the campaign computes `researchReport` at the end. `comparator`\n * is a `variantId`. Other fields are forwarded verbatim.\n */\n report?: { comparator?: string } & Omit<\n ResearchReportOptions,\n 'comparator' | 'preregistrationHash' | 'generatedAt'\n >\n /**\n * Hash of a signed `HypothesisManifest` (see `pre-registration.ts`).\n * Embedded in the campaign fingerprint and the research report.\n */\n preregistrationHash?: string\n /** Local concurrency. Default `1` (sequential). */\n concurrency?: number\n /**\n * Override the time source. Tests pass a mock to make wallMs deterministic.\n */\n now?: () => number\n /** Override the runId generator. Tests pin this. */\n runId?: (params: CampaignFactoryParams) => string\n /**\n * Agent profile cell for campaign runs. Static profiles can pass an object;\n * routers or variant-specific harnesses can pass a factory. The campaign\n * stamps the built cell onto every `RunRecord` and rejects profile/model or\n * profile/prompt contradictions.\n */\n agentProfile?:\n | AgentProfileCell\n | AgentProfileCellInput\n | ((\n params: CampaignFactoryParams & {\n variant: V\n scenarioTags: Record<string, string>\n },\n ) =>\n | AgentProfileCell\n | AgentProfileCellInput\n | Promise<AgentProfileCell | AgentProfileCellInput>)\n}\n\nexport interface CampaignFactoryParams {\n campaignId: string\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n}\n\nexport interface FailedRun {\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n reason: string\n error?: string\n}\n\nexport interface EvalCampaignResult {\n campaignId: string\n /** SHA-256 over canonicalised `(variantIds, scenarioIds, seeds, comparator, splitTag, baseUrl, provider, preregistrationHash)`. */\n campaignFingerprint: string\n preregistrationHash: string | null\n /** Successful runs only. Failed runs land in `failedRuns`. */\n runs: RunRecord[]\n /** Integrity reports for every successful run. */\n integrityReports: RunIntegrityReport[]\n failedRuns: FailedRun[]\n /** Computed when `report` is set on options. */\n report?: ResearchReport\n startedAt: string\n endedAt: string\n}\n\n// ── Implementation ───────────────────────────────────────────────────────\n\nconst DEFAULT_INTEGRITY: RunIntegrityExpectations = {\n llmSpansMin: 1,\n requireRawCoverageOfLlmSpans: true,\n requireOutcome: true,\n}\n\nconst DEFAULT_ROUTE: LlmRouteRequirements = {\n requireExplicitBaseUrl: true,\n requireAuth: true,\n}\n\nexport async function runEvalCampaign<V>(\n opts: EvalCampaignOptions<V>,\n): Promise<EvalCampaignResult> {\n // ── Preflight ──────────────────────────────────────────────────────\n assertLlmRoute(opts.llmOpts, opts.routeRequirements ?? DEFAULT_ROUTE)\n\n if (opts.variants.length === 0) {\n throw new Error('runEvalCampaign: variants must be non-empty.')\n }\n if (opts.scenarios.length === 0) {\n throw new Error('runEvalCampaign: scenarios must be non-empty.')\n }\n const variantIds = new Set<string>()\n for (const v of opts.variants) {\n if (variantIds.has(v.id)) {\n throw new Error(`runEvalCampaign: duplicate variant id \"${v.id}\".`)\n }\n variantIds.add(v.id)\n }\n const scenarioIds = new Set<string>()\n for (const s of opts.scenarios) {\n if (scenarioIds.has(s.scenarioId)) {\n throw new Error(`runEvalCampaign: duplicate scenarioId \"${s.scenarioId}\".`)\n }\n scenarioIds.add(s.scenarioId)\n }\n if (opts.report?.comparator && !variantIds.has(opts.report.comparator)) {\n throw new Error(\n `runEvalCampaign: report.comparator \"${opts.report.comparator}\" is not a configured variantId.`,\n )\n }\n if (!opts.commitSha) {\n throw new Error('runEvalCampaign: commitSha is required (every RunRecord needs it).')\n }\n\n const seeds = opts.seeds ?? [0, 1, 2]\n const splitTag: RunSplitTag = opts.splitTag ?? 'holdout'\n const concurrency = Math.max(1, opts.concurrency ?? 1)\n const integrity = { ...DEFAULT_INTEGRITY, ...(opts.integrity ?? {}) }\n const onIntegrityFailure: CampaignIntegrityPolicy = opts.onIntegrityFailure ?? 'mark_failed'\n const now = opts.now ?? (() => Date.now())\n const baseUrl = (opts.llmOpts.baseUrl ?? '').replace(/\\/+$/, '')\n const provider = opts.llmOpts.provider ?? null\n const preregistrationHash = opts.preregistrationHash ?? null\n\n const rawSinkFactory = opts.rawSinkFactory ?? defaultRawSinkFactory(opts.workDir)\n\n // ── Fingerprint ────────────────────────────────────────────────────\n const campaignFingerprint = await hashJson(\n canonicalize({\n campaignId: opts.campaignId,\n variants: opts.variants.map((v) => v.id).sort(),\n scenarios: opts.scenarios.map((s) => s.scenarioId).sort(),\n seeds: [...seeds].sort((a, b) => a - b),\n splitTag,\n comparator: opts.report?.comparator ?? null,\n baseUrl,\n provider,\n preregistrationHash,\n }),\n )\n\n // ── Plan the matrix ────────────────────────────────────────────────\n type Cell = { variant: CampaignVariant<V>; scenario: CampaignScenario; seed: number }\n const cells: Cell[] = []\n for (const variant of opts.variants) {\n for (const scenario of opts.scenarios) {\n for (const seed of seeds) {\n cells.push({ variant, scenario, seed })\n }\n }\n }\n\n const startedAt = new Date(now()).toISOString()\n const runs: RunRecord[] = []\n const integrityReports: RunIntegrityReport[] = []\n const failedRuns: FailedRun[] = []\n\n // ── Execute (bounded-concurrency worker pool) ──────────────────────\n // A genuine (non-CellExecutionError) error from any worker is a bug, not a\n // run-level failure. We must NOT let `Promise.all` reject mid-flight and\n // orphan the other workers' in-progress runs (emitters never finalized,\n // sinks/handles leak, partial work silently discarded). Instead: capture the\n // first genuine error, stop dispatching new cells so in-flight workers wind\n // down, finalize every still-open run, then re-throw the aggregated error.\n let cursor = 0\n let aborting = false\n const genuineErrors: unknown[] = []\n // Emitters for runs that are currently mid-flight, keyed by runId. A worker\n // registers its emitter before invoking the runner and removes it once the\n // run is finalized (via endRun/abortRun, success or failure). Anything left\n // here after the pool settles is an orphan we must abort.\n const openRuns = new Map<string, TraceEmitter>()\n\n async function worker(): Promise<void> {\n while (!aborting) {\n const i = cursor++\n if (i >= cells.length) return\n const cell = cells[i]!\n try {\n const result = await runOneCell(cell)\n runs.push(result.record)\n integrityReports.push(result.integrity)\n } catch (err) {\n if (err instanceof CellExecutionError) {\n failedRuns.push(err.failed)\n if (err.integrity) integrityReports.push(err.integrity)\n } else {\n // Genuine bug — not a runner failure, not an integrity failure.\n // Capture it and stop dispatching so peers wind down gracefully;\n // re-thrown after the pool settles. Do not surface here — that would\n // reject Promise.all and orphan the other workers' runs.\n genuineErrors.push(err)\n aborting = true\n return\n }\n }\n }\n }\n\n async function runOneCell(\n cell: Cell,\n ): Promise<{ record: RunRecord; integrity: RunIntegrityReport }> {\n const runId = (opts.runId ?? defaultRunId)({\n campaignId: opts.campaignId,\n runId: '', // unused by default generator\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n })\n const factoryParams: CampaignFactoryParams = {\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n }\n const store = opts.storeFactory(factoryParams)\n const rawSink = rawSinkFactory(factoryParams)\n\n const emitter = new TraceEmitter(store, {\n runId,\n now: opts.now,\n onRunComplete: opts.onRunComplete,\n })\n // Track this run as open so a genuine error elsewhere in the pool can\n // finalize it instead of orphaning it. Removed in the finally below.\n openRuns.set(runId, emitter)\n\n const llmOpts: LlmClientOptions = {\n ...opts.llmOpts,\n rawSink,\n traceContext: { runId },\n }\n\n const ctx: CampaignRunContext<V> = {\n runId,\n experimentId: opts.campaignId,\n variant: cell.variant.payload,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n scenarioTags: cell.scenario.tags ?? {},\n seed: cell.seed,\n splitTag,\n emitter,\n store,\n rawSink,\n llmOpts,\n }\n\n try {\n const wallStart = now()\n let outcome: CampaignRunOutcome\n try {\n outcome = await opts.runner(ctx)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // The runner threw mid-execution. Abort the run so the emitter\n // finalizes. The only benign abortRun failure is \"the runner never\n // started the run\" (nothing to finalize). A store-write failure (disk\n // full, FS error) is a genuine diagnostic — surface it rather than\n // masking it as a plain runner failure.\n await finalizeAbort(emitter, runId, message)\n throw new CellExecutionError({\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'runner_threw',\n error: message,\n })\n }\n const wallMs = now() - wallStart\n\n const integrityReport = await assertRunCaptured(store, runId, { ...integrity, rawSink })\n if (!integrityReport.ok) {\n switch (onIntegrityFailure) {\n case 'throw':\n throw new RunIntegrityError(integrityReport)\n case 'mark_failed':\n throw new CellExecutionError(\n {\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'integrity_failed',\n error: integrityReport.issues.map((i) => i.code).join(', '),\n },\n integrityReport,\n )\n case 'log':\n // Caller wants the run admitted with a flagged report; fall through.\n break\n }\n }\n\n const recordOutcome: RunOutcome = {\n raw: outcome.raw ?? {},\n }\n if (splitTag === 'holdout') recordOutcome.holdoutScore = outcome.score\n else recordOutcome.searchScore = outcome.score\n if (outcome.judgeScores !== undefined) recordOutcome.judgeScores = outcome.judgeScores\n\n const record: RunRecord = {\n runId,\n experimentId: opts.campaignId,\n candidateId: cell.variant.id,\n seed: cell.seed,\n model: outcome.model,\n promptHash: outcome.promptHash,\n configHash: outcome.configHash,\n commitSha: opts.commitSha,\n wallMs,\n costUsd: outcome.costUsd,\n costProvenance: outcome.costProvenance,\n tokenUsage: outcome.tokenUsage,\n terminalOutcome: 'succeeded',\n judgeMetadata: outcome.judgeMetadata,\n outcome: recordOutcome,\n ...(outcome.failureClass ? { failureClass: outcome.failureClass } : {}),\n failureMode: outcome.failureMode,\n splitTag,\n scenarioId: cell.scenario.scenarioId,\n }\n const profileSource =\n outcome.agentProfile ??\n (typeof opts.agentProfile === 'function'\n ? await opts.agentProfile({\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n variant: cell.variant.payload,\n scenarioTags: cell.scenario.tags ?? {},\n })\n : opts.agentProfile)\n if (profileSource !== undefined) {\n const agentProfile = await resolveAgentProfileCell(profileSource)\n assertAgentProfileMatchesRun(agentProfile, outcome.model, outcome.promptHash)\n record.agentProfile = agentProfile\n }\n return { record: validateRunRecord(record), integrity: integrityReport }\n } finally {\n // This run's worker has finished with it (success, run-level failure, or\n // genuine error). It is no longer the pool's job to finalize — drop it so\n // the post-settle sweep doesn't double-abort a finalized run.\n openRuns.delete(runId)\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, cells.length) }, () => worker())\n // allSettled (not all): a genuine error in one worker must not reject the\n // pool mid-flight and orphan the others. Each worker captures its own\n // genuine error into `genuineErrors` and returns; we re-throw below.\n await Promise.allSettled(workers)\n\n // Finalize any run still open after the pool wound down. With the\n // stop-dispatch flag these are the runs that were mid-flight in peer workers\n // when the first genuine error fired — abort them so their emitters finalize\n // (hooks fire, store records a terminal status) instead of leaking.\n for (const [runId, emitter] of openRuns) {\n await finalizeAbort(emitter, runId, 'campaign aborted: genuine error in a sibling run')\n }\n openRuns.clear()\n\n if (genuineErrors.length > 0) {\n throw genuineErrors.length === 1\n ? genuineErrors[0]\n : new AggregateError(\n genuineErrors,\n `runEvalCampaign: ${genuineErrors.length} runs failed with genuine (non-run-level) errors`,\n )\n }\n\n // ── Optional research report ───────────────────────────────────────\n let report: ResearchReport | undefined\n if (opts.report) {\n const reportOpts: ResearchReportOptions = {\n ...opts.report,\n comparator: opts.report.comparator,\n split: splitTag === 'dev' ? 'search' : splitTag,\n generatedAt: new Date(now()).toISOString(),\n preregistrationHash: preregistrationHash ?? undefined,\n }\n report = await researchReport(runs, reportOpts)\n }\n\n const endedAt = new Date(now()).toISOString()\n\n return {\n campaignId: opts.campaignId,\n campaignFingerprint,\n preregistrationHash,\n runs,\n integrityReports,\n failedRuns,\n report,\n startedAt,\n endedAt,\n }\n}\n\n// ── Internal ─────────────────────────────────────────────────────────────\n\nclass CellExecutionError extends Error {\n readonly failed: FailedRun\n readonly integrity?: RunIntegrityReport\n constructor(failed: FailedRun, integrity?: RunIntegrityReport) {\n super(`cell ${failed.variantId}/${failed.scenarioId}@${failed.seed} failed: ${failed.reason}`)\n this.failed = failed\n this.integrity = integrity\n }\n}\n\n/**\n * Abort a run whose owning work threw or was orphaned by a sibling's genuine\n * error, finalizing the emitter so hooks fire and the store records a terminal\n * status. Safe to call unconditionally: it only aborts runs that are still\n * `running`. Two no-op cases are intentional and benign:\n *\n * - the run was never started (absent from the store) — nothing to finalize\n * - the run is already terminal (`completed` / `failed` / `aborted`) —\n * finalizing again would overwrite the real outcome (e.g. flip a passed run\n * to `aborted` with `{ pass: false, notes: reason }`), so we leave it alone\n *\n * Any OTHER failure of the store read or the abort write (disk full, FS fault,\n * backend down) is a genuine diagnostic and propagates rather than being\n * swallowed.\n */\nexport async function finalizeAbort(\n emitter: TraceEmitter,\n runId: string,\n reason: string,\n): Promise<void> {\n const existing = await emitter.traceStore.getRun(runId)\n if (existing === undefined) return // run never started; nothing to abort\n if (existing.status !== 'running') return // already finalized; never overwrite a real outcome\n await emitter.abortRun(reason)\n}\n\nfunction defaultRawSinkFactory(workDir: string | undefined) {\n return (params: CampaignFactoryParams): RawProviderSink => {\n if (!workDir) {\n throw new Error(\n 'runEvalCampaign: rawSinkFactory not supplied and workDir not set. Pass either to enable raw provider capture, or pass `new NoopRawProviderSink()` via rawSinkFactory to opt out explicitly.',\n )\n }\n return new FileSystemRawProviderSink({\n dir: `${workDir}/raw-events/${params.runId}`,\n })\n }\n}\n\nasync function resolveAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n if (isAgentProfileCell(input)) {\n if (!(await verifyAgentProfileCell(input))) {\n throw new Error(`runEvalCampaign: agentProfile.cellId does not match its content`)\n }\n return input\n }\n return buildAgentProfileCell(input)\n}\n\nfunction isAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): input is AgentProfileCell {\n return 'schemaVersion' in input && 'cellId' in input\n}\n\nfunction assertAgentProfileMatchesRun(\n profile: AgentProfileCell,\n model: string,\n promptHash: string,\n): void {\n if (profile.model !== undefined && profile.model !== model) {\n throw new Error(\n `runEvalCampaign: agentProfile.model \"${profile.model}\" does not match outcome.model \"${model}\"`,\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== promptHash) {\n throw new Error(\n `runEvalCampaign: agentProfile.promptHash \"${profile.promptHash}\" does not match outcome.promptHash \"${promptHash}\"`,\n )\n }\n}\n\nfunction defaultRunId(params: CampaignFactoryParams): string {\n // Stable across re-runs: fingerprint of (campaignId, variantId, scenarioId, seed).\n // Caller can override via opts.runId for non-deterministic IDs.\n const base = `${params.campaignId}::${params.variantId}::${params.scenarioId}::${params.seed}`\n // Lightweight hex: we don't need crypto-grade here, just stability + uniqueness.\n let h1 = 0x811c9dc5\n let h2 = 0x12345678\n for (let i = 0; i < base.length; i++) {\n const c = base.charCodeAt(i)\n h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0\n h2 = Math.imul(h2 ^ c, 0x9e3779b1) >>> 0\n }\n return `run-${h1.toString(16).padStart(8, '0')}${h2.toString(16).padStart(8, '0')}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"eval-campaign-DXhpZghy.js","names":[],"sources":["../src/eval-campaign.ts"],"sourcesContent":["/**\n * EvalCampaign — opinionated matrix runner that wires the four\n * capture-integrity directives by construction.\n *\n * The canonical benchmark shape — matrix runner → for each\n * (variant, scenario, seed) → start a TraceEmitter → call LLMs → end the\n * run → analyze — has a bug class at the integration boundary: raw\n * events not captured, route silently wrong, integrity not asserted,\n * analyst never run. The directives in `SKILL.md § Capture integrity`\n * are the mitigations.\n *\n * `EvalCampaign` is the structural fix — consumers don't wire the\n * integrity surface themselves; the campaign owns it. Specifically:\n *\n * - calls `assertLlmRoute` once at preflight before any work runs\n * - constructs a per-run `TraceStore` and `RawProviderSink` via factories\n * - constructs the `TraceEmitter` with `onRunComplete: [analyst hook]`\n * - hands the runner an `LlmClientOptions` pre-wired with the sink and\n * trace context — the runner can't accidentally call an LLM without\n * capturing the raw HTTP envelope\n * - calls `assertRunCaptured` after every `endRun` and routes failures\n * through a configurable policy (`throw` / `mark_failed` / `log`)\n * - assembles per-run `RunRecord`s and runs `researchReport` at the end\n * so the campaign artifact is launch-decision-grade by default\n * - embeds the campaign fingerprint (a SHA-256 over the canonicalised\n * run set) and optional `preregistrationHash` in the report\n *\n * The runner contract is intentionally narrow: produce a `CampaignRunOutcome`\n * given a fully-wired `CampaignRunContext`. Everything orchestration-shaped\n * lives in the campaign. This is the inversion-of-control point — consumers\n * stop writing matrix runners and start writing scenario-runners.\n *\n * Out of scope for v1 (tracked in `docs/research-report-methodology.md`):\n *\n * - Distributed/cluster execution (concurrency is local async)\n * - Adaptive sampling / sequential interim looks\n * - Resume from partial state across crashes\n * - LLM-call retry beyond what `LlmClient` already does\n */\n\nimport {\n type AgentProfileCell,\n type AgentProfileCellInput,\n buildAgentProfileCell,\n verifyAgentProfileCell,\n} from './agent-profile-cell'\nimport { assertLlmRoute, type LlmClientOptions, type LlmRouteRequirements } from './llm-client'\nimport { canonicalize, hashJson } from './pre-registration'\nimport type {\n JudgeScoresRecord,\n RunCostProvenance,\n RunJudgeMetadata,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTaskFailure,\n RunTokenUsage,\n} from './run-record'\nimport { validateRunRecord } from './run-record'\nimport { type ResearchReport, type ResearchReportOptions, researchReport } from './summary-report'\nimport type { RunCompleteHook } from './trace/emitter'\nimport { TraceEmitter } from './trace/emitter'\nimport {\n assertRunCaptured,\n RunIntegrityError,\n type RunIntegrityExpectations,\n type RunIntegrityReport,\n} from './trace/integrity'\nimport { FileSystemRawProviderSink, type RawProviderSink } from './trace/raw-provider-sink'\nimport type { TraceStore } from './trace/store'\n\n// ── Public types ─────────────────────────────────────────────────────────\n\nexport interface CampaignVariant<V> {\n id: string\n payload: V\n}\n\nexport interface CampaignScenario {\n scenarioId: string\n /** Free-form metadata propagated to runs and reports. */\n tags?: Record<string, string>\n}\n\nexport interface CampaignRunContext<V> {\n /** Stable run id. The campaign generates this; the runner does not. */\n runId: string\n /** Logical experiment id (campaignId by default; overridable per-run via opts). */\n experimentId: string\n variant: V\n variantId: string\n scenarioId: string\n scenarioTags: Record<string, string>\n seed: number\n splitTag: RunSplitTag\n /**\n * The TraceEmitter for this run, with `onRunComplete` hooks pre-wired\n * (analyst auto-execution if configured, plus integrity check). The\n * runner MUST call `emitter.startRun` before doing any work and either\n * `emitter.endRun` or `emitter.abortRun` before returning.\n */\n emitter: TraceEmitter\n store: TraceStore\n rawSink: RawProviderSink\n /**\n * Pre-wired LLM client options — `rawSink` and `traceContext` are populated\n * so any `callLlm(req, ctx.llmOpts)` automatically captures raw HTTP. The\n * runner can spread additional fields if needed.\n */\n llmOpts: LlmClientOptions\n}\n\ninterface CampaignRunOutcomeFields {\n /** Did the run pass? Mirrors `RunOutcome.pass` semantics. */\n pass: boolean\n /** Score for the run on its split. Maps to `searchScore` or `holdoutScore`. */\n score: number\n /** Cost in USD, or null when the runner could not capture it. */\n costUsd: number | null\n /** Source of the cost amount. */\n costProvenance: RunCostProvenance\n tokenUsage: RunTokenUsage\n /** Snapshot model id (e.g. `claude-sonnet-4-6@2025-04-15`). */\n model: string\n /** sha256 of the effective prompt sent to the model. */\n promptHash: string\n /** sha256 of the effective config (model, temperature, tools, judges, splits). */\n configHash: string\n /** Optional extra numeric metrics to land in `outcome.raw`. */\n raw?: Record<string, number>\n /** Optional judge metadata when a judge was used. */\n judgeMetadata?: RunJudgeMetadata\n /**\n * Optional per-judge / per-dim breakdown for ensemble-judged runs.\n * Propagated to `outcome.judgeScores` on the resulting `RunRecord`.\n * Single-judge or scalar-only runs leave this unset.\n */\n judgeScores?: JudgeScoresRecord\n /**\n * Agent profile cell observed by the runner. When supplied, it overrides\n * `EvalCampaignOptions.agentProfile` for this run and must match the\n * outcome's `model` and `promptHash`.\n */\n agentProfile?: AgentProfileCell | AgentProfileCellInput\n}\n\n/** Campaign result with the same task-failure invariant as `RunRecord`. */\nexport type CampaignRunOutcome = CampaignRunOutcomeFields & RunTaskFailure\n\nexport type CampaignRunner<V> = (ctx: CampaignRunContext<V>) => Promise<CampaignRunOutcome>\n\nexport type CampaignIntegrityPolicy = 'throw' | 'mark_failed' | 'log'\n\nexport interface EvalCampaignOptions<V> {\n /**\n * Stable id for the campaign. Used as the default `experimentId` on\n * every run, and folded into the campaign fingerprint.\n */\n campaignId: string\n variants: CampaignVariant<V>[]\n scenarios: CampaignScenario[]\n /** Default `[0, 1, 2]`. */\n seeds?: number[]\n /** Default `'holdout'` — the split that anchors a launch decision. */\n splitTag?: RunSplitTag\n /** Git SHA the campaign is run against. Mandatory; `RunRecord` rejects unset. */\n commitSha: string\n /**\n * LLM client config. Augmented per-run with `rawSink` and `traceContext`\n * before being passed to the runner. The campaign asserts this config\n * matches `routeRequirements` once at preflight.\n */\n llmOpts: LlmClientOptions\n /**\n * Default `{ requireExplicitBaseUrl: true, requireAuth: true }` — fail\n * loud if the campaign would silently fall back to the public router or\n * run unauthenticated. Override with an empty object to disable.\n */\n routeRequirements?: LlmRouteRequirements\n /**\n * Per-run TraceStore factory. Common shape: a fresh store per run keyed\n * on `runId`. Implementations that share a store across the campaign\n * are valid — the campaign only writes through `emitter`.\n */\n storeFactory: (params: CampaignFactoryParams) => TraceStore\n /**\n * Per-run RawProviderSink factory. Defaults to `FileSystemRawProviderSink`\n * rooted at `${workDir}/raw-events/${runId}` if `workDir` is supplied;\n * otherwise required. Forensic capture is non-negotiable in a campaign\n * run — pass `NoopRawProviderSink` explicitly if you want to opt out.\n */\n rawSinkFactory?: (params: CampaignFactoryParams) => RawProviderSink\n /**\n * Filesystem root for default `rawSinkFactory`. Ignored if\n * `rawSinkFactory` is supplied.\n */\n workDir?: string\n /**\n * Extra `onRunComplete` hooks the campaign appends (after its own\n * integrity-check hook). Pass `traceAnalystOnRunComplete(...)` here.\n */\n onRunComplete?: RunCompleteHook[]\n /**\n * Per-run integrity expectations. Defaults to:\n * `{ llmSpansMin: 1, requireRawCoverageOfLlmSpans: true, requireOutcome: true }`.\n * Override (e.g. `{ llmSpansMin: 0 }`) for runs that don't call LLMs.\n */\n integrity?: RunIntegrityExpectations\n /** Behaviour when integrity fails. Default `'mark_failed'`. */\n onIntegrityFailure?: CampaignIntegrityPolicy\n /**\n * Per-run runner. Receives a fully-wired context; produces an outcome\n * the campaign converts into a `RunRecord`.\n */\n runner: CampaignRunner<V>\n /**\n * If set, the campaign computes `researchReport` at the end. `comparator`\n * is a `variantId`. Other fields are forwarded verbatim.\n */\n report?: { comparator?: string } & Omit<\n ResearchReportOptions,\n 'comparator' | 'preregistrationHash' | 'generatedAt'\n >\n /**\n * Hash of a signed `HypothesisManifest` (see `pre-registration.ts`).\n * Embedded in the campaign fingerprint and the research report.\n */\n preregistrationHash?: string\n /** Local concurrency. Default `1` (sequential). */\n concurrency?: number\n /**\n * Override the time source. Tests pass a mock to make wallMs deterministic.\n */\n now?: () => number\n /** Override the runId generator. Tests pin this. */\n runId?: (params: CampaignFactoryParams) => string\n /**\n * Agent profile cell for campaign runs. Static profiles can pass an object;\n * routers or variant-specific harnesses can pass a factory. The campaign\n * stamps the built cell onto every `RunRecord` and rejects profile/model or\n * profile/prompt contradictions.\n */\n agentProfile?:\n | AgentProfileCell\n | AgentProfileCellInput\n | ((\n params: CampaignFactoryParams & {\n variant: V\n scenarioTags: Record<string, string>\n },\n ) =>\n | AgentProfileCell\n | AgentProfileCellInput\n | Promise<AgentProfileCell | AgentProfileCellInput>)\n}\n\nexport interface CampaignFactoryParams {\n campaignId: string\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n}\n\nexport interface FailedRun {\n runId: string\n variantId: string\n scenarioId: string\n seed: number\n reason: string\n error?: string\n}\n\nexport interface EvalCampaignResult {\n campaignId: string\n /** SHA-256 over canonicalised `(variantIds, scenarioIds, seeds, comparator, splitTag, baseUrl, provider, preregistrationHash)`. */\n campaignFingerprint: string\n preregistrationHash: string | null\n /** Successful runs only. Failed runs land in `failedRuns`. */\n runs: RunRecord[]\n /** Integrity reports for every successful run. */\n integrityReports: RunIntegrityReport[]\n failedRuns: FailedRun[]\n /** Computed when `report` is set on options. */\n report?: ResearchReport\n startedAt: string\n endedAt: string\n}\n\n// ── Implementation ───────────────────────────────────────────────────────\n\nconst DEFAULT_INTEGRITY: RunIntegrityExpectations = {\n llmSpansMin: 1,\n requireRawCoverageOfLlmSpans: true,\n requireOutcome: true,\n}\n\nconst DEFAULT_ROUTE: LlmRouteRequirements = {\n requireExplicitBaseUrl: true,\n requireAuth: true,\n}\n\nexport async function runEvalCampaign<V>(\n opts: EvalCampaignOptions<V>,\n): Promise<EvalCampaignResult> {\n // ── Preflight ──────────────────────────────────────────────────────\n assertLlmRoute(opts.llmOpts, opts.routeRequirements ?? DEFAULT_ROUTE)\n\n if (opts.variants.length === 0) {\n throw new Error('runEvalCampaign: variants must be non-empty.')\n }\n if (opts.scenarios.length === 0) {\n throw new Error('runEvalCampaign: scenarios must be non-empty.')\n }\n const variantIds = new Set<string>()\n for (const v of opts.variants) {\n if (variantIds.has(v.id)) {\n throw new Error(`runEvalCampaign: duplicate variant id \"${v.id}\".`)\n }\n variantIds.add(v.id)\n }\n const scenarioIds = new Set<string>()\n for (const s of opts.scenarios) {\n if (scenarioIds.has(s.scenarioId)) {\n throw new Error(`runEvalCampaign: duplicate scenarioId \"${s.scenarioId}\".`)\n }\n scenarioIds.add(s.scenarioId)\n }\n if (opts.report?.comparator && !variantIds.has(opts.report.comparator)) {\n throw new Error(\n `runEvalCampaign: report.comparator \"${opts.report.comparator}\" is not a configured variantId.`,\n )\n }\n if (!opts.commitSha) {\n throw new Error('runEvalCampaign: commitSha is required (every RunRecord needs it).')\n }\n\n const seeds = opts.seeds ?? [0, 1, 2]\n const splitTag: RunSplitTag = opts.splitTag ?? 'holdout'\n const concurrency = Math.max(1, opts.concurrency ?? 1)\n const integrity = { ...DEFAULT_INTEGRITY, ...(opts.integrity ?? {}) }\n const onIntegrityFailure: CampaignIntegrityPolicy = opts.onIntegrityFailure ?? 'mark_failed'\n const now = opts.now ?? (() => Date.now())\n const baseUrl = (opts.llmOpts.baseUrl ?? '').replace(/\\/+$/, '')\n const provider = opts.llmOpts.provider ?? null\n const preregistrationHash = opts.preregistrationHash ?? null\n\n const rawSinkFactory = opts.rawSinkFactory ?? defaultRawSinkFactory(opts.workDir)\n\n // ── Fingerprint ────────────────────────────────────────────────────\n const campaignFingerprint = await hashJson(\n canonicalize({\n campaignId: opts.campaignId,\n variants: opts.variants.map((v) => v.id).sort(),\n scenarios: opts.scenarios.map((s) => s.scenarioId).sort(),\n seeds: [...seeds].sort((a, b) => a - b),\n splitTag,\n comparator: opts.report?.comparator ?? null,\n baseUrl,\n provider,\n preregistrationHash,\n }),\n )\n\n // ── Plan the matrix ────────────────────────────────────────────────\n type Cell = { variant: CampaignVariant<V>; scenario: CampaignScenario; seed: number }\n const cells: Cell[] = []\n for (const variant of opts.variants) {\n for (const scenario of opts.scenarios) {\n for (const seed of seeds) {\n cells.push({ variant, scenario, seed })\n }\n }\n }\n\n const startedAt = new Date(now()).toISOString()\n const runs: RunRecord[] = []\n const integrityReports: RunIntegrityReport[] = []\n const failedRuns: FailedRun[] = []\n\n // ── Execute (bounded-concurrency worker pool) ──────────────────────\n // A genuine (non-CellExecutionError) error from any worker is a bug, not a\n // run-level failure. We must NOT let `Promise.all` reject mid-flight and\n // orphan the other workers' in-progress runs (emitters never finalized,\n // sinks/handles leak, partial work silently discarded). Instead: capture the\n // first genuine error, stop dispatching new cells so in-flight workers wind\n // down, finalize every still-open run, then re-throw the aggregated error.\n let cursor = 0\n let aborting = false\n const genuineErrors: unknown[] = []\n // Emitters for runs that are currently mid-flight, keyed by runId. A worker\n // registers its emitter before invoking the runner and removes it once the\n // run is finalized (via endRun/abortRun, success or failure). Anything left\n // here after the pool settles is an orphan we must abort.\n const openRuns = new Map<string, TraceEmitter>()\n\n async function worker(): Promise<void> {\n while (!aborting) {\n const i = cursor++\n if (i >= cells.length) return\n const cell = cells[i]!\n try {\n const result = await runOneCell(cell)\n runs.push(result.record)\n integrityReports.push(result.integrity)\n } catch (err) {\n if (err instanceof CellExecutionError) {\n failedRuns.push(err.failed)\n if (err.integrity) integrityReports.push(err.integrity)\n } else {\n // Genuine bug — not a runner failure, not an integrity failure.\n // Capture it and stop dispatching so peers wind down gracefully;\n // re-thrown after the pool settles. Do not surface here — that would\n // reject Promise.all and orphan the other workers' runs.\n genuineErrors.push(err)\n aborting = true\n return\n }\n }\n }\n }\n\n async function runOneCell(\n cell: Cell,\n ): Promise<{ record: RunRecord; integrity: RunIntegrityReport }> {\n const runId = (opts.runId ?? defaultRunId)({\n campaignId: opts.campaignId,\n runId: '', // unused by default generator\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n })\n const factoryParams: CampaignFactoryParams = {\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n }\n const store = opts.storeFactory(factoryParams)\n const rawSink = rawSinkFactory(factoryParams)\n\n const emitter = new TraceEmitter(store, {\n runId,\n now: opts.now,\n onRunComplete: opts.onRunComplete,\n })\n // Track this run as open so a genuine error elsewhere in the pool can\n // finalize it instead of orphaning it. Removed in the finally below.\n openRuns.set(runId, emitter)\n\n const llmOpts: LlmClientOptions = {\n ...opts.llmOpts,\n rawSink,\n traceContext: { runId },\n }\n\n const ctx: CampaignRunContext<V> = {\n runId,\n experimentId: opts.campaignId,\n variant: cell.variant.payload,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n scenarioTags: cell.scenario.tags ?? {},\n seed: cell.seed,\n splitTag,\n emitter,\n store,\n rawSink,\n llmOpts,\n }\n\n try {\n const wallStart = now()\n let outcome: CampaignRunOutcome\n try {\n outcome = await opts.runner(ctx)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // The runner threw mid-execution. Abort the run so the emitter\n // finalizes. The only benign abortRun failure is \"the runner never\n // started the run\" (nothing to finalize). A store-write failure (disk\n // full, FS error) is a genuine diagnostic — surface it rather than\n // masking it as a plain runner failure.\n await finalizeAbort(emitter, runId, message)\n throw new CellExecutionError({\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'runner_threw',\n error: message,\n })\n }\n const wallMs = now() - wallStart\n\n const integrityReport = await assertRunCaptured(store, runId, { ...integrity, rawSink })\n if (!integrityReport.ok) {\n switch (onIntegrityFailure) {\n case 'throw':\n throw new RunIntegrityError(integrityReport)\n case 'mark_failed':\n throw new CellExecutionError(\n {\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n reason: 'integrity_failed',\n error: integrityReport.issues.map((i) => i.code).join(', '),\n },\n integrityReport,\n )\n case 'log':\n // Caller wants the run admitted with a flagged report; fall through.\n break\n }\n }\n\n const recordOutcome: RunOutcome = {\n raw: outcome.raw ?? {},\n }\n if (splitTag === 'holdout') recordOutcome.holdoutScore = outcome.score\n else recordOutcome.searchScore = outcome.score\n if (outcome.judgeScores !== undefined) recordOutcome.judgeScores = outcome.judgeScores\n\n const record: RunRecord = {\n runId,\n experimentId: opts.campaignId,\n candidateId: cell.variant.id,\n seed: cell.seed,\n model: outcome.model,\n promptHash: outcome.promptHash,\n configHash: outcome.configHash,\n commitSha: opts.commitSha,\n wallMs,\n costUsd: outcome.costUsd,\n costProvenance: outcome.costProvenance,\n tokenUsage: outcome.tokenUsage,\n terminalOutcome: 'succeeded',\n judgeMetadata: outcome.judgeMetadata,\n outcome: recordOutcome,\n ...(outcome.failureClass ? { failureClass: outcome.failureClass } : {}),\n failureMode: outcome.failureMode,\n splitTag,\n scenarioId: cell.scenario.scenarioId,\n }\n const profileSource =\n outcome.agentProfile ??\n (typeof opts.agentProfile === 'function'\n ? await opts.agentProfile({\n campaignId: opts.campaignId,\n runId,\n variantId: cell.variant.id,\n scenarioId: cell.scenario.scenarioId,\n seed: cell.seed,\n variant: cell.variant.payload,\n scenarioTags: cell.scenario.tags ?? {},\n })\n : opts.agentProfile)\n if (profileSource !== undefined) {\n const agentProfile = await resolveAgentProfileCell(profileSource)\n assertAgentProfileMatchesRun(agentProfile, outcome.model, outcome.promptHash)\n record.agentProfile = agentProfile\n }\n return { record: validateRunRecord(record), integrity: integrityReport }\n } finally {\n // This run's worker has finished with it (success, run-level failure, or\n // genuine error). It is no longer the pool's job to finalize — drop it so\n // the post-settle sweep doesn't double-abort a finalized run.\n openRuns.delete(runId)\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, cells.length) }, () => worker())\n // allSettled (not all): a genuine error in one worker must not reject the\n // pool mid-flight and orphan the others. Each worker captures its own\n // genuine error into `genuineErrors` and returns; we re-throw below.\n await Promise.allSettled(workers)\n\n // Finalize any run still open after the pool wound down. With the\n // stop-dispatch flag these are the runs that were mid-flight in peer workers\n // when the first genuine error fired — abort them so their emitters finalize\n // (hooks fire, store records a terminal status) instead of leaking.\n for (const [runId, emitter] of openRuns) {\n await finalizeAbort(emitter, runId, 'campaign aborted: genuine error in a sibling run')\n }\n openRuns.clear()\n\n if (genuineErrors.length > 0) {\n throw genuineErrors.length === 1\n ? genuineErrors[0]\n : new AggregateError(\n genuineErrors,\n `runEvalCampaign: ${genuineErrors.length} runs failed with genuine (non-run-level) errors`,\n )\n }\n\n // ── Optional research report ───────────────────────────────────────\n let report: ResearchReport | undefined\n if (opts.report) {\n const reportOpts: ResearchReportOptions = {\n ...opts.report,\n comparator: opts.report.comparator,\n split: splitTag === 'dev' ? 'search' : splitTag,\n generatedAt: new Date(now()).toISOString(),\n preregistrationHash: preregistrationHash ?? undefined,\n }\n report = await researchReport(runs, reportOpts)\n }\n\n const endedAt = new Date(now()).toISOString()\n\n return {\n campaignId: opts.campaignId,\n campaignFingerprint,\n preregistrationHash,\n runs,\n integrityReports,\n failedRuns,\n report,\n startedAt,\n endedAt,\n }\n}\n\n// ── Internal ─────────────────────────────────────────────────────────────\n\nclass CellExecutionError extends Error {\n readonly failed: FailedRun\n readonly integrity?: RunIntegrityReport\n constructor(failed: FailedRun, integrity?: RunIntegrityReport) {\n super(`cell ${failed.variantId}/${failed.scenarioId}@${failed.seed} failed: ${failed.reason}`)\n this.failed = failed\n this.integrity = integrity\n }\n}\n\n/**\n * Abort a run whose owning work threw or was orphaned by a sibling's genuine\n * error, finalizing the emitter so hooks fire and the store records a terminal\n * status. Safe to call unconditionally: it only aborts runs that are still\n * `running`. Two no-op cases are intentional and benign:\n *\n * - the run was never started (absent from the store) — nothing to finalize\n * - the run is already terminal (`completed` / `failed` / `aborted`) —\n * finalizing again would overwrite the real outcome (e.g. flip a passed run\n * to `aborted` with `{ pass: false, notes: reason }`), so we leave it alone\n *\n * Any OTHER failure of the store read or the abort write (disk full, FS fault,\n * backend down) is a genuine diagnostic and propagates rather than being\n * swallowed.\n */\nexport async function finalizeAbort(\n emitter: TraceEmitter,\n runId: string,\n reason: string,\n): Promise<void> {\n const existing = await emitter.traceStore.getRun(runId)\n if (existing === undefined) return // run never started; nothing to abort\n if (existing.status !== 'running') return // already finalized; never overwrite a real outcome\n await emitter.abortRun(reason)\n}\n\nfunction defaultRawSinkFactory(workDir: string | undefined) {\n return (params: CampaignFactoryParams): RawProviderSink => {\n if (!workDir) {\n throw new Error(\n 'runEvalCampaign: rawSinkFactory not supplied and workDir not set. Pass either to enable raw provider capture, or pass `new NoopRawProviderSink()` via rawSinkFactory to opt out explicitly.',\n )\n }\n return new FileSystemRawProviderSink({\n dir: `${workDir}/raw-events/${params.runId}`,\n })\n }\n}\n\nasync function resolveAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n if (isAgentProfileCell(input)) {\n if (!(await verifyAgentProfileCell(input))) {\n throw new Error(`runEvalCampaign: agentProfile.cellId does not match its content`)\n }\n return input\n }\n return buildAgentProfileCell(input)\n}\n\nfunction isAgentProfileCell(\n input: AgentProfileCell | AgentProfileCellInput,\n): input is AgentProfileCell {\n return 'schemaVersion' in input && 'cellId' in input\n}\n\nfunction assertAgentProfileMatchesRun(\n profile: AgentProfileCell,\n model: string,\n promptHash: string,\n): void {\n if (profile.model !== undefined && profile.model !== model) {\n throw new Error(\n `runEvalCampaign: agentProfile.model \"${profile.model}\" does not match outcome.model \"${model}\"`,\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== promptHash) {\n throw new Error(\n `runEvalCampaign: agentProfile.promptHash \"${profile.promptHash}\" does not match outcome.promptHash \"${promptHash}\"`,\n )\n }\n}\n\nfunction defaultRunId(params: CampaignFactoryParams): string {\n // Stable across re-runs: fingerprint of (campaignId, variantId, scenarioId, seed).\n // Caller can override via opts.runId for non-deterministic IDs.\n const base = `${params.campaignId}::${params.variantId}::${params.scenarioId}::${params.seed}`\n // Lightweight hex: we don't need crypto-grade here, just stability + uniqueness.\n let h1 = 0x811c9dc5\n let h2 = 0x12345678\n for (let i = 0; i < base.length; i++) {\n const c = base.charCodeAt(i)\n h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0\n h2 = Math.imul(h2 ^ c, 0x9e3779b1) >>> 0\n }\n return `run-${h1.toString(16).padStart(8, '0')}${h2.toString(16).padStart(8, '0')}`\n}\n"],"mappings":"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"}
@@ -2,6 +2,8 @@ import { s as ValidationError } from "./errors-8YnH8WlF.js";
2
2
  import { LLM_CACHED_TOKEN_ATTR_KEYS, LLM_CACHE_WRITE_TOKEN_ATTR_KEYS, LLM_COST_ATTR_KEYS, LLM_INPUT_TOKEN_ATTR_KEYS, LLM_OUTPUT_TOKEN_ATTR_KEYS, LLM_REASONING_TOKEN_ATTR_KEYS, RUN_COST_ATTR_KEYS } from "./trace-attributes.js";
3
3
  import "./tools-BmuN627J.js";
4
4
  import { t as FAILURE_CLASSES } from "./schema-CRhEY1SO.js";
5
+ import { TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, firstTokenCount, tokenUsageSource } from "@tangle-network/agent-core/telemetry";
6
+ import { SSEChunkParser } from "@tangle-network/agent-core/sse";
5
7
  //#region src/trace/error-classification.ts
6
8
  /**
7
9
  * Classify errored spans without counting a propagated parent status as a
@@ -306,6 +308,156 @@ function readConsistentRootString(roots, key, context) {
306
308
  return values.values().next().value;
307
309
  }
308
310
  //#endregion
309
- export { summarizeTraceErrors as i, recordAggregateMeasurements as n, summarizeExecutionMeasurements as r, readTaskFailureLabels as t };
311
+ //#region src/trace/extract-usage.ts
312
+ /**
313
+ * Provider response and SSE usage extraction.
314
+ *
315
+ * Missing usage returns `null`; reported zeroes and cache-only activity remain
316
+ * distinguishable from absent telemetry.
317
+ */
318
+ const INPUT_OTHER_KEYS = ["input_other"];
319
+ const EXCLUSIVE_REASONING_KEYS = [
320
+ "reasoning",
321
+ "reasoning_tokens",
322
+ "reasoningTokens"
323
+ ];
324
+ const INCLUSIVE_REASONING_KEYS = ["reasoning_output_tokens", "reasoningOutputTokens"];
325
+ const INPUT_DETAIL_KEYS = ["prompt_tokens_details", "input_tokens_details"];
326
+ const OUTPUT_DETAIL_KEYS = ["completion_tokens_details", "output_tokens_details"];
327
+ const CACHED_KEYS = [
328
+ "cache",
329
+ "cached_tokens",
330
+ "cached_input_tokens",
331
+ "cache_read_tokens",
332
+ "cache_read_input_tokens",
333
+ "cachedTokens",
334
+ "cachedInputTokens",
335
+ "cacheReadTokens",
336
+ "cacheReadInputTokens",
337
+ "input_cache_read"
338
+ ];
339
+ const CACHE_WRITE_KEYS = [
340
+ "cache_creation_tokens",
341
+ "cache_creation_input_tokens",
342
+ "cacheCreationTokens",
343
+ "cacheCreationInputTokens",
344
+ "input_cache_creation"
345
+ ];
346
+ function nestedRecord(source, key) {
347
+ const value = source[key];
348
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
349
+ }
350
+ function nestedNumber(source, recordKeys, valueKeys) {
351
+ for (const recordKey of recordKeys) {
352
+ const value = firstTokenCount(nestedRecord(source, recordKey), valueKeys);
353
+ if (value !== void 0) return value;
354
+ }
355
+ }
356
+ /**
357
+ * Pull `{ input, output, cached?, cacheWrite? }` from a parsed response
358
+ * body. Accepts a top-level `usage` object (the common case) or a body that IS
359
+ * the usage object. Returns null only when none of those categories is present.
360
+ */
361
+ function extractUsage(body) {
362
+ if (!body || typeof body !== "object") return null;
363
+ const usage = tokenUsageSource(body);
364
+ const input = firstTokenCount(usage, TOKEN_USAGE_INPUT_KEYS);
365
+ const inputOther = firstTokenCount(usage, INPUT_OTHER_KEYS);
366
+ const output = firstTokenCount(usage, TOKEN_USAGE_OUTPUT_KEYS);
367
+ const exclusiveReasoning = firstTokenCount(usage, EXCLUSIVE_REASONING_KEYS);
368
+ const inclusiveReasoning = firstTokenCount(usage, INCLUSIVE_REASONING_KEYS) ?? nestedNumber(usage, OUTPUT_DETAIL_KEYS, ["reasoning_tokens", "reasoningTokens"]);
369
+ const reasoning = exclusiveReasoning ?? inclusiveReasoning;
370
+ const nestedCache = nestedRecord(usage, "cache");
371
+ const cached = firstTokenCount(usage, CACHED_KEYS) ?? firstTokenCount(nestedCache, ["read"]) ?? nestedNumber(usage, INPUT_DETAIL_KEYS, ["cached_tokens", "cachedTokens"]);
372
+ const cacheWrite = firstTokenCount(usage, CACHE_WRITE_KEYS) ?? firstTokenCount(nestedCache, ["write"]);
373
+ if (input === void 0 && inputOther === void 0 && output === void 0 && reasoning === void 0 && cached === void 0 && cacheWrite === void 0) return null;
374
+ const result = {
375
+ input: (input ?? 0) + (inputOther ?? 0),
376
+ output: (output ?? (inclusiveReasoning !== void 0 ? inclusiveReasoning : 0)) + (exclusiveReasoning ?? 0)
377
+ };
378
+ if (reasoning !== void 0) result.reasoning = reasoning;
379
+ if (cached !== void 0) result.cached = cached;
380
+ if (cacheWrite !== void 0) result.cacheWrite = cacheWrite;
381
+ return result;
382
+ }
383
+ /**
384
+ * Extract token usage from a complete SSE response body using the shared SSE
385
+ * frame parser. Cumulative snapshots are the fail-safe default because summing
386
+ * them inflates billing; callers with explicit delta events opt into `mode: 'delta'`.
387
+ */
388
+ function extractUsageFromSse(text, options = {}) {
389
+ const mode = options.mode ?? "cumulative";
390
+ let input = 0;
391
+ let output = 0;
392
+ let reasoning = 0;
393
+ let sawReasoning = false;
394
+ let cached = 0;
395
+ let sawCached = false;
396
+ let cacheWrite = 0;
397
+ let sawCacheWrite = false;
398
+ let found = false;
399
+ const parser = new SSEChunkParser({ transform: parseSseJson });
400
+ const events = [...parser.push(text), ...parser.flush()];
401
+ const merge = mode === "delta" ? (current, next) => current + next : Math.max;
402
+ for (const event of events) {
403
+ const usage = extractUsage(event.data);
404
+ if (!usage) continue;
405
+ input = merge(input, usage.input);
406
+ output = merge(output, usage.output);
407
+ if (usage.reasoning !== void 0) {
408
+ reasoning = merge(reasoning, usage.reasoning);
409
+ sawReasoning = true;
410
+ }
411
+ if (usage.cached !== void 0) {
412
+ cached = merge(cached, usage.cached);
413
+ sawCached = true;
414
+ }
415
+ if (usage.cacheWrite !== void 0) {
416
+ cacheWrite = merge(cacheWrite, usage.cacheWrite);
417
+ sawCacheWrite = true;
418
+ }
419
+ found = true;
420
+ }
421
+ if (!found) return null;
422
+ return {
423
+ input,
424
+ output,
425
+ ...sawReasoning ? { reasoning } : {},
426
+ ...sawCached ? { cached } : {},
427
+ ...sawCacheWrite ? { cacheWrite } : {}
428
+ };
429
+ }
430
+ function parseSseJson(raw) {
431
+ const payload = raw.trim();
432
+ if (!payload || payload === "[DONE]") return null;
433
+ try {
434
+ return JSON.parse(payload);
435
+ } catch {
436
+ return null;
437
+ }
438
+ }
439
+ /**
440
+ * Extract usage from an HTTP `Response` without consuming the caller's body:
441
+ * clones, reads the text, and tries the JSON parser first, then the SSE
442
+ * accumulator. Best-effort — returns null on any read/parse miss so a usage tee
443
+ * never takes down the underlying call.
444
+ */
445
+ async function extractUsageFromResponse(response, sseOptions) {
446
+ let text;
447
+ try {
448
+ text = await response.clone().text();
449
+ } catch {
450
+ return null;
451
+ }
452
+ let json;
453
+ try {
454
+ json = JSON.parse(text);
455
+ } catch {
456
+ json = void 0;
457
+ }
458
+ return extractUsage(json) ?? extractUsageFromSse(text, sseOptions);
459
+ }
460
+ //#endregion
461
+ export { recordAggregateMeasurements as a, readTaskFailureLabels as i, extractUsageFromResponse as n, summarizeExecutionMeasurements as o, extractUsageFromSse as r, summarizeTraceErrors as s, extractUsage as t };
310
462
 
311
- //# sourceMappingURL=task-failure-attributes-CQZlB3et.js.map
463
+ //# sourceMappingURL=extract-usage-2j25whHw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-usage-2j25whHw.js","names":["obj"],"sources":["../src/trace/error-classification.ts","../src/trace/execution-measurements.ts","../src/trace/task-failure-attributes.ts","../src/trace/extract-usage.ts"],"sourcesContent":["import type { OtlpSpanRole } from './otlp-attributes'\n\nexport type TraceErrorRole = OtlpSpanRole\n\nexport interface TraceErrorSignal {\n id: string\n parentId?: string\n role: TraceErrorRole\n error: boolean\n processRoot: boolean\n}\n\nexport interface TraceErrorSummary {\n total: number\n execution: number\n process: number\n guardrail: number\n evaluation: number\n propagated: number\n unclassified: number\n}\n\n/**\n * Classify errored spans without counting a propagated parent status as a\n * second execution failure.\n */\nexport function summarizeTraceErrors(signals: readonly TraceErrorSignal[]): TraceErrorSummary {\n const byId = new Map<string, TraceErrorSignal>()\n for (const signal of signals) {\n if (byId.has(signal.id)) {\n throw new Error(`summarizeTraceErrors: duplicate span id '${signal.id}'`)\n }\n byId.set(signal.id, signal)\n }\n\n const propagated = new Set<string>()\n for (const signal of signals) {\n if (!signal.error) continue\n const visited = new Set<string>()\n let parentId = signal.parentId\n while (parentId && !visited.has(parentId)) {\n visited.add(parentId)\n const parent = byId.get(parentId)\n if (!parent) break\n if (parent.error) propagated.add(parent.id)\n parentId = parent.parentId\n }\n }\n\n const summary: TraceErrorSummary = {\n total: 0,\n execution: 0,\n process: 0,\n guardrail: 0,\n evaluation: 0,\n propagated: 0,\n unclassified: 0,\n }\n\n for (const signal of signals) {\n if (!signal.error) continue\n summary.total += 1\n if (signal.role === 'GUARDRAIL') {\n summary.guardrail += 1\n } else if (signal.role === 'EVALUATOR') {\n summary.evaluation += 1\n } else if (signal.processRoot) {\n summary.process += 1\n } else if (propagated.has(signal.id)) {\n summary.propagated += 1\n } else if (\n signal.role === 'AGENT' ||\n signal.role === 'CHAIN' ||\n signal.role === 'LLM' ||\n signal.role === 'TOOL'\n ) {\n summary.execution += 1\n } else {\n summary.unclassified += 1\n }\n }\n\n return summary\n}\n","import type { RunTokenUsage } from '../run-record'\nimport {\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n LLM_CACHED_TOKEN_ATTR_KEYS,\n LLM_COST_ATTR_KEYS,\n LLM_INPUT_TOKEN_ATTR_KEYS,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n RUN_COST_ATTR_KEYS,\n} from './otlp-attributes'\n\nexport interface ExecutionMeasurementSpan {\n id: string\n parentId?: string\n attributes: Record<string, unknown>\n modelCall: boolean\n aggregate: boolean\n}\n\nexport interface MeasurementCoverage {\n value?: number\n reportingCalls: number\n complete: boolean\n}\n\nexport interface ExecutionMeasurements {\n tokenUsage: RunTokenUsage\n modelCallCount: number\n callSpanIds: string[]\n cost: MeasurementCoverage\n aggregate?: {\n tokenUsage: RunTokenUsage\n costUsd?: number\n }\n}\n\nconst TOKEN_MEASUREMENT_KEY_GROUPS = [\n LLM_INPUT_TOKEN_ATTR_KEYS,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n LLM_CACHED_TOKEN_ATTR_KEYS,\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n] as const\n\nconst EXECUTION_MEASUREMENT_KEY_GROUPS = [\n ...TOKEN_MEASUREMENT_KEY_GROUPS,\n LLM_COST_ATTR_KEYS,\n] as const\n\ninterface RetainedCallSummary {\n callCount: number\n measurements: Array<{\n total: number\n reportingCalls: number\n }>\n}\n\n/**\n * Reconcile execution measurements across nested telemetry wrappers.\n * A measured parent is used only when a descendant call does not report the\n * same field, so aggregate wrappers neither duplicate complete child data nor\n * erase complementary parent fields.\n */\nexport function summarizeExecutionMeasurements(\n spans: ExecutionMeasurementSpan[],\n): ExecutionMeasurements {\n const byId = new Map<string, ExecutionMeasurementSpan>()\n for (const span of spans) {\n if (byId.has(span.id)) {\n throw new Error(`summarizeExecutionMeasurements: duplicate span id \"${span.id}\"`)\n }\n byId.set(span.id, span)\n }\n const tokenMeasurementKeys = TOKEN_MEASUREMENT_KEY_GROUPS.flat()\n const candidates = spans.filter(\n (span) =>\n span.modelCall ||\n (!span.aggregate && readNumber(span.attributes, tokenMeasurementKeys) !== undefined),\n )\n const candidateIds = new Set(candidates.map((span) => span.id))\n const candidateChildren = new Map<string, ExecutionMeasurementSpan[]>()\n for (const candidate of candidates) {\n const parentId = nearestCandidateParent(candidate, byId, candidateIds)\n if (!parentId) continue\n const children = candidateChildren.get(parentId) ?? []\n children.push(candidate)\n candidateChildren.set(parentId, children)\n }\n const aggregateIds = classifyAggregateSpans(candidates, candidateChildren)\n const untypedRunCostIds = new Set(\n spans\n .filter(\n (span) =>\n !span.modelCall &&\n !span.aggregate &&\n !candidateIds.has(span.id) &&\n readNumber(span.attributes, RUN_COST_ATTR_KEYS) !== undefined,\n )\n .map((span) => span.id),\n )\n const aggregateSourceIds = new Set(\n spans\n .filter(\n (span) => span.aggregate || aggregateIds.has(span.id) || untypedRunCostIds.has(span.id),\n )\n .map((span) => span.id),\n )\n\n const calls = candidates.filter((span) => !aggregateIds.has(span.id))\n const input = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_INPUT_TOKEN_ATTR_KEYS)\n const reasoning = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n )\n const output = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n )\n const cached = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_CACHED_TOKEN_ATTR_KEYS)\n const cacheWrite = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n )\n const aggregate = summarizeAggregateMeasurements(\n spans,\n byId,\n new Set([...aggregateIds, ...untypedRunCostIds]),\n )\n\n return {\n tokenUsage: {\n input: input.value ?? 0,\n output: Math.max(output.value ?? 0, reasoning.value ?? 0),\n ...(reasoning.value !== undefined ? { reasoning: reasoning.value } : {}),\n ...(cached.value !== undefined ? { cached: cached.value } : {}),\n ...(cacheWrite.value !== undefined ? { cacheWrite: cacheWrite.value } : {}),\n },\n modelCallCount: calls.length,\n callSpanIds: calls.map((span) => span.id),\n cost: reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_COST_ATTR_KEYS),\n ...(aggregate ? { aggregate } : {}),\n }\n}\n\nexport function recordAggregateMeasurements(\n raw: Record<string, number>,\n aggregate: ExecutionMeasurements['aggregate'],\n): void {\n if (!aggregate) return\n raw.aggregate_prompt_tokens = aggregate.tokenUsage.input\n raw.aggregate_completion_tokens = aggregate.tokenUsage.output\n if (aggregate.tokenUsage.reasoning !== undefined)\n raw.aggregate_reasoning_tokens = aggregate.tokenUsage.reasoning\n if (aggregate.tokenUsage.cached !== undefined)\n raw.aggregate_cached_tokens = aggregate.tokenUsage.cached\n if (aggregate.tokenUsage.cacheWrite !== undefined)\n raw.aggregate_cache_write_tokens = aggregate.tokenUsage.cacheWrite\n if (aggregate.costUsd !== undefined) raw.aggregate_cost_usd = aggregate.costUsd\n}\n\nfunction summarizeAggregateMeasurements(\n spans: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n aggregateIds: Set<string>,\n): ExecutionMeasurements['aggregate'] {\n const aggregates = spans.filter((span) => span.aggregate || aggregateIds.has(span.id))\n const input = reconcileTopLevelMeasurement(aggregates, byId, LLM_INPUT_TOKEN_ATTR_KEYS)\n const output = reconcileTopLevelMeasurement(aggregates, byId, LLM_OUTPUT_TOKEN_ATTR_KEYS)\n const reasoning = reconcileTopLevelMeasurement(aggregates, byId, LLM_REASONING_TOKEN_ATTR_KEYS)\n const cached = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHED_TOKEN_ATTR_KEYS)\n const cacheWrite = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHE_WRITE_TOKEN_ATTR_KEYS)\n const costUsd = reconcileTopLevelMeasurement(aggregates, byId, LLM_COST_ATTR_KEYS)\n if (\n input === undefined &&\n output === undefined &&\n reasoning === undefined &&\n cached === undefined &&\n cacheWrite === undefined &&\n costUsd === undefined\n )\n return undefined\n return {\n tokenUsage: {\n input: input ?? 0,\n output: output ?? reasoning ?? 0,\n ...(reasoning !== undefined ? { reasoning } : {}),\n ...(cached !== undefined ? { cached } : {}),\n ...(cacheWrite !== undefined ? { cacheWrite } : {}),\n },\n ...(costUsd !== undefined ? { costUsd } : {}),\n }\n}\n\nfunction reconcileTopLevelMeasurement(\n spans: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n keys: readonly string[],\n): number | undefined {\n const selected = new Map<string, number>()\n for (const span of spans) {\n const value = readNumber(span.attributes, keys)\n if (value !== undefined) selected.set(span.id, value)\n }\n for (const spanId of [...selected.keys()]) {\n const span = byId.get(spanId)\n if (!span) continue\n if (ancestorIds(span, byId).some((ancestorId) => selected.has(ancestorId))) {\n selected.delete(spanId)\n }\n }\n return selected.size > 0\n ? [...selected.values()].reduce((total, value) => total + value, 0)\n : undefined\n}\n\nfunction reconcileMeasurement(\n calls: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n aggregateSourceIds: Set<string>,\n keys: readonly string[],\n fallbackKeys?: readonly string[],\n): MeasurementCoverage {\n const selected = new Map<string, number>()\n const callIds = new Set(calls.map((call) => call.id))\n let reportingCalls = 0\n\n for (const call of calls) {\n const primary = nearestMeasurement(call, byId, callIds, aggregateSourceIds, keys)\n const fallback = fallbackKeys\n ? nearestMeasurement(call, byId, callIds, aggregateSourceIds, fallbackKeys)\n : undefined\n const source =\n primary && fallback && primary.span.id === fallback.span.id\n ? { span: primary.span, value: Math.max(primary.value, fallback.value) }\n : (primary ?? fallback)\n if (!source) continue\n reportingCalls += 1\n selected.set(source.span.id, source.value)\n }\n\n for (const spanId of [...selected.keys()]) {\n const span = byId.get(spanId)\n if (!span) continue\n if (\n ancestorIds(span, byId).some(\n (ancestorId) => selected.has(ancestorId) && !callIds.has(ancestorId),\n )\n ) {\n selected.delete(spanId)\n }\n }\n\n return {\n ...(selected.size > 0\n ? { value: [...selected.values()].reduce((total, value) => total + value, 0) }\n : {}),\n reportingCalls,\n complete: calls.length > 0 && reportingCalls === calls.length,\n }\n}\n\nfunction nearestMeasurement(\n call: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n callIds: Set<string>,\n aggregateSourceIds: Set<string>,\n keys: readonly string[],\n): { span: ExecutionMeasurementSpan; value: number } | undefined {\n let current: ExecutionMeasurementSpan | undefined = call\n const seen = new Set<string>()\n while (current && !seen.has(current.id)) {\n seen.add(current.id)\n const value = readNumber(current.attributes, keys)\n if (\n value !== undefined &&\n (current.id === call.id || (!callIds.has(current.id) && aggregateSourceIds.has(current.id)))\n ) {\n return { span: current, value }\n }\n current = current.parentId ? byId.get(current.parentId) : undefined\n }\n return undefined\n}\n\nfunction classifyAggregateSpans(\n candidates: ExecutionMeasurementSpan[],\n childrenById: Map<string, ExecutionMeasurementSpan[]>,\n): Set<string> {\n const aggregateIds = new Set<string>()\n const summaries = new Map<string, RetainedCallSummary>()\n const visiting = new Set<string>()\n\n const visit = (span: ExecutionMeasurementSpan): RetainedCallSummary => {\n const cached = summaries.get(span.id)\n if (cached) return cached\n if (visiting.has(span.id)) return emptyRetainedCallSummary()\n visiting.add(span.id)\n\n const descendants = emptyRetainedCallSummary()\n for (const child of childrenById.get(span.id) ?? []) {\n const childDescendants = visit(child)\n if (!aggregateIds.has(child.id)) addRetainedCall(descendants, child)\n addRetainedCallSummary(descendants, childDescendants)\n }\n\n if (\n descendants.callCount > 0 &&\n (!span.modelCall || hasCompatibleDescendantMeasurements(span, descendants))\n ) {\n aggregateIds.add(span.id)\n }\n\n visiting.delete(span.id)\n summaries.set(span.id, descendants)\n return descendants\n }\n\n for (const candidate of candidates) visit(candidate)\n return aggregateIds\n}\n\nfunction emptyRetainedCallSummary(): RetainedCallSummary {\n return {\n callCount: 0,\n measurements: EXECUTION_MEASUREMENT_KEY_GROUPS.map(() => ({\n total: 0,\n reportingCalls: 0,\n })),\n }\n}\n\nfunction addRetainedCall(summary: RetainedCallSummary, span: ExecutionMeasurementSpan): void {\n summary.callCount += 1\n for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {\n const value = readNumber(span.attributes, EXECUTION_MEASUREMENT_KEY_GROUPS[index]!)\n if (value === undefined) continue\n const measurement = summary.measurements[index]!\n measurement.total += value\n measurement.reportingCalls += 1\n }\n}\n\nfunction addRetainedCallSummary(target: RetainedCallSummary, source: RetainedCallSummary): void {\n target.callCount += source.callCount\n for (let index = 0; index < target.measurements.length; index += 1) {\n const measurement = target.measurements[index]!\n const sourceMeasurement = source.measurements[index]!\n measurement.total += sourceMeasurement.total\n measurement.reportingCalls += sourceMeasurement.reportingCalls\n }\n}\n\nfunction hasCompatibleDescendantMeasurements(\n span: ExecutionMeasurementSpan,\n descendants: RetainedCallSummary,\n): boolean {\n let parentMeasurements = 0\n let descendantMeasurements = 0\n for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {\n const keys = EXECUTION_MEASUREMENT_KEY_GROUPS[index]!\n const parentValue = readNumber(span.attributes, keys)\n const measurement = descendants.measurements[index]!\n if (parentValue !== undefined) parentMeasurements += 1\n if (measurement.reportingCalls > 0) descendantMeasurements += 1\n if (parentValue === undefined || measurement.reportingCalls === 0) continue\n if (measurement.reportingCalls !== descendants.callCount) continue\n if (Math.abs(parentValue - measurement.total) > 1e-12) return false\n }\n return parentMeasurements === 0 || descendantMeasurements > 0\n}\n\nfunction ancestorIds(\n span: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n): string[] {\n const ids: string[] = []\n const seen = new Set<string>()\n let parentId = span.parentId\n while (parentId && !seen.has(parentId)) {\n ids.push(parentId)\n seen.add(parentId)\n parentId = byId.get(parentId)?.parentId\n }\n return ids\n}\n\nfunction nearestCandidateParent(\n span: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n candidateIds: Set<string>,\n): string | undefined {\n const seen = new Set<string>()\n let parentId = span.parentId\n while (parentId && !seen.has(parentId)) {\n if (candidateIds.has(parentId)) return parentId\n seen.add(parentId)\n parentId = byId.get(parentId)?.parentId\n }\n return undefined\n}\n\nfunction readNumber(\n attributes: Record<string, unknown>,\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n const value = attributes[key]\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string' && value.length > 0\n ? Number(value)\n : Number.NaN\n if (Number.isFinite(parsed) && parsed >= 0) return parsed\n }\n return undefined\n}\n","import { ValidationError } from '../errors'\nimport { FAILURE_CLASSES, type FailureClass } from './schema'\n\nconst TASK_FAILURE_CLASS_ATTR = 'tangle.task.failure_class'\nconst TASK_FAILURE_MODE_ATTR = 'tangle.task.failure_mode'\n\ninterface AttributeCarrier {\n attributes: Record<string, unknown>\n}\n\nexport type TaskFailureLabels =\n | { failureClass?: undefined; failureMode?: undefined }\n | { failureClass: 'success'; failureMode?: undefined }\n | { failureClass: Exclude<FailureClass, 'success'>; failureMode?: string }\n\nexport function readTaskFailureLabels(\n roots: readonly AttributeCarrier[],\n context: string,\n): TaskFailureLabels {\n const failureClass = readConsistentRootString(roots, TASK_FAILURE_CLASS_ATTR, context)\n const failureMode = readConsistentRootString(roots, TASK_FAILURE_MODE_ATTR, context)\n\n if (failureClass !== undefined && !FAILURE_CLASSES.includes(failureClass as FailureClass)) {\n throw new ValidationError(\n `${context}: ${TASK_FAILURE_CLASS_ATTR} must be one of ${FAILURE_CLASSES.join(', ')}`,\n )\n }\n if (failureMode !== undefined && (failureClass === undefined || failureClass === 'success')) {\n throw new ValidationError(\n `${context}: ${TASK_FAILURE_MODE_ATTR} requires a non-success ${TASK_FAILURE_CLASS_ATTR}`,\n )\n }\n\n if (failureClass === undefined) return {}\n if (failureClass === 'success') return { failureClass }\n return {\n failureClass: failureClass as Exclude<FailureClass, 'success'>,\n ...(failureMode ? { failureMode } : {}),\n }\n}\n\nfunction readConsistentRootString(\n roots: readonly AttributeCarrier[],\n key: string,\n context: string,\n): string | undefined {\n const values = new Set<string>()\n for (const root of roots) {\n if (!Object.hasOwn(root.attributes, key)) continue\n const value = root.attributes[key]\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new ValidationError(`${context}: ${key} must be a non-empty string`)\n }\n values.add(value)\n }\n\n if (values.size > 1) {\n throw new ValidationError(\n `${context}: conflicting ${key} values: ${[...values].sort().join(', ')}`,\n )\n }\n return values.values().next().value\n}\n","/**\n * Provider response and SSE usage extraction.\n *\n * Missing usage returns `null`; reported zeroes and cache-only activity remain\n * distinguishable from absent telemetry.\n */\n\nimport { SSEChunkParser } from '@tangle-network/agent-core/sse'\nimport {\n firstTokenCount,\n TOKEN_USAGE_INPUT_KEYS,\n TOKEN_USAGE_OUTPUT_KEYS,\n tokenUsageSource,\n} from '@tangle-network/agent-core/telemetry'\nimport type { RunTokenUsage } from '../run-record'\n\nexport type ExtractedUsage = RunTokenUsage\nexport type SseUsageMode = 'cumulative' | 'delta'\n\nexport interface ExtractUsageFromSseOptions {\n /** Provider usage events are cumulative snapshots unless explicitly marked as deltas. */\n mode?: SseUsageMode\n}\n\nconst INPUT_OTHER_KEYS = ['input_other'] as const\nconst EXCLUSIVE_REASONING_KEYS = ['reasoning', 'reasoning_tokens', 'reasoningTokens'] as const\nconst INCLUSIVE_REASONING_KEYS = ['reasoning_output_tokens', 'reasoningOutputTokens'] as const\nconst INPUT_DETAIL_KEYS = ['prompt_tokens_details', 'input_tokens_details'] as const\nconst OUTPUT_DETAIL_KEYS = ['completion_tokens_details', 'output_tokens_details'] as const\nconst CACHED_KEYS = [\n 'cache',\n 'cached_tokens',\n 'cached_input_tokens',\n 'cache_read_tokens',\n 'cache_read_input_tokens',\n 'cachedTokens',\n 'cachedInputTokens',\n 'cacheReadTokens',\n 'cacheReadInputTokens',\n 'input_cache_read',\n] as const\nconst CACHE_WRITE_KEYS = [\n 'cache_creation_tokens',\n 'cache_creation_input_tokens',\n 'cacheCreationTokens',\n 'cacheCreationInputTokens',\n 'input_cache_creation',\n] as const\n\nfunction nestedRecord(\n source: Record<string, unknown>,\n key: string,\n): Record<string, unknown> | undefined {\n const value = source[key]\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction nestedNumber(\n source: Record<string, unknown>,\n recordKeys: readonly string[],\n valueKeys: readonly string[],\n): number | undefined {\n for (const recordKey of recordKeys) {\n const value = firstTokenCount(nestedRecord(source, recordKey), valueKeys)\n if (value !== undefined) return value\n }\n return undefined\n}\n\n/**\n * Pull `{ input, output, cached?, cacheWrite? }` from a parsed response\n * body. Accepts a top-level `usage` object (the common case) or a body that IS\n * the usage object. Returns null only when none of those categories is present.\n */\nexport function extractUsage(body: unknown): ExtractedUsage | null {\n if (!body || typeof body !== 'object') return null\n const obj = body as Record<string, unknown>\n const usage = tokenUsageSource(obj)\n const input = firstTokenCount(usage, TOKEN_USAGE_INPUT_KEYS)\n const inputOther = firstTokenCount(usage, INPUT_OTHER_KEYS)\n const output = firstTokenCount(usage, TOKEN_USAGE_OUTPUT_KEYS)\n const exclusiveReasoning = firstTokenCount(usage, EXCLUSIVE_REASONING_KEYS)\n const inclusiveReasoning =\n firstTokenCount(usage, INCLUSIVE_REASONING_KEYS) ??\n nestedNumber(usage, OUTPUT_DETAIL_KEYS, ['reasoning_tokens', 'reasoningTokens'])\n const reasoning = exclusiveReasoning ?? inclusiveReasoning\n const nestedCache = nestedRecord(usage, 'cache')\n const cached =\n firstTokenCount(usage, CACHED_KEYS) ??\n firstTokenCount(nestedCache, ['read']) ??\n nestedNumber(usage, INPUT_DETAIL_KEYS, ['cached_tokens', 'cachedTokens'])\n const cacheWrite =\n firstTokenCount(usage, CACHE_WRITE_KEYS) ?? firstTokenCount(nestedCache, ['write'])\n if (\n input === undefined &&\n inputOther === undefined &&\n output === undefined &&\n reasoning === undefined &&\n cached === undefined &&\n cacheWrite === undefined\n )\n return null\n const result: ExtractedUsage = {\n input: (input ?? 0) + (inputOther ?? 0),\n output:\n (output ?? (inclusiveReasoning !== undefined ? inclusiveReasoning : 0)) +\n (exclusiveReasoning ?? 0),\n }\n if (reasoning !== undefined) result.reasoning = reasoning\n if (cached !== undefined) result.cached = cached\n if (cacheWrite !== undefined) result.cacheWrite = cacheWrite\n return result\n}\n\n/**\n * Extract token usage from a complete SSE response body using the shared SSE\n * frame parser. Cumulative snapshots are the fail-safe default because summing\n * them inflates billing; callers with explicit delta events opt into `mode: 'delta'`.\n */\nexport function extractUsageFromSse(\n text: string,\n options: ExtractUsageFromSseOptions = {},\n): ExtractedUsage | null {\n const mode = options.mode ?? 'cumulative'\n let input = 0\n let output = 0\n let reasoning = 0\n let sawReasoning = false\n let cached = 0\n let sawCached = false\n let cacheWrite = 0\n let sawCacheWrite = false\n let found = false\n const parser = new SSEChunkParser<unknown>({ transform: parseSseJson })\n const events = [...parser.push(text), ...parser.flush()]\n const merge = mode === 'delta' ? (current: number, next: number) => current + next : Math.max\n\n for (const event of events) {\n const usage = extractUsage(event.data)\n if (!usage) continue\n input = merge(input, usage.input)\n output = merge(output, usage.output)\n if (usage.reasoning !== undefined) {\n reasoning = merge(reasoning, usage.reasoning)\n sawReasoning = true\n }\n if (usage.cached !== undefined) {\n cached = merge(cached, usage.cached)\n sawCached = true\n }\n if (usage.cacheWrite !== undefined) {\n cacheWrite = merge(cacheWrite, usage.cacheWrite)\n sawCacheWrite = true\n }\n found = true\n }\n if (!found) return null\n return {\n input,\n output,\n ...(sawReasoning ? { reasoning } : {}),\n ...(sawCached ? { cached } : {}),\n ...(sawCacheWrite ? { cacheWrite } : {}),\n }\n}\n\nfunction parseSseJson(raw: string): unknown | null {\n const payload = raw.trim()\n if (!payload || payload === '[DONE]') return null\n try {\n return JSON.parse(payload)\n } catch {\n return null\n }\n}\n\n/**\n * Extract usage from an HTTP `Response` without consuming the caller's body:\n * clones, reads the text, and tries the JSON parser first, then the SSE\n * accumulator. Best-effort — returns null on any read/parse miss so a usage tee\n * never takes down the underlying call.\n */\nexport async function extractUsageFromResponse(\n response: Response,\n sseOptions?: ExtractUsageFromSseOptions,\n): Promise<ExtractedUsage | null> {\n let text: string\n try {\n text = await response.clone().text()\n } catch {\n return null\n }\n let json: unknown\n try {\n json = JSON.parse(text)\n } catch {\n json = undefined\n }\n return extractUsage(json) ?? extractUsageFromSse(text, sseOptions)\n}\n"],"mappings":"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"}
package/dist/fuzz.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { s as ValidationError } from "./errors-8YnH8WlF.js";
2
- import { i as CostLedger, o as CostReceiptCaptureError } from "./cost-ledger-ZAa_P4r0.js";
2
+ import { i as CostLedger, o as CostReceiptCaptureError } from "./cost-ledger-BrJxbrMy.js";
3
3
  import { r as varianceBasedCurriculum } from "./active-curriculum-C4mk67HP.js";
4
4
  //#region src/fuzz/cube.ts
5
5
  /** Enumerate every input cell (cartesian product of the axes), in stable order. */
@@ -1,5 +1,5 @@
1
1
  import { j as MutableSurface } from "../types-BokuXvOG.js";
2
- import { C as InsightReport, _ as UnixNanoTimestamp, a as hostedTenantFromEnv, c as EvalRunGenerationSnapshot, d as HostedIngestHeaders, f as HostedWireVersion, g as TraceSpanEvent, h as IngestTracesRequest, i as hostedClientFromEnv, l as EvalRunStatus, m as IngestResponse, n as HostedTenant, o as EvalRunCellScore, p as IngestEvalRunsRequest, r as createHostedClient, s as EvalRunEvent, t as HostedClient, u as HOSTED_WIRE_VERSION } from "../client-aZDHJiKO.js";
2
+ import { C as InsightReport, _ as UnixNanoTimestamp, a as hostedTenantFromEnv, c as EvalRunGenerationSnapshot, d as HostedIngestHeaders, f as HostedWireVersion, g as TraceSpanEvent, h as IngestTracesRequest, i as hostedClientFromEnv, l as EvalRunStatus, m as IngestResponse, n as HostedTenant, o as EvalRunCellScore, p as IngestEvalRunsRequest, r as createHostedClient, s as EvalRunEvent, t as HostedClient, u as HOSTED_WIRE_VERSION } from "../client-D4F9hdzR.js";
3
3
  import { z } from "zod";
4
4
  //#region src/hosted/schemas.d.ts
5
5
  declare const UnixNanoTimestampSchema: z.ZodType<UnixNanoTimestamp>;
@@ -923,4 +923,4 @@ declare function parseRolloutReleaseArgs(argv: string[]): RolloutReleaseCliArgs;
923
923
  declare function runRolloutReleaseCli(argv: string[]): Promise<number>;
924
924
  //#endregion
925
925
  export { ScorePreference as $, toVerifiersRolloutOutput as $t, ReleaseRowRef as A, GATE_CHECK_IDS as At, readOpencodeSessionMessages as B, RealnessLabels as Bt, scrubRolloutLine as C, HarborToolCall as Ct, FormatGateCounts as D, toHarborTrajectories as Dt, FORMAT_GATE_DISPOSITION as E, relabelImportedSplit as Et, DEFAULT_OPENCODE_DB as F, GateCheckedOutcome as Ft, claudeProjectSlug as G, VerifiersRolloutOutput as Gt, ClaudeTranscriptRef as H, RftItem as Ht, OpencodeSessionRow as I, GateEntryPoint as It, MintRolloutOptions as J, toJsonl as Jt, findClaudeTranscripts as K, VerifiersTokenUsage as Kt, findOpencodeSessionById as L, GatePolicy as Lt, gatedRolloutIds as M, GateCheck as Mt, measureFormatGate as N, GateCheckDisposition as Nt, GateDisposition as O, toHarborTrajectory as Ot, releaseRowRefs as P, GateCheckId as Pt, ScoreOrigin as Q, toSftRows as Qt, findOpencodeSessionsByDirectory as R, gateErrors as Rt, scrubLines as S, HarborSubagentTrajectoryRef as St, EmittedEvidence as T, fromHarborTrajectory as Tt, ClaudeUsageTotals as U, SftExportOptions as Ut, ClaudeTranscript as V, RewardRow as Vt, DEFAULT_CLAUDE_PROJECTS_DIR as W, SftRow as Wt, RolloutScrubber as X, toRftItem as Xt, MintRolloutResult as Y, toRewardRows as Yt, mintRolloutRows as Z, toRftItems as Zt, ScrubCounts as _, HarborMetrics as _t, ScrubReport as a, trainingScore as at, defaultRolloutScrubber as b, HarborStep as bt, planPushCommand as c, readRolloutLedger as ct, DatasetCardInputs as d, FromHarborOptions as dt, toVerifiersRolloutOutputs as en, isRealnessGated as et, FORMAT_FILES as f, HARBOR_IMPORT_GAP as ft, SCRUB_RULES as g, HarborImageSource as gt, buildDatasetCard as h, HarborFinalMetrics as ht, RolloutReleaseCliArgs as i, trainingReward as it, assertGateReport as j, GATE_POLICIES as jt, GateReport as k, GATE_CHECKS as kt, pushDataset as l, writeRolloutLedger as lt, ReleaseFormat as m, HarborContentPart as mt, BuildSummary as n, observedSplitScore as nt, buildHfDataset as o, appendRolloutLines as ot, RELEASE_FORMATS as p, HarborAgent as pt, readClaudeTranscript as q, realnessLabels as qt, ROLLOUT_RELEASE_USAGE as r, scoreOrigin as rt, parseRolloutReleaseArgs as s, readRolloutJournal as st, BuildOptions as t, observedScore as tt, runRolloutReleaseCli as u, ATIF_SCHEMA_VERSION as ut, ScrubRule as v, HarborObservation as vt, scrubText as w, HarborTrajectory as wt, emptyScrubCounts as x, HarborStepSource as xt, addScrubCounts as y, HarborObservationResult as yt, openOpencodeDb as z, gatedEvidenceOf as zt };
926
- //# sourceMappingURL=index-3cdlURSk2.d.ts.map
926
+ //# sourceMappingURL=index-3cdlURSk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-3cdlURSk.d.ts","names":[],"sources":["../src/rollout/exporters.ts","../src/rollout/gate-checks.ts","../src/rollout/interchange/harbor.ts","../src/rollout/ledger.ts","../src/rollout/reward.ts","../src/rollout/mint.ts","../src/rollout/readers/claude-jsonl.ts","../src/rollout/readers/opencode-sqlite.ts","../src/rollout/release/gate-report.ts","../src/rollout/release/scrub.ts","../src/rollout/release/card.ts","../src/rollout/release/hf-dataset.ts"],"mappings":"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"}
@@ -4,11 +4,11 @@ import { c as CostLedgerHandle, m as CostReceipt } from "./cost-ledger-fGS_u_O1.
4
4
  import { a as RunRecord, s as RunSplitTag } from "./run-record-DcObtIGh.js";
5
5
  import { l as RawProviderSink } from "./raw-provider-sink-BU29Sh8h.js";
6
6
  import { A as ChatClient } from "./types-Cc3qbqzj.js";
7
- import { c as EProcessState, d as PairedBootstrapOptions, f as PairedBootstrapResult, h as RiskDifferenceResult, u as McNemarResult } from "./statistics-DbvkkDPa.js";
8
7
  import { A as LabeledScenarioWrite, D as LabeledScenarioSampleArgs, E as LabeledScenarioRecord, O as LabeledScenarioSource, R as Scenario, S as JudgeConfig, T as LabelTrust, a as CampaignResult, b as GenerationRecord, d as DispatchContext, j as MutableSurface, k as LabeledScenarioStore, l as CodeSurface, p as Gate, u as ComponentSurface, w as JudgeScore } from "./types-BokuXvOG.js";
9
- import { rn as PlanCampaignRunOptions, sn as CampaignStorage, tn as CampaignRunPlan } from "./skillopt-optimization-method-C9M_lxdo.js";
8
+ import { rn as PlanCampaignRunOptions, sn as CampaignStorage, tn as CampaignRunPlan } from "./skillopt-optimization-method-CAASpcS3.js";
10
9
  import { n as AnalyzeTracesOptions, r as AnalyzeTracesResult, t as AnalyzeTracesInput } from "./analyst-BkTS3C58.js";
11
- import { o as LedgerHash } from "./index-BAvgST_9.js";
10
+ import { c as EProcessState, d as PairedBootstrapOptions, f as PairedBootstrapResult, h as RiskDifferenceResult, u as McNemarResult } from "./statistics-DbvkkDPa.js";
11
+ import { p as LedgerTrustedHead, w as LedgerHash } from "./index-nhIYz9hn.js";
12
12
  import { AgentProfile, AgentProfile as AgentProfile$1, HarnessType, HarnessType as HarnessType$1 } from "@tangle-network/agent-interface";
13
13
  //#region src/campaign/analyst-surface.d.ts
14
14
  /**
@@ -2064,15 +2064,35 @@ interface SearchLedgerAppendResult {
2064
2064
  /** Validate and return a canonical copy. Arrays whose order is not semantic are
2065
2065
  * sorted so retries from different processes produce byte-identical events. */
2066
2066
  declare function validateSearchLedgerEvent(input: unknown): SearchLedgerEvent;
2067
+ /**
2068
+ * How this ledger uses its trusted head — the `(sequence, entryHash)` pin kept
2069
+ * in the sibling `<path>.head` file that a hash chain needs to prove entries
2070
+ * were not deleted from the end. `ledger-core/trusted-head.ts` holds the threat
2071
+ * model.
2072
+ *
2073
+ * - `pin` (default): every append records the new head, and a pin that is
2074
+ * present is verified on every read.
2075
+ * - `require`: additionally refuses to read a non-empty ledger whose pin is
2076
+ * gone, so deleting the sibling file cannot downgrade the guarantee. Only for
2077
+ * ledgers written under `pin` from their first entry.
2078
+ * - `off`: chain verification only. Truncation to a valid shorter prefix is
2079
+ * undetectable.
2080
+ */
2081
+ type SearchLedgerTrustedHeadMode = 'pin' | 'require' | 'off';
2067
2082
  interface OpenSearchLedgerOptions {
2068
2083
  path: string;
2069
2084
  campaignId: string;
2085
+ trustedHead?: SearchLedgerTrustedHeadMode;
2070
2086
  }
2071
2087
  interface SearchLedger {
2072
2088
  readonly path: string;
2073
2089
  readonly campaignId: string;
2090
+ /** Sibling file holding this ledger's trusted head. */
2091
+ readonly trustedHeadPath: string;
2074
2092
  append(event: SearchLedgerEvent): Promise<SearchLedgerAppendResult>;
2075
2093
  replay(): Promise<SearchLedgerReplay>;
2094
+ /** The pinned head, or null when this ledger has never been pinned. */
2095
+ trustedHead(): Promise<LedgerTrustedHead | null>;
2076
2096
  }
2077
2097
  /** Open a durable filesystem search ledger. Construction performs no I/O; the
2078
2098
  * first `append` or `replay` validates the complete existing file. */
@@ -2081,10 +2101,13 @@ declare function openSearchLedger(options: OpenSearchLedgerOptions): SearchLedge
2081
2101
  declare class FileSearchLedger implements SearchLedger {
2082
2102
  readonly path: string;
2083
2103
  readonly campaignId: string;
2104
+ readonly trustedHeadPath: string;
2105
+ private readonly trustedHeadMode;
2084
2106
  private readonly journal;
2085
- constructor(path: string, campaignId: string);
2107
+ constructor(path: string, campaignId: string, trustedHead?: SearchLedgerTrustedHeadMode);
2086
2108
  replay(): Promise<SearchLedgerReplay>;
2087
2109
  append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult>;
2110
+ trustedHead(): Promise<LedgerTrustedHead | null>;
2088
2111
  }
2089
2112
  //#endregion
2090
2113
  //#region src/campaign/single-run-lock.d.ts
@@ -2246,5 +2269,5 @@ declare function verifyCodeSurface(surface: CodeSurface, worktreeDir?: string):
2246
2269
  * identity against the checkout at `worktreeRef`. */
2247
2270
  declare function resolveWorktreePath(surface: CodeSurface, worktreeDir?: string): string;
2248
2271
  //#endregion
2249
- export { SearchTaskAttemptedEvent as $, sequentialDecide as $n, CrossSurfaceRankedSingle as $r, ArtifactEventLike as $t, SearchCandidateSlot as A, FsLabeledScenarioStoreOptions as An, CrossSurfaceBootstrapPolicy as Ar, ProfileDispatchFn as At, SearchLedgerHash as B, HeldoutSignificance as Bn, CrossSurfaceEligibility as Br, assertRealBackend as Bt, SEARCH_LEDGER_SCHEMA as C, byteLengthRange as Cn, planEvalFixtureRun as Cr, UserStory as Ct, SearchCandidateDecidedEvent as D, regexMatch as Dn, CrossSurfaceAdditionRejectionReason as Dr, scoreUserStory as Dt, SearchAttemptAccounting as E, jsonHasKeys as En, CrossSurfaceAdditionDecision as Er, renderScoreboardMarkdown as Et, SearchFailureReason as F, ScoredRollout as Fn, CrossSurfaceCandidateSummary as Fr, ScenarioRollup as Ft, SearchPlan as G, heldoutSignificance as Gn, CrossSurfaceInteractionPath as Gr, HARNESS_NATIVE_MODEL as Gt, SearchModelIdentity as H, PairedHoldout as Hn, CrossSurfaceIneligibilityReason as Hr, summarizeBackendIntegrity as Ht, SearchLedger as I, UngroundedLiteralReport as In, CrossSurfaceComponent as Ir, runProfileMatrix as It, SearchPlannedTask as J, SequentialDecideOptions as Jn, CrossSurfaceNaiveStackSelection as Jr, agentProfileHash as Jt, SearchPlannedEvent as K, pairHoldout as Kn, CrossSurfaceInteractionReport as Kr, HarnessType$1 as Kt, SearchLedgerAppendResult as L, classifyUngroundedLiterals as Ln, CrossSurfaceComponentEvidence as Lr, BackendIntegrityError as Lt, SearchCandidateSurface as M, RolloutArgumentDiff as Mn, CrossSurfaceCandidateComparison as Mr, ProfileSummary as Mt, SearchCompletedEvent as N, RolloutArgumentDiffOptions as Nn, CrossSurfaceCandidateEvidence as Nr, RunProfileMatrixOptions as Nt, SearchCandidateLineage as O, neutralizeText as On, CrossSurfaceAttemptCompleteness as Or, scoreboardSummary as Ot, SearchCostAccounting as P, RolloutCall as Pn, CrossSurfaceCandidateOutcome as Pr, RunProfileMatrixResult as Pt, SearchSurfaceKind as Q, SequentialPairedGateOptions as Qn, CrossSurfacePairwiseEntry as Qr, harnessAxisOf as Qt, SearchLedgerEntry as R, rolloutArgumentDiff as Rn, CrossSurfaceCompositionStep as Rr, BackendIntegrityReport as Rt, OpenSearchLedgerOptions as S, failureModeRecallJudge as Si, ValidationResult as Sn, loadEvalFixtureScenarios as Sr, ScoreboardSummary as St, SearchArtifactRef as T, containsAll as Tn, AnalyzeCrossSurfaceInteractionsInput as Tr, makePlaybackDispatch as Tt, SearchOperationKind as U, detectScale as Un, CrossSurfaceInteractionAwareSelection as Ur, AgentProfile$1 as Ut, SearchLedgerReplay as V, HeldoutSignificanceOptions as Vn, CrossSurfaceEvidenceBreakdown as Vr, summarizeAgentReceiptIntegrity as Vt, SearchOperationRecordedEvent as W, dimensionRegressions as Wn, CrossSurfaceInteractionEffect as Wr, CODING_HARNESSES as Wt, SearchSurfaceEffect as X, SequentialObservation as Xn, CrossSurfacePairEvidence as Xr, agentProfileModelId as Xt, SearchSourceRef as Y, SequentialDecision as Yn, CrossSurfacePairCompatibility as Yr, agentProfileId as Yt, SearchSurfaceEvidence as Z, SequentialPairedGate as Zn, CrossSurfacePairIncompatibilityReason as Zr, expandProfileAxes as Zt, surfaceHash as _, AnalystArtifact as _i, verifyCompletion as _n, EvalFixtureValidationMode as _r, PlaybackContext as _t, WorktreeAdapterError as a, MatchedPair as ai, CompletionVerdict as an, canonicalize as ar, SearchLedgerError as at, acquireSingleRunLock as b, FailureModeRecallJudgeOptions as bi, ValidationContext as bn, discoverEvalFixtures as br, ScoreboardRenderOptions as bt, verifyCodeSurface as c, PairArmsResult as ci, ProducedProposal as cn, signManifest as cr, campaignBreakdown as ct, assertCodeSurfaceIdentity as d, PairedArmsComparison as di, SatisfiedBy as dn, neutralizationGate as dr, DiscriminationScore as dt, CrossSurfaceRelativeCost as ei, ProposalEventLike as en, sequentialPairedGate as er, SearchTaskOutcome as et, assertComponentSurface as f, PairedCorrectness as fi, TaskGold as fn, EvalFixture as fr, ScenarioSignal as ft, surfaceContentHash as g, pairRunRecords as gi, parseCorrectnessResponse as gn, EvalFixtureScenario as gr, tangleTracesRoot as gt, renderSurfaceDiff as h, pairArms as hi, createTokenRecallChecker as hn, EvalFixtureRunPlan as hr, resolveRunDir as ht, WorktreeAdapter as i, ComparePairedArmsOptions as ii, CompletionRequirement as in, SignedManifestAlgo as ir, SearchLedgerConflictError as it, SearchCandidateSlotClosedEvent as j, LabeledScenarioStoreError as jn, CrossSurfaceCandidate as jr, ProfileMatrixError as jt, SearchCandidateRegisteredEvent as k, FsLabeledScenarioStore as kn, CrossSurfaceBestSingleSelection as kr, userStoryScoreboard as kt, TransientFailureOptions as l, PairRunRecordsResult as li, ProducedState as ln, verifyManifest as lr, campaignMeanComposite as lt, componentSurfaceIdentityMaterial as m, comparePairedArms as mi, createLlmCorrectnessChecker as mn, EvalFixtureLoadOptions as mr, selectDiscriminative as mt, GitWorktreeAdapterOptions as n, CrossSurfaceSelections as ni, ToolCallEventLike as nn, HypothesisResult as nr, openSearchLedger as nt, gitWorktreeAdapter as o, MatchedRunRecordPair as oi, CorrectnessChecker as on, evaluateHypothesis as or, SearchLedgerIntegrityError as ot, codeSurfaceIdentityMaterial as p, PairedMetricDelta as pi, completionVerdict as pn, EvalFixtureFile as pr, scoreDiscrimination as pt, SearchPlannedOperation as q, SequentialDecideFn as qn, CrossSurfaceInteractionTask as qr, ProfileAxisSpec as qt, Worktree as r, CrossSurfaceTaskRow as ri, extractProducedState as rn, SignedManifest as rr, validateSearchLedgerEvent as rt, resolveWorktreePath as s, PairArmsOptions as si, LlmCorrectnessCheckerOpts as sn, hashJson as sr, CampaignBreakdown as st, CodeSurfaceVerification as t, CrossSurfaceSelectionPolicy as ti, RuntimeEventLike as tn, HypothesisManifest as tr, SearchTokenAccounting as tt, isTransientTransportFailure as u, PairedArmRow as ui, RequirementCheck as un, NeutralizationGateOptions as ur, compareRankKeys as ut, SingleRunLock as v, AnalystScenario as vi, Artifact as vn, LoadEvalFixtureScenariosOptions as vr, PlaybackDriver as vt, SearchAccountingAudit as w, composeValidators as wn, analyzeCrossSurfaceInteractions as wr, UserStoryVerdict as wt, FileSearchLedger as x, buildAnalystSurfaceDispatch as xi, ValidationIssue as xn, loadEvalFixture as xr, ScoreboardRow as xt, SingleRunLockOptions as y, BuildAnalystSurfaceDispatchOptions as yi, ArtifactValidator as yn, PlanEvalFixtureRunOptions as yr, PlaybackStep as yt, SearchLedgerEvent as z, DimensionRegression as zn, CrossSurfaceDistribution as zr, assertRealAgentReceipts as zt };
2250
- //# sourceMappingURL=index-FpfWFsKm.d.ts.map
2272
+ export { SearchSurfaceKind as $, SequentialPairedGateOptions as $n, CrossSurfacePairwiseEntry as $r, harnessAxisOf as $t, SearchCandidateSlot as A, FsLabeledScenarioStore as An, CrossSurfaceBestSingleSelection as Ar, userStoryScoreboard as At, SearchLedgerHash as B, DimensionRegression as Bn, CrossSurfaceDistribution as Br, assertRealAgentReceipts as Bt, SEARCH_LEDGER_SCHEMA as C, failureModeRecallJudge as Ci, ValidationResult as Cn, loadEvalFixtureScenarios as Cr, ScoreboardSummary as Ct, SearchCandidateDecidedEvent as D, jsonHasKeys as Dn, CrossSurfaceAdditionDecision as Dr, renderScoreboardMarkdown as Dt, SearchAttemptAccounting as E, containsAll as En, AnalyzeCrossSurfaceInteractionsInput as Er, makePlaybackDispatch as Et, SearchFailureReason as F, RolloutCall as Fn, CrossSurfaceCandidateOutcome as Fr, RunProfileMatrixResult as Ft, SearchOperationRecordedEvent as G, dimensionRegressions as Gn, CrossSurfaceInteractionEffect as Gr, CODING_HARNESSES as Gt, SearchLedgerTrustedHeadMode as H, HeldoutSignificanceOptions as Hn, CrossSurfaceEvidenceBreakdown as Hr, summarizeAgentReceiptIntegrity as Ht, SearchLedger as I, ScoredRollout as In, CrossSurfaceCandidateSummary as Ir, ScenarioRollup as It, SearchPlannedOperation as J, SequentialDecideFn as Jn, CrossSurfaceInteractionTask as Jr, ProfileAxisSpec as Jt, SearchPlan as K, heldoutSignificance as Kn, CrossSurfaceInteractionPath as Kr, HARNESS_NATIVE_MODEL as Kt, SearchLedgerAppendResult as L, UngroundedLiteralReport as Ln, CrossSurfaceComponent as Lr, runProfileMatrix as Lt, SearchCandidateSurface as M, LabeledScenarioStoreError as Mn, CrossSurfaceCandidate as Mr, ProfileMatrixError as Mt, SearchCompletedEvent as N, RolloutArgumentDiff as Nn, CrossSurfaceCandidateComparison as Nr, ProfileSummary as Nt, SearchCandidateLineage as O, regexMatch as On, CrossSurfaceAdditionRejectionReason as Or, scoreUserStory as Ot, SearchCostAccounting as P, RolloutArgumentDiffOptions as Pn, CrossSurfaceCandidateEvidence as Pr, RunProfileMatrixOptions as Pt, SearchSurfaceEvidence as Q, SequentialPairedGate as Qn, CrossSurfacePairIncompatibilityReason as Qr, expandProfileAxes as Qt, SearchLedgerEntry as R, classifyUngroundedLiterals as Rn, CrossSurfaceComponentEvidence as Rr, BackendIntegrityError as Rt, OpenSearchLedgerOptions as S, buildAnalystSurfaceDispatch as Si, ValidationIssue as Sn, loadEvalFixture as Sr, ScoreboardRow as St, SearchArtifactRef as T, composeValidators as Tn, analyzeCrossSurfaceInteractions as Tr, UserStoryVerdict as Tt, SearchModelIdentity as U, PairedHoldout as Un, CrossSurfaceIneligibilityReason as Ur, summarizeBackendIntegrity as Ut, SearchLedgerReplay as V, HeldoutSignificance as Vn, CrossSurfaceEligibility as Vr, assertRealBackend as Vt, SearchOperationKind as W, detectScale as Wn, CrossSurfaceInteractionAwareSelection as Wr, AgentProfile$1 as Wt, SearchSourceRef as X, SequentialDecision as Xn, CrossSurfacePairCompatibility as Xr, agentProfileId as Xt, SearchPlannedTask as Y, SequentialDecideOptions as Yn, CrossSurfaceNaiveStackSelection as Yr, agentProfileHash as Yt, SearchSurfaceEffect as Z, SequentialObservation as Zn, CrossSurfacePairEvidence as Zr, agentProfileModelId as Zt, surfaceHash as _, pairRunRecords as _i, parseCorrectnessResponse as _n, EvalFixtureScenario as _r, tangleTracesRoot as _t, WorktreeAdapterError as a, ComparePairedArmsOptions as ai, CompletionRequirement as an, SignedManifestAlgo as ar, SearchLedgerConflictError as at, acquireSingleRunLock as b, BuildAnalystSurfaceDispatchOptions as bi, ArtifactValidator as bn, PlanEvalFixtureRunOptions as br, PlaybackStep as bt, verifyCodeSurface as c, PairArmsOptions as ci, LlmCorrectnessCheckerOpts as cn, hashJson as cr, CampaignBreakdown as ct, assertCodeSurfaceIdentity as d, PairedArmRow as di, RequirementCheck as dn, NeutralizationGateOptions as dr, compareRankKeys as dt, CrossSurfaceRankedSingle as ei, ArtifactEventLike as en, sequentialDecide as er, SearchTaskAttemptedEvent as et, assertComponentSurface as f, PairedArmsComparison as fi, SatisfiedBy as fn, neutralizationGate as fr, DiscriminationScore as ft, surfaceContentHash as g, pairArms as gi, createTokenRecallChecker as gn, EvalFixtureRunPlan as gr, resolveRunDir as gt, renderSurfaceDiff as h, comparePairedArms as hi, createLlmCorrectnessChecker as hn, EvalFixtureLoadOptions as hr, selectDiscriminative as ht, WorktreeAdapter as i, CrossSurfaceTaskRow as ii, extractProducedState as in, SignedManifest as ir, validateSearchLedgerEvent as it, SearchCandidateSlotClosedEvent as j, FsLabeledScenarioStoreOptions as jn, CrossSurfaceBootstrapPolicy as jr, ProfileDispatchFn as jt, SearchCandidateRegisteredEvent as k, neutralizeText as kn, CrossSurfaceAttemptCompleteness as kr, scoreboardSummary as kt, TransientFailureOptions as l, PairArmsResult as li, ProducedProposal as ln, signManifest as lr, campaignBreakdown as lt, componentSurfaceIdentityMaterial as m, PairedMetricDelta as mi, completionVerdict as mn, EvalFixtureFile as mr, scoreDiscrimination as mt, GitWorktreeAdapterOptions as n, CrossSurfaceSelectionPolicy as ni, RuntimeEventLike as nn, HypothesisManifest as nr, SearchTokenAccounting as nt, gitWorktreeAdapter as o, MatchedPair as oi, CompletionVerdict as on, canonicalize as or, SearchLedgerError as ot, codeSurfaceIdentityMaterial as p, PairedCorrectness as pi, TaskGold as pn, EvalFixture as pr, ScenarioSignal as pt, SearchPlannedEvent as q, pairHoldout as qn, CrossSurfaceInteractionReport as qr, HarnessType$1 as qt, Worktree as r, CrossSurfaceSelections as ri, ToolCallEventLike as rn, HypothesisResult as rr, openSearchLedger as rt, resolveWorktreePath as s, MatchedRunRecordPair as si, CorrectnessChecker as sn, evaluateHypothesis as sr, SearchLedgerIntegrityError as st, CodeSurfaceVerification as t, CrossSurfaceRelativeCost as ti, ProposalEventLike as tn, sequentialPairedGate as tr, SearchTaskOutcome as tt, isTransientTransportFailure as u, PairRunRecordsResult as ui, ProducedState as un, verifyManifest as ur, campaignMeanComposite as ut, SingleRunLock as v, AnalystArtifact as vi, verifyCompletion as vn, EvalFixtureValidationMode as vr, PlaybackContext as vt, SearchAccountingAudit as w, byteLengthRange as wn, planEvalFixtureRun as wr, UserStory as wt, FileSearchLedger as x, FailureModeRecallJudgeOptions as xi, ValidationContext as xn, discoverEvalFixtures as xr, ScoreboardRenderOptions as xt, SingleRunLockOptions as y, AnalystScenario as yi, Artifact as yn, LoadEvalFixtureScenariosOptions as yr, PlaybackDriver as yt, SearchLedgerEvent as z, rolloutArgumentDiff as zn, CrossSurfaceCompositionStep as zr, BackendIntegrityReport as zt };
2273
+ //# sourceMappingURL=index-Ba636PKl.d.ts.map