@mastra/evals 1.1.2 → 1.2.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 (60) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/LICENSE.md +15 -0
  3. package/dist/chunk-EVBNIL5M.js +606 -0
  4. package/dist/chunk-EVBNIL5M.js.map +1 -0
  5. package/dist/chunk-XRUR5PBK.cjs +632 -0
  6. package/dist/chunk-XRUR5PBK.cjs.map +1 -0
  7. package/dist/docs/SKILL.md +20 -19
  8. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  9. package/dist/docs/references/docs-evals-built-in-scorers.md +2 -1
  10. package/dist/docs/references/docs-evals-overview.md +11 -16
  11. package/dist/docs/references/reference-evals-answer-relevancy.md +25 -25
  12. package/dist/docs/references/reference-evals-answer-similarity.md +33 -35
  13. package/dist/docs/references/reference-evals-bias.md +24 -24
  14. package/dist/docs/references/reference-evals-completeness.md +19 -20
  15. package/dist/docs/references/reference-evals-content-similarity.md +20 -20
  16. package/dist/docs/references/reference-evals-context-precision.md +36 -36
  17. package/dist/docs/references/reference-evals-context-relevance.md +136 -141
  18. package/dist/docs/references/reference-evals-faithfulness.md +24 -24
  19. package/dist/docs/references/reference-evals-hallucination.md +52 -69
  20. package/dist/docs/references/reference-evals-keyword-coverage.md +18 -18
  21. package/dist/docs/references/reference-evals-noise-sensitivity.md +167 -177
  22. package/dist/docs/references/reference-evals-prompt-alignment.md +111 -116
  23. package/dist/docs/references/reference-evals-scorer-utils.md +285 -105
  24. package/dist/docs/references/reference-evals-textual-difference.md +18 -18
  25. package/dist/docs/references/reference-evals-tone-consistency.md +19 -19
  26. package/dist/docs/references/reference-evals-tool-call-accuracy.md +165 -165
  27. package/dist/docs/references/reference-evals-toxicity.md +21 -21
  28. package/dist/docs/references/reference-evals-trajectory-accuracy.md +613 -0
  29. package/dist/scorers/code/index.d.ts +1 -0
  30. package/dist/scorers/code/index.d.ts.map +1 -1
  31. package/dist/scorers/code/trajectory/index.d.ts +147 -0
  32. package/dist/scorers/code/trajectory/index.d.ts.map +1 -0
  33. package/dist/scorers/llm/answer-similarity/index.d.ts +2 -2
  34. package/dist/scorers/llm/context-precision/index.d.ts +2 -2
  35. package/dist/scorers/llm/context-relevance/index.d.ts +1 -1
  36. package/dist/scorers/llm/faithfulness/index.d.ts +1 -1
  37. package/dist/scorers/llm/hallucination/index.d.ts +2 -2
  38. package/dist/scorers/llm/index.d.ts +1 -0
  39. package/dist/scorers/llm/index.d.ts.map +1 -1
  40. package/dist/scorers/llm/noise-sensitivity/index.d.ts +1 -1
  41. package/dist/scorers/llm/prompt-alignment/index.d.ts +5 -5
  42. package/dist/scorers/llm/tool-call-accuracy/index.d.ts +1 -1
  43. package/dist/scorers/llm/toxicity/index.d.ts +1 -1
  44. package/dist/scorers/llm/trajectory/index.d.ts +58 -0
  45. package/dist/scorers/llm/trajectory/index.d.ts.map +1 -0
  46. package/dist/scorers/llm/trajectory/prompts.d.ts +20 -0
  47. package/dist/scorers/llm/trajectory/prompts.d.ts.map +1 -0
  48. package/dist/scorers/prebuilt/index.cjs +638 -59
  49. package/dist/scorers/prebuilt/index.cjs.map +1 -1
  50. package/dist/scorers/prebuilt/index.js +578 -2
  51. package/dist/scorers/prebuilt/index.js.map +1 -1
  52. package/dist/scorers/utils.cjs +41 -17
  53. package/dist/scorers/utils.d.ts +171 -1
  54. package/dist/scorers/utils.d.ts.map +1 -1
  55. package/dist/scorers/utils.js +1 -1
  56. package/package.json +14 -11
  57. package/dist/chunk-OEOE7ZHN.js +0 -195
  58. package/dist/chunk-OEOE7ZHN.js.map +0 -1
  59. package/dist/chunk-W3U7MMDX.cjs +0 -212
  60. package/dist/chunk-W3U7MMDX.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scorers/utils.ts"],"names":["requestContext","RequestContext"],"mappings":"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","file":"chunk-XRUR5PBK.cjs","sourcesContent":["import type { MastraDBMessage } from '@mastra/core/agent';\nimport type {\n ExpectedStep,\n ScorerRunInputForAgent,\n ScorerRunOutputForAgent,\n ScoringInput,\n TrajectoryExpectation,\n TrajectoryStep,\n Trajectory,\n} from '@mastra/core/evals';\nimport { RequestContext } from '@mastra/core/request-context';\n\n/**\n * Extracts text content from a MastraDBMessage.\n *\n * This function matches the logic used in `MessageList.mastraDBMessageToAIV4UIMessage`.\n * It first checks for a string `content.content` field, then falls back to extracting\n * text from the `parts` array (returning only the last text part, like AI SDK does).\n *\n * @param message - The MastraDBMessage to extract text from\n * @returns The extracted text content, or an empty string if no text is found\n *\n * @example\n * ```ts\n * const message: MastraDBMessage = {\n * id: 'msg-1',\n * role: 'assistant',\n * content: { format: 2, parts: [{ type: 'text', text: 'Hello!' }] },\n * createdAt: new Date(),\n * };\n * const text = getTextContentFromMastraDBMessage(message); // 'Hello!'\n * ```\n */\nexport function getTextContentFromMastraDBMessage(message: MastraDBMessage): string {\n if (typeof message.content.content === 'string' && message.content.content !== '') {\n return message.content.content;\n }\n if (message.content.parts && Array.isArray(message.content.parts)) {\n // Return only the last text part like AI SDK does\n const textParts = message.content.parts.filter(p => p.type === 'text');\n return textParts.length > 0 ? textParts[textParts.length - 1]?.text || '' : '';\n }\n return '';\n}\n\n/**\n * Rounds a number to two decimal places.\n *\n * Uses `Number.EPSILON` to handle floating-point precision issues.\n *\n * @param num - The number to round\n * @returns The number rounded to two decimal places\n *\n * @example\n * ```ts\n * roundToTwoDecimals(0.1 + 0.2); // 0.3\n * roundToTwoDecimals(1.005); // 1.01\n * ```\n */\nexport const roundToTwoDecimals = (num: number) => {\n return Math.round((num + Number.EPSILON) * 100) / 100;\n};\n\n/**\n * Determines if a value is closer to the first target than the second.\n *\n * @param value - The value to compare\n * @param target1 - The first target value\n * @param target2 - The second target value\n * @returns `true` if `value` is closer to `target1` than `target2`\n *\n * @example\n * ```ts\n * isCloserTo(0.6, 1, 0); // true (0.6 is closer to 1)\n * isCloserTo(0.3, 1, 0); // false (0.3 is closer to 0)\n * ```\n */\nexport function isCloserTo(value: number, target1: number, target2: number): boolean {\n return Math.abs(value - target1) < Math.abs(value - target2);\n}\n\n/**\n * Represents a test case for scorer evaluation.\n */\nexport type TestCase = {\n /** The input text to evaluate */\n input: string;\n /** The output text to evaluate */\n output: string;\n /** The expected result of the evaluation */\n expectedResult: {\n /** The expected score */\n score: number;\n /** The optional expected reason */\n reason?: string;\n };\n};\n\n/**\n * Represents a test case with additional context for scorer evaluation.\n */\nexport type TestCaseWithContext = TestCase & {\n /** Additional context strings for the evaluation */\n context: string[];\n};\n\n/**\n * Creates a scoring input object for testing purposes.\n *\n * @param input - The user input text\n * @param output - The assistant output text\n * @param additionalContext - Optional additional context data\n * @param requestContext - Optional request context data\n * @returns A ScoringInput object ready for use in scorer tests\n *\n * @example\n * ```ts\n * const run = createTestRun(\n * 'What is 2+2?',\n * 'The answer is 4.',\n * { topic: 'math' }\n * );\n * ```\n */\nexport const createTestRun = (\n input: string,\n output: string,\n additionalContext?: Record<string, any>,\n requestContext?: Record<string, any>,\n): ScoringInput => {\n return {\n input: [{ role: 'user', content: input }],\n output: { role: 'assistant', text: output },\n additionalContext: additionalContext ?? {},\n requestContext: requestContext ?? {},\n };\n};\n\n/**\n * Extracts the user message text from a scorer run input.\n *\n * Finds the first message with role 'user' and extracts its text content.\n *\n * @param input - The scorer run input containing input messages\n * @returns The user message text, or `undefined` if no user message is found\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const userText = getUserMessageFromRunInput(run.input);\n * return { userText };\n * });\n * ```\n */\nexport const getUserMessageFromRunInput = (input?: ScorerRunInputForAgent): string | undefined => {\n const message = input?.inputMessages.find(({ role }) => role === 'user');\n return message ? getTextContentFromMastraDBMessage(message) : undefined;\n};\n\n/**\n * Extracts all system messages from a scorer run input.\n *\n * Collects text from both standard system messages and tagged system messages\n * (specialized system prompts like memory instructions).\n *\n * @param input - The scorer run input containing system messages\n * @returns An array of system message strings\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const systemMessages = getSystemMessagesFromRunInput(run.input);\n * return { systemPrompt: systemMessages.join('\\n') };\n * });\n * ```\n */\nexport const getSystemMessagesFromRunInput = (input?: ScorerRunInputForAgent): string[] => {\n const systemMessages: string[] = [];\n\n // Add standard system messages\n if (input?.systemMessages) {\n systemMessages.push(\n ...input.systemMessages\n .map(msg => {\n // Handle different content types - extract text if it's an array of parts\n if (typeof msg.content === 'string') {\n return msg.content;\n } else if (Array.isArray(msg.content)) {\n // Extract text from parts array\n return msg.content\n .filter((part: any) => part.type === 'text')\n .map((part: any) => part.text || '')\n .join(' ');\n }\n return '';\n })\n .filter(content => content),\n );\n }\n\n // Add tagged system messages (these are specialized system prompts)\n if (input?.taggedSystemMessages) {\n Object.values(input.taggedSystemMessages).forEach(messages => {\n messages.forEach(msg => {\n if (typeof msg.content === 'string') {\n systemMessages.push(msg.content);\n }\n });\n });\n }\n\n return systemMessages;\n};\n\n/**\n * Combines all system messages into a single prompt string.\n *\n * Joins all system messages (standard and tagged) with double newlines.\n *\n * @param input - The scorer run input containing system messages\n * @returns A combined system prompt string\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const systemPrompt = getCombinedSystemPrompt(run.input);\n * return { systemPrompt };\n * });\n * ```\n */\nexport const getCombinedSystemPrompt = (input?: ScorerRunInputForAgent): string => {\n const systemMessages = getSystemMessagesFromRunInput(input);\n return systemMessages.join('\\n\\n');\n};\n\n/**\n * Extracts the assistant message text from a scorer run output.\n *\n * Finds the first message with role 'assistant' and extracts its text content.\n *\n * @param output - The scorer run output (array of MastraDBMessage)\n * @returns The assistant message text, or `undefined` if no assistant message is found\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const response = getAssistantMessageFromRunOutput(run.output);\n * return { response };\n * });\n * ```\n */\nexport const getAssistantMessageFromRunOutput = (output?: ScorerRunOutputForAgent) => {\n const message = output?.find(({ role }) => role === 'assistant');\n return message ? getTextContentFromMastraDBMessage(message) : undefined;\n};\n\n/**\n * Extracts reasoning text from a scorer run output.\n *\n * This function extracts reasoning content from assistant messages, which is\n * produced by reasoning models like `deepseek-reasoner`. The reasoning can be\n * stored in two places:\n * 1. `content.reasoning` - a string field on the message content\n * 2. `content.parts` - as parts with `type: 'reasoning'` containing `details`\n *\n * @param output - The scorer run output (array of MastraDBMessage)\n * @returns The reasoning text, or `undefined` if no reasoning is present\n *\n * @example\n * ```ts\n * const reasoningScorer = createScorer({\n * id: 'reasoning-scorer',\n * name: 'Reasoning Quality',\n * description: 'Evaluates the quality of model reasoning',\n * type: 'agent',\n * })\n * .preprocess(({ run }) => {\n * const reasoning = getReasoningFromRunOutput(run.output);\n * const response = getAssistantMessageFromRunOutput(run.output);\n * return { reasoning, response };\n * })\n * .generateScore(({ results }) => {\n * // Score based on reasoning quality\n * return results.preprocessStepResult?.reasoning ? 1 : 0;\n * });\n * ```\n */\nexport const getReasoningFromRunOutput = (output?: ScorerRunOutputForAgent): string | undefined => {\n if (!output) return undefined;\n\n const message = output.find(({ role }) => role === 'assistant');\n if (!message) return undefined;\n\n // Check for reasoning in content.reasoning (string format)\n if (message.content.reasoning) {\n return message.content.reasoning;\n }\n\n // Check for reasoning in parts with type 'reasoning'\n // Reasoning models store reasoning in parts as { type: 'reasoning', details: [{ type: 'text', text: '...' }] }\n const reasoningParts = message.content.parts?.filter((p: any) => p.type === 'reasoning');\n if (reasoningParts && reasoningParts.length > 0) {\n const reasoningTexts = reasoningParts\n .map((p: any) => {\n // The reasoning text can be in p.reasoning or in p.details[].text\n if (p.details && Array.isArray(p.details)) {\n return p.details\n .filter((d: any) => d.type === 'text')\n .map((d: any) => d.text)\n .join('');\n }\n return p.reasoning || '';\n })\n .filter(Boolean);\n\n return reasoningTexts.length > 0 ? reasoningTexts.join('\\n') : undefined;\n }\n\n return undefined;\n};\n\n/**\n * Creates a tool invocation object for testing purposes.\n *\n * @param options - The tool invocation configuration\n * @param options.toolCallId - Unique identifier for the tool call\n * @param options.toolName - Name of the tool being called\n * @param options.args - Arguments passed to the tool\n * @param options.result - Result returned by the tool\n * @param options.state - State of the invocation (default: 'result')\n * @returns A tool invocation object\n *\n * @example\n * ```ts\n * const invocation = createToolInvocation({\n * toolCallId: 'call-123',\n * toolName: 'weatherTool',\n * args: { location: 'London' },\n * result: { temperature: 20, condition: 'sunny' },\n * });\n * ```\n */\nexport const createToolInvocation = ({\n toolCallId,\n toolName,\n args,\n result,\n state = 'result',\n}: {\n toolCallId: string;\n toolName: string;\n args: Record<string, any>;\n result: Record<string, any>;\n state?: 'call' | 'partial-call' | 'result';\n}): { toolCallId: string; toolName: string; args: Record<string, any>; result: Record<string, any>; state: string } => {\n return {\n toolCallId,\n toolName,\n args,\n result,\n state,\n };\n};\n\n/**\n * Creates a MastraDBMessage object for testing purposes.\n *\n * Supports optional tool invocations for testing tool call scenarios.\n *\n * @param options - The message configuration\n * @param options.content - The text content of the message\n * @param options.role - The role of the message sender ('user', 'assistant', or 'system')\n * @param options.id - Optional message ID (default: 'test-message')\n * @param options.toolInvocations - Optional array of tool invocations\n * @returns A MastraDBMessage object\n *\n * @example\n * ```ts\n * const message = createTestMessage({\n * content: 'Hello, how can I help?',\n * role: 'assistant',\n * });\n *\n * // With tool invocations\n * const messageWithTools = createTestMessage({\n * content: 'Let me check the weather.',\n * role: 'assistant',\n * toolInvocations: [{\n * toolCallId: 'call-1',\n * toolName: 'weatherTool',\n * args: { location: 'Paris' },\n * result: { temp: 22 },\n * state: 'result',\n * }],\n * });\n * ```\n */\nexport function createTestMessage({\n content,\n role,\n id = 'test-message',\n toolInvocations = [],\n}: {\n content: string;\n role: 'user' | 'assistant' | 'system';\n id?: string;\n toolInvocations?: Array<{\n toolCallId: string;\n toolName: string;\n args: Record<string, any>;\n result: Record<string, any>;\n state: any;\n }>;\n}): MastraDBMessage {\n return {\n id,\n role,\n content: {\n format: 2,\n parts: [{ type: 'text', text: content }],\n content,\n ...(toolInvocations.length > 0 && {\n toolInvocations: toolInvocations.map(ti => ({\n toolCallId: ti.toolCallId,\n toolName: ti.toolName,\n args: ti.args,\n result: ti.result,\n state: ti.state,\n })),\n }),\n },\n createdAt: new Date(),\n };\n}\n\n/**\n * Creates a complete agent test run object for testing scorers.\n *\n * Provides a convenient way to construct the full run object that scorers receive,\n * including input messages, output, system messages, and request context.\n *\n * @param options - The test run configuration\n * @param options.inputMessages - Array of input messages (default: [])\n * @param options.output - The output messages (required)\n * @param options.rememberedMessages - Array of remembered messages from memory (default: [])\n * @param options.systemMessages - Array of system messages (default: [])\n * @param options.taggedSystemMessages - Tagged system messages map (default: {})\n * @param options.requestContext - Request context (default: new RequestContext())\n * @param options.runId - Unique run ID (default: random UUID)\n * @returns A complete test run object\n *\n * @example\n * ```ts\n * const testRun = createAgentTestRun({\n * inputMessages: [createTestMessage({ content: 'Hello', role: 'user' })],\n * output: [createTestMessage({ content: 'Hi there!', role: 'assistant' })],\n * });\n *\n * const result = await scorer.run({\n * input: testRun.input,\n * output: testRun.output,\n * });\n * ```\n */\nexport const createAgentTestRun = ({\n inputMessages = [],\n output,\n rememberedMessages = [],\n systemMessages = [],\n taggedSystemMessages = {},\n requestContext = new RequestContext(),\n runId = crypto.randomUUID(),\n}: {\n inputMessages?: ScorerRunInputForAgent['inputMessages'];\n output: ScorerRunOutputForAgent;\n rememberedMessages?: ScorerRunInputForAgent['rememberedMessages'];\n systemMessages?: ScorerRunInputForAgent['systemMessages'];\n taggedSystemMessages?: ScorerRunInputForAgent['taggedSystemMessages'];\n requestContext?: RequestContext;\n runId?: string;\n}): {\n input: ScorerRunInputForAgent;\n output: ScorerRunOutputForAgent;\n requestContext: RequestContext;\n runId: string;\n} => {\n return {\n input: {\n inputMessages,\n rememberedMessages,\n systemMessages,\n taggedSystemMessages,\n },\n output,\n requestContext,\n runId,\n };\n};\n\n/**\n * Creates a test run for trajectory scorers where `output` is a `Trajectory`\n * (pre-extracted by the `runEvals` pipeline).\n *\n * @example\n * ```ts\n * const testRun = createTrajectoryTestRun({\n * inputMessages: [createTestMessage({ content: 'Do X', role: 'user', id: 'u1' })],\n * trajectory: {\n * steps: [\n * { stepType: 'tool_call', name: 'search', toolArgs: { q: 'test' } },\n * ],\n * },\n * });\n * ```\n */\nexport const createTrajectoryTestRun = ({\n inputMessages = [],\n trajectory,\n rememberedMessages = [],\n systemMessages = [],\n taggedSystemMessages = {},\n requestContext = new RequestContext(),\n runId = crypto.randomUUID(),\n expectedTrajectory,\n}: {\n inputMessages?: ScorerRunInputForAgent['inputMessages'];\n trajectory: Trajectory;\n rememberedMessages?: ScorerRunInputForAgent['rememberedMessages'];\n systemMessages?: ScorerRunInputForAgent['systemMessages'];\n taggedSystemMessages?: ScorerRunInputForAgent['taggedSystemMessages'];\n requestContext?: RequestContext;\n runId?: string;\n expectedTrajectory?: TrajectoryExpectation;\n}): {\n input: ScorerRunInputForAgent;\n output: Trajectory;\n requestContext: RequestContext;\n runId: string;\n expectedTrajectory?: TrajectoryExpectation;\n} => {\n return {\n input: {\n inputMessages,\n rememberedMessages,\n systemMessages,\n taggedSystemMessages,\n },\n output: trajectory,\n expectedTrajectory,\n requestContext,\n runId,\n };\n};\n\n/**\n * Information about a tool call extracted from scorer output.\n */\nexport type ToolCallInfo = {\n /** Name of the tool that was called */\n toolName: string;\n /** Unique identifier for the tool call */\n toolCallId: string;\n /** Index of the message containing this tool call */\n messageIndex: number;\n /** Index of the invocation within the message's tool invocations */\n invocationIndex: number;\n};\n\n/**\n * Extracts all tool calls from a scorer run output.\n *\n * Iterates through all messages and their tool invocations to collect\n * information about tools that were called (with state 'result' or 'call').\n *\n * @param output - The scorer run output (array of MastraDBMessage)\n * @returns An object containing tool names and detailed tool call info\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const { tools, toolCallInfos } = extractToolCalls(run.output);\n * return {\n * toolsUsed: tools,\n * toolCount: tools.length,\n * };\n * });\n * ```\n */\nexport function extractToolCalls(output: ScorerRunOutputForAgent): { tools: string[]; toolCallInfos: ToolCallInfo[] } {\n const toolCalls: string[] = [];\n const toolCallInfos: ToolCallInfo[] = [];\n\n for (let messageIndex = 0; messageIndex < output.length; messageIndex++) {\n const message = output[messageIndex];\n // Tool invocations are now nested under content\n if (message?.content?.toolInvocations) {\n for (let invocationIndex = 0; invocationIndex < message.content.toolInvocations.length; invocationIndex++) {\n const invocation = message.content.toolInvocations[invocationIndex];\n if (invocation && invocation.toolName && (invocation.state === 'result' || invocation.state === 'call')) {\n toolCalls.push(invocation.toolName);\n toolCallInfos.push({\n toolName: invocation.toolName,\n toolCallId: invocation.toolCallId || `${messageIndex}-${invocationIndex}`,\n messageIndex,\n invocationIndex,\n });\n }\n }\n }\n }\n\n return { tools: toolCalls, toolCallInfos };\n}\n\n/**\n * Extracts text content from all input messages.\n *\n * @param runInput - The scorer run input\n * @returns An array of text strings from each input message\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const messages = extractInputMessages(run.input);\n * return { allUserMessages: messages.join('\\n') };\n * });\n * ```\n */\nexport const extractInputMessages = (runInput: ScorerRunInputForAgent | undefined): string[] => {\n return runInput?.inputMessages?.map(msg => getTextContentFromMastraDBMessage(msg)) || [];\n};\n\n/**\n * Extracts text content from all assistant response messages.\n *\n * Filters for messages with role 'assistant' and extracts their text content.\n *\n * @param runOutput - The scorer run output (array of MastraDBMessage)\n * @returns An array of text strings from each assistant message\n *\n * @example\n * ```ts\n * const scorer = createScorer({ ... })\n * .preprocess(({ run }) => {\n * const responses = extractAgentResponseMessages(run.output);\n * return { allResponses: responses.join('\\n') };\n * });\n * ```\n */\nexport const extractAgentResponseMessages = (runOutput: ScorerRunOutputForAgent): string[] => {\n return runOutput.filter(msg => msg.role === 'assistant').map(msg => getTextContentFromMastraDBMessage(msg));\n};\n\n/**\n * Information about a tool result extracted from scorer output.\n */\nexport type ToolResultInfo = {\n /** Name of the tool that was called */\n toolName: string;\n /** Unique identifier for the tool call */\n toolCallId: string;\n /** Arguments passed to the tool */\n args: Record<string, any>;\n /** Result returned by the tool */\n result: any;\n};\n\n/**\n * Extracts tool results from a scorer run output.\n *\n * Returns structured objects that can be used with the hallucination scorer's\n * `getContext` hook or for other scorer logic.\n *\n * @param output - The scorer run output (array of MastraDBMessage)\n * @returns An array of ToolResultInfo objects\n *\n * @example\n * ```ts\n * import { extractToolResults } from '@mastra/evals/scorers';\n * import { createHallucinationScorer } from '@mastra/evals/scorers/prebuilt';\n *\n * const scorer = createHallucinationScorer({\n * model: openai('gpt-4o'),\n * options: {\n * getContext: (run) => {\n * const toolResults = extractToolResults(run.output);\n * return toolResults.map(t => JSON.stringify({ tool: t.toolName, result: t.result }));\n * },\n * },\n * });\n * ```\n */\nexport function extractToolResults(output: ScorerRunOutputForAgent): ToolResultInfo[] {\n const results: ToolResultInfo[] = [];\n\n for (const message of output) {\n const toolInvocations = message?.content?.toolInvocations;\n if (!toolInvocations) continue;\n\n for (const invocation of toolInvocations) {\n if (invocation.state === 'result' && invocation.result !== undefined) {\n results.push({\n toolName: invocation.toolName,\n toolCallId: invocation.toolCallId || '',\n args: invocation.args || {},\n result: invocation.result,\n });\n }\n }\n }\n\n return results;\n}\n\n// Re-export extractTrajectory from core — it's called automatically by runEvals\n// for trajectory scorers, but users may still want it for custom use cases.\nexport { extractTrajectory } from '@mastra/core/evals';\n\n/**\n * Compares two trajectories and returns detailed comparison results.\n *\n * This is the core comparison logic used by trajectory scorers. It supports\n * strict and non-strict ordering, optional step data comparison, and loop detection.\n *\n * @param actual - The trajectory the agent actually took\n * @param expected - The expected trajectory to compare against\n * @param options - Comparison configuration options\n * @returns Detailed comparison results including match scores and diagnostics\n *\n * @example\n * ```ts\n * const result = compareTrajectories(\n * { steps: [{ stepType: 'tool_call', name: 'search' }, { stepType: 'tool_call', name: 'summarize' }] },\n * { steps: [{ stepType: 'tool_call', name: 'search' }, { stepType: 'tool_call', name: 'summarize' }] },\n * { strictOrder: true }\n * );\n * // result.score = 1.0\n * ```\n */\nexport function compareTrajectories(\n actual: Trajectory,\n expected: Trajectory | { steps: ExpectedStep[] },\n options: {\n ordering?: 'strict' | 'relaxed' | 'unordered';\n /** @deprecated Use ordering: 'strict' instead */\n strictOrder?: boolean;\n compareStepData?: boolean;\n allowRepeatedSteps?: boolean;\n } = {},\n): TrajectoryComparisonResult {\n const { compareStepData = false, allowRepeatedSteps = true } = options;\n\n // Normalize expected to ExpectedStep[]. We need to distinguish between\n // Trajectory (containing TrajectoryStep[]) and { steps: ExpectedStep[] }.\n // TrajectoryStep variants have fields like toolArgs, toolResult, agentId, modelId, etc.\n // ExpectedStep has optional data, children (TrajectoryExpectation), and lacks those fields.\n const trajectoryStepKeys = [\n 'toolArgs',\n 'toolResult',\n 'agentId',\n 'modelId',\n 'durationMs',\n 'success',\n 'promptTokens',\n 'completionTokens',\n ];\n const hasTrajectorySteps =\n expected.steps.length > 0 && expected.steps.some((s: any) => trajectoryStepKeys.some(k => k in s));\n\n let normalizedExpected: { steps: ExpectedStep[] };\n if (hasTrajectorySteps) {\n // Convert TrajectoryStep[] to ExpectedStep[] by extracting step-specific data\n normalizedExpected = {\n steps: (expected.steps as TrajectoryStep[]).map((s: TrajectoryStep) => {\n const stepData = getStepData(s);\n const data: Record<string, unknown> = {};\n if (stepData.input !== undefined) data.input = stepData.input;\n if (stepData.output !== undefined) data.output = stepData.output;\n return {\n name: s.name,\n stepType: s.stepType,\n ...(Object.keys(data).length > 0 ? { data } : {}),\n } as ExpectedStep;\n }),\n };\n } else {\n // Already ExpectedStep[] — use as-is\n normalizedExpected = expected as { steps: ExpectedStep[] };\n }\n\n // Resolve ordering: new `ordering` option takes precedence over deprecated `strictOrder`\n let ordering: 'strict' | 'relaxed' | 'unordered' = 'relaxed';\n if (options.ordering) {\n ordering = options.ordering;\n } else if (options.strictOrder) {\n ordering = 'strict';\n }\n\n if (normalizedExpected.steps.length === 0) {\n return {\n score: actual.steps.length === 0 ? 1 : 0,\n matchedSteps: 0,\n totalExpectedSteps: 0,\n totalActualSteps: actual.steps.length,\n missingSteps: [],\n extraSteps: actual.steps.map((s: TrajectoryStep) => s.name),\n outOfOrderSteps: [],\n repeatedSteps: [],\n };\n }\n\n const actualNames = actual.steps.map((s: TrajectoryStep) => s.name);\n\n // Detect repeated steps\n const nameCounts = new Map<string, number>();\n for (const name of actualNames) {\n nameCounts.set(name, (nameCounts.get(name) || 0) + 1);\n }\n const repeatedSteps = [...nameCounts.entries()]\n .filter(([_, count]: [string, number]) => count > 1)\n .map(([name]: [string, number]) => name);\n\n if (ordering === 'strict') {\n return compareStrictOrder(actual, normalizedExpected, { compareStepData, allowRepeatedSteps, repeatedSteps });\n }\n\n if (ordering === 'unordered') {\n return compareUnorderedPresence(actual, normalizedExpected, {\n compareStepData,\n allowRepeatedSteps,\n repeatedSteps,\n });\n }\n\n return compareRelaxedOrder(actual, normalizedExpected, { compareStepData, allowRepeatedSteps, repeatedSteps });\n}\n\n/**\n * Result of comparing two trajectories.\n */\nexport type TrajectoryComparisonResult = {\n /** Overall match score from 0 to 1 */\n score: number;\n /** Number of expected steps that were matched */\n matchedSteps: number;\n /** Total number of expected steps */\n totalExpectedSteps: number;\n /** Total number of actual steps taken */\n totalActualSteps: number;\n /** Expected steps that were not found in the actual trajectory */\n missingSteps: string[];\n /** Actual steps that were not in the expected trajectory */\n extraSteps: string[];\n /** Steps that appear but not in the expected position */\n outOfOrderSteps: string[];\n /** Steps that were repeated (appeared more than once) */\n repeatedSteps: string[];\n};\n\nfunction compareStrictOrder(\n actual: Trajectory,\n expected: { steps: ExpectedStep[] },\n opts: { compareStepData: boolean; allowRepeatedSteps: boolean; repeatedSteps: string[] },\n): TrajectoryComparisonResult {\n const actualNames: string[] = actual.steps.map((s: TrajectoryStep) => s.name);\n const expectedNames: string[] = expected.steps.map((s: ExpectedStep) => s.name);\n\n // Strict: exact same sequence\n let matchedSteps = 0;\n const outOfOrderSteps: string[] = [];\n const matchedExpectedIndices = new Set<number>();\n const maxLen = Math.max(actualNames.length, expectedNames.length);\n\n for (let i = 0; i < maxLen; i++) {\n const actualName = actualNames[i];\n const expectedName = expectedNames[i];\n if (actualName === expectedName) {\n if (opts.compareStepData && actual.steps[i] && expected.steps[i]) {\n if (expectedStepMatches(actual.steps[i]!, expected.steps[i]!, true)) {\n matchedSteps++;\n matchedExpectedIndices.add(i);\n }\n } else if (actual.steps[i] && expected.steps[i]) {\n if (expectedStepMatches(actual.steps[i]!, expected.steps[i]!, false)) {\n matchedSteps++;\n matchedExpectedIndices.add(i);\n }\n } else {\n matchedSteps++;\n matchedExpectedIndices.add(i);\n }\n } else if (actualName && expectedNames.includes(actualName)) {\n outOfOrderSteps.push(actualName);\n }\n }\n\n // Missing steps = expected steps that were not matched (accounts for stepType/data mismatches)\n const missingSteps: string[] = expectedNames.filter((_: string, i: number) => !matchedExpectedIndices.has(i));\n const extraSteps: string[] = actualNames.filter((name: string) => !expectedNames.includes(name));\n\n let score = matchedSteps / expected.steps.length;\n\n // Penalize extra steps in strict mode\n if (actualNames.length > expectedNames.length) {\n const extraPenalty = (actualNames.length - expectedNames.length) / expectedNames.length;\n score = Math.max(0, score - extraPenalty * 0.5);\n }\n\n // Penalize repeated steps if not allowed\n if (!opts.allowRepeatedSteps && opts.repeatedSteps.length > 0) {\n score = Math.max(0, score - opts.repeatedSteps.length * 0.1);\n }\n\n return {\n score: roundToTwoDecimals(Math.max(0, Math.min(1, score))),\n matchedSteps,\n totalExpectedSteps: expected.steps.length,\n totalActualSteps: actual.steps.length,\n missingSteps,\n extraSteps,\n outOfOrderSteps,\n repeatedSteps: opts.repeatedSteps,\n };\n}\n\nfunction compareRelaxedOrder(\n actual: Trajectory,\n expected: { steps: ExpectedStep[] },\n opts: { compareStepData: boolean; allowRepeatedSteps: boolean; repeatedSteps: string[] },\n): TrajectoryComparisonResult {\n const actualNames: string[] = actual.steps.map((s: TrajectoryStep) => s.name);\n const expectedNames: string[] = expected.steps.map((s: ExpectedStep) => s.name);\n\n // Relaxed: expected steps must appear in order but extra steps are allowed\n let matchedSteps = 0;\n let lastMatchedIndex = -1;\n const outOfOrderSteps: string[] = [];\n const matchedExpectedIndices = new Set<number>();\n\n for (let i = 0; i < expectedNames.length; i++) {\n const expectedName = expectedNames[i];\n let found = false;\n\n for (let j = lastMatchedIndex + 1; j < actualNames.length; j++) {\n if (actualNames[j] === expectedName) {\n if (actual.steps[j] && expected.steps[i]) {\n if (expectedStepMatches(actual.steps[j]!, expected.steps[i]!, opts.compareStepData)) {\n matchedSteps++;\n lastMatchedIndex = j;\n matchedExpectedIndices.add(i);\n found = true;\n break;\n }\n } else {\n matchedSteps++;\n lastMatchedIndex = j;\n matchedExpectedIndices.add(i);\n found = true;\n break;\n }\n }\n }\n\n if (!found) {\n // Check if the step exists but is out of order\n if (actualNames.includes(expectedName!)) {\n outOfOrderSteps.push(expectedName!);\n }\n }\n }\n\n // Missing steps = expected steps that were not matched (by name + stepType + data, not just name)\n const missingSteps = expectedNames.filter((_, i) => !matchedExpectedIndices.has(i));\n const expectedSet = new Set(expectedNames);\n const extraSteps = actualNames.filter(name => !expectedSet.has(name));\n\n let score = matchedSteps / expected.steps.length;\n\n // Penalize repeated steps if not allowed\n if (!opts.allowRepeatedSteps && opts.repeatedSteps.length > 0) {\n score = Math.max(0, score - opts.repeatedSteps.length * 0.1);\n }\n\n return {\n score: roundToTwoDecimals(Math.max(0, Math.min(1, score))),\n matchedSteps,\n totalExpectedSteps: expected.steps.length,\n totalActualSteps: actual.steps.length,\n missingSteps,\n extraSteps,\n outOfOrderSteps,\n repeatedSteps: opts.repeatedSteps,\n };\n}\n\n/**\n * Extract the data fields from a step for comparison purposes.\n * Returns an object with `input` and `output` fields based on the step type.\n */\nfunction getStepData(step: TrajectoryStep): { input?: unknown; output?: unknown } {\n switch (step.stepType) {\n case 'tool_call':\n case 'mcp_tool_call':\n return { input: step.toolArgs, output: step.toolResult };\n case 'workflow_step':\n return { output: step.output };\n default:\n return {};\n }\n}\n\n/**\n * Check if an actual TrajectoryStep matches an ExpectedStep.\n * Matches by name, optionally by stepType, and optionally by data fields.\n */\nfunction expectedStepMatches(actual: TrajectoryStep, expected: ExpectedStep, compareData: boolean): boolean {\n if (actual.name !== expected.name) return false;\n if (expected.stepType && actual.stepType !== expected.stepType) return false;\n\n if (compareData && expected.data) {\n const actualData = getStepData(actual);\n for (const [key, value] of Object.entries(expected.data)) {\n const actualField = key === 'input' ? actualData.input : key === 'output' ? actualData.output : undefined;\n if (actualField === undefined) return false;\n try {\n if (JSON.stringify(actualField) !== JSON.stringify(value)) return false;\n } catch {\n return false;\n }\n }\n }\n\n return true;\n}\n\nfunction compareUnorderedPresence(\n actual: Trajectory,\n expected: { steps: ExpectedStep[] },\n opts: { compareStepData: boolean; allowRepeatedSteps: boolean; repeatedSteps: string[] },\n): TrajectoryComparisonResult {\n const actualNames: string[] = actual.steps.map((s: TrajectoryStep) => s.name);\n const expectedNames: string[] = expected.steps.map((s: ExpectedStep) => s.name);\n\n let matchedSteps = 0;\n const matchedExpectedIndices = new Set<number>();\n\n if (opts.compareStepData) {\n // For data comparison, try to match each expected step to an unused actual step\n const usedIndices = new Set<number>();\n for (let i = 0; i < expected.steps.length; i++) {\n const expectedStep = expected.steps[i]!;\n for (let j = 0; j < actual.steps.length; j++) {\n if (!usedIndices.has(j) && expectedStepMatches(actual.steps[j]!, expectedStep, true)) {\n matchedSteps++;\n matchedExpectedIndices.add(i);\n usedIndices.add(j);\n break;\n }\n }\n }\n } else {\n // Name + stepType based presence check using expectedStepMatches\n const usedIndices = new Set<number>();\n for (let i = 0; i < expected.steps.length; i++) {\n const expectedStep = expected.steps[i]!;\n for (let j = 0; j < actual.steps.length; j++) {\n if (!usedIndices.has(j) && expectedStepMatches(actual.steps[j]!, expectedStep, false)) {\n matchedSteps++;\n matchedExpectedIndices.add(i);\n usedIndices.add(j);\n break;\n }\n }\n }\n }\n\n // Missing steps = expected steps that were not matched (accounts for stepType/data mismatches)\n const missingSteps = expectedNames.filter((_, i) => !matchedExpectedIndices.has(i));\n const expectedSet = new Set(expectedNames);\n const extraSteps = actualNames.filter(name => !expectedSet.has(name));\n\n let score = matchedSteps / expected.steps.length;\n\n // Penalize repeated steps if not allowed\n if (!opts.allowRepeatedSteps && opts.repeatedSteps.length > 0) {\n score = Math.max(0, score - opts.repeatedSteps.length * 0.1);\n }\n\n return {\n score: roundToTwoDecimals(Math.max(0, Math.min(1, score))),\n matchedSteps,\n totalExpectedSteps: expected.steps.length,\n totalActualSteps: actual.steps.length,\n missingSteps,\n extraSteps,\n outOfOrderSteps: [], // ordering not checked in unordered mode\n repeatedSteps: opts.repeatedSteps,\n };\n}\n\n// ─── Efficiency evaluation ───\n\n/**\n * Result of checking trajectory efficiency.\n */\nexport type TrajectoryEfficiencyResult = {\n /** Overall efficiency score from 0 to 1 */\n score: number;\n /** Total number of steps taken */\n totalSteps: number;\n /** Whether the step budget was exceeded */\n overStepBudget: boolean;\n /** Total tokens used across model_generation steps */\n totalTokens: number;\n /** Whether the token budget was exceeded */\n overTokenBudget: boolean;\n /** Total duration in milliseconds */\n totalDurationMs: number;\n /** Whether the duration budget was exceeded */\n overDurationBudget: boolean;\n /** Redundant calls detected (same tool + same args consecutively) */\n redundantCalls: Array<{ name: string; index: number }>;\n};\n\n/**\n * Evaluate trajectory efficiency against budgets and redundancy checks.\n */\nexport function checkTrajectoryEfficiency(\n trajectory: Trajectory,\n options: {\n maxSteps?: number;\n maxTotalTokens?: number;\n maxTotalDurationMs?: number;\n noRedundantCalls?: boolean;\n } = {},\n): TrajectoryEfficiencyResult {\n const { maxSteps, maxTotalTokens, maxTotalDurationMs, noRedundantCalls = true } = options;\n\n const totalSteps = trajectory.steps.length;\n\n // Calculate total tokens from model_generation steps\n let totalTokens = 0;\n for (const step of trajectory.steps) {\n if (step.stepType === 'model_generation') {\n totalTokens += (step.promptTokens ?? 0) + (step.completionTokens ?? 0);\n }\n }\n\n // Calculate total duration\n const totalDurationMs =\n trajectory.totalDurationMs ?? trajectory.steps.reduce((sum, s) => sum + (s.durationMs ?? 0), 0);\n\n // Detect redundant calls (same tool name + same args in consecutive calls)\n const redundantCalls: Array<{ name: string; index: number }> = [];\n if (noRedundantCalls) {\n for (let i = 1; i < trajectory.steps.length; i++) {\n const prev = trajectory.steps[i - 1]!;\n const curr = trajectory.steps[i]!;\n if (\n prev.name === curr.name &&\n prev.stepType === curr.stepType &&\n (prev.stepType === 'tool_call' || prev.stepType === 'mcp_tool_call')\n ) {\n const prevArgs = (prev as TrajectoryStep & { toolArgs?: Record<string, unknown> }).toolArgs;\n const currArgs = (curr as TrajectoryStep & { toolArgs?: Record<string, unknown> }).toolArgs;\n try {\n if (JSON.stringify(prevArgs) === JSON.stringify(currArgs)) {\n redundantCalls.push({ name: curr.name, index: i });\n }\n } catch {\n // If serialization fails, don't flag as redundant\n }\n }\n }\n }\n\n const overStepBudget = maxSteps !== undefined && totalSteps > maxSteps;\n const overTokenBudget = maxTotalTokens !== undefined && totalTokens > maxTotalTokens;\n const overDurationBudget = maxTotalDurationMs !== undefined && totalDurationMs > maxTotalDurationMs;\n\n // Calculate score: each dimension contributes equally\n const dimensions: number[] = [];\n\n if (maxSteps !== undefined) {\n dimensions.push(overStepBudget ? Math.max(0, 1 - (totalSteps - maxSteps) / maxSteps) : 1);\n }\n if (maxTotalTokens !== undefined) {\n dimensions.push(overTokenBudget ? Math.max(0, 1 - (totalTokens - maxTotalTokens) / maxTotalTokens) : 1);\n }\n if (maxTotalDurationMs !== undefined) {\n dimensions.push(\n overDurationBudget ? Math.max(0, 1 - (totalDurationMs - maxTotalDurationMs) / maxTotalDurationMs) : 1,\n );\n }\n if (noRedundantCalls) {\n dimensions.push(redundantCalls.length === 0 ? 1 : Math.max(0, 1 - redundantCalls.length * 0.2));\n }\n\n const score = dimensions.length > 0 ? dimensions.reduce((a, b) => a + b, 0) / dimensions.length : 1;\n\n return {\n score: roundToTwoDecimals(Math.max(0, Math.min(1, score))),\n totalSteps,\n overStepBudget,\n totalTokens,\n overTokenBudget,\n totalDurationMs,\n overDurationBudget,\n redundantCalls,\n };\n}\n\n// ─── Blacklist evaluation ───\n\n/**\n * Result of checking trajectory against a blacklist.\n */\nexport type TrajectoryBlacklistResult = {\n /** Score: 1.0 if clean, 0.0 if any violation found */\n score: number;\n /** Individual blacklisted tools that were found */\n violatedTools: string[];\n /** Blacklisted sequences that were found */\n violatedSequences: string[][];\n};\n\n/**\n * Check if a trajectory violates any blacklist rules.\n * Returns score 0.0 if any violation is found (hard fail).\n */\nexport function checkTrajectoryBlacklist(\n trajectory: Trajectory,\n options: {\n blacklistedTools?: string[];\n blacklistedSequences?: string[][];\n } = {},\n): TrajectoryBlacklistResult {\n const { blacklistedTools = [], blacklistedSequences = [] } = options;\n const violatedTools: string[] = [];\n const violatedSequences: string[][] = [];\n\n const stepNames = trajectory.steps.map(s => s.name);\n\n // Check blacklisted tools\n for (const forbidden of blacklistedTools) {\n if (stepNames.includes(forbidden)) {\n violatedTools.push(forbidden);\n }\n }\n\n // Check blacklisted sequences (contiguous subsequences)\n for (const sequence of blacklistedSequences) {\n if (sequence.length === 0) continue;\n for (let i = 0; i <= stepNames.length - sequence.length; i++) {\n let match = true;\n for (let j = 0; j < sequence.length; j++) {\n if (stepNames[i + j] !== sequence[j]) {\n match = false;\n break;\n }\n }\n if (match) {\n violatedSequences.push(sequence);\n break; // Only report each sequence once\n }\n }\n }\n\n const hasViolations = violatedTools.length > 0 || violatedSequences.length > 0;\n\n return {\n score: hasViolations ? 0 : 1,\n violatedTools,\n violatedSequences,\n };\n}\n\n// ─── Tool failure analysis ───\n\n/**\n * A detected tool failure pattern in the trajectory.\n */\nexport type ToolFailurePattern = {\n /** The tool name that experienced failure */\n toolName: string;\n /** Number of consecutive retries (same tool, same or similar args) */\n retryCount: number;\n /** Whether the agent fell back to a different tool after failures */\n fellBackToAlternative: boolean;\n /** The alternative tool used, if any */\n alternativeTool?: string;\n /** Whether any retry eventually succeeded */\n eventuallySucceeded: boolean;\n};\n\n/**\n * Result of analyzing tool failure patterns in a trajectory.\n */\nexport type ToolFailureAnalysisResult = {\n /** Score from 0 to 1 (lower = more failures/retries) */\n score: number;\n /** Tool failure patterns detected */\n patterns: ToolFailurePattern[];\n /** Total number of retries across all tools */\n totalRetries: number;\n /** Tools that exceeded the retry threshold */\n excessiveRetryTools: string[];\n};\n\n/**\n * Analyze tool failure and retry patterns in a trajectory.\n */\nexport function analyzeToolFailures(\n trajectory: Trajectory,\n options: {\n maxRetriesPerTool?: number;\n } = {},\n): ToolFailureAnalysisResult {\n const { maxRetriesPerTool = 2 } = options;\n const patterns: ToolFailurePattern[] = [];\n let totalRetries = 0;\n\n const toolCallSteps = trajectory.steps.filter(s => s.stepType === 'tool_call' || s.stepType === 'mcp_tool_call');\n\n if (toolCallSteps.length === 0) {\n return { score: 1, patterns: [], totalRetries: 0, excessiveRetryTools: [] };\n }\n\n // Group consecutive calls to the same tool as potential retry sequences\n let i = 0;\n while (i < toolCallSteps.length) {\n const currentTool = toolCallSteps[i]!;\n let retryCount = 0;\n let j = i + 1;\n\n // Count consecutive calls to the same tool\n // (toolCallSteps is pre-filtered to tool_call/mcp_tool_call, so no stepType checks needed)\n while (j < toolCallSteps.length && toolCallSteps[j]!.name === currentTool.name) {\n const prevStep = toolCallSteps[j - 1]! as TrajectoryStep & { success?: boolean };\n if (prevStep.success === false) {\n retryCount++;\n }\n j++;\n }\n\n if (retryCount > 0) {\n // Check if agent fell back to a different tool after retries\n const nextDifferentTool = j < toolCallSteps.length ? toolCallSteps[j] : undefined;\n const lastRetry = toolCallSteps[j - 1]! as TrajectoryStep & { success?: boolean };\n const lastSuccess = lastRetry.success !== false;\n\n patterns.push({\n toolName: currentTool.name,\n retryCount,\n fellBackToAlternative: nextDifferentTool !== undefined && !lastSuccess,\n alternativeTool: nextDifferentTool !== undefined && !lastSuccess ? nextDifferentTool.name : undefined,\n eventuallySucceeded: lastSuccess,\n });\n\n totalRetries += retryCount;\n }\n\n i = j;\n }\n\n // Score: penalize excessive retries\n const excessiveRetryTools = patterns.filter(p => p.retryCount > maxRetriesPerTool).map(p => p.toolName);\n\n let score = 1;\n if (toolCallSteps.length > 0) {\n // Each retry beyond the threshold costs more\n const excessRetries = patterns.reduce((sum, p) => sum + Math.max(0, p.retryCount - maxRetriesPerTool), 0);\n score = Math.max(0, 1 - excessRetries * 0.2);\n }\n\n return {\n score: roundToTwoDecimals(Math.max(0, Math.min(1, score))),\n patterns,\n totalRetries,\n excessiveRetryTools,\n };\n}\n"]}
@@ -3,7 +3,7 @@ name: mastra-evals
3
3
  description: Documentation for @mastra/evals. Use when working with @mastra/evals APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/evals"
6
- version: "1.1.2"
6
+ version: "1.2.0-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -16,28 +16,29 @@ Read the individual reference documents for detailed explanations and code examp
16
16
 
17
17
  ### Docs
18
18
 
19
- - [Built-in Scorers](references/docs-evals-built-in-scorers.md) - Overview of Mastra's ready-to-use scorers for evaluating AI outputs across quality, safety, and performance dimensions.
19
+ - [Built-in scorers](references/docs-evals-built-in-scorers.md) - Overview of Mastra's ready-to-use scorers for evaluating AI outputs across quality, safety, and performance dimensions.
20
20
  - [Scorers overview](references/docs-evals-overview.md) - Overview of scorers in Mastra, detailing their capabilities for evaluating AI outputs and measuring performance.
21
21
 
22
22
  ### Reference
23
23
 
24
- - [Reference: Answer Relevancy Scorer](references/reference-evals-answer-relevancy.md) - Documentation for the Answer Relevancy Scorer in Mastra, which evaluates how well LLM outputs address the input query.
25
- - [Reference: Answer Similarity Scorer](references/reference-evals-answer-similarity.md) - Documentation for the Answer Similarity Scorer in Mastra, which compares agent outputs against ground truth answers for CI/CD testing.
26
- - [Reference: Bias Scorer](references/reference-evals-bias.md) - Documentation for the Bias Scorer in Mastra, which evaluates LLM outputs for various forms of bias, including gender, political, racial/ethnic, or geographical bias.
27
- - [Reference: Completeness Scorer](references/reference-evals-completeness.md) - Documentation for the Completeness Scorer in Mastra, which evaluates how thoroughly LLM outputs cover key elements present in the input.
28
- - [Reference: Content Similarity Scorer](references/reference-evals-content-similarity.md) - Documentation for the Content Similarity Scorer in Mastra, which measures textual similarity between strings and provides a matching score.
29
- - [Reference: Context Precision Scorer](references/reference-evals-context-precision.md) - Documentation for the Context Precision Scorer in Mastra. Evaluates the relevance and precision of retrieved context for generating expected outputs using Mean Average Precision.
30
- - [Reference: Context Relevance Scorer](references/reference-evals-context-relevance.md) - Documentation for the Context Relevance Scorer in Mastra. Evaluates the relevance and utility of provided context for generating agent responses using weighted relevance scoring.
31
- - [Reference: Faithfulness Scorer](references/reference-evals-faithfulness.md) - Documentation for the Faithfulness Scorer in Mastra, which evaluates the factual accuracy of LLM outputs compared to the provided context.
32
- - [Reference: Hallucination Scorer](references/reference-evals-hallucination.md) - Documentation for the Hallucination Scorer in Mastra, which evaluates the factual correctness of LLM outputs by identifying contradictions with provided context.
33
- - [Reference: Keyword Coverage Scorer](references/reference-evals-keyword-coverage.md) - Documentation for the Keyword Coverage Scorer in Mastra, which evaluates how well LLM outputs cover important keywords from the input.
34
- - [Reference: Noise Sensitivity Scorer](references/reference-evals-noise-sensitivity.md) - Documentation for the Noise Sensitivity Scorer in Mastra. A CI/testing scorer that evaluates agent robustness by comparing responses between clean and noisy inputs in controlled test environments.
35
- - [Reference: Prompt Alignment Scorer](references/reference-evals-prompt-alignment.md) - Documentation for the Prompt Alignment Scorer in Mastra. Evaluates how well agent responses align with user prompt intent, requirements, completeness, and appropriateness using multi-dimensional analysis.
36
- - [Reference: Scorer Utils](references/reference-evals-scorer-utils.md) - Utility functions for extracting data from scorer run inputs and outputs, including text content, reasoning, system messages, and tool calls.
37
- - [Reference: Textual Difference Scorer](references/reference-evals-textual-difference.md) - Documentation for the Textual Difference Scorer in Mastra, which measures textual differences between strings using sequence matching.
38
- - [Reference: Tone Consistency Scorer](references/reference-evals-tone-consistency.md) - Documentation for the Tone Consistency Scorer in Mastra, which evaluates emotional tone and sentiment consistency in text.
39
- - [Reference: Tool Call Accuracy Scorers](references/reference-evals-tool-call-accuracy.md) - Documentation for the Tool Call Accuracy Scorers in Mastra, which evaluate whether LLM outputs call the correct tools from available options.
40
- - [Reference: Toxicity Scorer](references/reference-evals-toxicity.md) - Documentation for the Toxicity Scorer in Mastra, which evaluates LLM outputs for racist, biased, or toxic elements.
24
+ - [Reference: Answer relevancy scorer](references/reference-evals-answer-relevancy.md) - Documentation for the Answer Relevancy Scorer in Mastra, which evaluates how well LLM outputs address the input query.
25
+ - [Reference: Answer similarity scorer](references/reference-evals-answer-similarity.md) - Documentation for the Answer Similarity Scorer in Mastra, which compares agent outputs against ground truth answers for CI/CD testing.
26
+ - [Reference: Bias scorer](references/reference-evals-bias.md) - Documentation for the Bias Scorer in Mastra, which evaluates LLM outputs for various forms of bias, including gender, political, racial/ethnic, or geographical bias.
27
+ - [Reference: Completeness scorer](references/reference-evals-completeness.md) - Documentation for the Completeness Scorer in Mastra, which evaluates how thoroughly LLM outputs cover key elements present in the input.
28
+ - [Reference: Content similarity scorer](references/reference-evals-content-similarity.md) - Documentation for the Content Similarity Scorer in Mastra, which measures textual similarity between strings and provides a matching score.
29
+ - [Reference: Context precision scorer](references/reference-evals-context-precision.md) - Documentation for the Context Precision Scorer in Mastra. Evaluates the relevance and precision of retrieved context for generating expected outputs using Mean Average Precision.
30
+ - [Reference: Context relevance scorer](references/reference-evals-context-relevance.md) - Documentation for the Context Relevance Scorer in Mastra. Evaluates the relevance and utility of provided context for generating agent responses using weighted relevance scoring.
31
+ - [Reference: Faithfulness scorer](references/reference-evals-faithfulness.md) - Documentation for the Faithfulness Scorer in Mastra, which evaluates the factual accuracy of LLM outputs compared to the provided context.
32
+ - [Reference: Hallucination scorer](references/reference-evals-hallucination.md) - Documentation for the Hallucination Scorer in Mastra, which evaluates the factual correctness of LLM outputs by identifying contradictions with provided context.
33
+ - [Reference: Keyword coverage scorer](references/reference-evals-keyword-coverage.md) - Documentation for the Keyword Coverage Scorer in Mastra, which evaluates how well LLM outputs cover important keywords from the input.
34
+ - [Reference: Noise sensitivity scorer](references/reference-evals-noise-sensitivity.md) - Documentation for the Noise Sensitivity Scorer in Mastra. A CI/testing scorer that evaluates agent robustness by comparing responses between clean and noisy inputs in controlled test environments.
35
+ - [Reference: Prompt alignment scorer](references/reference-evals-prompt-alignment.md) - Documentation for the Prompt Alignment Scorer in Mastra. Evaluates how well agent responses align with user prompt intent, requirements, completeness, and appropriateness using multi-dimensional analysis.
36
+ - [Reference: Scorer utils](references/reference-evals-scorer-utils.md) - Utility functions for extracting data from scorer run inputs and outputs, including text content, reasoning, system messages, and tool calls.
37
+ - [Reference: Textual difference scorer](references/reference-evals-textual-difference.md) - Documentation for the Textual Difference Scorer in Mastra, which measures textual differences between strings using sequence matching.
38
+ - [Reference: Tone consistency scorer](references/reference-evals-tone-consistency.md) - Documentation for the Tone Consistency Scorer in Mastra, which evaluates emotional tone and sentiment consistency in text.
39
+ - [Reference: Tool call accuracy scorers](references/reference-evals-tool-call-accuracy.md) - Documentation for the Tool Call Accuracy Scorers in Mastra, which evaluate whether LLM outputs call the correct tools from available options.
40
+ - [Reference: Toxicity scorer](references/reference-evals-toxicity.md) - Documentation for the Toxicity Scorer in Mastra, which evaluates LLM outputs for racist, biased, or toxic elements.
41
+ - [Reference: Trajectory accuracy scorers](references/reference-evals-trajectory-accuracy.md) - Documentation for the Trajectory Accuracy Scorers in Mastra, which evaluate whether an agent or workflow follows the expected sequence of actions.
41
42
 
42
43
 
43
44
  Read [assets/SOURCE_MAP.json](assets/SOURCE_MAP.json) for source code references.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.2",
2
+ "version": "1.2.0-alpha.0",
3
3
  "package": "@mastra/evals",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -1,4 +1,4 @@
1
- # Built-in Scorers
1
+ # Built-in scorers
2
2
 
3
3
  Mastra provides a comprehensive set of built-in scorers for evaluating AI outputs. These scorers are optimized for common evaluation scenarios and are ready to use in your agents and workflows.
4
4
 
@@ -18,6 +18,7 @@ These scorers evaluate how correct, truthful, and complete your agent's answers
18
18
  - [`content-similarity`](https://mastra.ai/reference/evals/content-similarity): Measures textual similarity using character-level matching (`0-1`, higher is better)
19
19
  - [`textual-difference`](https://mastra.ai/reference/evals/textual-difference): Measures textual differences between strings (`0-1`, higher means more similar)
20
20
  - [`tool-call-accuracy`](https://mastra.ai/reference/evals/tool-call-accuracy): Evaluates whether the LLM selects the correct tool from available options (`0-1`, higher is better)
21
+ - [`trajectory-accuracy`](https://mastra.ai/reference/evals/trajectory-accuracy): Evaluates whether an agent follows the expected sequence of actions (tool calls, model generations, workflow steps, and other span types) (`0-1`, higher is better)
21
22
  - [`prompt-alignment`](https://mastra.ai/reference/evals/prompt-alignment): Measures how well agent responses align with user prompt intent, requirements, completeness, and format (`0-1`, higher is better)
22
23
 
23
24
  ### Context quality
@@ -6,9 +6,9 @@ Scorers are automated tests that evaluate Agents outputs using model-graded, rul
6
6
 
7
7
  Scorers can be run in the cloud, capturing real-time results. But scorers can also be part of your CI/CD pipeline, allowing you to test and monitor your agents over time.
8
8
 
9
- ## Types of Scorers
9
+ ## Types of scorers
10
10
 
11
- There are different kinds of scorers, each serving a specific purpose. Here are some common types:
11
+ Mastra provides different kinds of scorers, each serving a specific purpose. Here are some common types:
12
12
 
13
13
  1. **Textual Scorers**: Evaluate accuracy, reliability, and context understanding of agent responses
14
14
  2. **Classification Scorers**: Measure accuracy in categorizing data based on predefined categories
@@ -51,24 +51,21 @@ bun add @mastra/evals@latest
51
51
  You can add built-in scorers to your agents to automatically evaluate their outputs. See the [full list of built-in scorers](https://mastra.ai/docs/evals/built-in-scorers) for all available options.
52
52
 
53
53
  ```typescript
54
- import { Agent } from "@mastra/core/agent";
55
- import {
56
- createAnswerRelevancyScorer,
57
- createToxicityScorer,
58
- } from "@mastra/evals/scorers/prebuilt";
54
+ import { Agent } from '@mastra/core/agent'
55
+ import { createAnswerRelevancyScorer, createToxicityScorer } from '@mastra/evals/scorers/prebuilt'
59
56
 
60
57
  export const evaluatedAgent = new Agent({
61
58
  scorers: {
62
59
  relevancy: {
63
- scorer: createAnswerRelevancyScorer({ model: "openai/gpt-4.1-nano" }),
64
- sampling: { type: "ratio", rate: 0.5 },
60
+ scorer: createAnswerRelevancyScorer({ model: 'openai/gpt-5-mini' }),
61
+ sampling: { type: 'ratio', rate: 0.5 },
65
62
  },
66
63
  safety: {
67
- scorer: createToxicityScorer({ model: "openai/gpt-4.1-nano" }),
68
- sampling: { type: "ratio", rate: 1 },
64
+ scorer: createToxicityScorer({ model: 'openai/gpt-5-mini' }),
65
+ sampling: { type: 'ratio', rate: 1 },
69
66
  },
70
67
  },
71
- });
68
+ })
72
69
  ```
73
70
 
74
71
  ### Adding scorers to workflow steps
@@ -114,9 +111,7 @@ export const contentWorkflow = createWorkflow({ ... })
114
111
 
115
112
  In addition to live evaluations, you can use scorers to evaluate historical traces from your agent interactions and workflows. This is particularly useful for analyzing past performance, debugging issues, or running batch evaluations.
116
113
 
117
- > **Info:** **Observability Required**
118
- >
119
- > To score traces, you must first configure observability in your Mastra instance to collect trace data. See [Tracing documentation](https://mastra.ai/docs/observability/tracing/overview) for setup instructions.
114
+ > **Observability Required:** To score traces, you must first configure observability in your Mastra instance to collect trace data. See [Tracing documentation](https://mastra.ai/docs/observability/tracing/overview) for setup instructions.
120
115
 
121
116
  ### Scoring traces with Studio
122
117
 
@@ -128,7 +123,7 @@ const mastra = new Mastra({
128
123
  answerRelevancy: myAnswerRelevancyScorer,
129
124
  responseQuality: myResponseQualityScorer,
130
125
  },
131
- });
126
+ })
132
127
  ```
133
128
 
134
129
  Once registered, you can score traces interactively within Studio under the Observability section. This provides a user-friendly interface for running scorers against historical traces.
@@ -1,36 +1,36 @@
1
- # Answer Relevancy Scorer
1
+ # Answer relevancy scorer
2
2
 
3
3
  The `createAnswerRelevancyScorer()` function accepts a single options object with the following properties:
4
4
 
5
5
  ## Parameters
6
6
 
7
- **model:** (`LanguageModel`): Configuration for the model used to evaluate relevancy.
7
+ **model** (`LanguageModel`): Configuration for the model used to evaluate relevancy.
8
8
 
9
- **uncertaintyWeight:** (`number`): Weight given to 'unsure' verdicts in scoring (0-1). (Default: `0.3`)
9
+ **uncertaintyWeight** (`number`): Weight given to 'unsure' verdicts in scoring (0-1). (Default: `0.3`)
10
10
 
11
- **scale:** (`number`): Maximum score value. (Default: `1`)
11
+ **scale** (`number`): Maximum score value. (Default: `1`)
12
12
 
13
13
  This function returns an instance of the MastraScorer class. The `.run()` method accepts the same input as other scorers (see the [MastraScorer reference](https://mastra.ai/reference/evals/mastra-scorer)), but the return value includes LLM-specific fields as documented below.
14
14
 
15
- ## .run() Returns
15
+ ## `.run()` returns
16
16
 
17
- **runId:** (`string`): The id of the run (optional).
17
+ **runId** (`string`): The id of the run (optional).
18
18
 
19
- **score:** (`number`): Relevancy score (0 to scale, default 0-1)
19
+ **score** (`number`): Relevancy score (0 to scale, default 0-1)
20
20
 
21
- **preprocessPrompt:** (`string`): The prompt sent to the LLM for the preprocess step (optional).
21
+ **preprocessPrompt** (`string`): The prompt sent to the LLM for the preprocess step (optional).
22
22
 
23
- **preprocessStepResult:** (`object`): Object with extracted statements: { statements: string\[] }
23
+ **preprocessStepResult** (`object`): Object with extracted statements: { statements: string\[] }
24
24
 
25
- **analyzePrompt:** (`string`): The prompt sent to the LLM for the analyze step (optional).
25
+ **analyzePrompt** (`string`): The prompt sent to the LLM for the analyze step (optional).
26
26
 
27
- **analyzeStepResult:** (`object`): Object with results: { results: Array<{ result: 'yes' | 'unsure' | 'no', reason: string }> }
27
+ **analyzeStepResult** (`object`): Object with results: { results: Array<{ result: 'yes' | 'unsure' | 'no', reason: string }> }
28
28
 
29
- **generateReasonPrompt:** (`string`): The prompt sent to the LLM for the reason step (optional).
29
+ **generateReasonPrompt** (`string`): The prompt sent to the LLM for the reason step (optional).
30
30
 
31
- **reason:** (`string`): Explanation of the score.
31
+ **reason** (`string`): Explanation of the score.
32
32
 
33
- ## Scoring Details
33
+ ## Scoring details
34
34
 
35
35
  The scorer evaluates relevancy through query-answer alignment, considering completeness and detail level, but not factual correctness.
36
36
 
@@ -58,29 +58,29 @@ A relevancy score between 0 and 1:
58
58
  - **0.7–0.9**: The response mostly answers the query but may include minor unrelated content.
59
59
  - **0.4–0.6**: The response partially answers the query, mixing relevant and unrelated information.
60
60
  - **0.1–0.3**: The response includes minimal relevant content and largely misses the intent of the query.
61
- - **0.0**: The response is entirely unrelated and does not answer the query.
61
+ - **0.0**: The response is entirely unrelated and doesn't answer the query.
62
62
 
63
63
  ## Example
64
64
 
65
65
  Evaluate agent responses for relevancy across different scenarios:
66
66
 
67
67
  ```typescript
68
- import { runEvals } from "@mastra/core/evals";
69
- import { createAnswerRelevancyScorer } from "@mastra/evals/scorers/prebuilt";
70
- import { myAgent } from "./agent";
68
+ import { runEvals } from '@mastra/core/evals'
69
+ import { createAnswerRelevancyScorer } from '@mastra/evals/scorers/prebuilt'
70
+ import { myAgent } from './agent'
71
71
 
72
- const scorer = createAnswerRelevancyScorer({ model: "openai/gpt-4o" });
72
+ const scorer = createAnswerRelevancyScorer({ model: 'openai/gpt-5.4' })
73
73
 
74
74
  const result = await runEvals({
75
75
  data: [
76
76
  {
77
- input: "What are the health benefits of regular exercise?",
77
+ input: 'What are the health benefits of regular exercise?',
78
78
  },
79
79
  {
80
- input: "What should a healthy breakfast include?",
80
+ input: 'What should a healthy breakfast include?',
81
81
  },
82
82
  {
83
- input: "What are the benefits of meditation?",
83
+ input: 'What are the benefits of meditation?',
84
84
  },
85
85
  ],
86
86
  scorers: [scorer],
@@ -89,11 +89,11 @@ const result = await runEvals({
89
89
  console.log({
90
90
  score: scorerResults[scorer.id].score,
91
91
  reason: scorerResults[scorer.id].reason,
92
- });
92
+ })
93
93
  },
94
- });
94
+ })
95
95
 
96
- console.log(result.scores);
96
+ console.log(result.scores)
97
97
  ```
98
98
 
99
99
  For more details on `runEvals`, see the [runEvals reference](https://mastra.ai/reference/evals/run-evals).
@@ -1,50 +1,48 @@
1
- # Answer Similarity Scorer
1
+ # Answer similarity scorer
2
2
 
3
3
  The `createAnswerSimilarityScorer()` function creates a scorer that evaluates how similar an agent's output is to a ground truth answer. This scorer is specifically designed for CI/CD testing scenarios where you have expected answers and want to ensure consistency over time.
4
4
 
5
5
  ## Parameters
6
6
 
7
- **model:** (`LanguageModel`): The language model used to evaluate semantic similarity between outputs and ground truth.
7
+ **model** (`LanguageModel`): The language model used to evaluate semantic similarity between outputs and ground truth.
8
8
 
9
- **options:** (`AnswerSimilarityOptions`): Configuration options for the scorer.
9
+ **options** (`AnswerSimilarityOptions`): Configuration options for the scorer.
10
10
 
11
- ### AnswerSimilarityOptions
11
+ **options.requireGroundTruth** (`boolean`): Whether to require ground truth for evaluation. If false, missing ground truth returns score 0.
12
12
 
13
- **requireGroundTruth:** (`boolean`): Whether to require ground truth for evaluation. If false, missing ground truth returns score 0. (Default: `true`)
13
+ **options.semanticThreshold** (`number`): Weight for semantic matches vs exact matches (0-1).
14
14
 
15
- **semanticThreshold:** (`number`): Weight for semantic matches vs exact matches (0-1). (Default: `0.8`)
15
+ **options.exactMatchBonus** (`number`): Additional score bonus for exact matches (0-1).
16
16
 
17
- **exactMatchBonus:** (`number`): Additional score bonus for exact matches (0-1). (Default: `0.2`)
17
+ **options.missingPenalty** (`number`): Penalty per missing key concept from ground truth.
18
18
 
19
- **missingPenalty:** (`number`): Penalty per missing key concept from ground truth. (Default: `0.15`)
19
+ **options.contradictionPenalty** (`number`): Penalty for contradictory information. High value ensures wrong answers score near 0.
20
20
 
21
- **contradictionPenalty:** (`number`): Penalty for contradictory information. High value ensures wrong answers score near 0. (Default: `1.0`)
21
+ **options.extraInfoPenalty** (`number`): Mild penalty for extra information not present in ground truth (capped at 0.2).
22
22
 
23
- **extraInfoPenalty:** (`number`): Mild penalty for extra information not present in ground truth (capped at 0.2). (Default: `0.05`)
24
-
25
- **scale:** (`number`): Score scaling factor. (Default: `1`)
23
+ **options.scale** (`number`): Score scaling factor.
26
24
 
27
25
  This function returns an instance of the MastraScorer class. The `.run()` method accepts the same input as other scorers (see the [MastraScorer reference](https://mastra.ai/reference/evals/mastra-scorer)), but **requires ground truth** to be provided in the run object.
28
26
 
29
- ## .run() Returns
27
+ ## `.run()` returns
30
28
 
31
- **runId:** (`string`): The id of the run (optional).
29
+ **runId** (`string`): The id of the run (optional).
32
30
 
33
- **score:** (`number`): Similarity score between 0-1 (or 0-scale if custom scale used). Higher scores indicate better similarity to ground truth.
31
+ **score** (`number`): Similarity score between 0-1 (or 0-scale if custom scale used). Higher scores indicate better similarity to ground truth.
34
32
 
35
- **reason:** (`string`): Human-readable explanation of the score with actionable feedback.
33
+ **reason** (`string`): Human-readable explanation of the score with actionable feedback.
36
34
 
37
- **preprocessStepResult:** (`object`): Extracted semantic units from output and ground truth.
35
+ **preprocessStepResult** (`object`): Extracted semantic units from output and ground truth.
38
36
 
39
- **analyzeStepResult:** (`object`): Detailed analysis of matches, contradictions, and extra information.
37
+ **analyzeStepResult** (`object`): Detailed analysis of matches, contradictions, and extra information.
40
38
 
41
- **preprocessPrompt:** (`string`): The prompt used for semantic unit extraction.
39
+ **preprocessPrompt** (`string`): The prompt used for semantic unit extraction.
42
40
 
43
- **analyzePrompt:** (`string`): The prompt used for similarity analysis.
41
+ **analyzePrompt** (`string`): The prompt used for similarity analysis.
44
42
 
45
- **generateReasonPrompt:** (`string`): The prompt used for generating the explanation.
43
+ **generateReasonPrompt** (`string`): The prompt used for generating the explanation.
46
44
 
47
- ## Scoring Details
45
+ ## Scoring details
48
46
 
49
47
  The scorer uses a multi-step process:
50
48
 
@@ -60,25 +58,25 @@ Score calculation: `max(0, base_score - contradiction_penalty - missing_penalty
60
58
  Evaluate agent responses for similarity to ground truth across different scenarios:
61
59
 
62
60
  ```typescript
63
- import { runEvals } from "@mastra/core/evals";
64
- import { createAnswerSimilarityScorer } from "@mastra/evals/scorers/prebuilt";
65
- import { myAgent } from "./agent";
61
+ import { runEvals } from '@mastra/core/evals'
62
+ import { createAnswerSimilarityScorer } from '@mastra/evals/scorers/prebuilt'
63
+ import { myAgent } from './agent'
66
64
 
67
- const scorer = createAnswerSimilarityScorer({ model: "openai/gpt-4o" });
65
+ const scorer = createAnswerSimilarityScorer({ model: 'openai/gpt-5.4' })
68
66
 
69
67
  const result = await runEvals({
70
68
  data: [
71
69
  {
72
- input: "What is 2+2?",
73
- groundTruth: "4",
70
+ input: 'What is 2+2?',
71
+ groundTruth: '4',
74
72
  },
75
73
  {
76
- input: "What is the capital of France?",
77
- groundTruth: "The capital of France is Paris",
74
+ input: 'What is the capital of France?',
75
+ groundTruth: 'The capital of France is Paris',
78
76
  },
79
77
  {
80
- input: "What are the primary colors?",
81
- groundTruth: "The primary colors are red, blue, and yellow",
78
+ input: 'What are the primary colors?',
79
+ groundTruth: 'The primary colors are red, blue, and yellow',
82
80
  },
83
81
  ],
84
82
  scorers: [scorer],
@@ -87,11 +85,11 @@ const result = await runEvals({
87
85
  console.log({
88
86
  score: scorerResults[scorer.id].score,
89
87
  reason: scorerResults[scorer.id].reason,
90
- });
88
+ })
91
89
  },
92
- });
90
+ })
93
91
 
94
- console.log(result.scores);
92
+ console.log(result.scores)
95
93
  ```
96
94
 
97
95
  For more details on `runEvals`, see the [runEvals reference](https://mastra.ai/reference/evals/run-evals).