@mastra/evals 1.9.0 → 1.10.0-alpha.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 (73) hide show
  1. package/LICENSE.md +6 -4
  2. package/dist/docs/SKILL.md +29 -27
  3. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  4. package/dist/docs/references/docs-evals-built-in-scorers.md +3 -0
  5. package/dist/docs/references/docs-evals-overview.md +74 -10
  6. package/dist/docs/references/docs-evals-quick-checks.md +3 -1
  7. package/dist/docs/references/docs-evals-vitest-integration.md +136 -0
  8. package/dist/docs/references/reference-evals-answer-relevancy.md +2 -0
  9. package/dist/docs/references/reference-evals-answer-similarity.md +2 -0
  10. package/dist/docs/references/reference-evals-bias.md +2 -0
  11. package/dist/docs/references/reference-evals-checks.md +8 -0
  12. package/dist/docs/references/reference-evals-completeness.md +2 -0
  13. package/dist/docs/references/reference-evals-content-similarity.md +2 -0
  14. package/dist/docs/references/reference-evals-context-precision.md +2 -0
  15. package/dist/docs/references/reference-evals-context-recall.md +2 -0
  16. package/dist/docs/references/reference-evals-context-relevance.md +2 -0
  17. package/dist/docs/references/reference-evals-faithfulness.md +2 -0
  18. package/dist/docs/references/reference-evals-hallucination.md +2 -0
  19. package/dist/docs/references/reference-evals-keyword-coverage.md +2 -0
  20. package/dist/docs/references/reference-evals-multi-turn-judge.md +103 -0
  21. package/dist/docs/references/reference-evals-noise-sensitivity.md +2 -0
  22. package/dist/docs/references/reference-evals-prompt-alignment.md +2 -0
  23. package/dist/docs/references/reference-evals-rubric.md +3 -1
  24. package/dist/docs/references/reference-evals-scorer-utils.md +2 -0
  25. package/dist/docs/references/reference-evals-summarization.md +2 -0
  26. package/dist/docs/references/reference-evals-textual-difference.md +2 -0
  27. package/dist/docs/references/reference-evals-tone-consistency.md +2 -0
  28. package/dist/docs/references/reference-evals-tool-call-accuracy.md +2 -0
  29. package/dist/docs/references/reference-evals-toxicity.md +2 -0
  30. package/dist/docs/references/reference-evals-trajectory-accuracy.md +2 -0
  31. package/dist/docs/references/reference-migrations-upgrade-to-v1-evals.md +2 -0
  32. package/dist/matchers-D3c6f71B.js +98 -0
  33. package/dist/matchers-D3c6f71B.js.map +1 -0
  34. package/dist/matchers-DzWDR4_h.cjs +109 -0
  35. package/dist/matchers-DzWDR4_h.cjs.map +1 -0
  36. package/dist/scorers/code/completeness/index.d.ts.map +1 -1
  37. package/dist/scorers/code/keyword-coverage/index.d.ts +1 -1
  38. package/dist/scorers/code/keyword-coverage/index.d.ts.map +1 -1
  39. package/dist/scorers/code/tone/index.d.ts +3 -3
  40. package/dist/scorers/code/trajectory/index.d.ts +1 -1
  41. package/dist/scorers/code/trajectory/index.d.ts.map +1 -1
  42. package/dist/scorers/llm/answer-relevancy/prompts.d.ts.map +1 -1
  43. package/dist/scorers/llm/answer-similarity/index.d.ts +1 -1
  44. package/dist/scorers/llm/answer-similarity/prompts.d.ts.map +1 -1
  45. package/dist/scorers/llm/context-relevance/index.d.ts +2 -2
  46. package/dist/scorers/llm/noise-sensitivity/index.d.ts +2 -2
  47. package/dist/scorers/llm/tool-call-accuracy/prompts.d.ts.map +1 -1
  48. package/dist/scorers/llm/trajectory/index.d.ts +1 -1
  49. package/dist/scorers/llm/trajectory/prompts.d.ts.map +1 -1
  50. package/dist/scorers/utils.d.ts +9 -9
  51. package/dist/scorers/utils.d.ts.map +1 -1
  52. package/dist/vitest/expect-evals.d.ts +78 -0
  53. package/dist/vitest/expect-evals.d.ts.map +1 -0
  54. package/dist/vitest/index.cjs +269 -0
  55. package/dist/vitest/index.cjs.map +1 -0
  56. package/dist/vitest/index.d.ts +8 -0
  57. package/dist/vitest/index.d.ts.map +1 -0
  58. package/dist/vitest/index.js +262 -0
  59. package/dist/vitest/index.js.map +1 -0
  60. package/dist/vitest/matchers.d.ts +49 -0
  61. package/dist/vitest/matchers.d.ts.map +1 -0
  62. package/dist/vitest/meta.d.ts +45 -0
  63. package/dist/vitest/meta.d.ts.map +1 -0
  64. package/dist/vitest/reporter.d.ts +29 -0
  65. package/dist/vitest/reporter.d.ts.map +1 -0
  66. package/dist/vitest/setup.cjs +11 -0
  67. package/dist/vitest/setup.cjs.map +1 -0
  68. package/dist/vitest/setup.d.ts +2 -0
  69. package/dist/vitest/setup.d.ts.map +1 -0
  70. package/dist/vitest/setup.js +13 -0
  71. package/dist/vitest/setup.js.map +1 -0
  72. package/package.json +36 -11
  73. package/CHANGELOG.md +0 -3709
@@ -0,0 +1,78 @@
1
+ import type { RunEvalsConfig, RunEvalsResult } from '@mastra/core/evals';
2
+ /**
3
+ * Options accepted by `expectEvals`: exactly the `runEvals` configuration
4
+ * (target, data items, scorers/gates/thresholds, etc.).
5
+ */
6
+ export type ExpectEvalsOptions = RunEvalsConfig;
7
+ /** A single eval data item, as accepted by `runEvals` in its `data` array. */
8
+ export type EvalDataItem = RunEvalsConfig['data'][number];
9
+ /**
10
+ * Options accepted by `expectEval`: same as `expectEvals`, but `data` is a single item.
11
+ * Distributes over the config union so each target keeps its own data-item contract
12
+ * (e.g. `turns` stays agent-only).
13
+ */
14
+ export type ExpectEvalOptions = RunEvalsConfig extends infer T ? T extends RunEvalsConfig ? Omit<T, 'data'> & {
15
+ data: T['data'][number];
16
+ } : never : never;
17
+ /** Thrown by `expectEval`/`expectEvals` `.toPass()` when the pass rate is not met. */
18
+ export declare class EvalPassRateError extends Error {
19
+ readonly result: RunEvalsResult;
20
+ constructor(message: string, result: RunEvalsResult);
21
+ }
22
+ /** Fluent assertion returned by `expectEval` and `expectEvals`. */
23
+ export type EvalScoresAssertion = {
24
+ /**
25
+ * Runs the eval and asserts it passes.
26
+ *
27
+ * - Every gate's pass rate across data items must be `>= minPassRate`
28
+ * (gates score 1 on pass and 0 on failure, so the averaged gate score
29
+ * is exactly the fraction of items that passed the gate).
30
+ * - Every scorer threshold must pass (thresholds compare the average
31
+ * score across items and are not relaxed by `minPassRate`).
32
+ *
33
+ * @param minPassRate Minimum per-gate pass rate in `[0, 1]`. Defaults to 1
34
+ * (all items must pass every gate).
35
+ * @returns The full `RunEvalsResult` for further assertions.
36
+ */
37
+ toPass(minPassRate?: number): Promise<RunEvalsResult>;
38
+ };
39
+ /**
40
+ * Fluent eval assertion over a dataset, for use inside a regular `test()`.
41
+ *
42
+ * Runs `runEvals` with the given options when awaited and asserts the outcome.
43
+ * The run's scores are attached to the current test's meta so
44
+ * `MastraEvalsReporter` displays them in the runner output.
45
+ *
46
+ * Must be awaited — otherwise the test finishes before the eval runs.
47
+ *
48
+ * @example
49
+ * test('capitals agent answers with the expected city', async () => {
50
+ * await expectEvals({
51
+ * target: capitalsAgent,
52
+ * data: [{ input: 'What is the capital of France?', groundTruth: 'Paris' }],
53
+ * gates: [containsGroundTruth],
54
+ * scorers: [{ scorer: createKeywordCoverageScorer(), threshold: 0.4 }],
55
+ * }).toPass(0.8);
56
+ * });
57
+ */
58
+ export declare function expectEvals(options: ExpectEvalsOptions): EvalScoresAssertion;
59
+ /**
60
+ * Single-item variant of `expectEvals`: `data` is one item instead of an array.
61
+ *
62
+ * Use it with `test.each`/`it.each` for matrix testing when you want one test
63
+ * (and one reporter entry) per data item instead of one per dataset run.
64
+ *
65
+ * @example
66
+ * test.each([
67
+ * { input: 'What is the capital of France?', groundTruth: 'Paris' },
68
+ * { input: 'What is the capital of Japan?', groundTruth: 'Tokyo' },
69
+ * ])('capitals agent: $input', async item => {
70
+ * await expectEval({
71
+ * target: capitalsAgent,
72
+ * data: item,
73
+ * gates: [containsGroundTruth],
74
+ * }).toPass();
75
+ * });
76
+ */
77
+ export declare function expectEval(options: ExpectEvalOptions): EvalScoresAssertion;
78
+ //# sourceMappingURL=expect-evals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expect-evals.d.ts","sourceRoot":"","sources":["../../src/vitest/expect-evals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKzE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAEhD,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,SAAS,MAAM,CAAC,GAC1D,CAAC,SAAS,cAAc,GACtB,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;CAAE,GAC7C,KAAK,GACP,KAAK,CAAC;AAEV,sFAAsF;AACtF,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAEhC,YAAY,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAIlD;CACF;AAED,mEAAmE;AACnE,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACvD,CAAC;AAiFF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,mBAAmB,CAE5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CAE1E"}
@@ -0,0 +1,269 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_matchers = require("../matchers-DzWDR4_h.cjs");
3
+ let _mastra_core_evals = require("@mastra/core/evals");
4
+ //#region src/vitest/meta.ts
5
+ /**
6
+ * Flattens the `scores` record of a `RunEvalsResult` into `Record<string, number>`.
7
+ * Categorized results (`agent`, `workflow`, `steps`, `trajectory`) are flattened
8
+ * into dot-separated keys, e.g. `agent.my-scorer` or `steps.step-1.my-scorer`.
9
+ */
10
+ function flattenScores(scores, prefix = "", out = {}) {
11
+ for (const [id, value] of Object.entries(scores)) {
12
+ const key = prefix ? `${prefix}.${id}` : id;
13
+ if (typeof value === "number") out[key] = value;
14
+ else if (value && typeof value === "object") flattenScores(value, key, out);
15
+ }
16
+ return out;
17
+ }
18
+ /**
19
+ * Projects a `RunEvalsResult` into the serializable `MastraEvalMeta` shape
20
+ * stored in `task.meta.mastraEval`.
21
+ */
22
+ function toEvalMeta(result) {
23
+ const meta = {
24
+ scores: flattenScores(result.scores),
25
+ totalItems: result.summary.totalItems
26
+ };
27
+ if (result.verdict !== void 0) meta.verdict = result.verdict;
28
+ if (result.gateResults) meta.gateResults = result.gateResults.map((g) => ({ ...g }));
29
+ if (result.thresholdResults) meta.thresholdResults = result.thresholdResults.map((t) => ({ ...t }));
30
+ if (result.turnResults) meta.turnResults = result.turnResults;
31
+ return meta;
32
+ }
33
+ //#endregion
34
+ //#region src/vitest/expect-evals.ts
35
+ /** Thrown by `expectEval`/`expectEvals` `.toPass()` when the pass rate is not met. */
36
+ var EvalPassRateError = class extends Error {
37
+ result;
38
+ constructor(message, result) {
39
+ super(message);
40
+ this.name = "EvalPassRateError";
41
+ this.result = result;
42
+ }
43
+ };
44
+ async function attachMetaToCurrentTest(result) {
45
+ try {
46
+ const task = (await import("vitest")).TestRunner?.getCurrentTest?.();
47
+ if (task?.meta) {
48
+ task.meta.mastraEval = toEvalMeta(result);
49
+ return;
50
+ }
51
+ const legacyTask = (await import("vitest/suite")).getCurrentTest?.();
52
+ if (legacyTask?.meta) legacyTask.meta.mastraEval = toEvalMeta(result);
53
+ } catch {}
54
+ }
55
+ function assertPassRate(result, minPassRate) {
56
+ if (!Number.isFinite(minPassRate) || minPassRate < 0 || minPassRate > 1) throw new Error(`toPass(minPassRate): minPassRate must be within [0, 1], got ${minPassRate}`);
57
+ const lines = [];
58
+ for (const gate of result.gateResults ?? []) if (gate.score < minPassRate) lines.push(` ✗ gate ${gate.id}: pass rate ${formatRate(gate.score)} < required ${formatRate(minPassRate)}`);
59
+ for (const t of result.thresholdResults ?? []) if (!t.passed) lines.push(` ✗ threshold ${t.id}: average score ${t.averageScore} (threshold: ${JSON.stringify(t.threshold)})`);
60
+ for (const turn of result.turnResults ?? []) {
61
+ for (const gate of turn.gateResults ?? []) if (gate.score < minPassRate) lines.push(` ✗ turn ${turn.index} gate ${gate.id}: pass rate ${formatRate(gate.score)} < required ${formatRate(minPassRate)}`);
62
+ for (const t of turn.thresholdResults ?? []) if (!t.passed) lines.push(` ✗ turn ${turn.index} threshold ${t.id}: average score ${t.averageScore} (threshold: ${JSON.stringify(t.threshold)})`);
63
+ }
64
+ if (lines.length > 0) throw new EvalPassRateError([`Eval did not pass (required pass rate: ${formatRate(minPassRate)}).`, ...lines].join("\n"), result);
65
+ }
66
+ function formatRate(rate) {
67
+ return `${Math.round(rate * 1e3) / 10}%`;
68
+ }
69
+ function makeAssertion(options) {
70
+ return { async toPass(minPassRate = 1) {
71
+ const result = await (0, _mastra_core_evals.runEvals)(options);
72
+ await attachMetaToCurrentTest(result);
73
+ assertPassRate(result, minPassRate);
74
+ return result;
75
+ } };
76
+ }
77
+ /**
78
+ * Fluent eval assertion over a dataset, for use inside a regular `test()`.
79
+ *
80
+ * Runs `runEvals` with the given options when awaited and asserts the outcome.
81
+ * The run's scores are attached to the current test's meta so
82
+ * `MastraEvalsReporter` displays them in the runner output.
83
+ *
84
+ * Must be awaited — otherwise the test finishes before the eval runs.
85
+ *
86
+ * @example
87
+ * test('capitals agent answers with the expected city', async () => {
88
+ * await expectEvals({
89
+ * target: capitalsAgent,
90
+ * data: [{ input: 'What is the capital of France?', groundTruth: 'Paris' }],
91
+ * gates: [containsGroundTruth],
92
+ * scorers: [{ scorer: createKeywordCoverageScorer(), threshold: 0.4 }],
93
+ * }).toPass(0.8);
94
+ * });
95
+ */
96
+ function expectEvals(options) {
97
+ return makeAssertion(options);
98
+ }
99
+ /**
100
+ * Single-item variant of `expectEvals`: `data` is one item instead of an array.
101
+ *
102
+ * Use it with `test.each`/`it.each` for matrix testing when you want one test
103
+ * (and one reporter entry) per data item instead of one per dataset run.
104
+ *
105
+ * @example
106
+ * test.each([
107
+ * { input: 'What is the capital of France?', groundTruth: 'Paris' },
108
+ * { input: 'What is the capital of Japan?', groundTruth: 'Tokyo' },
109
+ * ])('capitals agent: $input', async item => {
110
+ * await expectEval({
111
+ * target: capitalsAgent,
112
+ * data: item,
113
+ * gates: [containsGroundTruth],
114
+ * }).toPass();
115
+ * });
116
+ */
117
+ function expectEval(options) {
118
+ return makeAssertion({
119
+ ...options,
120
+ data: [options.data]
121
+ });
122
+ }
123
+ //#endregion
124
+ //#region src/vitest/reporter.ts
125
+ const GREEN = "\x1B[32m";
126
+ const RED = "\x1B[31m";
127
+ const YELLOW = "\x1B[33m";
128
+ const BOLD = "\x1B[1m";
129
+ const DIM = "\x1B[2m";
130
+ const RESET = "\x1B[0m";
131
+ function supportsColor() {
132
+ return process.stdout.isTTY === true && process.env.NO_COLOR === void 0;
133
+ }
134
+ /**
135
+ * Vitest reporter that prints a per-test score table for every eval run
136
+ * using `expectEval`/`expectEvals` (or any test that populates `task.meta.mastraEval`).
137
+ *
138
+ * Usage in `vitest.config.ts`:
139
+ * test: { reporters: ['default', new MastraEvalsReporter()] }
140
+ */
141
+ var MastraEvalsReporter = class {
142
+ color;
143
+ constructor(options = {}) {
144
+ this.color = options.color ?? supportsColor();
145
+ }
146
+ onTestRunEnd(testModules) {
147
+ const entries = [];
148
+ for (const module of testModules) for (const test of module.children.allTests()) {
149
+ const meta = test.meta().mastraEval;
150
+ if (meta) entries.push({
151
+ fullName: test.fullName,
152
+ meta
153
+ });
154
+ }
155
+ if (entries.length === 0) return;
156
+ this.print(this.render(entries));
157
+ }
158
+ /** Renders the score report as plain lines. Exposed for testing. */
159
+ render(entries) {
160
+ const lines = [];
161
+ lines.push("");
162
+ lines.push(this.style(BOLD, " Mastra Evals "));
163
+ for (const { fullName, meta } of entries) {
164
+ lines.push("");
165
+ lines.push(`${this.verdictBadge(meta.verdict)} ${this.style(BOLD, fullName)} ${this.style(DIM, `(${meta.totalItems} item${meta.totalItems === 1 ? "" : "s"})`)}`);
166
+ const rows = [];
167
+ for (const gate of meta.gateResults ?? []) rows.push([
168
+ `${gate.id} ${this.style(DIM, "(gate)")}`,
169
+ formatScore(gate.score),
170
+ this.passMark(gate.passed)
171
+ ]);
172
+ for (const t of meta.thresholdResults ?? []) rows.push([
173
+ `${t.id} ${this.style(DIM, `(threshold: ${formatThreshold(t.threshold)})`)}`,
174
+ formatScore(t.averageScore),
175
+ this.passMark(t.passed)
176
+ ]);
177
+ const covered = /* @__PURE__ */ new Set([...(meta.gateResults ?? []).map((g) => g.id), ...(meta.thresholdResults ?? []).map((t) => t.id)]);
178
+ for (const [id, score] of Object.entries(meta.scores)) {
179
+ if (covered.has(id)) continue;
180
+ rows.push([
181
+ id,
182
+ formatScore(score),
183
+ ""
184
+ ]);
185
+ }
186
+ lines.push(...this.table(rows));
187
+ for (const turn of meta.turnResults ?? []) {
188
+ const turnRows = [];
189
+ for (const gate of turn.gateResults ?? []) turnRows.push([
190
+ `${gate.id} ${this.style(DIM, "(gate)")}`,
191
+ formatScore(gate.score),
192
+ this.passMark(gate.passed)
193
+ ]);
194
+ for (const t of turn.thresholdResults ?? []) turnRows.push([
195
+ `${t.id} ${this.style(DIM, `(threshold: ${formatThreshold(t.threshold)})`)}`,
196
+ formatScore(t.averageScore),
197
+ this.passMark(t.passed)
198
+ ]);
199
+ const turnCovered = /* @__PURE__ */ new Set([...(turn.gateResults ?? []).map((g) => g.id), ...(turn.thresholdResults ?? []).map((t) => t.id)]);
200
+ for (const [id, score] of Object.entries(turn.scores ?? {})) {
201
+ if (turnCovered.has(id)) continue;
202
+ turnRows.push([
203
+ id,
204
+ formatScore(score),
205
+ ""
206
+ ]);
207
+ }
208
+ if (turnRows.length === 0) continue;
209
+ lines.push(` ${this.style(DIM, `turn ${turn.index}`)}`);
210
+ lines.push(...this.table(turnRows, " "));
211
+ }
212
+ }
213
+ const withVerdict = entries.filter((e) => e.meta.verdict !== void 0);
214
+ const passed = withVerdict.filter((e) => e.meta.verdict === "passed").length;
215
+ const failed = withVerdict.filter((e) => e.meta.verdict === "failed").length;
216
+ const scored = entries.length - passed - failed;
217
+ lines.push("");
218
+ const parts = [];
219
+ if (passed > 0) parts.push(this.style(GREEN, `${passed} passed`));
220
+ if (failed > 0) parts.push(this.style(RED, `${failed} failed`));
221
+ if (scored > 0) parts.push(this.style(YELLOW, `${scored} scored`));
222
+ lines.push(` Eval runs: ${entries.length} ${this.style(DIM, `(${parts.join(", ")})`)}`);
223
+ lines.push("");
224
+ return lines.join("\n");
225
+ }
226
+ table(rows, indent = "") {
227
+ if (rows.length === 0) return [];
228
+ const nameWidth = Math.max(...rows.map(([name]) => stripAnsi(name).length));
229
+ const scoreWidth = Math.max(5, ...rows.map(([, score]) => score.length));
230
+ return rows.map(([name, score, mark]) => {
231
+ return `${indent} ${name}${" ".repeat(nameWidth - stripAnsi(name).length)} ${score.padStart(scoreWidth)} ${mark}`.trimEnd();
232
+ });
233
+ }
234
+ verdictBadge(verdict) {
235
+ if (verdict === "passed") return this.style(GREEN, "✓");
236
+ if (verdict === "failed") return this.style(RED, "✗");
237
+ return this.style(YELLOW, "•");
238
+ }
239
+ passMark(passed) {
240
+ return passed ? this.style(GREEN, "✓") : this.style(RED, "✗");
241
+ }
242
+ style(code, text) {
243
+ return this.color ? `${code}${text}${RESET}` : text;
244
+ }
245
+ print(output) {
246
+ process.stdout.write(`${output}\n`);
247
+ }
248
+ };
249
+ function formatScore(score) {
250
+ return Number.isInteger(score) ? score.toFixed(1) : score.toFixed(3).replace(/0+$/, "").replace(/\.$/, ".0");
251
+ }
252
+ function formatThreshold(threshold) {
253
+ if (typeof threshold === "number") return `min ${threshold}`;
254
+ return Object.entries(threshold).map(([key, value]) => `${key} ${value}`).join(", ");
255
+ }
256
+ const ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
257
+ function stripAnsi(text) {
258
+ return text.replace(ANSI_PATTERN, "");
259
+ }
260
+ //#endregion
261
+ exports.EvalPassRateError = EvalPassRateError;
262
+ exports.MastraEvalsReporter = MastraEvalsReporter;
263
+ exports.evalMatchers = require_matchers.evalMatchers;
264
+ exports.expectEval = expectEval;
265
+ exports.expectEvals = expectEvals;
266
+ exports.registerEvalMatchers = require_matchers.registerEvalMatchers;
267
+ exports.toEvalMeta = toEvalMeta;
268
+
269
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/vitest/meta.ts","../../src/vitest/expect-evals.ts","../../src/vitest/reporter.ts"],"sourcesContent":["import type { EvalVerdict, GateResult, RunEvalsResult, ThresholdConfig, TurnResult } from '@mastra/core/evals';\n\n/** Per-threshold-scorer result, as reported in `RunEvalsResult.thresholdResults`. */\nexport type EvalThresholdResult = {\n id: string;\n passed: boolean;\n averageScore: number;\n threshold: ThresholdConfig;\n};\n\n/**\n * Serializable projection of a `RunEvalsResult` stored in `task.meta.mastraEval`.\n *\n * This is the contract between the test worker (which runs `runEvals`) and the\n * `MastraEvalsReporter` running in the main process. It intentionally excludes\n * raw agent/workflow payloads: `task.meta` is structured-cloned from worker to\n * main, so only lightweight, serializable data belongs here.\n */\nexport type MastraEvalMeta = {\n /**\n * Average score per scorer id across all data items. Categorized scorer\n * configs are flattened into dot-separated keys (e.g. `agent.my-scorer`,\n * `steps.step-1.my-scorer`).\n */\n scores: Record<string, number>;\n /** Number of data items evaluated. */\n totalItems: number;\n /** Present when gates or threshold-bearing scorers were provided. */\n verdict?: EvalVerdict;\n /** Per-gate results (averaged across all data items). */\n gateResults?: GateResult[];\n /** Per-threshold-scorer results (averaged across all data items). */\n thresholdResults?: EvalThresholdResult[];\n /** Per-turn assertion results, present when data items use `turns`. */\n turnResults?: TurnResult[];\n};\n\ndeclare module 'vitest' {\n interface TaskMeta {\n mastraEval?: MastraEvalMeta;\n }\n}\n\n/**\n * Flattens the `scores` record of a `RunEvalsResult` into `Record<string, number>`.\n * Categorized results (`agent`, `workflow`, `steps`, `trajectory`) are flattened\n * into dot-separated keys, e.g. `agent.my-scorer` or `steps.step-1.my-scorer`.\n */\nfunction flattenScores(scores: Record<string, any>, prefix = '', out: Record<string, number> = {}) {\n for (const [id, value] of Object.entries(scores)) {\n const key = prefix ? `${prefix}.${id}` : id;\n if (typeof value === 'number') {\n out[key] = value;\n } else if (value && typeof value === 'object') {\n flattenScores(value, key, out);\n }\n }\n return out;\n}\n\n/**\n * Projects a `RunEvalsResult` into the serializable `MastraEvalMeta` shape\n * stored in `task.meta.mastraEval`.\n */\nexport function toEvalMeta(result: RunEvalsResult): MastraEvalMeta {\n const meta: MastraEvalMeta = {\n scores: flattenScores(result.scores),\n totalItems: result.summary.totalItems,\n };\n if (result.verdict !== undefined) meta.verdict = result.verdict;\n if (result.gateResults) meta.gateResults = result.gateResults.map(g => ({ ...g }));\n if (result.thresholdResults) meta.thresholdResults = result.thresholdResults.map(t => ({ ...t }));\n if (result.turnResults) meta.turnResults = result.turnResults;\n return meta;\n}\n","import type { RunEvalsConfig, RunEvalsResult } from '@mastra/core/evals';\nimport { runEvals } from '@mastra/core/evals';\n\nimport { toEvalMeta } from './meta';\n\n/**\n * Options accepted by `expectEvals`: exactly the `runEvals` configuration\n * (target, data items, scorers/gates/thresholds, etc.).\n */\nexport type ExpectEvalsOptions = RunEvalsConfig;\n\n/** A single eval data item, as accepted by `runEvals` in its `data` array. */\nexport type EvalDataItem = RunEvalsConfig['data'][number];\n\n/**\n * Options accepted by `expectEval`: same as `expectEvals`, but `data` is a single item.\n * Distributes over the config union so each target keeps its own data-item contract\n * (e.g. `turns` stays agent-only).\n */\nexport type ExpectEvalOptions = RunEvalsConfig extends infer T\n ? T extends RunEvalsConfig\n ? Omit<T, 'data'> & { data: T['data'][number] }\n : never\n : never;\n\n/** Thrown by `expectEval`/`expectEvals` `.toPass()` when the pass rate is not met. */\nexport class EvalPassRateError extends Error {\n readonly result: RunEvalsResult;\n\n constructor(message: string, result: RunEvalsResult) {\n super(message);\n this.name = 'EvalPassRateError';\n this.result = result;\n }\n}\n\n/** Fluent assertion returned by `expectEval` and `expectEvals`. */\nexport type EvalScoresAssertion = {\n /**\n * Runs the eval and asserts it passes.\n *\n * - Every gate's pass rate across data items must be `>= minPassRate`\n * (gates score 1 on pass and 0 on failure, so the averaged gate score\n * is exactly the fraction of items that passed the gate).\n * - Every scorer threshold must pass (thresholds compare the average\n * score across items and are not relaxed by `minPassRate`).\n *\n * @param minPassRate Minimum per-gate pass rate in `[0, 1]`. Defaults to 1\n * (all items must pass every gate).\n * @returns The full `RunEvalsResult` for further assertions.\n */\n toPass(minPassRate?: number): Promise<RunEvalsResult>;\n};\n\nasync function attachMetaToCurrentTest(result: RunEvalsResult): Promise<void> {\n try {\n const vitest = await import('vitest');\n // Vitest >= 4.1\n const task = (vitest as any).TestRunner?.getCurrentTest?.();\n if (task?.meta) {\n task.meta.mastraEval = toEvalMeta(result);\n return;\n }\n // Vitest 3.x / < 4.1\n const suite = await import('vitest/suite');\n const legacyTask = (suite as any).getCurrentTest?.();\n if (legacyTask?.meta) {\n legacyTask.meta.mastraEval = toEvalMeta(result);\n }\n } catch {\n // Outside a Vitest test context — assertion still works, reporter meta is skipped.\n }\n}\n\nfunction assertPassRate(result: RunEvalsResult, minPassRate: number): void {\n if (!Number.isFinite(minPassRate) || minPassRate < 0 || minPassRate > 1) {\n throw new Error(`toPass(minPassRate): minPassRate must be within [0, 1], got ${minPassRate}`);\n }\n\n const lines: string[] = [];\n\n for (const gate of result.gateResults ?? []) {\n if (gate.score < minPassRate) {\n lines.push(` ✗ gate ${gate.id}: pass rate ${formatRate(gate.score)} < required ${formatRate(minPassRate)}`);\n }\n }\n\n for (const t of result.thresholdResults ?? []) {\n if (!t.passed) {\n lines.push(` ✗ threshold ${t.id}: average score ${t.averageScore} (threshold: ${JSON.stringify(t.threshold)})`);\n }\n }\n\n for (const turn of result.turnResults ?? []) {\n for (const gate of turn.gateResults ?? []) {\n if (gate.score < minPassRate) {\n lines.push(\n ` ✗ turn ${turn.index} gate ${gate.id}: pass rate ${formatRate(gate.score)} < required ${formatRate(minPassRate)}`,\n );\n }\n }\n for (const t of turn.thresholdResults ?? []) {\n if (!t.passed) {\n lines.push(\n ` ✗ turn ${turn.index} threshold ${t.id}: average score ${t.averageScore} (threshold: ${JSON.stringify(t.threshold)})`,\n );\n }\n }\n }\n\n if (lines.length > 0) {\n throw new EvalPassRateError(\n [`Eval did not pass (required pass rate: ${formatRate(minPassRate)}).`, ...lines].join('\\n'),\n result,\n );\n }\n}\n\nfunction formatRate(rate: number): string {\n return `${Math.round(rate * 1000) / 10}%`;\n}\n\nfunction makeAssertion(options: ExpectEvalsOptions): EvalScoresAssertion {\n return {\n async toPass(minPassRate = 1): Promise<RunEvalsResult> {\n const result = await runEvals(options as Parameters<typeof runEvals>[0]);\n await attachMetaToCurrentTest(result);\n assertPassRate(result, minPassRate);\n return result;\n },\n };\n}\n\n/**\n * Fluent eval assertion over a dataset, for use inside a regular `test()`.\n *\n * Runs `runEvals` with the given options when awaited and asserts the outcome.\n * The run's scores are attached to the current test's meta so\n * `MastraEvalsReporter` displays them in the runner output.\n *\n * Must be awaited — otherwise the test finishes before the eval runs.\n *\n * @example\n * test('capitals agent answers with the expected city', async () => {\n * await expectEvals({\n * target: capitalsAgent,\n * data: [{ input: 'What is the capital of France?', groundTruth: 'Paris' }],\n * gates: [containsGroundTruth],\n * scorers: [{ scorer: createKeywordCoverageScorer(), threshold: 0.4 }],\n * }).toPass(0.8);\n * });\n */\nexport function expectEvals(options: ExpectEvalsOptions): EvalScoresAssertion {\n return makeAssertion(options);\n}\n\n/**\n * Single-item variant of `expectEvals`: `data` is one item instead of an array.\n *\n * Use it with `test.each`/`it.each` for matrix testing when you want one test\n * (and one reporter entry) per data item instead of one per dataset run.\n *\n * @example\n * test.each([\n * { input: 'What is the capital of France?', groundTruth: 'Paris' },\n * { input: 'What is the capital of Japan?', groundTruth: 'Tokyo' },\n * ])('capitals agent: $input', async item => {\n * await expectEval({\n * target: capitalsAgent,\n * data: item,\n * gates: [containsGroundTruth],\n * }).toPass();\n * });\n */\nexport function expectEval(options: ExpectEvalOptions): EvalScoresAssertion {\n return makeAssertion({ ...options, data: [options.data] } as ExpectEvalsOptions);\n}\n","import type { ThresholdConfig } from '@mastra/core/evals';\nimport type { Reporter, TestCase, TestModule } from 'vitest/node';\n\nimport type { MastraEvalMeta } from './meta';\n\ntype EvalEntry = {\n fullName: string;\n meta: MastraEvalMeta;\n};\n\nconst GREEN = '\\u001b[32m';\nconst RED = '\\u001b[31m';\nconst YELLOW = '\\u001b[33m';\nconst BOLD = '\\u001b[1m';\nconst DIM = '\\u001b[2m';\nconst RESET = '\\u001b[0m';\n\nfunction supportsColor(): boolean {\n return process.stdout.isTTY === true && process.env.NO_COLOR === undefined;\n}\n\n/**\n * Vitest reporter that prints a per-test score table for every eval run\n * using `expectEval`/`expectEvals` (or any test that populates `task.meta.mastraEval`).\n *\n * Usage in `vitest.config.ts`:\n * test: { reporters: ['default', new MastraEvalsReporter()] }\n */\nexport class MastraEvalsReporter implements Reporter {\n private readonly color: boolean;\n\n constructor(options: { color?: boolean } = {}) {\n this.color = options.color ?? supportsColor();\n }\n\n onTestRunEnd(testModules: ReadonlyArray<TestModule>): void {\n const entries: EvalEntry[] = [];\n for (const module of testModules) {\n for (const test of module.children.allTests()) {\n const meta = ((test as TestCase).meta() as { mastraEval?: MastraEvalMeta }).mastraEval;\n if (meta) {\n entries.push({ fullName: test.fullName, meta });\n }\n }\n }\n\n if (entries.length === 0) return;\n\n this.print(this.render(entries));\n }\n\n /** Renders the score report as plain lines. Exposed for testing. */\n render(entries: EvalEntry[]): string {\n const lines: string[] = [];\n lines.push('');\n lines.push(this.style(BOLD, ' Mastra Evals '));\n\n for (const { fullName, meta } of entries) {\n lines.push('');\n lines.push(\n `${this.verdictBadge(meta.verdict)} ${this.style(BOLD, fullName)} ${this.style(DIM, `(${meta.totalItems} item${meta.totalItems === 1 ? '' : 's'})`)}`,\n );\n\n const rows: Array<[string, string, string]> = [];\n for (const gate of meta.gateResults ?? []) {\n rows.push([`${gate.id} ${this.style(DIM, '(gate)')}`, formatScore(gate.score), this.passMark(gate.passed)]);\n }\n for (const t of meta.thresholdResults ?? []) {\n rows.push([\n `${t.id} ${this.style(DIM, `(threshold: ${formatThreshold(t.threshold)})`)}`,\n formatScore(t.averageScore),\n this.passMark(t.passed),\n ]);\n }\n const covered = new Set([\n ...(meta.gateResults ?? []).map(g => g.id),\n ...(meta.thresholdResults ?? []).map(t => t.id),\n ]);\n for (const [id, score] of Object.entries(meta.scores)) {\n if (covered.has(id)) continue;\n rows.push([id, formatScore(score), '']);\n }\n\n lines.push(...this.table(rows));\n\n for (const turn of meta.turnResults ?? []) {\n const turnRows: Array<[string, string, string]> = [];\n for (const gate of turn.gateResults ?? []) {\n turnRows.push([\n `${gate.id} ${this.style(DIM, '(gate)')}`,\n formatScore(gate.score),\n this.passMark(gate.passed),\n ]);\n }\n for (const t of turn.thresholdResults ?? []) {\n turnRows.push([\n `${t.id} ${this.style(DIM, `(threshold: ${formatThreshold(t.threshold)})`)}`,\n formatScore(t.averageScore),\n this.passMark(t.passed),\n ]);\n }\n const turnCovered = new Set([\n ...(turn.gateResults ?? []).map(g => g.id),\n ...(turn.thresholdResults ?? []).map(t => t.id),\n ]);\n for (const [id, score] of Object.entries(turn.scores ?? {})) {\n if (turnCovered.has(id)) continue;\n turnRows.push([id, formatScore(score), '']);\n }\n if (turnRows.length === 0) continue;\n lines.push(` ${this.style(DIM, `turn ${turn.index}`)}`);\n lines.push(...this.table(turnRows, ' '));\n }\n }\n\n const withVerdict = entries.filter(e => e.meta.verdict !== undefined);\n const passed = withVerdict.filter(e => e.meta.verdict === 'passed').length;\n const failed = withVerdict.filter(e => e.meta.verdict === 'failed').length;\n const scored = entries.length - passed - failed;\n lines.push('');\n const parts: string[] = [];\n if (passed > 0) parts.push(this.style(GREEN, `${passed} passed`));\n if (failed > 0) parts.push(this.style(RED, `${failed} failed`));\n if (scored > 0) parts.push(this.style(YELLOW, `${scored} scored`));\n lines.push(` Eval runs: ${entries.length} ${this.style(DIM, `(${parts.join(', ')})`)}`);\n lines.push('');\n\n return lines.join('\\n');\n }\n\n private table(rows: Array<[string, string, string]>, indent = ''): string[] {\n if (rows.length === 0) return [];\n const nameWidth = Math.max(...rows.map(([name]) => stripAnsi(name).length));\n const scoreWidth = Math.max(5, ...rows.map(([, score]) => score.length));\n return rows.map(([name, score, mark]) => {\n const namePad = ' '.repeat(nameWidth - stripAnsi(name).length);\n return `${indent} ${name}${namePad} ${score.padStart(scoreWidth)} ${mark}`.trimEnd();\n });\n }\n\n private verdictBadge(verdict: MastraEvalMeta['verdict']): string {\n if (verdict === 'passed') return this.style(GREEN, '✓');\n if (verdict === 'failed') return this.style(RED, '✗');\n return this.style(YELLOW, '•');\n }\n\n private passMark(passed: boolean): string {\n return passed ? this.style(GREEN, '✓') : this.style(RED, '✗');\n }\n\n private style(code: string, text: string): string {\n return this.color ? `${code}${text}${RESET}` : text;\n }\n\n private print(output: string): void {\n process.stdout.write(`${output}\\n`);\n }\n}\n\nfunction formatScore(score: number): string {\n return Number.isInteger(score) ? score.toFixed(1) : score.toFixed(3).replace(/0+$/, '').replace(/\\.$/, '.0');\n}\n\nfunction formatThreshold(threshold: ThresholdConfig): string {\n if (typeof threshold === 'number') return `min ${threshold}`;\n return Object.entries(threshold)\n .map(([key, value]) => `${key} ${value}`)\n .join(', ');\n}\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_PATTERN = /\\u001b\\[[0-9;]*m/g;\n\nfunction stripAnsi(text: string): string {\n return text.replace(ANSI_PATTERN, '');\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { expectEval, expectEvals, EvalPassRateError } from './expect-evals.js';
2
+ export type { EvalDataItem, EvalScoresAssertion, ExpectEvalOptions, ExpectEvalsOptions } from './expect-evals.js';
3
+ export { evalMatchers, registerEvalMatchers } from './matchers.js';
4
+ export type { EvalMatchers } from './matchers.js';
5
+ export { toEvalMeta } from './meta.js';
6
+ export type { MastraEvalMeta, EvalThresholdResult } from './meta.js';
7
+ export { MastraEvalsReporter } from './reporter.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vitest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}