@cogitator-ai/evals 0.11.0 → 0.13.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 (155) hide show
  1. package/README.md +159 -40
  2. package/dist/calibrate-judge.d.ts +53 -0
  3. package/dist/calibrate-judge.d.ts.map +1 -0
  4. package/dist/calibrate-judge.js +114 -0
  5. package/dist/calibrate-judge.js.map +1 -0
  6. package/dist/comparison-stats.d.ts +104 -0
  7. package/dist/comparison-stats.d.ts.map +1 -0
  8. package/dist/comparison-stats.js +179 -0
  9. package/dist/comparison-stats.js.map +1 -0
  10. package/dist/datasets/dataset.d.ts.map +1 -1
  11. package/dist/datasets/dataset.js +3 -27
  12. package/dist/datasets/dataset.js.map +1 -1
  13. package/dist/eval-comparison.d.ts +30 -10
  14. package/dist/eval-comparison.d.ts.map +1 -1
  15. package/dist/eval-comparison.js +73 -103
  16. package/dist/eval-comparison.js.map +1 -1
  17. package/dist/eval-suite.d.ts +33 -0
  18. package/dist/eval-suite.d.ts.map +1 -1
  19. package/dist/eval-suite.js +81 -2
  20. package/dist/eval-suite.js.map +1 -1
  21. package/dist/index.d.ts +21 -5
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +10 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/metrics/g-eval.d.ts +29 -0
  26. package/dist/metrics/g-eval.d.ts.map +1 -0
  27. package/dist/metrics/g-eval.js +89 -0
  28. package/dist/metrics/g-eval.js.map +1 -0
  29. package/dist/metrics/index.d.ts +3 -1
  30. package/dist/metrics/index.d.ts.map +1 -1
  31. package/dist/metrics/index.js +1 -0
  32. package/dist/metrics/index.js.map +1 -1
  33. package/dist/metrics/judge-prompt.d.ts +31 -0
  34. package/dist/metrics/judge-prompt.d.ts.map +1 -0
  35. package/dist/metrics/judge-prompt.js +90 -0
  36. package/dist/metrics/judge-prompt.js.map +1 -0
  37. package/dist/metrics/llm-judge.d.ts +96 -9
  38. package/dist/metrics/llm-judge.d.ts.map +1 -1
  39. package/dist/metrics/llm-judge.js +265 -120
  40. package/dist/metrics/llm-judge.js.map +1 -1
  41. package/dist/metrics/types.d.ts +25 -0
  42. package/dist/metrics/types.d.ts.map +1 -1
  43. package/dist/metrics/types.js.map +1 -1
  44. package/dist/options.d.ts +4 -0
  45. package/dist/options.d.ts.map +1 -0
  46. package/dist/options.js +9 -0
  47. package/dist/options.js.map +1 -0
  48. package/dist/pairwise.d.ts +53 -0
  49. package/dist/pairwise.d.ts.map +1 -0
  50. package/dist/pairwise.js +118 -0
  51. package/dist/pairwise.js.map +1 -0
  52. package/dist/reporters/comparison.d.ts +24 -0
  53. package/dist/reporters/comparison.d.ts.map +1 -0
  54. package/dist/reporters/comparison.js +290 -0
  55. package/dist/reporters/comparison.js.map +1 -0
  56. package/dist/reporters/format.d.ts +21 -0
  57. package/dist/reporters/format.d.ts.map +1 -1
  58. package/dist/reporters/format.js +31 -0
  59. package/dist/reporters/format.js.map +1 -1
  60. package/dist/reporters/github.d.ts.map +1 -1
  61. package/dist/reporters/github.js +1 -16
  62. package/dist/reporters/github.js.map +1 -1
  63. package/dist/reporters/html-format.d.ts +11 -0
  64. package/dist/reporters/html-format.d.ts.map +1 -0
  65. package/dist/reporters/html-format.js +111 -0
  66. package/dist/reporters/html-format.js.map +1 -0
  67. package/dist/reporters/html.d.ts +12 -0
  68. package/dist/reporters/html.d.ts.map +1 -0
  69. package/dist/reporters/html.js +119 -0
  70. package/dist/reporters/html.js.map +1 -0
  71. package/dist/reporters/index.d.ts +20 -6
  72. package/dist/reporters/index.d.ts.map +1 -1
  73. package/dist/reporters/index.js +15 -4
  74. package/dist/reporters/index.js.map +1 -1
  75. package/dist/reporters/markdown.d.ts +15 -0
  76. package/dist/reporters/markdown.d.ts.map +1 -0
  77. package/dist/reporters/markdown.js +67 -0
  78. package/dist/reporters/markdown.js.map +1 -0
  79. package/dist/runs/compare.d.ts +103 -0
  80. package/dist/runs/compare.d.ts.map +1 -0
  81. package/dist/runs/compare.js +208 -0
  82. package/dist/runs/compare.js.map +1 -0
  83. package/dist/runs/index.d.ts +9 -0
  84. package/dist/runs/index.d.ts.map +1 -0
  85. package/dist/runs/index.js +5 -0
  86. package/dist/runs/index.js.map +1 -0
  87. package/dist/runs/json.d.ts +11 -0
  88. package/dist/runs/json.d.ts.map +1 -0
  89. package/dist/runs/json.js +58 -0
  90. package/dist/runs/json.js.map +1 -0
  91. package/dist/runs/run.d.ts +44 -0
  92. package/dist/runs/run.d.ts.map +1 -0
  93. package/dist/runs/run.js +136 -0
  94. package/dist/runs/run.js.map +1 -0
  95. package/dist/runs/schema.d.ts +504 -0
  96. package/dist/runs/schema.d.ts.map +1 -0
  97. package/dist/runs/schema.js +171 -0
  98. package/dist/runs/schema.js.map +1 -0
  99. package/dist/runs/store.d.ts +57 -0
  100. package/dist/runs/store.d.ts.map +1 -0
  101. package/dist/runs/store.js +146 -0
  102. package/dist/runs/store.js.map +1 -0
  103. package/dist/schema.d.ts +16 -0
  104. package/dist/schema.d.ts.map +1 -1
  105. package/dist/schema.js +17 -0
  106. package/dist/schema.js.map +1 -1
  107. package/dist/stats/bootstrap.d.ts +22 -0
  108. package/dist/stats/bootstrap.d.ts.map +1 -0
  109. package/dist/stats/bootstrap.js +34 -0
  110. package/dist/stats/bootstrap.js.map +1 -0
  111. package/dist/stats/correlation.d.ts +11 -0
  112. package/dist/stats/correlation.d.ts.map +1 -0
  113. package/dist/stats/correlation.js +42 -0
  114. package/dist/stats/correlation.js.map +1 -0
  115. package/dist/stats/effect-size.d.ts +7 -0
  116. package/dist/stats/effect-size.d.ts.map +1 -0
  117. package/dist/stats/effect-size.js +17 -0
  118. package/dist/stats/effect-size.js.map +1 -0
  119. package/dist/stats/holm.d.ts +7 -0
  120. package/dist/stats/holm.d.ts.map +1 -0
  121. package/dist/stats/holm.js +21 -0
  122. package/dist/stats/holm.js.map +1 -0
  123. package/dist/stats/index.d.ts +10 -2
  124. package/dist/stats/index.d.ts.map +1 -1
  125. package/dist/stats/index.js +7 -1
  126. package/dist/stats/index.js.map +1 -1
  127. package/dist/stats/mcnemar.d.ts +9 -0
  128. package/dist/stats/mcnemar.d.ts.map +1 -1
  129. package/dist/stats/mcnemar.js +27 -13
  130. package/dist/stats/mcnemar.js.map +1 -1
  131. package/dist/stats/normal.d.ts +5 -0
  132. package/dist/stats/normal.d.ts.map +1 -0
  133. package/dist/stats/normal.js +19 -0
  134. package/dist/stats/normal.js.map +1 -0
  135. package/dist/stats/precision.d.ts +12 -0
  136. package/dist/stats/precision.d.ts.map +1 -0
  137. package/dist/stats/precision.js +29 -0
  138. package/dist/stats/precision.js.map +1 -0
  139. package/dist/stats/random.d.ts +6 -0
  140. package/dist/stats/random.d.ts.map +1 -0
  141. package/dist/stats/random.js +25 -0
  142. package/dist/stats/random.js.map +1 -0
  143. package/dist/stats/ranks.d.ts +5 -0
  144. package/dist/stats/ranks.d.ts.map +1 -0
  145. package/dist/stats/ranks.js +24 -0
  146. package/dist/stats/ranks.js.map +1 -0
  147. package/dist/stats/t-test.d.ts +4 -0
  148. package/dist/stats/t-test.d.ts.map +1 -1
  149. package/dist/stats/t-test.js +9 -3
  150. package/dist/stats/t-test.js.map +1 -1
  151. package/dist/stats/wilcoxon.d.ts +19 -0
  152. package/dist/stats/wilcoxon.d.ts.map +1 -0
  153. package/dist/stats/wilcoxon.js +70 -0
  154. package/dist/stats/wilcoxon.js.map +1 -0
  155. package/package.json +1 -1
@@ -0,0 +1,67 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ import { caseLabel, caseProblems, cell, num, trialsPerCase } from './format.js';
3
+ /** Most failures the summary lists before it counts the rest */
4
+ export const MARKDOWN_MAX_FAILURES = 25;
5
+ /** The failures of the cases, of every trial: errored runs, then metrics that failed */
6
+ function failures(result) {
7
+ return result.results.flatMap((r, i) => {
8
+ const label = caseLabel(i, r.case.input);
9
+ return caseProblems(r).map((problem) => ({ label, problem }));
10
+ });
11
+ }
12
+ /**
13
+ * A compact Markdown summary of a suite run for a pull request comment: the totals, the mean of
14
+ * each metric with the cases it covers, the assertions and the failures of every case and trial.
15
+ * Every value from the run is escaped, so no answer can break the tables or hide the rest of the
16
+ * comment
17
+ */
18
+ export function markdownSummary(result) {
19
+ const { stats } = result;
20
+ const passed = result.assertions.filter((a) => a.passed).length;
21
+ const failed = result.assertions.length - passed;
22
+ const trials = trialsPerCase(result);
23
+ const totals = [
24
+ `**${stats.total}** cases${trials > 1 ? ` x **${trials}** trials` : ''}`,
25
+ `**${stats.errors ?? 0}** errored`,
26
+ ...(stats.metricErrors ? [`**${stats.metricErrors}** metric errors`] : []),
27
+ `${stats.duration} ms`,
28
+ `${num(stats.cost)} USD`,
29
+ ...(result.assertions.length > 0
30
+ ? [`assertions: **${passed}** passed, **${failed}** failed`]
31
+ : []),
32
+ ];
33
+ const title = result.name === undefined ? 'Eval results' : `Eval results: ${cell(result.name)}`;
34
+ const lines = [`### ${title}`, '', totals.join(' | '), ''];
35
+ const metrics = Object.values(result.aggregated);
36
+ if (metrics.length > 0) {
37
+ lines.push('| Metric | Mean | Cases |', '| --- | ---: | ---: |');
38
+ for (const m of metrics) {
39
+ lines.push(`| ${cell(m.name)} | ${num(m.mean)} | ${m.count === undefined ? '-' : m.count} |`);
40
+ }
41
+ lines.push('');
42
+ }
43
+ if (result.assertions.length > 0) {
44
+ lines.push('| Assertion | Result | Details |', '| --- | --- | --- |');
45
+ for (const a of result.assertions) {
46
+ lines.push(`| ${cell(a.name)} | ${a.passed ? 'pass' : '**fail**'} | ${cell(a.message)} |`);
47
+ }
48
+ lines.push('');
49
+ }
50
+ const failedCases = failures(result);
51
+ if (failedCases.length > 0) {
52
+ lines.push(`**Failures** (${failedCases.length})`, '', '| Case | Problem |', '| --- | --- |');
53
+ for (const { label, problem } of failedCases.slice(0, MARKDOWN_MAX_FAILURES)) {
54
+ lines.push(`| ${cell(label)} | ${cell(problem)} |`);
55
+ }
56
+ if (failedCases.length > MARKDOWN_MAX_FAILURES) {
57
+ lines.push('', `and ${failedCases.length - MARKDOWN_MAX_FAILURES} more`);
58
+ }
59
+ lines.push('');
60
+ }
61
+ return lines.join('\n');
62
+ }
63
+ /** Writes the Markdown summary of a suite run */
64
+ export function markdownReport(result, options) {
65
+ writeFileSync(options.path, markdownSummary(result), 'utf-8');
66
+ }
67
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/reporters/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { z } from 'zod';
2
+ import type { ComparisonTest } from '../comparison-stats.js';
3
+ import type { EvalRunSource } from './run.js';
4
+ export declare const CompareRunsOptionsSchema: z.ZodObject<{
5
+ alpha: z.ZodDefault<z.ZodNumber>;
6
+ test: z.ZodDefault<z.ZodEnum<{
7
+ t: "t";
8
+ wilcoxon: "wilcoxon";
9
+ }>>;
10
+ seed: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
11
+ metrics: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ }, z.core.$strip>;
13
+ export interface CompareRunsOptions {
14
+ /**
15
+ * Significance level, 0.05 by default. A metric is significant when its p-value, adjusted with
16
+ * Holm's correction across the compared metrics, is below it, and its `ci` covers `1 - alpha`
17
+ */
18
+ alpha?: number;
19
+ /** Test of metrics that are not binary: `t` (paired t-test, the default) or `wilcoxon` */
20
+ test?: 't' | 'wilcoxon';
21
+ /** Seeds the bootstrap of each metric's `ci`, so the intervals are the same on every call */
22
+ seed?: number | string;
23
+ /**
24
+ * The metrics to compare. Default: every per-case metric both runs have and scored on at least
25
+ * one matched case, the others named in `warnings`, so a metric without data neither shows two
26
+ * means of 0 nor weakens the Holm correction of the others
27
+ */
28
+ metrics?: string[];
29
+ }
30
+ export type RunWinner = 'base' | 'head' | 'tie';
31
+ /** How the score of a case moved from the base run to the head run */
32
+ export interface RunCaseChange {
33
+ caseKey: string;
34
+ /** The case input on one line, shortened */
35
+ input: string;
36
+ base: number;
37
+ head: number;
38
+ /** `head` minus `base` */
39
+ delta: number;
40
+ }
41
+ export interface RunMetricComparison {
42
+ /** Mean score of the base run over the compared cases, NaN when `n` is 0 */
43
+ base: number;
44
+ head: number;
45
+ /** Cases compared: matched cases at least one run scored, an errored side counting as a 0 */
46
+ n: number;
47
+ /** Mean of the paired differences, head minus base */
48
+ difference: number;
49
+ /** Percentile bootstrap confidence interval of `difference` at `1 - alpha` */
50
+ ci: {
51
+ low: number;
52
+ high: number;
53
+ };
54
+ /** Cohen's d of the paired differences (dz), NaN with fewer than 2 cases */
55
+ effectSize: number;
56
+ test: ComparisonTest;
57
+ pValue: number;
58
+ /** `pValue` after Holm's correction across the compared metrics */
59
+ adjustedPValue: number;
60
+ significant: boolean;
61
+ /** The higher run when significant, by the test's direction */
62
+ winner: RunWinner;
63
+ /** Cases whose score rose, the largest rise first */
64
+ improved: RunCaseChange[];
65
+ /** Cases whose score fell, the largest fall first */
66
+ regressed: RunCaseChange[];
67
+ }
68
+ /** Which run a side of a comparison is */
69
+ export interface RunRef {
70
+ runId: string;
71
+ name?: string;
72
+ startedAt: string;
73
+ }
74
+ /** A case only one of the runs has */
75
+ export interface RunCaseRef {
76
+ caseKey: string;
77
+ input: string;
78
+ }
79
+ export interface RunComparison {
80
+ base: RunRef;
81
+ head: RunRef;
82
+ /** The run more metrics name as their winner, a tie when as many name each */
83
+ winner: RunWinner;
84
+ metrics: Record<string, RunMetricComparison>;
85
+ /** Cases both runs have, matched by `caseKey` */
86
+ matched: number;
87
+ /** Cases only the head run has */
88
+ added: RunCaseRef[];
89
+ /** Cases only the base run has */
90
+ removed: RunCaseRef[];
91
+ /**
92
+ * What makes the runs harder to compare: other cases, other prompts, other metrics or judge,
93
+ * and metrics left out because no matched case was scored on them
94
+ */
95
+ warnings: string[];
96
+ }
97
+ /**
98
+ * Compares two saved runs, or suite results, case by case: cases are matched by their `caseKey`,
99
+ * and each metric both runs have is compared as `EvalComparison` compares its sides, the base run
100
+ * in the baseline's place and the head run in the challenger's
101
+ */
102
+ export declare function compareRuns(baseSource: EvalRunSource, headSource: EvalRunSource, options?: CompareRunsOptions): RunComparison;
103
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/runs/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AAI5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,eAAO,MAAM,wBAAwB;;;;;;;;iBAKnC,CAAC;AAEH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,IAAI,CAAC,EAAE,GAAG,GAAG,UAAU,CAAC;IACxB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEhD,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,CAAC,EAAE,MAAM,CAAC;IACV,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,MAAM,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,qDAAqD;IACrD,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC7C,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,kCAAkC;IAClC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA8JD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EACzB,UAAU,EAAE,aAAa,EACzB,OAAO,GAAE,kBAAuB,GAC/B,aAAa,CAyDf"}
@@ -0,0 +1,208 @@
1
+ import { z } from 'zod';
2
+ import { parseOptions } from '../options.js';
3
+ import { caseChanges, compareMetrics, determineOverallWinner, pairedScores, scoredMetricNames, } from '../comparison-stats.js';
4
+ import { truncateInput } from '../reporters/format.js';
5
+ import { canonicalJson } from './json.js';
6
+ import { runOf } from './run.js';
7
+ export const CompareRunsOptionsSchema = z.object({
8
+ alpha: z.number().gt(0).lt(1).default(0.05),
9
+ test: z.enum(['t', 'wilcoxon']).default('t'),
10
+ seed: z.union([z.number(), z.string()]).optional(),
11
+ metrics: z.array(z.string().min(1)).min(1).optional(),
12
+ });
13
+ const WINNERS = {
14
+ baseline: 'base',
15
+ challenger: 'head',
16
+ tie: 'tie',
17
+ };
18
+ function refOf(run) {
19
+ return {
20
+ runId: run.runId,
21
+ ...(run.name !== undefined && { name: run.name }),
22
+ startedAt: run.startedAt,
23
+ };
24
+ }
25
+ function caseRef(result) {
26
+ return { caseKey: result.caseKey, input: truncateInput(result.case.input) };
27
+ }
28
+ /**
29
+ * Pairs the cases of the runs by `caseKey`, in the order of the base run. A key that repeats pairs
30
+ * its first case of one run with its first case of the other, its second with the second, and so on
31
+ */
32
+ function matchCases(base, head) {
33
+ const headByKey = new Map();
34
+ for (const result of head.results) {
35
+ const list = headByKey.get(result.caseKey);
36
+ if (list)
37
+ list.push(result);
38
+ else
39
+ headByKey.set(result.caseKey, [result]);
40
+ }
41
+ const pairs = [];
42
+ const removed = [];
43
+ for (const result of base.results) {
44
+ const match = headByKey.get(result.caseKey)?.shift();
45
+ if (match)
46
+ pairs.push([result, match]);
47
+ else
48
+ removed.push(caseRef(result));
49
+ }
50
+ const added = [...headByKey.values()].flat();
51
+ const addedSet = new Set(added);
52
+ return {
53
+ pairs,
54
+ removed,
55
+ added: head.results.filter((result) => addedSet.has(result)).map(caseRef),
56
+ };
57
+ }
58
+ /** The per-case metrics of a run: those it was set up with and those its cases were scored on */
59
+ function caseMetricNames(run) {
60
+ return new Set([...run.config.metrics, ...scoredMetricNames(run.results)]);
61
+ }
62
+ function metricsToCompare(base, head, requested) {
63
+ const baseNames = caseMetricNames(base);
64
+ const headNames = caseMetricNames(head);
65
+ const shared = [...baseNames].filter((name) => headNames.has(name));
66
+ if (requested === undefined)
67
+ return shared;
68
+ const missing = requested.filter((name) => !shared.includes(name));
69
+ if (missing.length > 0) {
70
+ throw new Error(`compareRuns: ${missing.map((name) => `'${name}'`).join(', ')} not in both runs, the base run has ${[...baseNames].join(', ') || 'no metrics'} and the head run ${[...headNames].join(', ') || 'no metrics'}`);
71
+ }
72
+ return [...new Set(requested)];
73
+ }
74
+ function promptLabel(prompt) {
75
+ if (prompt.abTest)
76
+ return `A/B test ${prompt.abTest.id} (${prompt.abTest.variant})`;
77
+ if (prompt.version !== undefined) {
78
+ return prompt.versionId !== undefined
79
+ ? `v${prompt.version} (${prompt.versionId})`
80
+ : `v${prompt.version}`;
81
+ }
82
+ return prompt.versionId ?? 'unversioned instructions';
83
+ }
84
+ function promptsByKey(run) {
85
+ const byKey = new Map();
86
+ for (const prompt of run.prompts) {
87
+ const labels = byKey.get(prompt.key) ?? new Map();
88
+ labels.set(canonicalJson(prompt), promptLabel(prompt));
89
+ byKey.set(prompt.key, labels);
90
+ }
91
+ return byKey;
92
+ }
93
+ function promptWarnings(base, head) {
94
+ const baseKeys = promptsByKey(base);
95
+ const headKeys = promptsByKey(head);
96
+ const warnings = [];
97
+ for (const key of new Set([...baseKeys.keys(), ...headKeys.keys()])) {
98
+ const before = baseKeys.get(key);
99
+ const after = headKeys.get(key);
100
+ const list = (labels) => [...labels.values()].join(', ');
101
+ if (!before) {
102
+ warnings.push(`Prompt '${key}' is used by the head run only (${list(after)})`);
103
+ }
104
+ else if (!after) {
105
+ warnings.push(`Prompt '${key}' is used by the base run only (${list(before)})`);
106
+ }
107
+ else if (before.size !== after.size ||
108
+ [...before.keys()].some((identity) => !after.has(identity))) {
109
+ warnings.push(`Prompt '${key}' differs: the base run used ${list(before)}, the head run ${list(after)}`);
110
+ }
111
+ }
112
+ return warnings;
113
+ }
114
+ function difference(label, base, head) {
115
+ const onlyBase = base.filter((name) => !head.includes(name));
116
+ const onlyHead = head.filter((name) => !base.includes(name));
117
+ if (onlyBase.length === 0 && onlyHead.length === 0)
118
+ return undefined;
119
+ const parts = [
120
+ ...(onlyBase.length > 0 ? [`only the base run has ${onlyBase.join(', ')}`] : []),
121
+ ...(onlyHead.length > 0 ? [`only the head run has ${onlyHead.join(', ')}`] : []),
122
+ ];
123
+ return `${label} differ: ${parts.join(', ')}`;
124
+ }
125
+ function judgeLabel(judge) {
126
+ if (!judge)
127
+ return 'no judge';
128
+ const samples = judge.samples !== undefined ? `, ${judge.samples} samples` : '';
129
+ return `${judge.model} at temperature ${judge.temperature}${samples}`;
130
+ }
131
+ function configWarnings(base, head) {
132
+ const warnings = [];
133
+ const metrics = difference('Metrics', [...base.config.metrics, ...base.config.statisticalMetrics], [...head.config.metrics, ...head.config.statisticalMetrics]);
134
+ if (metrics)
135
+ warnings.push(metrics);
136
+ if (canonicalJson(base.config.judge ?? null) !== canonicalJson(head.config.judge ?? null)) {
137
+ warnings.push(`Judge differs: the base run used ${judgeLabel(base.config.judge)}, the head run ${judgeLabel(head.config.judge)}`);
138
+ }
139
+ return warnings;
140
+ }
141
+ function datasetWarning(base, head, added, removed) {
142
+ if (base.dataset.fingerprint === head.dataset.fingerprint)
143
+ return undefined;
144
+ if (added === 0 && removed === 0) {
145
+ return 'The datasets differ (fingerprints differ) while every case matches by input, turns and expected answer: their order, context or metadata changed';
146
+ }
147
+ return `The datasets differ (fingerprints differ): ${added} cases only in the head run, ${removed} only in the base run`;
148
+ }
149
+ /**
150
+ * Compares two saved runs, or suite results, case by case: cases are matched by their `caseKey`,
151
+ * and each metric both runs have is compared as `EvalComparison` compares its sides, the base run
152
+ * in the baseline's place and the head run in the challenger's
153
+ */
154
+ export function compareRuns(baseSource, headSource, options = {}) {
155
+ const config = parseOptions(CompareRunsOptionsSchema, options, 'compareRuns');
156
+ const base = runOf(baseSource);
157
+ const head = runOf(headSource);
158
+ const { pairs, added, removed } = matchCases(base, head);
159
+ const paired = new Map();
160
+ const unscored = [];
161
+ for (const name of metricsToCompare(base, head, config.metrics)) {
162
+ const scores = pairedScores(pairs, name);
163
+ if (scores[0].length === 0 && config.metrics === undefined)
164
+ unscored.push(name);
165
+ else
166
+ paired.set(name, scores);
167
+ }
168
+ const names = [...paired.keys()];
169
+ const compared = compareMetrics(paired, config);
170
+ const metrics = {};
171
+ for (const name of names) {
172
+ const { baseline, challenger, winner, ...stats } = compared[name];
173
+ const changes = caseChanges(pairs, name, (index) => pairs[index][0].case.input);
174
+ const toRunChange = (change) => ({
175
+ caseKey: pairs[change.index][0].caseKey,
176
+ input: change.input,
177
+ base: change.before,
178
+ head: change.after,
179
+ delta: change.delta,
180
+ });
181
+ metrics[name] = {
182
+ base: baseline,
183
+ head: challenger,
184
+ ...stats,
185
+ winner: WINNERS[winner],
186
+ improved: changes.improved.map(toRunChange),
187
+ regressed: changes.regressed.map(toRunChange),
188
+ };
189
+ }
190
+ const dataset = datasetWarning(base, head, added.length, removed.length);
191
+ const warnings = [
192
+ ...(dataset ? [dataset] : []),
193
+ ...promptWarnings(base, head),
194
+ ...configWarnings(base, head),
195
+ ...unscored.map((name) => `Metric '${name}' was scored on no case the runs share (every case errored or went unscored), so it is not compared`),
196
+ ];
197
+ return {
198
+ base: refOf(base),
199
+ head: refOf(head),
200
+ winner: WINNERS[determineOverallWinner(compared)],
201
+ metrics,
202
+ matched: pairs.length,
203
+ added,
204
+ removed,
205
+ warnings,
206
+ };
207
+ }
208
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/runs/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { loadRun, caseKey } from './run.js';
2
+ export type { EvalRunSource } from './run.js';
3
+ export { RunStore } from './store.js';
4
+ export type { RunSummary, RunFilter, RunStoreOptions, SkippedRunFile } from './store.js';
5
+ export { compareRuns } from './compare.js';
6
+ export type { CompareRunsOptions, RunComparison, RunMetricComparison, RunCaseChange, RunCaseRef, RunRef, RunWinner, } from './compare.js';
7
+ export { EvalRunSchema, EVAL_RUN_FORMAT, EVAL_RUN_VERSION } from './schema.js';
8
+ export type { EvalRun, EvalRunCase, EvalRunConfig, JsonMetadata } from './schema.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,MAAM,EACN,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { loadRun, caseKey } from './run.js';
2
+ export { RunStore } from './store.js';
3
+ export { compareRuns } from './compare.js';
4
+ export { EvalRunSchema, EVAL_RUN_FORMAT, EVAL_RUN_VERSION } from './schema.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAUxC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A value as JSON keeps it, as `JSON.stringify` would write it (`toJSON` called once per value),
3
+ * except that a bigint becomes its
4
+ * decimal string and a circular reference the string `[Circular]` instead of throwing
5
+ */
6
+ export declare function toJson(value: unknown): unknown;
7
+ /** JSON of a value with the keys of every object sorted, the same text for the same data */
8
+ export declare function canonicalJson(value: unknown): string;
9
+ /** Hex SHA-256 of the canonical JSON of a value */
10
+ export declare function fingerprint(value: unknown): string;
11
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/runs/json.ts"],"names":[],"mappings":"AA8CA;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9C;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElD"}
@@ -0,0 +1,58 @@
1
+ import { createHash } from 'node:crypto';
2
+ function hasToJson(value) {
3
+ return typeof value.toJSON === 'function';
4
+ }
5
+ function convert(value, key, ancestors, sortKeys, calledToJson = false) {
6
+ if (value === null)
7
+ return null;
8
+ switch (typeof value) {
9
+ case 'string':
10
+ case 'boolean':
11
+ return value;
12
+ case 'number':
13
+ return Number.isFinite(value) ? value : null;
14
+ case 'bigint':
15
+ return value.toString();
16
+ case 'undefined':
17
+ case 'function':
18
+ case 'symbol':
19
+ return undefined;
20
+ }
21
+ const object = value;
22
+ if (!calledToJson && hasToJson(object)) {
23
+ return convert(object.toJSON(key), key, ancestors, sortKeys, true);
24
+ }
25
+ if (ancestors.includes(object))
26
+ return '[Circular]';
27
+ const nested = [...ancestors, object];
28
+ if (Array.isArray(object)) {
29
+ return object.map((item, at) => convert(item, String(at), nested, sortKeys) ?? null);
30
+ }
31
+ const keys = Object.keys(object);
32
+ if (sortKeys)
33
+ keys.sort();
34
+ const out = {};
35
+ for (const name of keys) {
36
+ const converted = convert(object[name], name, nested, sortKeys);
37
+ if (converted !== undefined)
38
+ out[name] = converted;
39
+ }
40
+ return out;
41
+ }
42
+ /**
43
+ * A value as JSON keeps it, as `JSON.stringify` would write it (`toJSON` called once per value),
44
+ * except that a bigint becomes its
45
+ * decimal string and a circular reference the string `[Circular]` instead of throwing
46
+ */
47
+ export function toJson(value) {
48
+ return convert(value, '', [], false);
49
+ }
50
+ /** JSON of a value with the keys of every object sorted, the same text for the same data */
51
+ export function canonicalJson(value) {
52
+ return JSON.stringify(convert(value, '', [], true) ?? null);
53
+ }
54
+ /** Hex SHA-256 of the canonical JSON of a value */
55
+ export function fingerprint(value) {
56
+ return createHash('sha256').update(canonicalJson(value)).digest('hex');
57
+ }
58
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/runs/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,OAAQ,KAA8B,CAAC,MAAM,KAAK,UAAU,CAAC;AACtE,CAAC;AAED,SAAS,OAAO,CACd,KAAc,EACd,GAAW,EACX,SAAmB,EACnB,QAAiB,EACjB,YAAY,GAAG,KAAK;IAEpB,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,KAAK,WAAW,CAAC;QACjB,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,KAAe,CAAC;IAC/B,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IACpD,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,QAAQ;QAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,OAAO,CAAE,MAAkC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7F,IAAI,SAAS,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { EvalCase } from '../schema.js';
2
+ import type { ScoredCaseResult } from '../metrics/types.js';
3
+ import type { AggregatedMetric, AssertionResult } from '../assertions/index.js';
4
+ import type { EvalRun, EvalRunConfig, JsonMetadata } from './schema.js';
5
+ /** A saved run, or a suite result that turns into one */
6
+ export type EvalRunSource = EvalRun | {
7
+ toRun(): EvalRun;
8
+ };
9
+ /** Everything a run file records of a finished suite run */
10
+ export interface RunRecord {
11
+ runId: string;
12
+ startedAt: Date;
13
+ finishedAt: Date;
14
+ name?: string;
15
+ metadata?: JsonMetadata;
16
+ cases: readonly EvalCase[];
17
+ config: EvalRunConfig;
18
+ results: readonly ScoredCaseResult[];
19
+ aggregated: Record<string, AggregatedMetric>;
20
+ assertions: readonly AssertionResult[];
21
+ stats: EvalRun['stats'];
22
+ }
23
+ /** A run id that sorts by start time: `20261022T101530123Z-1a2b3c4d` */
24
+ export declare function newRunId(startedAt: Date): string;
25
+ /** The stable key a case is matched by across runs: its input, turns and expected answer */
26
+ export declare function caseKey(evalCase: Pick<EvalCase, 'input' | 'turns' | 'expected'>): string;
27
+ /** The run file of a finished suite run, every value as JSON keeps it */
28
+ export declare function buildRun(record: RunRecord): EvalRun;
29
+ /** The run of a source: the run itself, or a suite result's `toRun()` */
30
+ export declare function runOf(source: EvalRunSource): EvalRun;
31
+ /**
32
+ * Validates a parsed run file. Throws naming `origin` when it is not a run file, when it is of
33
+ * another format version, or when a field does not fit the format
34
+ */
35
+ export declare function parseRun(value: unknown, origin: string): EvalRun;
36
+ /** Reads and validates a run file written by `result.saveRun()` or a `RunStore` */
37
+ export declare function loadRun(path: string): EvalRun;
38
+ /**
39
+ * Validates a run, so its id can never lead outside the directory, then writes its run file
40
+ * and returns its path: `<target>/<runId>.json` when `target` is a directory
41
+ * or ends with a path separator, `target` itself otherwise. Missing directories are created
42
+ */
43
+ export declare function writeRun(run: EvalRun, target: string): string;
44
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/runs/run.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGrE,yDAAyD;AACzD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IAAE,KAAK,IAAI,OAAO,CAAA;CAAE,CAAC;AAE3D,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC7C,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IACvC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACzB;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAGhD;AAED,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC,GAAG,MAAM,CAExF;AA0BD,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAuBnD;AAED,yEAAyE;AACzE,wBAAgB,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAIpD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAgBhE;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAc7C;AAUD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAiB7D"}