@cogitator-ai/evals 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -54
- package/dist/assertions/error-rate.d.ts +8 -0
- package/dist/assertions/error-rate.d.ts.map +1 -0
- package/dist/assertions/error-rate.js +27 -0
- package/dist/assertions/error-rate.js.map +1 -0
- package/dist/assertions/index.d.ts +3 -0
- package/dist/assertions/index.d.ts.map +1 -1
- package/dist/assertions/index.js +1 -0
- package/dist/assertions/index.js.map +1 -1
- package/dist/assertions/regression.d.ts.map +1 -1
- package/dist/assertions/regression.js +3 -1
- package/dist/assertions/regression.js.map +1 -1
- package/dist/assertions/threshold.d.ts.map +1 -1
- package/dist/assertions/threshold.js +4 -1
- package/dist/assertions/threshold.js.map +1 -1
- package/dist/datasets/csv-loader.d.ts +5 -0
- package/dist/datasets/csv-loader.d.ts.map +1 -1
- package/dist/datasets/csv-loader.js +89 -7
- package/dist/datasets/csv-loader.js.map +1 -1
- package/dist/datasets/dataset.d.ts +11 -2
- package/dist/datasets/dataset.d.ts.map +1 -1
- package/dist/datasets/dataset.js +42 -13
- package/dist/datasets/dataset.js.map +1 -1
- package/dist/datasets/issues.d.ts +4 -0
- package/dist/datasets/issues.d.ts.map +1 -0
- package/dist/datasets/issues.js +7 -0
- package/dist/datasets/issues.js.map +1 -0
- package/dist/datasets/jsonl-loader.d.ts.map +1 -1
- package/dist/datasets/jsonl-loader.js +6 -1
- package/dist/datasets/jsonl-loader.js.map +1 -1
- package/dist/eval-builder.d.ts +3 -0
- package/dist/eval-builder.d.ts.map +1 -1
- package/dist/eval-builder.js +7 -0
- package/dist/eval-builder.js.map +1 -1
- package/dist/eval-comparison.d.ts +7 -0
- package/dist/eval-comparison.d.ts.map +1 -1
- package/dist/eval-comparison.js +42 -12
- package/dist/eval-comparison.js.map +1 -1
- package/dist/eval-suite.d.ts +55 -8
- package/dist/eval-suite.d.ts.map +1 -1
- package/dist/eval-suite.js +254 -53
- package/dist/eval-suite.js.map +1 -1
- package/dist/index.d.ts +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/matchers.d.ts +68 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +112 -0
- package/dist/matchers.js.map +1 -0
- package/dist/metrics/custom.d.ts +19 -7
- package/dist/metrics/custom.d.ts.map +1 -1
- package/dist/metrics/custom.js +5 -0
- package/dist/metrics/custom.js.map +1 -1
- package/dist/metrics/index.d.ts +8 -4
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +4 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/llm-judge.d.ts +20 -1
- package/dist/metrics/llm-judge.d.ts.map +1 -1
- package/dist/metrics/llm-judge.js +162 -20
- package/dist/metrics/llm-judge.js.map +1 -1
- package/dist/metrics/matching.d.ts +28 -0
- package/dist/metrics/matching.d.ts.map +1 -0
- package/dist/metrics/matching.js +124 -0
- package/dist/metrics/matching.js.map +1 -0
- package/dist/metrics/retrieval.d.ts +21 -0
- package/dist/metrics/retrieval.d.ts.map +1 -0
- package/dist/metrics/retrieval.js +108 -0
- package/dist/metrics/retrieval.js.map +1 -0
- package/dist/metrics/statistical.d.ts +28 -0
- package/dist/metrics/statistical.d.ts.map +1 -1
- package/dist/metrics/statistical.js +61 -0
- package/dist/metrics/statistical.js.map +1 -1
- package/dist/metrics/tool-calls.d.ts +43 -0
- package/dist/metrics/tool-calls.d.ts.map +1 -0
- package/dist/metrics/tool-calls.js +106 -0
- package/dist/metrics/tool-calls.js.map +1 -0
- package/dist/metrics/types.d.ts +53 -5
- package/dist/metrics/types.d.ts.map +1 -1
- package/dist/metrics/types.js.map +1 -1
- package/dist/reporters/ci.d.ts +4 -0
- package/dist/reporters/ci.d.ts.map +1 -1
- package/dist/reporters/ci.js +5 -1
- package/dist/reporters/ci.js.map +1 -1
- package/dist/reporters/console.d.ts.map +1 -1
- package/dist/reporters/console.js +11 -4
- package/dist/reporters/console.js.map +1 -1
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +5 -2
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/format.d.ts +19 -0
- package/dist/reporters/format.d.ts.map +1 -0
- package/dist/reporters/format.js +31 -0
- package/dist/reporters/format.js.map +1 -0
- package/dist/reporters/github.d.ts +11 -0
- package/dist/reporters/github.d.ts.map +1 -0
- package/dist/reporters/github.js +95 -0
- package/dist/reporters/github.js.map +1 -0
- package/dist/reporters/index.d.ts +44 -20
- package/dist/reporters/index.d.ts.map +1 -1
- package/dist/reporters/index.js +14 -3
- package/dist/reporters/index.js.map +1 -1
- package/dist/reporters/junit.d.ts +8 -0
- package/dist/reporters/junit.d.ts.map +1 -0
- package/dist/reporters/junit.js +107 -0
- package/dist/reporters/junit.js.map +1 -0
- package/dist/schema.d.ts +25 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +29 -0
- package/dist/schema.js.map +1 -1
- package/dist/vitest.d.ts +35 -0
- package/dist/vitest.d.ts.map +1 -0
- package/dist/vitest.js +85 -0
- package/dist/vitest.js.map +1 -0
- package/package.json +17 -3
|
@@ -75,4 +75,65 @@ export function tokenUsage() {
|
|
|
75
75
|
};
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
+
/** Whether a statistical metric is a `passAtK()` one */
|
|
79
|
+
export function isPassAtKMetric(metric) {
|
|
80
|
+
return 'passAtK' in metric && typeof metric.passAtK === 'object';
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The chance that at least one of `k` trials drawn from `n`, `c` of which passed, passes:
|
|
84
|
+
* 1 - C(n - c, k) / C(n, k), computed as a product so large counts do not overflow
|
|
85
|
+
*/
|
|
86
|
+
export function passAtKEstimate(n, c, k) {
|
|
87
|
+
if (n - c < k)
|
|
88
|
+
return 1;
|
|
89
|
+
let allFail = 1;
|
|
90
|
+
for (let i = n - c + 1; i <= n; i++)
|
|
91
|
+
allFail *= 1 - k / i;
|
|
92
|
+
return 1 - allFail;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* pass@k of a per-case metric over the suite's trials: for each case, the unbiased estimate of
|
|
96
|
+
* the chance that at least one of `k` trials scores `threshold` or more, averaged over the cases
|
|
97
|
+
* the metric scored at least one trial of. A trial that errored counts as a failure. Named
|
|
98
|
+
* `passAtK(<metric>,<k>)`. The suite must run at least `k` trials and have the metric.
|
|
99
|
+
*/
|
|
100
|
+
export function passAtK(metricName, opts) {
|
|
101
|
+
const { k, threshold = 1 } = opts;
|
|
102
|
+
if (!Number.isInteger(k) || k < 1) {
|
|
103
|
+
throw new Error(`passAtK k must be a positive integer, got ${k}`);
|
|
104
|
+
}
|
|
105
|
+
if (!Number.isFinite(threshold)) {
|
|
106
|
+
throw new Error(`passAtK threshold must be a finite number, got ${threshold}`);
|
|
107
|
+
}
|
|
108
|
+
const name = `passAtK(${metricName},${k})`;
|
|
109
|
+
const fn = createStatisticalFn(name, (results) => {
|
|
110
|
+
const values = [];
|
|
111
|
+
for (const result of results) {
|
|
112
|
+
const trials = result.trials ?? [result];
|
|
113
|
+
if (trials.length < k) {
|
|
114
|
+
throw new Error(`${name} needs at least ${k} trials per case, a case has ${trials.length}: run the suite with trials: ${k} or more`);
|
|
115
|
+
}
|
|
116
|
+
const scores = trials.map((trial) => trial.error === undefined ? trial.scores?.find((s) => s.name === metricName) : undefined);
|
|
117
|
+
if (scores.every((s) => s === undefined))
|
|
118
|
+
continue;
|
|
119
|
+
const passed = scores.filter((s) => s !== undefined && s.score >= threshold).length;
|
|
120
|
+
values.push(passAtKEstimate(trials.length, passed, k));
|
|
121
|
+
}
|
|
122
|
+
const metadata = { metric: metricName, k, threshold, cases: values.length };
|
|
123
|
+
if (values.length === 0) {
|
|
124
|
+
return {
|
|
125
|
+
name,
|
|
126
|
+
score: Number.NaN,
|
|
127
|
+
details: `no case has a trial scored on ${metricName}`,
|
|
128
|
+
metadata,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { name, score: mean(values), values, metadata };
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(fn, 'passAtK', {
|
|
134
|
+
value: Object.freeze({ metric: metricName, k, threshold }),
|
|
135
|
+
writable: false,
|
|
136
|
+
});
|
|
137
|
+
return fn;
|
|
138
|
+
}
|
|
78
139
|
//# sourceMappingURL=statistical.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statistical.js","sourceRoot":"","sources":["../../src/metrics/statistical.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"statistical.js","sourceRoot":"","sources":["../../src/metrics/statistical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ExpectedToolCall } from '../schema.js';
|
|
2
|
+
import type { EvalToolCall, MetricFn, MetricOptions } from './types.js';
|
|
3
|
+
/** How the arguments of an expected tool call are compared with the actual call's */
|
|
4
|
+
export type ToolArgumentsMatch = 'ignore' | 'subset' | 'exact';
|
|
5
|
+
/** Which figure of the tool call match `toolCalls()` scores */
|
|
6
|
+
export type ToolCallsScore = 'f1' | 'recall' | 'precision';
|
|
7
|
+
/** How strictly `trajectory()` compares the order of the tool calls */
|
|
8
|
+
export type TrajectoryOrder = 'exact' | 'in-order' | 'any-order';
|
|
9
|
+
export interface ToolCallsOptions extends MetricOptions {
|
|
10
|
+
/**
|
|
11
|
+
* `'subset'` (default): the expected arguments must all be in the call with equal values,
|
|
12
|
+
* others may be there too. `'exact'`: the arguments must be equal. `'ignore'`: only the name
|
|
13
|
+
* counts. An expected call without `arguments` matches on its name alone
|
|
14
|
+
*/
|
|
15
|
+
arguments?: ToolArgumentsMatch;
|
|
16
|
+
/** `'f1'` (default), `'recall'` (expected calls made) or `'precision'` (calls that were expected) */
|
|
17
|
+
score?: ToolCallsScore;
|
|
18
|
+
}
|
|
19
|
+
export interface TrajectoryOptions extends MetricOptions {
|
|
20
|
+
/**
|
|
21
|
+
* `'exact'` (default): 1 when the tool names are the expected ones in the same order, else 0.
|
|
22
|
+
* `'in-order'`: the longest common subsequence over the longer of the two sequences.
|
|
23
|
+
* `'any-order'`: the names both share, as multisets, over the longer of the two
|
|
24
|
+
*/
|
|
25
|
+
order?: TrajectoryOrder;
|
|
26
|
+
}
|
|
27
|
+
/** Whether an actual call is the expected one, its arguments compared as `mode` says */
|
|
28
|
+
export declare function toolCallMatches(expected: ExpectedToolCall, actual: EvalToolCall, mode?: ToolArgumentsMatch): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Compares the tool calls of the run, over every turn, with the case's `expectedToolCalls` as
|
|
31
|
+
* multisets: each expected call pairs with at most one actual call. Scores the F1 of the match
|
|
32
|
+
* by default, or its recall or precision. A case expecting no calls scores 1 when the agent made
|
|
33
|
+
* none and 0 otherwise, and so does a case expecting calls when the agent made none.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toolCalls(opts?: ToolCallsOptions): MetricFn;
|
|
36
|
+
/** How well a sequence of tool names follows the expected one, 0 to 1 */
|
|
37
|
+
export declare function trajectoryScore(expected: readonly string[], actual: readonly string[], order: TrajectoryOrder): number;
|
|
38
|
+
/**
|
|
39
|
+
* Compares the sequence of tools the agent called, over every turn, with the names of the
|
|
40
|
+
* case's `expectedToolCalls`. Arguments are not looked at: pair it with `toolCalls()` for them.
|
|
41
|
+
*/
|
|
42
|
+
export declare function trajectory(opts?: TrajectoryOptions): MetricFn;
|
|
43
|
+
//# sourceMappingURL=tool-calls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-calls.d.ts","sourceRoot":"","sources":["../../src/metrics/tool-calls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AASrE,qFAAqF;AACrF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE/D,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE3D,uEAAuE;AACvE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD;;;;OAIG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,qGAAqG;IACrG,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAwBD,wFAAwF;AACxF,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,kBAA6B,GAClC,OAAO,CAMT;AAYD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAqC3D;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,eAAe,GACrB,MAAM,CAWR;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,QAAQ,CAsB7D"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { deepEqual, isSubset, longestCommonSubsequence, maxMatching, multisetOverlap, } from './matching.js';
|
|
2
|
+
const ARGUMENT_MODES = ['ignore', 'subset', 'exact'];
|
|
3
|
+
const SCORE_MODES = ['f1', 'recall', 'precision'];
|
|
4
|
+
const ORDERS = ['exact', 'in-order', 'any-order'];
|
|
5
|
+
function checkOption(metric, option, value, allowed) {
|
|
6
|
+
if (!allowed.includes(value)) {
|
|
7
|
+
throw new Error(`${metric} ${option} must be one of ${allowed.map((v) => `'${v}'`).join(', ')}, got ${String(value)}`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function createMetricFn(name, fn) {
|
|
11
|
+
fn.metricName = name;
|
|
12
|
+
return fn;
|
|
13
|
+
}
|
|
14
|
+
/** Whether an actual call is the expected one, its arguments compared as `mode` says */
|
|
15
|
+
export function toolCallMatches(expected, actual, mode = 'subset') {
|
|
16
|
+
if (expected.name !== actual.name)
|
|
17
|
+
return false;
|
|
18
|
+
if (mode === 'ignore' || expected.arguments === undefined)
|
|
19
|
+
return true;
|
|
20
|
+
return mode === 'exact'
|
|
21
|
+
? deepEqual(expected.arguments, actual.arguments)
|
|
22
|
+
: isSubset(expected.arguments, actual.arguments);
|
|
23
|
+
}
|
|
24
|
+
function describeCall(call) {
|
|
25
|
+
return call.arguments === undefined
|
|
26
|
+
? call.name
|
|
27
|
+
: `${call.name}(${JSON.stringify(call.arguments)})`;
|
|
28
|
+
}
|
|
29
|
+
function ratio(part, whole) {
|
|
30
|
+
return whole === 0 ? 0 : part / whole;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compares the tool calls of the run, over every turn, with the case's `expectedToolCalls` as
|
|
34
|
+
* multisets: each expected call pairs with at most one actual call. Scores the F1 of the match
|
|
35
|
+
* by default, or its recall or precision. A case expecting no calls scores 1 when the agent made
|
|
36
|
+
* none and 0 otherwise, and so does a case expecting calls when the agent made none.
|
|
37
|
+
*/
|
|
38
|
+
export function toolCalls(opts) {
|
|
39
|
+
const mode = opts?.arguments ?? 'subset';
|
|
40
|
+
const scoring = opts?.score ?? 'f1';
|
|
41
|
+
const name = opts?.name ?? 'toolCalls';
|
|
42
|
+
checkOption('toolCalls', 'arguments', mode, ARGUMENT_MODES);
|
|
43
|
+
checkOption('toolCalls', 'score', scoring, SCORE_MODES);
|
|
44
|
+
return createMetricFn(name, (async (result) => {
|
|
45
|
+
const expected = result.case.expectedToolCalls;
|
|
46
|
+
if (expected === undefined) {
|
|
47
|
+
return { name, score: 0, details: 'no expected tool calls provided' };
|
|
48
|
+
}
|
|
49
|
+
const actual = result.toolCalls ?? [];
|
|
50
|
+
const pairs = maxMatching(expected, actual, (e, a) => toolCallMatches(e, a, mode));
|
|
51
|
+
const precision = actual.length === 0 ? (expected.length === 0 ? 1 : 0) : ratio(pairs.size, actual.length);
|
|
52
|
+
const recall = expected.length === 0 ? (actual.length === 0 ? 1 : 0) : ratio(pairs.size, expected.length);
|
|
53
|
+
const f1 = precision + recall === 0 ? 0 : (2 * precision * recall) / (precision + recall);
|
|
54
|
+
const score = scoring === 'precision' ? precision : scoring === 'recall' ? recall : f1;
|
|
55
|
+
const matchedActual = new Set(pairs.values());
|
|
56
|
+
const missing = expected.filter((_, i) => !pairs.has(i)).map(describeCall);
|
|
57
|
+
const unexpected = actual.filter((_, j) => !matchedActual.has(j)).map(describeCall);
|
|
58
|
+
const problems = [
|
|
59
|
+
...(missing.length > 0 ? [`missing ${missing.join(', ')}`] : []),
|
|
60
|
+
...(unexpected.length > 0 ? [`unexpected ${unexpected.join(', ')}`] : []),
|
|
61
|
+
];
|
|
62
|
+
return {
|
|
63
|
+
name,
|
|
64
|
+
score,
|
|
65
|
+
details: problems.length > 0 ? problems.join(' | ') : undefined,
|
|
66
|
+
metadata: { precision, recall, f1, matched: pairs.size },
|
|
67
|
+
};
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
/** How well a sequence of tool names follows the expected one, 0 to 1 */
|
|
71
|
+
export function trajectoryScore(expected, actual, order) {
|
|
72
|
+
if (order === 'exact') {
|
|
73
|
+
return expected.length === actual.length && expected.every((n, i) => n === actual[i]) ? 1 : 0;
|
|
74
|
+
}
|
|
75
|
+
const longest = Math.max(expected.length, actual.length);
|
|
76
|
+
if (longest === 0)
|
|
77
|
+
return 1;
|
|
78
|
+
const shared = order === 'in-order'
|
|
79
|
+
? longestCommonSubsequence(expected, actual)
|
|
80
|
+
: multisetOverlap(expected, actual);
|
|
81
|
+
return shared / longest;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compares the sequence of tools the agent called, over every turn, with the names of the
|
|
85
|
+
* case's `expectedToolCalls`. Arguments are not looked at: pair it with `toolCalls()` for them.
|
|
86
|
+
*/
|
|
87
|
+
export function trajectory(opts) {
|
|
88
|
+
const order = opts?.order ?? 'exact';
|
|
89
|
+
const name = opts?.name ?? 'trajectory';
|
|
90
|
+
checkOption('trajectory', 'order', order, ORDERS);
|
|
91
|
+
return createMetricFn(name, (async (result) => {
|
|
92
|
+
const expectedCalls = result.case.expectedToolCalls;
|
|
93
|
+
if (expectedCalls === undefined) {
|
|
94
|
+
return { name, score: 0, details: 'no expected tool calls provided' };
|
|
95
|
+
}
|
|
96
|
+
const expected = expectedCalls.map((c) => c.name);
|
|
97
|
+
const actual = (result.toolCalls ?? []).map((c) => c.name);
|
|
98
|
+
const score = trajectoryScore(expected, actual, order);
|
|
99
|
+
return {
|
|
100
|
+
name,
|
|
101
|
+
score,
|
|
102
|
+
details: score < 1 ? `expected [${expected.join(', ')}], got [${actual.join(', ')}]` : undefined,
|
|
103
|
+
};
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=tool-calls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-calls.js","sourceRoot":"","sources":["../../src/metrics/tool-calls.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics/types.d.ts
CHANGED
|
@@ -19,6 +19,34 @@ export interface MetricScore {
|
|
|
19
19
|
/** What computing the score cost, for metrics that call a model such as the LLM judge */
|
|
20
20
|
usage?: MetricUsage;
|
|
21
21
|
}
|
|
22
|
+
/** A tool call the agent made */
|
|
23
|
+
export interface EvalToolCall {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
arguments: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/** What a tool call returned, as the run's `onToolResult` reported it */
|
|
29
|
+
export interface EvalToolResult {
|
|
30
|
+
callId: string;
|
|
31
|
+
name: string;
|
|
32
|
+
result?: unknown;
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
/** A passage the agent's retrieval surfaced, such as one result of a `rag_search` call */
|
|
36
|
+
export interface Passage {
|
|
37
|
+
id?: string;
|
|
38
|
+
content: string;
|
|
39
|
+
score?: number;
|
|
40
|
+
source?: string;
|
|
41
|
+
}
|
|
42
|
+
/** One user turn of a multi-turn case and the answer to it */
|
|
43
|
+
export interface EvalTurnResult {
|
|
44
|
+
input: string;
|
|
45
|
+
output: string;
|
|
46
|
+
toolCalls?: readonly EvalToolCall[];
|
|
47
|
+
/** Set on the turn that failed, the last one the case ran */
|
|
48
|
+
error?: string;
|
|
49
|
+
}
|
|
22
50
|
export interface EvalCaseResult {
|
|
23
51
|
case: EvalCase;
|
|
24
52
|
output: string;
|
|
@@ -38,11 +66,27 @@ export interface EvalCaseResult {
|
|
|
38
66
|
cost: number;
|
|
39
67
|
duration: number;
|
|
40
68
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
69
|
+
/** The tool calls of the run, over every turn */
|
|
70
|
+
toolCalls?: readonly EvalToolCall[];
|
|
71
|
+
/** What the tool calls returned, over every turn, raw */
|
|
72
|
+
toolResults?: readonly EvalToolResult[];
|
|
73
|
+
/** The passages the tool results surfaced, over every turn, in the order they came */
|
|
74
|
+
retrieved?: readonly Passage[];
|
|
75
|
+
/** Each turn of a case with `turns`: `input` first, then the further turns */
|
|
76
|
+
turns?: readonly EvalTurnResult[];
|
|
77
|
+
/**
|
|
78
|
+
* Every run of the case when the suite runs several `trials`, each with its own scores. The
|
|
79
|
+
* case result itself is the first of them
|
|
80
|
+
*/
|
|
81
|
+
trials?: ReadonlyArray<EvalCaseResult & {
|
|
82
|
+
scores: MetricScore[];
|
|
83
|
+
}>;
|
|
84
|
+
/** The agent's answer stopped at its output token limit */
|
|
85
|
+
truncated?: boolean;
|
|
86
|
+
/** Tool calls used up the agent's `maxIterations` before it answered */
|
|
87
|
+
iterationLimitReached?: boolean;
|
|
88
|
+
/** The run paused for tool approvals, so `output` holds no answer */
|
|
89
|
+
paused?: boolean;
|
|
46
90
|
}
|
|
47
91
|
export type MetricFn = ((result: EvalCaseResult) => Promise<MetricScore>) & {
|
|
48
92
|
metricName: string;
|
|
@@ -57,6 +101,10 @@ export interface StatisticalScore extends MetricScore {
|
|
|
57
101
|
export type StatisticalMetricFn = ((results: EvalCaseResult[]) => StatisticalScore) & {
|
|
58
102
|
metricName: string;
|
|
59
103
|
};
|
|
104
|
+
/** A case result with the scores of its metrics, as a suite run returns it */
|
|
105
|
+
export type ScoredCaseResult = EvalCaseResult & {
|
|
106
|
+
scores: MetricScore[];
|
|
107
|
+
};
|
|
60
108
|
/** Options every built-in per-case metric factory takes */
|
|
61
109
|
export interface MetricOptions {
|
|
62
110
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AA4HA,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1E,OAAO,SAAS,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC;AACzD,CAAC"}
|
package/dist/reporters/ci.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { EvalSuiteResult } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Prints a short pass or fail summary and sets `process.exitCode` to 1 when an assertion
|
|
4
|
+
* failed. It does not end the process, so output flushes and later hooks still run.
|
|
5
|
+
*/
|
|
2
6
|
export declare function ciReport(result: EvalSuiteResult): void;
|
|
3
7
|
//# sourceMappingURL=ci.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../src/reporters/ci.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAuBtD"}
|
|
1
|
+
{"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../src/reporters/ci.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAuBtD"}
|
package/dist/reporters/ci.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const GREEN = '\x1b[32m';
|
|
2
2
|
const RED = '\x1b[31m';
|
|
3
3
|
const RESET = '\x1b[0m';
|
|
4
|
+
/**
|
|
5
|
+
* Prints a short pass or fail summary and sets `process.exitCode` to 1 when an assertion
|
|
6
|
+
* failed. It does not end the process, so output flushes and later hooks still run.
|
|
7
|
+
*/
|
|
4
8
|
export function ciReport(result) {
|
|
5
9
|
const passed = result.assertions.filter((a) => a.passed).length;
|
|
6
10
|
const failed = result.assertions.filter((a) => !a.passed).length;
|
|
@@ -16,7 +20,7 @@ export function ciReport(result) {
|
|
|
16
20
|
}
|
|
17
21
|
console.log(`Result: ${passed} passed, ${failed} failed`);
|
|
18
22
|
if (failed > 0) {
|
|
19
|
-
process.
|
|
23
|
+
process.exitCode = 1;
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
//# sourceMappingURL=ci.js.map
|
package/dist/reporters/ci.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci.js","sourceRoot":"","sources":["../../src/reporters/ci.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB,MAAM,UAAU,QAAQ,CAAC,MAAuB;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CACT,SAAS,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,SAAS,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CACpI,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,YAAY,MAAM,SAAS,CAAC,CAAC;IAE1D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"ci.js","sourceRoot":"","sources":["../../src/reporters/ci.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAuB;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CACT,SAAS,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,SAAS,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CACpI,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,YAAY,MAAM,SAAS,CAAC,CAAC;IAE1D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/reporters/console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/reporters/console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAiB/C,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAoD3D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { trialsPerCase } from './format.js';
|
|
1
2
|
const GREEN = '\x1b[32m';
|
|
2
3
|
const RED = '\x1b[31m';
|
|
3
4
|
const BOLD = '\x1b[1m';
|
|
@@ -12,13 +13,16 @@ function fmt(n) {
|
|
|
12
13
|
export function consoleReport(result) {
|
|
13
14
|
const metrics = Object.values(result.aggregated);
|
|
14
15
|
if (metrics.length > 0) {
|
|
15
|
-
const
|
|
16
|
+
const metricWidth = Math.max(14, ...metrics.map((m) => m.name.length + 2));
|
|
17
|
+
const cols = { metric: metricWidth, mean: 10, median: 10, p95: 10, min: 10, max: 10, cases: 8 };
|
|
18
|
+
const showCount = metrics.some((m) => m.count !== undefined);
|
|
16
19
|
const header = pad('Metric', cols.metric) +
|
|
17
20
|
pad('Mean', cols.mean) +
|
|
18
21
|
pad('Median', cols.median) +
|
|
19
22
|
pad('P95', cols.p95) +
|
|
20
23
|
pad('Min', cols.min) +
|
|
21
|
-
pad('Max', cols.max)
|
|
24
|
+
pad('Max', cols.max) +
|
|
25
|
+
(showCount ? pad('Cases', cols.cases) : '');
|
|
22
26
|
console.log(`\n${BOLD}${header}${RESET}`);
|
|
23
27
|
console.log(DIM + '─'.repeat(header.length) + RESET);
|
|
24
28
|
for (const m of metrics) {
|
|
@@ -27,7 +31,8 @@ export function consoleReport(result) {
|
|
|
27
31
|
pad(fmt(m.median), cols.median) +
|
|
28
32
|
pad(fmt(m.p95), cols.p95) +
|
|
29
33
|
pad(fmt(m.min), cols.min) +
|
|
30
|
-
pad(fmt(m.max), cols.max)
|
|
34
|
+
pad(fmt(m.max), cols.max) +
|
|
35
|
+
(showCount ? pad(m.count === undefined ? '-' : String(m.count), cols.cases) : '');
|
|
31
36
|
console.log(row);
|
|
32
37
|
}
|
|
33
38
|
}
|
|
@@ -43,6 +48,8 @@ export function consoleReport(result) {
|
|
|
43
48
|
const failed = result.assertions.filter((a) => !a.passed).length;
|
|
44
49
|
const errors = result.stats.errors ?? 0;
|
|
45
50
|
const errorPart = errors > 0 ? ` | ${RED}${errors} errored${RESET}` : '';
|
|
46
|
-
|
|
51
|
+
const trials = trialsPerCase(result);
|
|
52
|
+
const trialPart = trials > 1 ? ` x ${trials} trials` : '';
|
|
53
|
+
console.log(`\n${BOLD}Summary${RESET}: ${result.stats.total} cases${trialPart}${errorPart} | ${result.stats.duration}ms | $${result.stats.cost} | ${GREEN}${passed} passed${RESET} ${failed > 0 ? `${RED}${failed} failed${RESET}` : ''}`);
|
|
47
54
|
}
|
|
48
55
|
//# sourceMappingURL=console.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/reporters/console.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/reporters/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/reporters/csv.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/reporters/csv.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAU/C,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA2BlF"}
|
package/dist/reporters/csv.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { CASE_FLAGS } from './format.js';
|
|
2
3
|
function escapeField(value) {
|
|
3
|
-
if (
|
|
4
|
+
if (/[",\r\n]/.test(value)) {
|
|
4
5
|
return `"${value.replace(/"/g, '""')}"`;
|
|
5
6
|
}
|
|
6
7
|
return value;
|
|
@@ -13,7 +14,8 @@ export function csvReport(result, options) {
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
const metrics = [...metricNames];
|
|
16
|
-
const
|
|
17
|
+
const flags = CASE_FLAGS.filter((flag) => result.results.some((r) => r[flag] === true));
|
|
18
|
+
const headers = ['input', 'expected', 'output', 'duration', ...flags, ...metrics];
|
|
17
19
|
const lines = [headers.join(',')];
|
|
18
20
|
for (const r of result.results) {
|
|
19
21
|
const scoreMap = new Map(r.scores.map((s) => [s.name, s.score]));
|
|
@@ -22,6 +24,7 @@ export function csvReport(result, options) {
|
|
|
22
24
|
escapeField(r.case.expected ?? ''),
|
|
23
25
|
escapeField(r.output),
|
|
24
26
|
String(r.duration),
|
|
27
|
+
...flags.map((flag) => (r[flag] === true ? 'true' : '')),
|
|
25
28
|
...metrics.map((m) => String(scoreMap.get(m) ?? '')),
|
|
26
29
|
];
|
|
27
30
|
lines.push(row.join(','));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/reporters/csv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/reporters/csv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAuB,EAAE,OAAyB;IAC1E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAExF,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC,CAAC;IAClF,MAAM,KAAK,GAAa,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG;YACV,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACzB,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;YAClC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YAClB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxD,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SACrD,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** The run flags a case result can carry, in the order reports list them */
|
|
2
|
+
export declare const CASE_FLAGS: readonly ["truncated", "iterationLimitReached", "paused"];
|
|
3
|
+
export type CaseFlag = (typeof CASE_FLAGS)[number];
|
|
4
|
+
/** The flags set on a case result, in `CASE_FLAGS` order */
|
|
5
|
+
export declare function caseFlags(result: Partial<Record<CaseFlag, boolean>>): CaseFlag[];
|
|
6
|
+
/**
|
|
7
|
+
* A one-line label for a case input: whitespace collapsed and cut to `max` characters with an
|
|
8
|
+
* ellipsis, so test names and annotation titles stay readable
|
|
9
|
+
*/
|
|
10
|
+
export declare function truncateInput(input: string, max?: number): string;
|
|
11
|
+
/** The label of the case at `index` (zero based) in a report or test name */
|
|
12
|
+
export declare function caseLabel(index: number, input: string): string;
|
|
13
|
+
/** How many trials each case ran, 1 for a suite without several trials */
|
|
14
|
+
export declare function trialsPerCase(result: {
|
|
15
|
+
results: ReadonlyArray<{
|
|
16
|
+
trials?: readonly unknown[];
|
|
17
|
+
}>;
|
|
18
|
+
}): number;
|
|
19
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/reporters/format.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,eAAO,MAAM,UAAU,2DAA4D,CAAC;AACpF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,GAAG,QAAQ,EAAE,CAEhF;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAA6B,GAAG,MAAM,CAQvF;AAED,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,OAAO,EAAE,aAAa,CAAC;QAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;CACzD,GAAG,MAAM,CAET"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** The run flags a case result can carry, in the order reports list them */
|
|
2
|
+
export const CASE_FLAGS = ['truncated', 'iterationLimitReached', 'paused'];
|
|
3
|
+
/** The flags set on a case result, in `CASE_FLAGS` order */
|
|
4
|
+
export function caseFlags(result) {
|
|
5
|
+
return CASE_FLAGS.filter((flag) => result[flag] === true);
|
|
6
|
+
}
|
|
7
|
+
const DEFAULT_LABEL_LENGTH = 60;
|
|
8
|
+
/**
|
|
9
|
+
* A one-line label for a case input: whitespace collapsed and cut to `max` characters with an
|
|
10
|
+
* ellipsis, so test names and annotation titles stay readable
|
|
11
|
+
*/
|
|
12
|
+
export function truncateInput(input, max = DEFAULT_LABEL_LENGTH) {
|
|
13
|
+
const line = input.replace(/\s+/g, ' ').trim();
|
|
14
|
+
const chars = [...line];
|
|
15
|
+
if (chars.length <= max)
|
|
16
|
+
return line;
|
|
17
|
+
return `${chars
|
|
18
|
+
.slice(0, max - 3)
|
|
19
|
+
.join('')
|
|
20
|
+
.trimEnd()}...`;
|
|
21
|
+
}
|
|
22
|
+
/** The label of the case at `index` (zero based) in a report or test name */
|
|
23
|
+
export function caseLabel(index, input) {
|
|
24
|
+
const text = truncateInput(input);
|
|
25
|
+
return `[${index + 1}] ${text === '' ? '(empty input)' : text}`;
|
|
26
|
+
}
|
|
27
|
+
/** How many trials each case ran, 1 for a suite without several trials */
|
|
28
|
+
export function trialsPerCase(result) {
|
|
29
|
+
return result.results.reduce((most, r) => Math.max(most, r.trials?.length ?? 1), 1);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/reporters/format.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,WAAW,EAAE,uBAAuB,EAAE,QAAQ,CAAU,CAAC;AAGpF,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,MAA0C;IAClE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,MAAc,oBAAoB;IAC7E,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACxB,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,GAAG,KAAK;SACZ,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;SACjB,IAAI,CAAC,EAAE,CAAC;SACR,OAAO,EAAE,KAAK,CAAC;AACpB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,KAAa;IACpD,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,IAAI,KAAK,GAAG,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,MAE7B;IACC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EvalSuiteResult } from './index.js';
|
|
2
|
+
/** The workflow commands that annotate the run: failures as errors, metric errors as warnings */
|
|
3
|
+
export declare function githubAnnotations(result: EvalSuiteResult): string[];
|
|
4
|
+
/** The Markdown summary of the run for `$GITHUB_STEP_SUMMARY` */
|
|
5
|
+
export declare function githubSummary(result: EvalSuiteResult): string;
|
|
6
|
+
/**
|
|
7
|
+
* Prints GitHub Actions annotations to stdout, and appends a Markdown summary to the file in
|
|
8
|
+
* `GITHUB_STEP_SUMMARY` when the variable is set
|
|
9
|
+
*/
|
|
10
|
+
export declare function githubReport(result: EvalSuiteResult): void;
|
|
11
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/reporters/github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAiB/C,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAoBnE;AAmBD,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CA2C7D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAK1D"}
|