Skip to content

Commit ce304ab

Browse files
committed
Test failed Mastra classifier evaluations
1 parent 4c71676 commit ce304ab

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import * as Sentry from '@sentry/node';
2+
import { Mastra } from '@mastra/core';
3+
import { Classifier } from '@mastra/core/classifier';
4+
import { Observability } from '@mastra/observability';
5+
import { SentryMastraExporter } from '@sentry/node';
6+
7+
// Inlined `EvaluationModelV4` mock: the ESM/CJS runner copies only this file into its temp dir.
8+
const evaluationModel = {
9+
specificationVersion: 'v4',
10+
provider: 'typesafe-ai.evaluation',
11+
modelId: 'jev-latest',
12+
supportedQuestionTypes: ['choice', 'score', 'boolean'],
13+
async doEvaluate() {
14+
throw new Error('evaluation failed');
15+
},
16+
};
17+
18+
async function run() {
19+
const classifier = new Classifier({
20+
id: 'request-classifier',
21+
model: evaluationModel,
22+
questions: { urgent: { type: 'boolean', instructions: 'Does this request need an immediate response?' } },
23+
});
24+
25+
const mastra = new Mastra({
26+
classifiers: { classifier },
27+
logger: false,
28+
observability: new Observability({
29+
configs: {
30+
default: {
31+
serviceName: 'mastra-test',
32+
exporters: [new SentryMastraExporter()],
33+
},
34+
},
35+
}),
36+
});
37+
38+
await Sentry.startSpan({ op: 'function', name: 'mastra-test' }, async () => {
39+
await mastra
40+
.getClassifier('classifier')
41+
.evaluate({ state: { message: 'I was charged twice.' }, maxRetries: 0 })
42+
.catch(() => undefined);
43+
});
44+
45+
await mastra.observability.shutdown();
46+
}
47+
48+
run();

‎dev-packages/node-integration-tests/suites/tracing/mastra/test.ts‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,32 @@ conditionalTest({ min: 22 })('Mastra integration', () => {
274274
MASTRA_CLASSIFIER_DEPENDENCIES,
275275
);
276276

277+
createEsmAndCjsTests(
278+
__dirname,
279+
'scenario-classifier-error.mjs',
280+
'instrument-with-pii.mjs',
281+
(createRunner, test) => {
282+
test('ends a failed classifier evaluation span with an error status', async () => {
283+
await createRunner()
284+
.ignore('event')
285+
.expect({ transaction: { transaction: 'mastra-test' } })
286+
.expect({
287+
span: container => {
288+
expect(container.items.map(span => span.name)).toEqual(['evaluate jev-latest']);
289+
290+
const evaluateSpan = container.items[0]!;
291+
expect(evaluateSpan.status).toBe('error');
292+
expect(evaluateSpan.attributes[GEN_AI_INPUT_MESSAGES].value).toContain('I was charged twice.');
293+
expect(evaluateSpan.attributes[GEN_AI_OUTPUT_MESSAGES]).toBeUndefined();
294+
},
295+
})
296+
.start()
297+
.completed();
298+
});
299+
},
300+
MASTRA_CLASSIFIER_DEPENDENCIES,
301+
);
302+
277303
createEsmAndCjsTests(
278304
__dirname,
279305
'scenario-auto.mjs',

0 commit comments

Comments
 (0)