@tangle-network/agent-eval 0.119.0 → 0.119.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 (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/analyst/index.d.ts +30 -39
  3. package/dist/analyst/index.js +9 -5
  4. package/dist/analyst/index.js.map +1 -1
  5. package/dist/benchmarks/index.js +5 -5
  6. package/dist/campaign/index.d.ts +28 -29
  7. package/dist/campaign/index.js +5 -5
  8. package/dist/{chunk-LMJ2TGWJ.js → chunk-JM2SKQMS.js} +2 -2
  9. package/dist/{chunk-RLCJQ6VZ.js → chunk-PSXJ32SR.js} +157 -3
  10. package/dist/chunk-PSXJ32SR.js.map +1 -0
  11. package/dist/{chunk-6QIM2EAP.js → chunk-PXD6ZFNY.js} +99 -1
  12. package/dist/chunk-PXD6ZFNY.js.map +1 -0
  13. package/dist/{chunk-GERDAIAL.js → chunk-QWMPPZ3X.js} +3 -3
  14. package/dist/{chunk-7A4LIMMY.js → chunk-S5TT5R3L.js} +229 -97
  15. package/dist/chunk-S5TT5R3L.js.map +1 -0
  16. package/dist/{chunk-ZYHJNKI3.js → chunk-ULOKLHIQ.js} +42 -5
  17. package/dist/chunk-ULOKLHIQ.js.map +1 -0
  18. package/dist/{chunk-FIUFRXP3.js → chunk-WW2A73HW.js} +49 -91
  19. package/dist/chunk-WW2A73HW.js.map +1 -0
  20. package/dist/{chunk-F6YUH3L4.js → chunk-XMBOU5W7.js} +12 -165
  21. package/dist/chunk-XMBOU5W7.js.map +1 -0
  22. package/dist/contract/index.d.ts +25 -16
  23. package/dist/contract/index.js +281 -5
  24. package/dist/contract/index.js.map +1 -1
  25. package/dist/index.d.ts +71 -68
  26. package/dist/index.js +31 -32
  27. package/dist/index.js.map +1 -1
  28. package/dist/openapi.json +1 -1
  29. package/dist/traces.d.ts +39 -25
  30. package/dist/traces.js +3 -5
  31. package/docs/trace-analysis.md +6 -2
  32. package/package.json +2 -2
  33. package/dist/chunk-6QIM2EAP.js.map +0 -1
  34. package/dist/chunk-7A4LIMMY.js.map +0 -1
  35. package/dist/chunk-F6YUH3L4.js.map +0 -1
  36. package/dist/chunk-FIUFRXP3.js.map +0 -1
  37. package/dist/chunk-RLCJQ6VZ.js.map +0 -1
  38. package/dist/chunk-ZYHJNKI3.js.map +0 -1
  39. /package/dist/{chunk-LMJ2TGWJ.js.map → chunk-JM2SKQMS.js.map} +0 -0
  40. /package/dist/{chunk-GERDAIAL.js.map → chunk-QWMPPZ3X.js.map} +0 -0
@@ -1,3 +1,4 @@
1
+ import { AgentImprovementMeasuredComparison, Sha256Digest } from '@tangle-network/agent-interface';
1
2
  import { AxFunction, AxAIService } from '@ax-llm/ax';
2
3
  import { z } from 'zod';
3
4
 
@@ -1122,6 +1123,8 @@ interface AnalystCost {
1122
1123
  est_usd_per_run?: number;
1123
1124
  /** Models the analyst expects to use (informational). */
1124
1125
  models?: string[];
1126
+ /** Maximum post-cancellation wait for provider usage. Model analysts default to 5 seconds. */
1127
+ settlement_timeout_ms?: number;
1125
1128
  }
1126
1129
  interface AnalystRequirements {
1127
1130
  /** Min number of shots / samples the analyst needs to produce signal. */
@@ -1145,7 +1148,7 @@ interface AnalystContext {
1145
1148
  runId: string;
1146
1149
  /** Stable correlation id so logs from a single registry.run() share a tag. */
1147
1150
  correlationId: string;
1148
- /** Wall-clock deadline (epoch ms). Analysts SHOULD honor for graceful cancel. */
1151
+ /** Enforced wall-clock deadline (epoch ms). */
1149
1152
  deadlineMs?: number;
1150
1153
  /** Per-analyst USD budget. Analysts MAY check before issuing LLM calls. */
1151
1154
  budgetUsd?: number;
@@ -4000,6 +4003,15 @@ interface DefinedAgentEval<TScenario extends Scenario, TArtifact> {
4000
4003
  */
4001
4004
  declare function defineAgentEval<TScenario extends Scenario, TArtifact>(defaults: DefineAgentEvalOptions<TScenario, TArtifact>): DefinedAgentEval<TScenario, TArtifact>;
4002
4005
 
4006
+ interface MeasuredComparisonFromSelfImproveResultOptions<TScenario extends Scenario, TArtifact> {
4007
+ result: SelfImproveResult<TScenario, TArtifact>;
4008
+ benchmark: AgentImprovementMeasuredComparison['benchmark'];
4009
+ baselineProfileDigest: Sha256Digest;
4010
+ candidateBundleDigest: Sha256Digest;
4011
+ }
4012
+ /** Convert one paired self-improvement result into the portable Interface evidence record. */
4013
+ declare function measuredComparisonFromSelfImproveResult<TScenario extends Scenario, TArtifact>(options: MeasuredComparisonFromSelfImproveResultOptions<TScenario, TArtifact>): AgentImprovementMeasuredComparison;
4014
+
4003
4015
  /**
4004
4016
  * Typed Ax output for analyst findings.
4005
4017
  *
@@ -4065,8 +4077,8 @@ type CanonicalRawAnalystFinding = z.infer<typeof CanonicalRawAnalystFindingSchem
4065
4077
  * Analyst-kind factory — the typed way to define trace analysts.
4066
4078
  *
4067
4079
  * A "kind" is a specialized analyst whose actor prompt, tool subset,
4068
- * and Ax recursion config target one failure-mode lens (failure-mode
4069
- * classification, knowledge gap discovery, knowledge poisoning, recursive
4080
+ * and bounded Ax subqueries target one failure-mode lens (failure-mode
4081
+ * classification, knowledge gap discovery, knowledge poisoning,
4070
4082
  * self-improvement, ...). Kinds emit findings in the typed
4071
4083
  * `CanonicalRawAnalystFinding` shape via a JSON-array Ax output; the factory
4072
4084
  * validates each row with Zod and lifts it into `AnalystFinding[]`.
@@ -4077,12 +4089,11 @@ type CanonicalRawAnalystFinding = z.infer<typeof CanonicalRawAnalystFindingSchem
4077
4089
  * - Each kind picks a narrow tool subset from `ANALYST_TOOL_GROUPS`.
4078
4090
  * A kind that never needs full-trace dumps can drop `viewTrace` /
4079
4091
  * `viewSpans` and stay cheap.
4080
- * - Each kind declares its recursion + parallelism budget. Discovery-
4081
- * heavy kinds (failure-mode) get higher `maxDepth`; lens kinds
4082
- * (poisoning) usually stay at 0 since they have a tighter brief.
4092
+ * - Each kind declares its subquery + parallelism budget. Discovery-heavy
4093
+ * kinds can fan out more bounded semantic questions than narrow lenses.
4083
4094
  *
4084
4095
  * Optimizer hook: kinds may declare `goldens` — labeled examples used
4085
- * by `AxMiPRO` / `AxBootstrapFewShot` / `AxGEPA` to fit the actor
4096
+ * by `AxBootstrapFewShot` / `AxGEPA` to fit the actor
4086
4097
  * description programmatically. Stored on the kind, not the registry,
4087
4098
  * because the right metric is kind-specific.
4088
4099
  */
@@ -4102,20 +4113,18 @@ interface TraceAnalystKindSpec {
4102
4113
  version: string;
4103
4114
  /** Actor system prompt. Must instruct the LLM to emit `findings` per the schema. */
4104
4115
  actorDescription: string;
4105
- /** Responder system prompt; falls back to a minimal "format the findings" instruction. */
4106
- responderDescription?: string;
4107
4116
  /** Tool functions the actor may call. Pick narrow subsets via `ANALYST_TOOL_GROUPS`. */
4108
4117
  buildTools: (store: TraceAnalysisStore) => AxFunction[];
4109
- /** Recursion budget. `maxDepth: 0` disables subagents. */
4110
- recursion?: {
4111
- maxDepth: number;
4112
- maxParallelSubagents?: number;
4118
+ /** Bounded semantic subqueries. `maxCalls: 0` disables model fan-out. */
4119
+ subqueries?: {
4120
+ maxCalls: number;
4121
+ maxParallel?: number;
4113
4122
  };
4114
4123
  /** Actor turn cap. Default 12. */
4115
4124
  maxTurns?: number;
4116
4125
  /** Runtime char cap. Default 6000. */
4117
4126
  maxRuntimeChars?: number;
4118
- /** Maximum output tokens for every actor, responder, and recursive model call. Default 4096. */
4127
+ /** Maximum output tokens for every actor and subquery model call. Default 4096. */
4119
4128
  maxOutputTokens?: number;
4120
4129
  /** Cost classification surfaced in `registry.list()` and budget enforcement. */
4121
4130
  cost: AnalystCost;
@@ -4219,7 +4228,7 @@ interface RegistryRunOpts {
4219
4228
  skip?: string[];
4220
4229
  /** Budget policy — totalUsd + optional weights/allocator. Falls back to options.defaultBudget. */
4221
4230
  budget?: BudgetPolicy;
4222
- /** Wall-clock cap. Analysts SHOULD honor `ctx.deadlineMs`. */
4231
+ /** Active-work cap for the complete registry run. Model receipt settlement may follow. */
4223
4232
  timeoutMs?: number;
4224
4233
  /** Abort signal — forwarded into every analyst's context. */
4225
4234
  signal?: AbortSignal;
@@ -4933,4 +4942,4 @@ interface FromOtelSpansOptions {
4933
4942
  }
4934
4943
  declare function fromOtelSpans(opts: FromOtelSpansOptions): RunRecord[];
4935
4944
 
4936
- export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type ChatClient, type CodeAgentSessionDiagnostic, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionSource, type CodeSurface, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runEval, runImprovementLoop, runReferenceEquivalenceJudge, selfImprove, summarizeExecution };
4945
+ export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type ChatClient, type CodeAgentSessionDiagnostic, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionSource, type CodeSurface, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type MeasuredComparisonFromSelfImproveResultOptions, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, measuredComparisonFromSelfImproveResult, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runEval, runImprovementLoop, runReferenceEquivalenceJudge, selfImprove, summarizeExecution };
@@ -26,6 +26,7 @@ import {
26
26
  evolutionaryProposer,
27
27
  gepaProposer,
28
28
  heldOutGate,
29
+ pairArms,
29
30
  paretoPolicy,
30
31
  paretoSignificanceGate,
31
32
  powerPreflight,
@@ -34,8 +35,9 @@ import {
34
35
  runReferenceEquivalenceJudge,
35
36
  surfaceContentHash,
36
37
  surfaceHash
37
- } from "../chunk-RLCJQ6VZ.js";
38
+ } from "../chunk-PSXJ32SR.js";
38
39
  import {
40
+ canonicalJson,
39
41
  createRunCostLedger,
40
42
  fsCampaignStorage,
41
43
  inMemoryCampaignStorage,
@@ -45,9 +47,9 @@ import {
45
47
  import {
46
48
  buildDefaultAnalystRegistry,
47
49
  createChatClient
48
- } from "../chunk-GERDAIAL.js";
50
+ } from "../chunk-QWMPPZ3X.js";
49
51
  import "../chunk-HHWE3POT.js";
50
- import "../chunk-7A4LIMMY.js";
52
+ import "../chunk-S5TT5R3L.js";
51
53
  import {
52
54
  FileSystemOutcomeStore,
53
55
  InMemoryOutcomeStore
@@ -55,7 +57,9 @@ import {
55
57
  import "../chunk-ARU2PZFM.js";
56
58
  import "../chunk-NJC7U437.js";
57
59
  import "../chunk-DPZAEKA6.js";
58
- import "../chunk-PJQFMIOX.js";
60
+ import {
61
+ pairedBootstrap
62
+ } from "../chunk-PJQFMIOX.js";
59
63
  import "../chunk-JHOJHHU7.js";
60
64
  import "../chunk-VI2UW6B6.js";
61
65
  import {
@@ -65,7 +69,7 @@ import {
65
69
  import "../chunk-PXE2VKMX.js";
66
70
  import "../chunk-ZET2UAYW.js";
67
71
  import "../chunk-GGE4NNQT.js";
68
- import "../chunk-6QIM2EAP.js";
72
+ import "../chunk-PXD6ZFNY.js";
69
73
  import "../chunk-PC4UYEBM.js";
70
74
  import {
71
75
  parseRunRecordSafe
@@ -536,6 +540,277 @@ function requirePositiveInteger(value, field) {
536
540
  return value;
537
541
  }
538
542
 
543
+ // src/contract/measured-comparison.ts
544
+ import { createHash as createHash2 } from "crypto";
545
+ import {
546
+ agentImprovementMeasuredComparisonSchema
547
+ } from "@tangle-network/agent-interface";
548
+ function measuredComparisonFromSelfImproveResult(options) {
549
+ const { result } = options;
550
+ const power = result.power;
551
+ if (!power) throw new Error("agent improvement comparison requires heldout power analysis");
552
+ if (result.provenance.gate.reasons.length === 0) {
553
+ throw new Error("agent improvement comparison requires measured decision reasons");
554
+ }
555
+ const pairs = pairMeasuredCells(
556
+ result.raw.baselineOnHoldout.cells,
557
+ result.raw.winnerOnHoldout.cells
558
+ );
559
+ const composite = measuredObjective(
560
+ {
561
+ kind: "objective",
562
+ name: "composite",
563
+ direction: "higher-is-better",
564
+ unit: "score"
565
+ },
566
+ pairs,
567
+ measuredComposite
568
+ );
569
+ assertMeasuredNumber(result.lift, composite.delta, "heldout lift");
570
+ assertMeasuredNumber(result.baseline.compositeMean, composite.baseline, "heldout baseline");
571
+ assertMeasuredNumber(result.winner.compositeMean, composite.candidate, "heldout candidate");
572
+ assertMeasuredNumber(result.provenance.heldOutLift, composite.delta, "provenance heldout lift");
573
+ if (result.gateDecision !== result.provenance.gate.decision || power.n !== composite.n || power.confidence !== 0.95) {
574
+ throw new Error("agent improvement measurement sources do not agree");
575
+ }
576
+ return agentImprovementMeasuredComparisonSchema.parse({
577
+ schemaVersion: 1,
578
+ kind: "agent-improvement-measured-comparison",
579
+ benchmark: options.benchmark,
580
+ baselineProfileDigest: options.baselineProfileDigest,
581
+ candidateBundleDigest: options.candidateBundleDigest,
582
+ overall: {
583
+ name: "composite",
584
+ baseline: composite.baseline,
585
+ candidate: composite.candidate,
586
+ delta: composite.delta,
587
+ confidenceInterval: composite.confidenceInterval,
588
+ n: composite.n,
589
+ direction: "higher-is-better",
590
+ unit: "score"
591
+ },
592
+ objectives: measuredObjectives(pairs),
593
+ ...result.winner.label || result.winner.rationale ? {
594
+ candidate: {
595
+ ...result.winner.label ? { label: result.winner.label } : {},
596
+ ...result.winner.rationale ? { rationale: result.winner.rationale } : {}
597
+ }
598
+ } : {},
599
+ decision: {
600
+ outcome: result.gateDecision,
601
+ reasons: result.provenance.gate.reasons,
602
+ contributingChecks: result.provenance.gate.contributingGates.map((check) => ({
603
+ name: check.name,
604
+ passed: check.passed
605
+ }))
606
+ },
607
+ power: {
608
+ sufficient: power.scaleAssumed && !power.underpowered,
609
+ n: power.n,
610
+ minimumDetectableDelta: power.mde,
611
+ confidenceLevel: power.confidence,
612
+ scaleAssumed: power.scaleAssumed,
613
+ sharedScorerChannel: power.sharedChannelCaveat !== void 0,
614
+ reason: power.recommendation
615
+ },
616
+ provenance: {
617
+ kind: "agent-eval-loop",
618
+ schema: result.provenance.schema,
619
+ runId: result.provenance.runId,
620
+ recordDigest: digest(result.provenance),
621
+ baselineContentHash: result.provenance.baselineContentHash,
622
+ candidateContentHash: result.provenance.winnerContentHash
623
+ },
624
+ diff: result.diff,
625
+ evaluation: {
626
+ generationsExplored: result.generationsExplored,
627
+ durationMs: result.durationMs,
628
+ totalCostUsd: result.totalCostUsd
629
+ }
630
+ });
631
+ }
632
+ function measuredObjectives(pairs) {
633
+ const qualityColumns = /* @__PURE__ */ new Map();
634
+ for (const [baseline, candidate] of pairs) {
635
+ for (const cell of [baseline, candidate]) {
636
+ for (const [objective, score] of Object.entries(cell.judgeScores)) {
637
+ if (score.failed) continue;
638
+ qualityColumns.set(`objective:${objective}`, {
639
+ kind: "objective",
640
+ name: objective,
641
+ direction: "higher-is-better",
642
+ unit: "score"
643
+ });
644
+ for (const name of Object.keys(score.dimensions)) {
645
+ qualityColumns.set(`dimension:${objective}:${name}`, {
646
+ kind: "dimension",
647
+ objective,
648
+ name,
649
+ direction: "higher-is-better",
650
+ unit: "score"
651
+ });
652
+ }
653
+ }
654
+ }
655
+ }
656
+ return [
657
+ ...[...qualityColumns.entries()].sort(([left], [right]) => left.localeCompare(right)).map(
658
+ ([, column]) => measuredObjective(column, pairs, (cell) => measuredQuality(cell, column))
659
+ ),
660
+ measuredCostObjective(pairs),
661
+ measuredObjective(
662
+ {
663
+ kind: "latency",
664
+ name: "latency",
665
+ direction: "lower-is-better",
666
+ unit: "milliseconds"
667
+ },
668
+ pairs,
669
+ (cell) => cell.durationMs
670
+ )
671
+ ];
672
+ }
673
+ function measuredCostObjective(pairs) {
674
+ const cells = pairs.flat();
675
+ for (const cell of cells) finiteMeasuredValue(cell.costUsd, "cost:cost");
676
+ const reported = cells.some(
677
+ (cell) => cell.costUsd !== 0 || cell.tokenUsage !== void 0 && (cell.tokenUsage.input > 0 || cell.tokenUsage.output > 0)
678
+ );
679
+ if (!reported) {
680
+ return {
681
+ kind: "cost",
682
+ name: "cost",
683
+ availability: "unavailable",
684
+ reason: "heldout cells did not report model usage or cost",
685
+ direction: "lower-is-better",
686
+ unit: "usd"
687
+ };
688
+ }
689
+ return measuredObjective(
690
+ {
691
+ kind: "cost",
692
+ name: "cost",
693
+ direction: "lower-is-better",
694
+ unit: "usd"
695
+ },
696
+ pairs,
697
+ (cell) => cell.costUsd
698
+ );
699
+ }
700
+ function measuredComposite(cell) {
701
+ const values = Object.values(cell.judgeScores).filter((score) => !score.failed).map((score) => score.composite).filter(Number.isFinite);
702
+ if (values.length === 0) {
703
+ throw new Error(`heldout cell ${measuredCellKey(cell)} has no successful composite score`);
704
+ }
705
+ return measuredMean(values);
706
+ }
707
+ function pairMeasuredCells(baselineCells, candidateCells) {
708
+ const errors = [...baselineCells, ...candidateCells].filter((cell) => cell.error);
709
+ if (errors.length > 0) {
710
+ throw new Error(
711
+ `measured objectives cannot publish ${errors.length} errored heldout cells: ${errors.map((cell) => measuredCellKey(cell)).join(", ")}`
712
+ );
713
+ }
714
+ const rows = [
715
+ ...baselineCells.map((cell) => ({
716
+ pairKey: cell.scenarioId,
717
+ repKey: String(cell.rep),
718
+ arm: "baseline",
719
+ cell
720
+ })),
721
+ ...candidateCells.map((cell) => ({
722
+ pairKey: cell.scenarioId,
723
+ repKey: String(cell.rep),
724
+ arm: "candidate",
725
+ cell
726
+ }))
727
+ ];
728
+ const paired = pairArms(rows, { baselineArm: "baseline", treatmentArm: "candidate" });
729
+ if (paired.pairs.length === 0 || paired.unpairedBaseline.length > 0 || paired.unpairedTreatment.length > 0) {
730
+ throw new Error("measured objectives require the same non-empty paired heldout cells");
731
+ }
732
+ return paired.pairs.map(
733
+ (pair) => [pair.baseline.cell, pair.treatment.cell]
734
+ );
735
+ }
736
+ function measuredObjective(identity, pairs, value) {
737
+ const key = measuredObjectiveKey(identity);
738
+ const baseline = pairs.map(([cell]) => finiteMeasuredValue(value(cell), key));
739
+ const candidate = pairs.map(([, cell]) => finiteMeasuredValue(value(cell), key));
740
+ const interval = pairedBootstrap(baseline, candidate, {
741
+ confidence: 0.95,
742
+ resamples: 2e3,
743
+ statistic: "mean",
744
+ seed: measuredSeed(key)
745
+ });
746
+ const baselineMean = measuredMean(baseline);
747
+ const candidateMean = measuredMean(candidate);
748
+ return {
749
+ ...identity,
750
+ availability: "measured",
751
+ baseline: baselineMean,
752
+ candidate: candidateMean,
753
+ delta: candidateMean - baselineMean,
754
+ confidenceInterval: {
755
+ level: interval.confidence,
756
+ lower: interval.low,
757
+ upper: interval.high,
758
+ method: "paired-bootstrap",
759
+ statistic: "mean",
760
+ resamples: interval.resamples
761
+ },
762
+ n: interval.n
763
+ };
764
+ }
765
+ function measuredQuality(cell, column) {
766
+ const objective = column.kind === "objective" ? column.name : column.objective;
767
+ const score = cell.judgeScores[objective];
768
+ if (!score || score.failed) {
769
+ throw new Error(
770
+ `heldout cell ${measuredCellKey(cell)} is missing measured objective '${objective}'`
771
+ );
772
+ }
773
+ const value = column.kind === "objective" ? score.composite : score.dimensions[column.name];
774
+ if (value === void 0) {
775
+ throw new Error(
776
+ `heldout cell ${measuredCellKey(cell)} is missing '${objective}' dimension '${column.name}'`
777
+ );
778
+ }
779
+ return finiteMeasuredValue(value, measuredObjectiveKey(column));
780
+ }
781
+ function measuredObjectiveKey(identity) {
782
+ return identity.kind === "dimension" ? `${identity.kind}:${identity.objective}:${identity.name}` : `${identity.kind}:${identity.name}`;
783
+ }
784
+ function measuredCellKey(cell) {
785
+ return `${cell.scenarioId}:${cell.rep}`;
786
+ }
787
+ function finiteMeasuredValue(value, name) {
788
+ if (!Number.isFinite(value)) throw new Error(`measured objective '${name}' is not finite`);
789
+ return value;
790
+ }
791
+ function measuredMean(values) {
792
+ if (values.length === 0) throw new Error("measured objective has no paired values");
793
+ return values.reduce((sum, value) => sum + value, 0) / values.length;
794
+ }
795
+ function measuredSeed(value) {
796
+ let seed = 2166136261;
797
+ for (const byte of Buffer.from(value, "utf8")) {
798
+ seed = Math.imul(seed ^ byte, 16777619) >>> 0;
799
+ }
800
+ return seed;
801
+ }
802
+ function assertMeasuredNumber(actual, expected, name) {
803
+ const tolerance = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 8;
804
+ if (!Number.isFinite(actual) || !Number.isFinite(expected) || Math.abs(actual - expected) > tolerance) {
805
+ throw new Error(`${name} does not agree across the measured comparison`);
806
+ }
807
+ }
808
+ function digest(value) {
809
+ const json = JSON.stringify(value);
810
+ if (json === void 0) throw new Error("agent improvement provenance is not serializable");
811
+ return `sha256:${createHash2("sha256").update(canonicalJson(JSON.parse(json))).digest("hex")}`;
812
+ }
813
+
539
814
  // src/contract/eval-reporting-suite.ts
540
815
  import { mkdir, writeFile } from "fs/promises";
541
816
  import { dirname, join as join2 } from "path";
@@ -1074,6 +1349,7 @@ export {
1074
1349
  gepaProposer,
1075
1350
  heldOutGate,
1076
1351
  inMemoryCampaignStorage,
1352
+ measuredComparisonFromSelfImproveResult,
1077
1353
  paretoPolicy,
1078
1354
  paretoSignificanceGate,
1079
1355
  parseAgentTrace,