@tangle-network/agent-eval 0.23.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +141 -79
  3. package/dist/baseline-4R5deP0N.d.ts +108 -0
  4. package/dist/benchmarks/index.d.ts +3 -2
  5. package/dist/benchmarks/index.js +1 -1
  6. package/dist/builder-eval/index.d.ts +249 -0
  7. package/dist/builder-eval/index.js +391 -0
  8. package/dist/builder-eval/index.js.map +1 -0
  9. package/dist/{chunk-IOXMGMHQ.js → chunk-2A5XJB43.js} +142 -318
  10. package/dist/chunk-2A5XJB43.js.map +1 -0
  11. package/dist/chunk-47X6LRCE.js +76 -0
  12. package/dist/chunk-47X6LRCE.js.map +1 -0
  13. package/dist/{chunk-6M774GY6.js → chunk-4F5DQN55.js} +1 -1
  14. package/dist/chunk-4F5DQN55.js.map +1 -0
  15. package/dist/{chunk-KAO3Q65R.js → chunk-4S4BM3QQ.js} +15 -13
  16. package/dist/chunk-4S4BM3QQ.js.map +1 -0
  17. package/dist/chunk-5BKGXME7.js +65 -0
  18. package/dist/chunk-5BKGXME7.js.map +1 -0
  19. package/dist/{chunk-42I2QC2L.js → chunk-6QDKWHLS.js} +18 -14
  20. package/dist/chunk-6QDKWHLS.js.map +1 -0
  21. package/dist/chunk-I4MBDTY5.js +272 -0
  22. package/dist/chunk-I4MBDTY5.js.map +1 -0
  23. package/dist/chunk-K2TPS5LB.js +569 -0
  24. package/dist/chunk-K2TPS5LB.js.map +1 -0
  25. package/dist/chunk-KKHDIONI.js +414 -0
  26. package/dist/chunk-KKHDIONI.js.map +1 -0
  27. package/dist/chunk-KMPRBJK4.js +74 -0
  28. package/dist/chunk-KMPRBJK4.js.map +1 -0
  29. package/dist/{chunk-QUKKGHTZ.js → chunk-KTGTIOFD.js} +6 -3
  30. package/dist/chunk-KTGTIOFD.js.map +1 -0
  31. package/dist/chunk-LSH4MMOZ.js +838 -0
  32. package/dist/chunk-LSH4MMOZ.js.map +1 -0
  33. package/dist/chunk-NG236HPC.js +57 -0
  34. package/dist/chunk-NG236HPC.js.map +1 -0
  35. package/dist/{chunk-QBW3YBTR.js → chunk-NLMNWKVM.js} +14 -6
  36. package/dist/chunk-NLMNWKVM.js.map +1 -0
  37. package/dist/chunk-NU65VQ7M.js +99 -0
  38. package/dist/chunk-NU65VQ7M.js.map +1 -0
  39. package/dist/chunk-OHEPNJQN.js +554 -0
  40. package/dist/chunk-OHEPNJQN.js.map +1 -0
  41. package/dist/chunk-OWLAAMME.js +250 -0
  42. package/dist/chunk-OWLAAMME.js.map +1 -0
  43. package/dist/{chunk-SQQLHODJ.js → chunk-PC4UYEBM.js} +7 -4
  44. package/dist/chunk-PC4UYEBM.js.map +1 -0
  45. package/dist/{chunk-7EAUOUQS.js → chunk-RAF443UI.js} +213 -115
  46. package/dist/chunk-RAF443UI.js.map +1 -0
  47. package/dist/chunk-RZTMDUO7.js +49 -0
  48. package/dist/chunk-RZTMDUO7.js.map +1 -0
  49. package/dist/{chunk-EXGR4XEM.js → chunk-SESZDQPX.js} +23 -19
  50. package/dist/chunk-SESZDQPX.js.map +1 -0
  51. package/dist/{chunk-6KQG5HAH.js → chunk-SY6WAAAD.js} +84 -71
  52. package/dist/chunk-SY6WAAAD.js.map +1 -0
  53. package/dist/{chunk-5IIQKMD5.js → chunk-TVVP3ZZQ.js} +14 -4
  54. package/dist/chunk-TVVP3ZZQ.js.map +1 -0
  55. package/dist/{chunk-VQQSPGSM.js → chunk-VRJVTXRV.js} +169 -111
  56. package/dist/chunk-VRJVTXRV.js.map +1 -0
  57. package/dist/chunk-WWYCWKUM.js +196 -0
  58. package/dist/chunk-WWYCWKUM.js.map +1 -0
  59. package/dist/{chunk-AXHNWLIX.js → chunk-YRZ4M5GS.js} +2 -90
  60. package/dist/chunk-YRZ4M5GS.js.map +1 -0
  61. package/dist/chunk-ZN274SWR.js +613 -0
  62. package/dist/chunk-ZN274SWR.js.map +1 -0
  63. package/dist/cli.js +10 -6
  64. package/dist/cli.js.map +1 -1
  65. package/dist/{control-DvkH87qJ.d.ts → control-CBShYYA6.d.ts} +32 -33
  66. package/dist/control-runtime-BuJHoLg0.d.ts +180 -0
  67. package/dist/control.d.ts +8 -6
  68. package/dist/control.js +10 -7
  69. package/dist/{dataset-B9qvlm_o.d.ts → dataset-CiK_3LDr.d.ts} +5 -2
  70. package/dist/{emitter-B2XqDKFU.d.ts → emitter-DP_cSSiw.d.ts} +1 -1
  71. package/dist/errors-BZ9sTdz7.d.ts +70 -0
  72. package/dist/failure-cluster-C2EGSDiT.d.ts +76 -0
  73. package/dist/feedback-trajectory-DfFdrraJ.d.ts +169 -0
  74. package/dist/governance/index.d.ts +5 -0
  75. package/dist/governance/index.js +18 -0
  76. package/dist/governance/index.js.map +1 -0
  77. package/dist/{index-DDTlbHEK.d.ts → index--fVrWDiR.d.ts} +1 -1
  78. package/dist/index-Oj9fAPPN.d.ts +270 -0
  79. package/dist/index.d.ts +1866 -3151
  80. package/dist/index.js +5457 -7809
  81. package/dist/index.js.map +1 -1
  82. package/dist/{integrity-Cr5YodSY.d.ts → integrity-DK2EBVZC.d.ts} +4 -3
  83. package/dist/knowledge/index.d.ts +102 -0
  84. package/dist/knowledge/index.js +18 -0
  85. package/dist/knowledge/index.js.map +1 -0
  86. package/dist/meta-eval/index.d.ts +99 -0
  87. package/dist/meta-eval/index.js +324 -0
  88. package/dist/meta-eval/index.js.map +1 -0
  89. package/dist/multi-layer-verifier-LkP3LVKj.d.ts +141 -0
  90. package/dist/openapi.json +1 -1
  91. package/dist/optimization.d.ts +11 -8
  92. package/dist/optimization.js +11 -9
  93. package/dist/outcome-store-D6KWmYvj.d.ts +63 -0
  94. package/dist/pipelines/index.d.ts +172 -0
  95. package/dist/pipelines/index.js +409 -0
  96. package/dist/pipelines/index.js.map +1 -0
  97. package/dist/prm/index.d.ts +99 -0
  98. package/dist/prm/index.js +222 -0
  99. package/dist/prm/index.js.map +1 -0
  100. package/dist/query-DODUYdPg.d.ts +30 -0
  101. package/dist/release-report-TDPn1cxq.d.ts +292 -0
  102. package/dist/replay-BL96gCEP.d.ts +226 -0
  103. package/dist/reporting.d.ts +10 -295
  104. package/dist/reporting.js +10 -6
  105. package/dist/{eval-campaign-Ds5QljIh.d.ts → researcher-CUOiGcGv.d.ts} +148 -146
  106. package/dist/rl.d.ts +1762 -8
  107. package/dist/rl.js +2035 -58
  108. package/dist/rl.js.map +1 -1
  109. package/dist/rubric-D5tjHNJQ.d.ts +72 -0
  110. package/dist/rubric-predictive-validity-C0uDYwG6.d.ts +105 -0
  111. package/dist/{run-record-DNiOMBrZ.d.ts → run-record-CqzahIbx.d.ts} +4 -1
  112. package/dist/sequential-Dgz1n51-.d.ts +139 -0
  113. package/dist/{store-u47QaJ9G.d.ts → store-Db2Bv8Cf.d.ts} +1 -1
  114. package/dist/{summary-report-Ce1r4EYo.d.ts → summary-report-BXGs_9V0.d.ts} +3 -76
  115. package/dist/telemetry/file.js +4 -1
  116. package/dist/telemetry/file.js.map +1 -1
  117. package/dist/telemetry/index.js +57 -57
  118. package/dist/telemetry/index.js.map +1 -1
  119. package/dist/test-graded-scenario-B2kWEdh9.d.ts +146 -0
  120. package/dist/traces.d.ts +142 -387
  121. package/dist/traces.js +1302 -40
  122. package/dist/traces.js.map +1 -1
  123. package/dist/trajectory-CnoBo-JY.d.ts +32 -0
  124. package/dist/wire/index.d.ts +22 -22
  125. package/dist/wire/index.js +4 -3
  126. package/package.json +44 -18
  127. package/dist/chunk-42I2QC2L.js.map +0 -1
  128. package/dist/chunk-5IIQKMD5.js.map +0 -1
  129. package/dist/chunk-6KQG5HAH.js.map +0 -1
  130. package/dist/chunk-6M774GY6.js.map +0 -1
  131. package/dist/chunk-7EAUOUQS.js.map +0 -1
  132. package/dist/chunk-AXHNWLIX.js.map +0 -1
  133. package/dist/chunk-EXGR4XEM.js.map +0 -1
  134. package/dist/chunk-IOXMGMHQ.js.map +0 -1
  135. package/dist/chunk-KAO3Q65R.js.map +0 -1
  136. package/dist/chunk-LZKIOBG2.js +0 -2026
  137. package/dist/chunk-LZKIOBG2.js.map +0 -1
  138. package/dist/chunk-QBW3YBTR.js.map +0 -1
  139. package/dist/chunk-QUKKGHTZ.js.map +0 -1
  140. package/dist/chunk-SQQLHODJ.js.map +0 -1
  141. package/dist/chunk-V5QSWN7L.js +0 -1310
  142. package/dist/chunk-V5QSWN7L.js.map +0 -1
  143. package/dist/chunk-VQQSPGSM.js.map +0 -1
  144. package/dist/chunk-XPHOZPOM.js +0 -1947
  145. package/dist/chunk-XPHOZPOM.js.map +0 -1
  146. package/dist/feedback-trajectory-c43WGtTX.d.ts +0 -346
  147. package/dist/index-ekBXweiQ.d.ts +0 -1894
  148. package/dist/sequential-DgU2mFsE.d.ts +0 -304
@@ -1,4 +1,5 @@
1
- import { T as TraceStore } from './store-u47QaJ9G.js';
1
+ import { C as CaptureIntegrityError } from './errors-BZ9sTdz7.js';
2
+ import { T as TraceStore } from './store-Db2Bv8Cf.js';
2
3
 
3
4
  /**
4
5
  * RawProviderSink — first-class persistence for the actual HTTP-level
@@ -199,7 +200,7 @@ interface RunIntegrityReport {
199
200
  };
200
201
  issues: RunIntegrityIssue[];
201
202
  }
202
- declare class RunIntegrityError extends Error {
203
+ declare class RunIntegrityError extends CaptureIntegrityError {
203
204
  readonly report: RunIntegrityReport;
204
205
  constructor(report: RunIntegrityReport);
205
206
  }
@@ -207,4 +208,4 @@ declare function assertRunCaptured(store: TraceStore, runId: string, expectation
207
208
  /** Strict mode: throws `RunIntegrityError` when the report isn't ok. */
208
209
  declare function throwIfRunIncomplete(report: RunIntegrityReport): void;
209
210
 
210
- export { FileSystemRawProviderSink as F, InMemoryRawProviderSink as I, NoopRawProviderSink as N, type ProviderRedactor as P, type RawProviderSink as R, type RunIntegrityExpectations as a, type RunIntegrityReport as b, type FileSystemRawProviderSinkOptions as c, type InMemoryRawProviderSinkOptions as d, type RawProviderDirection as e, type RawProviderEvent as f, type RawProviderSinkFilter as g, RunIntegrityError as h, type RunIntegrityIssue as i, type RunIntegrityIssueCode as j, assertRunCaptured as k, defaultProviderRedactor as l, providerFromBaseUrl as p, throwIfRunIncomplete as t };
211
+ export { FileSystemRawProviderSink as F, InMemoryRawProviderSink as I, NoopRawProviderSink as N, type ProviderRedactor as P, type RawProviderSink as R, type RunIntegrityExpectations as a, type RunIntegrityReport as b, type RawProviderEvent as c, type FileSystemRawProviderSinkOptions as d, type InMemoryRawProviderSinkOptions as e, type RawProviderDirection as f, type RawProviderSinkFilter as g, RunIntegrityError as h, type RunIntegrityIssue as i, type RunIntegrityIssueCode as j, assertRunCaptured as k, defaultProviderRedactor as l, providerFromBaseUrl as p, throwIfRunIncomplete as t };
@@ -0,0 +1,102 @@
1
+ import { j as ControlSeverity, C as ControlEvalResult } from '../control-runtime-BuJHoLg0.js';
2
+ import { T as TraceEmitter } from '../emitter-DP_cSSiw.js';
3
+ import '../store-Db2Bv8Cf.js';
4
+
5
+ type KnowledgeRequirementCategory = 'user_specific' | 'company_specific' | 'domain_specific' | 'codebase_specific' | 'market_specific' | 'regulatory' | 'tool_api' | 'credential_or_secret' | 'runtime_environment' | 'preference' | 'historical_context';
6
+ type KnowledgeAcquisitionMode = 'ask_user' | 'search_web' | 'query_connector' | 'inspect_repo' | 'run_command' | 'infer_low_confidence' | 'not_available';
7
+ type KnowledgeImportance = 'blocking' | 'high' | 'medium' | 'low';
8
+ type KnowledgeFreshness = 'static' | 'monthly' | 'weekly' | 'daily' | 'realtime';
9
+ type KnowledgeSensitivity = 'public' | 'private' | 'secret';
10
+ type KnowledgeFallbackPolicy = 'block' | 'ask' | 'continue_with_caveat' | 'use_default';
11
+ interface KnowledgeRequirement {
12
+ id: string;
13
+ description: string;
14
+ requiredFor: string[];
15
+ category: KnowledgeRequirementCategory;
16
+ acquisitionMode: KnowledgeAcquisitionMode;
17
+ importance: KnowledgeImportance;
18
+ freshness: KnowledgeFreshness;
19
+ sensitivity: KnowledgeSensitivity;
20
+ confidenceNeeded: number;
21
+ currentConfidence: number;
22
+ evidenceIds: string[];
23
+ fallbackPolicy: KnowledgeFallbackPolicy;
24
+ /**
25
+ * ISO timestamp after which this requirement must be treated as stale.
26
+ * Stale requirements score as missing even when they still have evidence.
27
+ */
28
+ validUntil?: string;
29
+ /** ISO timestamp for the last source-grounding or human verification pass. */
30
+ lastVerifiedAt?: string;
31
+ metadata?: Record<string, unknown>;
32
+ }
33
+ interface KnowledgeBundle {
34
+ taskId: string;
35
+ requirements: KnowledgeRequirement[];
36
+ evidenceIds: string[];
37
+ claimIds: string[];
38
+ wikiPageIds: string[];
39
+ userAnswers: Record<string, string>;
40
+ missing: KnowledgeRequirement[];
41
+ readinessScore: number;
42
+ metadata?: Record<string, unknown>;
43
+ }
44
+ type KnowledgeRecommendedAction = 'run_agent' | 'ask_user' | 'collect_web_data' | 'query_connectors' | 'inspect_repo' | 'build_domain_wiki' | 'continue_with_caveat' | 'abort_or_rescope';
45
+ interface KnowledgeReadinessReport {
46
+ taskId: string;
47
+ readinessScore: number;
48
+ blockingMissingRequirements: KnowledgeRequirement[];
49
+ nonBlockingGaps: KnowledgeRequirement[];
50
+ recommendedAction: KnowledgeRecommendedAction;
51
+ bundle: KnowledgeBundle;
52
+ severity: ControlSeverity;
53
+ reason: string;
54
+ }
55
+ interface UserQuestion {
56
+ id: string;
57
+ question: string;
58
+ reason: string;
59
+ requirementId: string;
60
+ importance: KnowledgeImportance;
61
+ answerType: 'free_text' | 'select_one' | 'multi_select' | 'file_upload' | 'credential' | 'url';
62
+ defaultIfSkipped?: string;
63
+ impactIfUnknown: string;
64
+ options?: string[];
65
+ metadata?: Record<string, unknown>;
66
+ }
67
+ interface DataAcquisitionPlan {
68
+ id: string;
69
+ requirementIds: string[];
70
+ mode: Exclude<KnowledgeAcquisitionMode, 'not_available' | 'infer_low_confidence'> | 'build_domain_wiki';
71
+ description: string;
72
+ priority: KnowledgeImportance;
73
+ expectedEvidenceIds?: string[];
74
+ questions?: UserQuestion[];
75
+ metadata?: Record<string, unknown>;
76
+ }
77
+ type KnowledgeResponsibleSurface = 'knowledge-requirements' | 'data-acquisition' | 'retrieval-policy' | 'user-question-policy';
78
+
79
+ interface ScoreKnowledgeReadinessOptions {
80
+ taskId: string;
81
+ requirements: KnowledgeRequirement[];
82
+ evidenceIds?: string[];
83
+ claimIds?: string[];
84
+ wikiPageIds?: string[];
85
+ userAnswers?: Record<string, string>;
86
+ metadata?: Record<string, unknown>;
87
+ now?: Date;
88
+ }
89
+ declare function scoreKnowledgeReadiness(options: ScoreKnowledgeReadinessOptions): KnowledgeReadinessReport;
90
+ declare function blockingKnowledgeEval(report: KnowledgeReadinessReport, options?: {
91
+ id?: string;
92
+ minimumScore?: number;
93
+ emitter?: TraceEmitter;
94
+ }): ControlEvalResult;
95
+ declare function knowledgeReadinessTracePayload(report: KnowledgeReadinessReport, options?: {
96
+ passed?: boolean;
97
+ minimumScore?: number;
98
+ }): Record<string, unknown>;
99
+ declare function userQuestionsForKnowledgeGaps(gaps: KnowledgeRequirement[]): UserQuestion[];
100
+ declare function acquisitionPlansForKnowledgeGaps(gaps: KnowledgeRequirement[]): DataAcquisitionPlan[];
101
+
102
+ export { type DataAcquisitionPlan, type KnowledgeAcquisitionMode, type KnowledgeBundle, type KnowledgeFallbackPolicy, type KnowledgeFreshness, type KnowledgeImportance, type KnowledgeReadinessReport, type KnowledgeRecommendedAction, type KnowledgeRequirement, type KnowledgeRequirementCategory, type KnowledgeResponsibleSurface, type KnowledgeSensitivity, type ScoreKnowledgeReadinessOptions, type UserQuestion, acquisitionPlansForKnowledgeGaps, blockingKnowledgeEval, knowledgeReadinessTracePayload, scoreKnowledgeReadiness, userQuestionsForKnowledgeGaps };
@@ -0,0 +1,18 @@
1
+ import {
2
+ acquisitionPlansForKnowledgeGaps,
3
+ blockingKnowledgeEval,
4
+ knowledgeReadinessTracePayload,
5
+ scoreKnowledgeReadiness,
6
+ userQuestionsForKnowledgeGaps
7
+ } from "../chunk-WWYCWKUM.js";
8
+ import "../chunk-LSH4MMOZ.js";
9
+ import "../chunk-TVVP3ZZQ.js";
10
+ import "../chunk-PZ5AY32C.js";
11
+ export {
12
+ acquisitionPlansForKnowledgeGaps,
13
+ blockingKnowledgeEval,
14
+ knowledgeReadinessTracePayload,
15
+ scoreKnowledgeReadiness,
16
+ userQuestionsForKnowledgeGaps
17
+ };
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,99 @@
1
+ import { R as Run, T as TraceStore } from '../store-Db2Bv8Cf.js';
2
+ import { a as OutcomeFilter, O as OutcomeStore } from '../outcome-store-D6KWmYvj.js';
3
+ export { D as DeploymentOutcome, F as FileSystemOutcomeStore, b as FileSystemOutcomeStoreOptions, I as InMemoryOutcomeStore } from '../outcome-store-D6KWmYvj.js';
4
+ export { R as RubricOutcomePair, a as RubricPredictiveValidityInput, b as RubricPredictiveValidityReport, c as RubricRanking, r as rubricPredictiveValidity } from '../rubric-predictive-validity-C0uDYwG6.js';
5
+ import '../run-record-CqzahIbx.js';
6
+ import '../errors-BZ9sTdz7.js';
7
+
8
+ /**
9
+ * Correlation study — "does our eval score predict real-world outcomes?"
10
+ *
11
+ * This is the load-bearing signal. Takes a TraceStore + OutcomeStore,
12
+ * joins on runId, computes Pearson + Spearman + bootstrap CI for every
13
+ * (evalMetric, outcomeMetric) pair the caller declares.
14
+ *
15
+ * Without this number the framework is ornamental. With it and r > 0.6
16
+ * the framework is a moat — no other agent-eval tool publishes one.
17
+ */
18
+
19
+ interface EvalMetricSpec {
20
+ id: string;
21
+ /** Extract a scalar from a run (defaults cover score/pass/durationMs/costUsd/tokens). */
22
+ extract?: (run: Run, store: TraceStore) => Promise<number | null>;
23
+ }
24
+ interface OutcomePair {
25
+ evalMetric: string;
26
+ outcomeMetric: string;
27
+ }
28
+ interface CorrelationResult {
29
+ evalMetric: string;
30
+ outcomeMetric: string;
31
+ n: number;
32
+ pearson: number;
33
+ spearman: number;
34
+ /** 95% bootstrap CI for Pearson. */
35
+ pearsonCi95: {
36
+ lower: number;
37
+ upper: number;
38
+ };
39
+ /** Rough verdict: 'strong' ≥ 0.7, 'moderate' ≥ 0.4, else 'weak'. */
40
+ verdict: 'strong' | 'moderate' | 'weak';
41
+ }
42
+ interface CorrelationStudyResult {
43
+ pairs: CorrelationResult[];
44
+ joinedSamples: number;
45
+ skippedRuns: number;
46
+ }
47
+ interface CorrelationStudyOptions {
48
+ /** Only join outcomes captured within this window after run.startedAt. */
49
+ maxCaptureLagMs?: number;
50
+ /** Restrict to a subset of outcomes (cohort, region, source). */
51
+ outcomeFilter?: OutcomeFilter;
52
+ /** Which outcome per run to use when multiple exist. Default 'latest'. */
53
+ reduction?: 'latest' | 'mean' | 'max';
54
+ /** Bootstrap iterations for the CI. Default 500. */
55
+ bootstrapIterations?: number;
56
+ }
57
+ declare function correlationStudy(traceStore: TraceStore, outcomeStore: OutcomeStore, evalMetrics: EvalMetricSpec[], outcomeMetricNames: string[], options?: CorrelationStudyOptions): Promise<CorrelationStudyResult>;
58
+
59
+ /**
60
+ * Calibration curve — binned "if eval says X, what does reality show?"
61
+ *
62
+ * Companion to correlationStudy. Raw correlation is a single number;
63
+ * the calibration curve shows *where* the eval is well-calibrated vs
64
+ * overconfident / underconfident. Buckets the eval metric, computes
65
+ * mean outcome per bucket, reports expected-calibration-error (ECE).
66
+ */
67
+
68
+ interface CalibrationBin {
69
+ lower: number;
70
+ upper: number;
71
+ n: number;
72
+ evalMean: number;
73
+ outcomeMean: number;
74
+ /** |outcomeMean − evalMean|; contributes to ECE weighted by n/total. */
75
+ gap: number;
76
+ }
77
+ interface CalibrationReport {
78
+ evalMetric: string;
79
+ outcomeMetric: string;
80
+ n: number;
81
+ bins: CalibrationBin[];
82
+ /** Expected Calibration Error — Σ (n_i/N) × |outcomeMean_i − evalMean_i|. */
83
+ ece: number;
84
+ /** Max bin gap — upper bound on miscalibration. */
85
+ maxGap: number;
86
+ }
87
+ interface CalibrationOptions {
88
+ bins?: number;
89
+ /** Equal-width (fixed bin edges) or equal-frequency (quantile bins). */
90
+ binning?: 'equal-width' | 'equal-frequency';
91
+ /** Clip eval values to [lo, hi] before binning. */
92
+ range?: {
93
+ lo: number;
94
+ hi: number;
95
+ };
96
+ }
97
+ declare function calibrationCurve(traceStore: TraceStore, outcomeStore: OutcomeStore, evalMetric: EvalMetricSpec, outcomeMetric: string, options?: CalibrationOptions): Promise<CalibrationReport | null>;
98
+
99
+ export { type CalibrationBin, type CalibrationOptions, type CalibrationReport, type CorrelationResult, type CorrelationStudyOptions, type CorrelationStudyResult, type EvalMetricSpec, OutcomeFilter, type OutcomePair, OutcomeStore, calibrationCurve, correlationStudy };
@@ -0,0 +1,324 @@
1
+ import {
2
+ rubricPredictiveValidity
3
+ } from "../chunk-YRZ4M5GS.js";
4
+ import {
5
+ aggregateLlm,
6
+ llmSpans
7
+ } from "../chunk-47X6LRCE.js";
8
+ import "../chunk-5BKGXME7.js";
9
+ import "../chunk-PZ5AY32C.js";
10
+
11
+ // src/meta-eval/calibration.ts
12
+ async function calibrationCurve(traceStore, outcomeStore, evalMetric, outcomeMetric, options = {}) {
13
+ const runs = await traceStore.listRuns();
14
+ const outcomes = await outcomeStore.list();
15
+ const byRun = /* @__PURE__ */ new Map();
16
+ for (const o of outcomes) {
17
+ const arr = byRun.get(o.runId) ?? [];
18
+ arr.push(o);
19
+ byRun.set(o.runId, arr);
20
+ }
21
+ const extract = evalMetric.extract ?? defaultExtract(evalMetric.id);
22
+ const pairs = [];
23
+ for (const run of runs) {
24
+ const os = byRun.get(run.runId);
25
+ if (!os?.length) continue;
26
+ const x = await extract(run, traceStore);
27
+ if (x === null || !Number.isFinite(x)) continue;
28
+ const latest = [...os].sort((a, b) => b.capturedAt - a.capturedAt)[0];
29
+ const y = latest.metrics[outcomeMetric];
30
+ if (typeof y !== "number" || !Number.isFinite(y)) continue;
31
+ pairs.push({ x, y });
32
+ }
33
+ if (pairs.length < 2) return null;
34
+ const numBins = options.bins ?? 10;
35
+ const binning = options.binning ?? "equal-width";
36
+ const xs = pairs.map((p) => p.x);
37
+ const lo = options.range?.lo ?? Math.min(...xs);
38
+ const hi = options.range?.hi ?? Math.max(...xs);
39
+ const bins = [];
40
+ if (binning === "equal-frequency") {
41
+ const sorted = [...pairs].sort((a, b) => a.x - b.x);
42
+ const perBin = Math.max(1, Math.floor(sorted.length / numBins));
43
+ for (let i = 0; i < sorted.length; i += perBin) {
44
+ const chunk = sorted.slice(i, i + perBin);
45
+ if (chunk.length === 0) continue;
46
+ bins.push(toBin(chunk));
47
+ }
48
+ } else {
49
+ const width = (hi - lo) / numBins;
50
+ if (width === 0) return null;
51
+ for (let i = 0; i < numBins; i++) {
52
+ const binLo = lo + i * width;
53
+ const binHi = i === numBins - 1 ? hi + 1e-9 : lo + (i + 1) * width;
54
+ const chunk = pairs.filter((p) => p.x >= binLo && p.x < binHi);
55
+ if (chunk.length === 0) continue;
56
+ bins.push(toBin(chunk, binLo, binHi));
57
+ }
58
+ }
59
+ const total = bins.reduce((a, b) => a + b.n, 0);
60
+ const ece = bins.reduce((a, b) => a + b.n / total * b.gap, 0);
61
+ const maxGap = bins.reduce((a, b) => Math.max(a, b.gap), 0);
62
+ return { evalMetric: evalMetric.id, outcomeMetric, n: pairs.length, bins, ece, maxGap };
63
+ }
64
+ function toBin(chunk, lower, upper) {
65
+ const xs = chunk.map((c) => c.x);
66
+ const ys = chunk.map((c) => c.y);
67
+ const evalMean = mean(xs);
68
+ const outcomeMean = mean(ys);
69
+ return {
70
+ lower: lower ?? Math.min(...xs),
71
+ upper: upper ?? Math.max(...xs),
72
+ n: chunk.length,
73
+ evalMean,
74
+ outcomeMean,
75
+ gap: Math.abs(outcomeMean - evalMean)
76
+ };
77
+ }
78
+ function mean(xs) {
79
+ return xs.reduce((a, b) => a + b, 0) / xs.length;
80
+ }
81
+ function defaultExtract(metric) {
82
+ return async (run) => run.outcome?.score ?? (metric === "pass" ? run.outcome?.pass === true ? 1 : 0 : null);
83
+ }
84
+
85
+ // src/meta-eval/correlation-study.ts
86
+ async function correlationStudy(traceStore, outcomeStore, evalMetrics, outcomeMetricNames, options = {}) {
87
+ const runs = await traceStore.listRuns();
88
+ const outcomes = await outcomeStore.list(options.outcomeFilter);
89
+ const outcomesByRun = /* @__PURE__ */ new Map();
90
+ for (const o of outcomes) {
91
+ const arr = outcomesByRun.get(o.runId) ?? [];
92
+ arr.push(o);
93
+ outcomesByRun.set(o.runId, arr);
94
+ }
95
+ const reduction = options.reduction ?? "latest";
96
+ const maxLag = options.maxCaptureLagMs ?? Infinity;
97
+ const pairs = [];
98
+ for (const em of evalMetrics) {
99
+ for (const om of outcomeMetricNames) {
100
+ pairs.push({ evalMetric: em.id, outcomeMetric: om, xs: [], ys: [] });
101
+ }
102
+ }
103
+ let joined = 0;
104
+ let skipped = 0;
105
+ for (const run of runs) {
106
+ const os = outcomesByRun.get(run.runId);
107
+ if (!os || os.length === 0) {
108
+ skipped++;
109
+ continue;
110
+ }
111
+ const eligible = os.filter((o) => o.capturedAt - run.startedAt <= maxLag);
112
+ if (eligible.length === 0) {
113
+ skipped++;
114
+ continue;
115
+ }
116
+ for (const em of evalMetrics) {
117
+ const extract = em.extract ?? defaultExtract2(em.id);
118
+ const x = await extract(run, traceStore);
119
+ if (x === null || !Number.isFinite(x)) continue;
120
+ for (const om of outcomeMetricNames) {
121
+ const values = eligible.map((o) => o.metrics[om]).filter((v) => typeof v === "number" && Number.isFinite(v));
122
+ if (values.length === 0) continue;
123
+ const y = reduce(values, reduction, eligible);
124
+ if (y === null) continue;
125
+ const pair = pairs.find((p) => p.evalMetric === em.id && p.outcomeMetric === om);
126
+ pair.xs.push(x);
127
+ pair.ys.push(y);
128
+ }
129
+ }
130
+ joined++;
131
+ }
132
+ const results = pairs.filter((p) => p.xs.length >= 3).map((p) => {
133
+ const pearson = pearsonR(p.xs, p.ys);
134
+ const spearman = pearsonR(ranks(p.xs), ranks(p.ys));
135
+ const pearsonCi95 = bootstrapPearsonCi(p.xs, p.ys, options.bootstrapIterations ?? 500);
136
+ const verdict = Math.abs(pearson) >= 0.7 ? "strong" : Math.abs(pearson) >= 0.4 ? "moderate" : "weak";
137
+ return {
138
+ evalMetric: p.evalMetric,
139
+ outcomeMetric: p.outcomeMetric,
140
+ n: p.xs.length,
141
+ pearson,
142
+ spearman,
143
+ pearsonCi95,
144
+ verdict
145
+ };
146
+ });
147
+ return { pairs: results, joinedSamples: joined, skippedRuns: skipped };
148
+ }
149
+ function reduce(values, kind, outcomes) {
150
+ if (values.length === 0) return null;
151
+ if (kind === "mean") return values.reduce((a, b) => a + b, 0) / values.length;
152
+ if (kind === "max") return Math.max(...values);
153
+ const latest = [...outcomes].sort((a, b) => b.capturedAt - a.capturedAt)[0];
154
+ if (!latest) return null;
155
+ const latestKey = Object.keys(latest.metrics)[0];
156
+ const v = latestKey !== void 0 ? latest.metrics[latestKey] : void 0;
157
+ const paired = outcomes.map((o) => {
158
+ const k = Object.keys(o.metrics)[0];
159
+ return {
160
+ at: o.capturedAt,
161
+ v: k !== void 0 ? values.find((x) => o.metrics[k] === x) : void 0
162
+ };
163
+ }).filter((p) => p.v !== void 0);
164
+ if (paired.length === 0) return v ?? null;
165
+ return paired.sort((a, b) => b.at - a.at)[0]?.v ?? null;
166
+ }
167
+ function pearsonR(a, b) {
168
+ if (a.length !== b.length || a.length < 2) return NaN;
169
+ const mA = a.reduce((s, v) => s + v, 0) / a.length;
170
+ const mB = b.reduce((s, v) => s + v, 0) / b.length;
171
+ let num = 0, dA = 0, dB = 0;
172
+ for (let i = 0; i < a.length; i++) {
173
+ const da = a[i] - mA, db = b[i] - mB;
174
+ num += da * db;
175
+ dA += da * da;
176
+ dB += db * db;
177
+ }
178
+ if (dA === 0 || dB === 0) return dA === 0 && dB === 0 ? 1 : 0;
179
+ return num / Math.sqrt(dA * dB);
180
+ }
181
+ function ranks(xs) {
182
+ const indexed = xs.map((v, i) => ({ v, i })).sort((x, y) => x.v - y.v);
183
+ const r = new Array(xs.length);
184
+ for (let i = 0; i < indexed.length; i++) {
185
+ let j = i;
186
+ while (j + 1 < indexed.length && indexed[j + 1].v === indexed[i].v) j++;
187
+ const avg = (i + j + 2) / 2;
188
+ for (let k = i; k <= j; k++) r[indexed[k].i] = avg;
189
+ i = j;
190
+ }
191
+ return r;
192
+ }
193
+ function bootstrapPearsonCi(xs, ys, iterations) {
194
+ const n = xs.length;
195
+ if (n < 3) return { lower: NaN, upper: NaN };
196
+ const rs = [];
197
+ for (let b = 0; b < iterations; b++) {
198
+ const rx = new Array(n);
199
+ const ry = new Array(n);
200
+ for (let i = 0; i < n; i++) {
201
+ const idx = Math.floor(Math.random() * n);
202
+ rx[i] = xs[idx];
203
+ ry[i] = ys[idx];
204
+ }
205
+ const r = pearsonR(rx, ry);
206
+ if (Number.isFinite(r)) rs.push(r);
207
+ }
208
+ rs.sort((a, b) => a - b);
209
+ if (rs.length === 0) return { lower: NaN, upper: NaN };
210
+ return {
211
+ lower: rs[Math.floor(0.025 * rs.length)],
212
+ upper: rs[Math.min(rs.length - 1, Math.floor(0.975 * rs.length))]
213
+ };
214
+ }
215
+ function defaultExtract2(metric) {
216
+ return async (run, store) => {
217
+ switch (metric) {
218
+ case "score":
219
+ case "overallScore":
220
+ return run.outcome?.score ?? null;
221
+ case "pass":
222
+ return run.outcome?.pass === true ? 1 : 0;
223
+ case "durationMs":
224
+ return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null;
225
+ case "costUsd": {
226
+ const llm = await llmSpans(store, run.runId);
227
+ return aggregateLlm(llm).costUsd;
228
+ }
229
+ case "inputTokens": {
230
+ const llm = await llmSpans(store, run.runId);
231
+ return aggregateLlm(llm).inputTokens;
232
+ }
233
+ default:
234
+ return null;
235
+ }
236
+ };
237
+ }
238
+
239
+ // src/meta-eval/outcome-store.ts
240
+ var InMemoryOutcomeStore = class {
241
+ items = [];
242
+ async append(outcome) {
243
+ this.items.push({ ...outcome });
244
+ }
245
+ async forRun(runId) {
246
+ return this.items.filter((o) => o.runId === runId).map((o) => ({ ...o }));
247
+ }
248
+ async list(filter = {}) {
249
+ return this.items.filter((o) => matches(o, filter)).map((o) => ({ ...o }));
250
+ }
251
+ };
252
+ var FileSystemOutcomeStore = class {
253
+ dir;
254
+ maxBytes;
255
+ memo;
256
+ loaded = false;
257
+ constructor(options) {
258
+ this.dir = options.dir;
259
+ this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024;
260
+ }
261
+ async ensureDir() {
262
+ const fs = await import("fs/promises");
263
+ await fs.mkdir(this.dir, { recursive: true });
264
+ }
265
+ async append(outcome) {
266
+ await this.ensureDir();
267
+ const fs = await import("fs/promises");
268
+ const path = await import("path");
269
+ const active = path.join(this.dir, "outcomes.ndjson");
270
+ try {
271
+ const stat = await fs.stat(active);
272
+ if (stat.size >= this.maxBytes) {
273
+ await fs.rename(active, path.join(this.dir, `outcomes.${Date.now()}.ndjson`));
274
+ }
275
+ } catch {
276
+ }
277
+ await fs.appendFile(active, `${JSON.stringify(outcome)}
278
+ `, "utf8");
279
+ if (this.memo) await this.memo.append(outcome);
280
+ }
281
+ async load() {
282
+ if (this.loaded && this.memo) return this.memo;
283
+ const fs = await import("fs/promises");
284
+ const path = await import("path");
285
+ const memo = new InMemoryOutcomeStore();
286
+ try {
287
+ const entries = await fs.readdir(this.dir);
288
+ for (const file of entries) {
289
+ if (!file.endsWith(".ndjson")) continue;
290
+ const content = await fs.readFile(path.join(this.dir, file), "utf8");
291
+ for (const line of content.split("\n")) {
292
+ if (!line.trim()) continue;
293
+ await memo.append(JSON.parse(line));
294
+ }
295
+ }
296
+ } catch {
297
+ }
298
+ this.memo = memo;
299
+ this.loaded = true;
300
+ return memo;
301
+ }
302
+ async forRun(runId) {
303
+ return (await this.load()).forRun(runId);
304
+ }
305
+ async list(filter) {
306
+ return (await this.load()).list(filter);
307
+ }
308
+ };
309
+ function matches(o, f) {
310
+ if (f.runIds && !f.runIds.includes(o.runId)) return false;
311
+ if (f.since !== void 0 && o.capturedAt < f.since) return false;
312
+ if (f.until !== void 0 && o.capturedAt > f.until) return false;
313
+ if (f.source && o.source !== f.source) return false;
314
+ if (f.label && o.labels?.[f.label.key] !== f.label.value) return false;
315
+ return true;
316
+ }
317
+ export {
318
+ FileSystemOutcomeStore,
319
+ InMemoryOutcomeStore,
320
+ calibrationCurve,
321
+ correlationStudy,
322
+ rubricPredictiveValidity
323
+ };
324
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/meta-eval/calibration.ts","../../src/meta-eval/correlation-study.ts","../../src/meta-eval/outcome-store.ts"],"sourcesContent":["/**\n * Calibration curve — binned \"if eval says X, what does reality show?\"\n *\n * Companion to correlationStudy. Raw correlation is a single number;\n * the calibration curve shows *where* the eval is well-calibrated vs\n * overconfident / underconfident. Buckets the eval metric, computes\n * mean outcome per bucket, reports expected-calibration-error (ECE).\n */\n\nimport type { Run } from '../trace/schema'\nimport type { TraceStore } from '../trace/store'\nimport type { EvalMetricSpec } from './correlation-study'\nimport type { DeploymentOutcome, OutcomeStore } from './outcome-store'\n\nexport interface CalibrationBin {\n lower: number\n upper: number\n n: number\n evalMean: number\n outcomeMean: number\n /** |outcomeMean − evalMean|; contributes to ECE weighted by n/total. */\n gap: number\n}\n\nexport interface CalibrationReport {\n evalMetric: string\n outcomeMetric: string\n n: number\n bins: CalibrationBin[]\n /** Expected Calibration Error — Σ (n_i/N) × |outcomeMean_i − evalMean_i|. */\n ece: number\n /** Max bin gap — upper bound on miscalibration. */\n maxGap: number\n}\n\nexport interface CalibrationOptions {\n bins?: number\n /** Equal-width (fixed bin edges) or equal-frequency (quantile bins). */\n binning?: 'equal-width' | 'equal-frequency'\n /** Clip eval values to [lo, hi] before binning. */\n range?: { lo: number; hi: number }\n}\n\nexport async function calibrationCurve(\n traceStore: TraceStore,\n outcomeStore: OutcomeStore,\n evalMetric: EvalMetricSpec,\n outcomeMetric: string,\n options: CalibrationOptions = {},\n): Promise<CalibrationReport | null> {\n const runs = await traceStore.listRuns()\n const outcomes = await outcomeStore.list()\n const byRun = new Map<string, DeploymentOutcome[]>()\n for (const o of outcomes) {\n const arr = byRun.get(o.runId) ?? []\n arr.push(o)\n byRun.set(o.runId, arr)\n }\n\n const extract = evalMetric.extract ?? defaultExtract(evalMetric.id)\n const pairs: Array<{ x: number; y: number }> = []\n for (const run of runs) {\n const os = byRun.get(run.runId)\n if (!os?.length) continue\n const x = await extract(run, traceStore)\n if (x === null || !Number.isFinite(x)) continue\n const latest = [...os].sort((a, b) => b.capturedAt - a.capturedAt)[0]!\n const y = latest.metrics[outcomeMetric]\n if (typeof y !== 'number' || !Number.isFinite(y)) continue\n pairs.push({ x, y })\n }\n if (pairs.length < 2) return null\n\n const numBins = options.bins ?? 10\n const binning = options.binning ?? 'equal-width'\n const xs = pairs.map((p) => p.x)\n const lo = options.range?.lo ?? Math.min(...xs)\n const hi = options.range?.hi ?? Math.max(...xs)\n\n const bins: CalibrationBin[] = []\n if (binning === 'equal-frequency') {\n const sorted = [...pairs].sort((a, b) => a.x - b.x)\n const perBin = Math.max(1, Math.floor(sorted.length / numBins))\n for (let i = 0; i < sorted.length; i += perBin) {\n const chunk = sorted.slice(i, i + perBin)\n if (chunk.length === 0) continue\n bins.push(toBin(chunk))\n }\n } else {\n const width = (hi - lo) / numBins\n if (width === 0) return null\n for (let i = 0; i < numBins; i++) {\n const binLo = lo + i * width\n const binHi = i === numBins - 1 ? hi + 1e-9 : lo + (i + 1) * width\n const chunk = pairs.filter((p) => p.x >= binLo && p.x < binHi)\n if (chunk.length === 0) continue\n bins.push(toBin(chunk, binLo, binHi))\n }\n }\n\n const total = bins.reduce((a, b) => a + b.n, 0)\n const ece = bins.reduce((a, b) => a + (b.n / total) * b.gap, 0)\n const maxGap = bins.reduce((a, b) => Math.max(a, b.gap), 0)\n\n return { evalMetric: evalMetric.id, outcomeMetric, n: pairs.length, bins, ece, maxGap }\n}\n\nfunction toBin(\n chunk: Array<{ x: number; y: number }>,\n lower?: number,\n upper?: number,\n): CalibrationBin {\n const xs = chunk.map((c) => c.x)\n const ys = chunk.map((c) => c.y)\n const evalMean = mean(xs)\n const outcomeMean = mean(ys)\n return {\n lower: lower ?? Math.min(...xs),\n upper: upper ?? Math.max(...xs),\n n: chunk.length,\n evalMean,\n outcomeMean,\n gap: Math.abs(outcomeMean - evalMean),\n }\n}\n\nfunction mean(xs: number[]): number {\n return xs.reduce((a, b) => a + b, 0) / xs.length\n}\n\nfunction defaultExtract(metric: string): (run: Run, store: TraceStore) => Promise<number | null> {\n return async (run) =>\n run.outcome?.score ?? (metric === 'pass' ? (run.outcome?.pass === true ? 1 : 0) : null)\n}\n","/**\n * Correlation study — \"does our eval score predict real-world outcomes?\"\n *\n * This is the load-bearing signal. Takes a TraceStore + OutcomeStore,\n * joins on runId, computes Pearson + Spearman + bootstrap CI for every\n * (evalMetric, outcomeMetric) pair the caller declares.\n *\n * Without this number the framework is ornamental. With it and r > 0.6\n * the framework is a moat — no other agent-eval tool publishes one.\n */\n\nimport { aggregateLlm, llmSpans } from '../trace/query'\nimport type { Run } from '../trace/schema'\nimport type { TraceStore } from '../trace/store'\nimport type { DeploymentOutcome, OutcomeFilter, OutcomeStore } from './outcome-store'\n\nexport interface EvalMetricSpec {\n id: string\n /** Extract a scalar from a run (defaults cover score/pass/durationMs/costUsd/tokens). */\n extract?: (run: Run, store: TraceStore) => Promise<number | null>\n}\n\nexport interface OutcomePair {\n evalMetric: string\n outcomeMetric: string\n}\n\nexport interface CorrelationResult {\n evalMetric: string\n outcomeMetric: string\n n: number\n pearson: number\n spearman: number\n /** 95% bootstrap CI for Pearson. */\n pearsonCi95: { lower: number; upper: number }\n /** Rough verdict: 'strong' ≥ 0.7, 'moderate' ≥ 0.4, else 'weak'. */\n verdict: 'strong' | 'moderate' | 'weak'\n}\n\nexport interface CorrelationStudyResult {\n pairs: CorrelationResult[]\n joinedSamples: number\n skippedRuns: number\n}\n\nexport interface CorrelationStudyOptions {\n /** Only join outcomes captured within this window after run.startedAt. */\n maxCaptureLagMs?: number\n /** Restrict to a subset of outcomes (cohort, region, source). */\n outcomeFilter?: OutcomeFilter\n /** Which outcome per run to use when multiple exist. Default 'latest'. */\n reduction?: 'latest' | 'mean' | 'max'\n /** Bootstrap iterations for the CI. Default 500. */\n bootstrapIterations?: number\n}\n\nexport async function correlationStudy(\n traceStore: TraceStore,\n outcomeStore: OutcomeStore,\n evalMetrics: EvalMetricSpec[],\n outcomeMetricNames: string[],\n options: CorrelationStudyOptions = {},\n): Promise<CorrelationStudyResult> {\n const runs = await traceStore.listRuns()\n const outcomes = await outcomeStore.list(options.outcomeFilter)\n const outcomesByRun = new Map<string, DeploymentOutcome[]>()\n for (const o of outcomes) {\n const arr = outcomesByRun.get(o.runId) ?? []\n arr.push(o)\n outcomesByRun.set(o.runId, arr)\n }\n\n const reduction = options.reduction ?? 'latest'\n const maxLag = options.maxCaptureLagMs ?? Infinity\n\n const pairs: Array<{ evalMetric: string; outcomeMetric: string; xs: number[]; ys: number[] }> = []\n for (const em of evalMetrics) {\n for (const om of outcomeMetricNames) {\n pairs.push({ evalMetric: em.id, outcomeMetric: om, xs: [], ys: [] })\n }\n }\n\n let joined = 0\n let skipped = 0\n for (const run of runs) {\n const os = outcomesByRun.get(run.runId)\n if (!os || os.length === 0) {\n skipped++\n continue\n }\n const eligible = os.filter((o) => o.capturedAt - run.startedAt <= maxLag)\n if (eligible.length === 0) {\n skipped++\n continue\n }\n\n for (const em of evalMetrics) {\n const extract = em.extract ?? defaultExtract(em.id)\n const x = await extract(run, traceStore)\n if (x === null || !Number.isFinite(x)) continue\n\n for (const om of outcomeMetricNames) {\n const values = eligible\n .map((o) => o.metrics[om])\n .filter((v): v is number => typeof v === 'number' && Number.isFinite(v))\n if (values.length === 0) continue\n const y = reduce(values, reduction, eligible)\n if (y === null) continue\n const pair = pairs.find((p) => p.evalMetric === em.id && p.outcomeMetric === om)!\n pair.xs.push(x)\n pair.ys.push(y)\n }\n }\n joined++\n }\n\n const results: CorrelationResult[] = pairs\n .filter((p) => p.xs.length >= 3)\n .map((p) => {\n const pearson = pearsonR(p.xs, p.ys)\n const spearman = pearsonR(ranks(p.xs), ranks(p.ys))\n const pearsonCi95 = bootstrapPearsonCi(p.xs, p.ys, options.bootstrapIterations ?? 500)\n const verdict: CorrelationResult['verdict'] =\n Math.abs(pearson) >= 0.7 ? 'strong' : Math.abs(pearson) >= 0.4 ? 'moderate' : 'weak'\n return {\n evalMetric: p.evalMetric,\n outcomeMetric: p.outcomeMetric,\n n: p.xs.length,\n pearson,\n spearman,\n pearsonCi95,\n verdict,\n }\n })\n\n return { pairs: results, joinedSamples: joined, skippedRuns: skipped }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction reduce(\n values: number[],\n kind: 'latest' | 'mean' | 'max',\n outcomes: DeploymentOutcome[],\n): number | null {\n if (values.length === 0) return null\n if (kind === 'mean') return values.reduce((a, b) => a + b, 0) / values.length\n if (kind === 'max') return Math.max(...values)\n // 'latest': pick the outcome captured last, then lookup its metric\n const latest = [...outcomes].sort((a, b) => b.capturedAt - a.capturedAt)[0]\n if (!latest) return null\n const latestKey = Object.keys(latest.metrics)[0]\n const v = latestKey !== undefined ? latest.metrics[latestKey] : undefined\n // For 'latest' we already have `values` aligned; use the last-captured one\n const paired = outcomes\n .map((o) => {\n const k = Object.keys(o.metrics)[0]\n return {\n at: o.capturedAt,\n v: k !== undefined ? values.find((x) => o.metrics[k] === x) : undefined,\n }\n })\n .filter((p) => p.v !== undefined)\n if (paired.length === 0) return v ?? null\n return paired.sort((a, b) => b.at - a.at)[0]?.v ?? null\n}\n\nfunction pearsonR(a: number[], b: number[]): number {\n if (a.length !== b.length || a.length < 2) return NaN\n const mA = a.reduce((s, v) => s + v, 0) / a.length\n const mB = b.reduce((s, v) => s + v, 0) / b.length\n let num = 0,\n dA = 0,\n dB = 0\n for (let i = 0; i < a.length; i++) {\n const da = a[i]! - mA,\n db = b[i]! - mB\n num += da * db\n dA += da * da\n dB += db * db\n }\n if (dA === 0 || dB === 0) return dA === 0 && dB === 0 ? 1 : 0\n return num / Math.sqrt(dA * dB)\n}\n\nfunction ranks(xs: number[]): number[] {\n const indexed = xs.map((v, i) => ({ v, i })).sort((x, y) => x.v - y.v)\n const r = new Array<number>(xs.length)\n for (let i = 0; i < indexed.length; i++) {\n let j = i\n while (j + 1 < indexed.length && indexed[j + 1]!.v === indexed[i]!.v) j++\n const avg = (i + j + 2) / 2\n for (let k = i; k <= j; k++) r[indexed[k]!.i] = avg\n i = j\n }\n return r\n}\n\nfunction bootstrapPearsonCi(\n xs: number[],\n ys: number[],\n iterations: number,\n): { lower: number; upper: number } {\n const n = xs.length\n if (n < 3) return { lower: NaN, upper: NaN }\n const rs: number[] = []\n for (let b = 0; b < iterations; b++) {\n const rx: number[] = new Array(n)\n const ry: number[] = new Array(n)\n for (let i = 0; i < n; i++) {\n const idx = Math.floor(Math.random() * n)\n rx[i] = xs[idx]!\n ry[i] = ys[idx]!\n }\n const r = pearsonR(rx, ry)\n if (Number.isFinite(r)) rs.push(r)\n }\n rs.sort((a, b) => a - b)\n if (rs.length === 0) return { lower: NaN, upper: NaN }\n return {\n lower: rs[Math.floor(0.025 * rs.length)]!,\n upper: rs[Math.min(rs.length - 1, Math.floor(0.975 * rs.length))]!,\n }\n}\n\nfunction defaultExtract(metric: string): (run: Run, store: TraceStore) => Promise<number | null> {\n return async (run, store) => {\n switch (metric) {\n case 'score':\n case 'overallScore':\n return run.outcome?.score ?? null\n case 'pass':\n return run.outcome?.pass === true ? 1 : 0\n case 'durationMs':\n return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null\n case 'costUsd': {\n const llm = await llmSpans(store, run.runId)\n return aggregateLlm(llm).costUsd\n }\n case 'inputTokens': {\n const llm = await llmSpans(store, run.runId)\n return aggregateLlm(llm).inputTokens\n }\n default:\n return null\n }\n }\n}\n","/**\n * OutcomeStore — deployment outcomes attached to Run IDs.\n *\n * Outcomes arrive asynchronously from production telemetry after the\n * eval run completed: user ratings, retention flags, conversion events,\n * revenue, support-ticket rate, anything a product team can measure.\n * The store is a peer to TraceStore — separate lifecycle, same runId\n * foreign key.\n *\n * The whole point of this module is to make the meta-eval correlation\n * question computable: `correlate(evalMetric, outcomeMetric) → r, ρ, n, CI`.\n */\n\nexport interface DeploymentOutcome {\n runId: string\n capturedAt: number\n /** Numeric outcomes keyed by name — retention_7d, csat, revenue_usd, etc. */\n metrics: Record<string, number>\n /** Dimensions for stratified analysis — cohort, region, user_segment. */\n labels?: Record<string, string>\n /** Free-form provenance (source system, pipeline version). */\n source?: string\n}\n\nexport interface OutcomeFilter {\n runIds?: string[]\n since?: number\n until?: number\n label?: { key: string; value: string }\n source?: string\n}\n\nexport interface OutcomeStore {\n append(outcome: DeploymentOutcome): Promise<void>\n /** All outcomes attached to this run (a single run can have many — multiple\n * capture windows over deployment time). */\n forRun(runId: string): Promise<DeploymentOutcome[]>\n list(filter?: OutcomeFilter): Promise<DeploymentOutcome[]>\n}\n\nexport class InMemoryOutcomeStore implements OutcomeStore {\n private items: DeploymentOutcome[] = []\n\n async append(outcome: DeploymentOutcome): Promise<void> {\n this.items.push({ ...outcome })\n }\n\n async forRun(runId: string): Promise<DeploymentOutcome[]> {\n return this.items.filter((o) => o.runId === runId).map((o) => ({ ...o }))\n }\n\n async list(filter: OutcomeFilter = {}): Promise<DeploymentOutcome[]> {\n return this.items.filter((o) => matches(o, filter)).map((o) => ({ ...o }))\n }\n}\n\nexport interface FileSystemOutcomeStoreOptions {\n dir: string\n maxBytes?: number\n}\n\nexport class FileSystemOutcomeStore implements OutcomeStore {\n private dir: string\n private maxBytes: number\n private memo?: InMemoryOutcomeStore\n private loaded = false\n\n constructor(options: FileSystemOutcomeStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n async append(outcome: DeploymentOutcome): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, 'outcomes.ndjson')\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n await fs.rename(active, path.join(this.dir, `outcomes.${Date.now()}.ndjson`))\n }\n } catch {\n /* first write */\n }\n await fs.appendFile(active, `${JSON.stringify(outcome)}\\n`, 'utf8')\n if (this.memo) await this.memo.append(outcome)\n }\n\n private async load(): Promise<InMemoryOutcomeStore> {\n if (this.loaded && this.memo) return this.memo\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const memo = new InMemoryOutcomeStore()\n try {\n const entries = await fs.readdir(this.dir)\n for (const file of entries) {\n if (!file.endsWith('.ndjson')) continue\n const content = await fs.readFile(path.join(this.dir, file), 'utf8')\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue\n await memo.append(JSON.parse(line))\n }\n }\n } catch {\n /* empty */\n }\n this.memo = memo\n this.loaded = true\n return memo\n }\n\n async forRun(runId: string): Promise<DeploymentOutcome[]> {\n return (await this.load()).forRun(runId)\n }\n\n async list(filter?: OutcomeFilter): Promise<DeploymentOutcome[]> {\n return (await this.load()).list(filter)\n }\n}\n\nfunction matches(o: DeploymentOutcome, f: OutcomeFilter): boolean {\n if (f.runIds && !f.runIds.includes(o.runId)) return false\n if (f.since !== undefined && o.capturedAt < f.since) return false\n if (f.until !== undefined && o.capturedAt > f.until) return false\n if (f.source && o.source !== f.source) return false\n if (f.label && o.labels?.[f.label.key] !== f.label.value) return false\n return true\n}\n"],"mappings":"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","names":["defaultExtract"]}