{"version":3,"sources":["../src/scorers/utils.ts"],"names":["message","requestContext","RequestContext"],"mappings":"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","file":"chunk-UNQXHPOD.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\nexport type ScorerRunInputForLLMJudge =\n  | ScorerRunInputForAgent\n  | string\n  | {\n      inputMessages?: unknown[];\n      messages?: unknown[];\n      prompt?: string;\n      text?: string;\n      content?: unknown;\n      input?: unknown;\n      user?: unknown;\n      [key: string]: unknown;\n    };\n\nexport type ScorerRunOutputForLLMJudge =\n  | ScorerRunOutputForAgent\n  | string\n  | unknown[]\n  | {\n      text?: string;\n      content?: unknown;\n      role?: string;\n      [key: string]: unknown;\n    };\n\n/**\n * Extracts text content from a MastraDBMessage or ModelMessage-like object.\n *\n * @param message - The message 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  const content = message.content as any;\n\n  if (typeof content === 'string') {\n    return content;\n  }\n  if (Array.isArray(content)) {\n    const textParts = content.filter(p => p.type === 'text');\n    return textParts.length > 0 ? textParts[textParts.length - 1]?.text || '' : '';\n  }\n  if (typeof content?.content === 'string' && content.content !== '') {\n    return content.content;\n  }\n  if (typeof content?.text === 'string' && content.text !== '') {\n    return content.text;\n  }\n  if (content?.parts && Array.isArray(content.parts)) {\n    // Return only the last text part like AI SDK does\n    const textParts = content.parts.filter((p: any) => p.type === 'text');\n    return textParts.length > 0 ? textParts[textParts.length - 1]?.text || '' : '';\n  }\n  return '';\n}\n\nconst isRecord = (value: unknown): value is Record<string, any> => {\n  return typeof value === 'object' && value !== null;\n};\n\nconst getTextFromValue = (value: unknown): string | undefined => {\n  if (typeof value === 'string') return value === '' ? undefined : value;\n  if (Array.isArray(value)) {\n    const textParts = value\n      .filter(part => isRecord(part) && part.type === 'text' && typeof part.text === 'string')\n      .map(part => part.text);\n    return textParts.length > 0 ? textParts[textParts.length - 1] : undefined;\n  }\n  if (!isRecord(value)) return undefined;\n\n  const fromParts = Array.isArray(value.parts) ? getTextFromValue(value.parts) : undefined;\n\n  return (\n    getTextFromValue(value.content) ??\n    (typeof value.text === 'string' && value.text !== '' ? value.text : undefined) ??\n    (typeof value.body === 'string' && value.body !== '' ? value.body : undefined) ??\n    fromParts\n  );\n};\n\nexport const isScorerRunInputForAgent = (input: unknown): input is ScorerRunInputForAgent => {\n  return (\n    isRecord(input) &&\n    Array.isArray(input.inputMessages) &&\n    Array.isArray(input.rememberedMessages) &&\n    Array.isArray(input.systemMessages) &&\n    isRecord(input.taggedSystemMessages)\n  );\n};\n\nconst isMastraDBMessageLike = (message: unknown): message is MastraDBMessage => {\n  return (\n    isRecord(message) &&\n    typeof message.id === 'string' &&\n    typeof message.role === 'string' &&\n    'content' in message &&\n    'createdAt' in message\n  );\n};\n\nexport const isScorerRunOutputForAgent = (output: unknown): output is ScorerRunOutputForAgent => {\n  return Array.isArray(output) && output.every(isMastraDBMessageLike);\n};\n\nconst getTextFromMessages = (messages: unknown, role: string): string | undefined => {\n  if (!Array.isArray(messages)) return undefined;\n\n  const message = messages.find(message => isRecord(message) && message.role === role);\n  return message ? getTextFromValue(message) : undefined;\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 * Accepts the agent shape (`{ inputMessages }`), `ModelMessage[]`\n * (`{ messages }`), workflow input (`{ prompt }`), and a bare string.\n *\n * @param input - The scorer run input\n * @returns The user message text, or `undefined` if none can be extracted\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?: unknown): string | undefined => {\n  if (typeof input === 'string') return input;\n  if (!isRecord(input)) return undefined;\n\n  return (\n    getTextFromMessages(input.inputMessages, 'user') ??\n    getTextFromMessages(input.messages, 'user') ??\n    (typeof input.prompt === 'string' ? input.prompt : undefined) ??\n    (typeof input.text === 'string' ? input.text : undefined) ??\n    getTextFromValue(input.content) ??\n    getTextFromValue(input.input) ??\n    getTextFromValue(input.user)\n  );\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?: unknown): string[] => {\n  const systemMessages: string[] = [];\n  if (!isRecord(input)) return systemMessages;\n\n  // Add standard system messages\n  if (Array.isArray(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  const addSystemMessages = (messages: unknown) => {\n    if (!Array.isArray(messages)) return;\n\n    systemMessages.push(\n      ...messages\n        .filter(message => isRecord(message) && message.role === 'system')\n        .map(message => getTextFromValue(message))\n        .filter((content): content is string => Boolean(content)),\n    );\n  };\n\n  addSystemMessages(input.inputMessages);\n  addSystemMessages(input.messages);\n\n  // Add tagged system messages (these are specialized system prompts)\n  if (isRecord(input.taggedSystemMessages)) {\n    Object.values(input.taggedSystemMessages).forEach(messages => {\n      if (!Array.isArray(messages)) return;\n      messages.forEach(msg => {\n        const content = getTextFromValue(msg);\n        if (content) {\n          systemMessages.push(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?: unknown): 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 * Accepts the agent shape (`MastraDBMessage[]` / `ModelMessage[]`), workflow\n * output (`{ text }`), task output (`{ content }`), a single assistant message\n * object, and a bare string.\n *\n * @param output - The scorer run output\n * @returns The assistant message text, or `undefined` if none can be extracted\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?: unknown) => {\n  if (typeof output === 'string') return output;\n  if (Array.isArray(output)) return getTextFromMessages(output, 'assistant');\n  if (!isRecord(output)) return undefined;\n\n  const isAssistantOutput = output.role === undefined || output.role === 'assistant';\n\n  if (isAssistantOutput && typeof output.text === 'string') return output.text;\n  if (isAssistantOutput && typeof output.content === 'string') return output.content;\n  if (isAssistantOutput && (isRecord(output.content) || Array.isArray(output.content))) {\n    return (\n      getTextContentFromMastraDBMessage(output as MastraDBMessage) ||\n      getTextContentFromMastraDBMessage(output.content as MastraDBMessage) ||\n      undefined\n    );\n  }\n  if (output.role === 'assistant') return getTextContentFromMastraDBMessage(output as MastraDBMessage) || undefined;\n\n  return 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    // Prefer the legacy toolInvocations array when present; fall back to\n    // V2 content.parts for messages that only store tool calls there.\n    const legacy = message?.content?.toolInvocations;\n    const fromParts = legacy\n      ? undefined\n      : message?.content?.parts\n          ?.filter((p): p is Extract<typeof p, { type: 'tool-invocation' }> => p.type === 'tool-invocation')\n          .map(p => p.toolInvocation);\n    const toolInvocations = legacy ?? fromParts;\n\n    if (!toolInvocations?.length) continue;\n\n    for (let invocationIndex = 0; invocationIndex < toolInvocations.length; invocationIndex++) {\n      const invocation = 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  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    // Prefer the legacy toolInvocations array when present; fall back to\n    // V2 content.parts for messages that only store tool calls there.\n    const legacy = message?.content?.toolInvocations;\n    const fromParts = legacy\n      ? undefined\n      : message?.content?.parts\n          ?.filter((p): p is Extract<typeof p, { type: 'tool-invocation' }> => p.type === 'tool-invocation')\n          .map(p => p.toolInvocation);\n    const toolInvocations = legacy ?? fromParts;\n\n    if (!toolInvocations?.length) 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 *   { ordering: 'strict' }\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    allowRepeatedSteps?: boolean;\n  } = {},\n): TrajectoryComparisonResult {\n  const { allowRepeatedSteps = true, ordering = 'relaxed' } = options;\n\n  // Normalize expected to ExpectedStep[]. TrajectoryStep and ExpectedStep share\n  // the same field names, so TrajectoryStep[] can be used directly as ExpectedStep[].\n  // The only structural difference is `children` (TrajectoryStep[] vs TrajectoryExpectation),\n  // but compareTrajectories doesn't recurse into children.\n  const normalizedExpected: { steps: ExpectedStep[] } = {\n    steps: expected.steps as ExpectedStep[],\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, { allowRepeatedSteps, repeatedSteps });\n  }\n\n  if (ordering === 'unordered') {\n    return compareUnorderedPresence(actual, normalizedExpected, { allowRepeatedSteps, repeatedSteps });\n  }\n\n  return compareRelaxedOrder(actual, normalizedExpected, { 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: { 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 (actual.steps[i] && expected.steps[i]) {\n        if (expectedStepMatches(actual.steps[i]!, expected.steps[i]!)) {\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: { 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]!)) {\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 * Fields on each ExpectedStep variant that are comparable data (not structural).\n * Used by `expectedStepMatches` to know which fields to compare when `compareData` is true.\n */\nconst COMPARABLE_FIELDS_BY_TYPE: Record<string, string[]> = {\n  tool_call: ['toolArgs', 'toolResult', 'success'],\n  mcp_tool_call: ['toolArgs', 'toolResult', 'mcpServer', 'success'],\n  model_generation: ['modelId', 'promptTokens', 'completionTokens', 'finishReason'],\n  agent_run: ['agentId'],\n  workflow_step: ['stepId', 'status', 'output'],\n  workflow_run: ['workflowId', 'status'],\n  workflow_conditional: ['conditionCount', 'selectedSteps'],\n  workflow_parallel: ['branchCount', 'parallelSteps'],\n  workflow_loop: ['loopType', 'totalIterations'],\n  workflow_sleep: ['sleepDurationMs', 'sleepType'],\n  workflow_wait_event: ['eventName', 'eventReceived'],\n  processor_run: ['processorId'],\n};\n\n/**\n * Check if an actual TrajectoryStep matches an ExpectedStep.\n * Matches by name, optionally by stepType, and auto-compares any variant-specific\n * fields that are present on the expected step.\n */\nfunction expectedStepMatches(actual: TrajectoryStep, expected: ExpectedStep): boolean {\n  if (actual.name !== expected.name) return false;\n  if (expected.stepType && actual.stepType !== expected.stepType) return false;\n\n  if (expected.stepType) {\n    const fields = COMPARABLE_FIELDS_BY_TYPE[expected.stepType] ?? [];\n    for (const field of fields) {\n      const expectedVal = (expected as any)[field];\n      if (expectedVal === undefined) continue; // field not specified in expectation, skip\n      const actualVal = (actual as any)[field];\n      if (actualVal === undefined) return false;\n      try {\n        if (JSON.stringify(actualVal) !== JSON.stringify(expectedVal)) 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: { 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  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)) {\n        matchedSteps++;\n        matchedExpectedIndices.add(i);\n        usedIndices.add(j);\n        break;\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"]}