{"version":3,"sources":["../src/index.ts","../src/harness.ts","../src/judges/judgeHarness.ts","../src/wrapText.ts","../src/judges/factualityJudge.ts","../src/internal/matchers.ts","../src/internal/structuredOutputScorer.ts","../src/judges/structuredOutputJudge.ts","../src/internal/toolCallScorer.ts","../src/judges/toolCallJudge.ts"],"sourcesContent":["import { assert, describe, expect, test, type TestAPI } from \"vitest\";\nimport \"vitest\";\nimport type {\n  Harness,\n  HarnessContext,\n  HarnessMetadata,\n  HarnessRun,\n  JsonValue,\n  NormalizedSession,\n  ToolCallRecord,\n} from \"./harness\";\nimport {\n  createFailedHarnessRun,\n  ensureRunTrace,\n  getHarnessRunFromError,\n  isHarnessRun,\n  isNormalizedSession,\n  latestAssistantMessageContent,\n  normalizeContent,\n  toolCalls,\n  userMessages,\n} from \"./harness\";\nimport type {\n  JudgeContext,\n  Judge,\n  JudgeAssessFn,\n  JudgeAssessWithAssessorFn,\n  JudgeAssessor,\n  JudgeOptions,\n  JudgeResult,\n} from \"./judges/types\";\nimport type { JudgeHarness } from \"./judges/judgeHarness\";\nimport { createRunJudge } from \"./judges/judgeHarness\";\nimport { wrapText } from \"./wrapText\";\n\ntype EvalTaskMeta = {\n  eval?: {\n    scores: (JudgeResult & { name: string })[];\n    avgScore: number;\n    output?: unknown;\n    toolCalls?: ToolCallRecord[];\n    thresholdFailed?: boolean;\n  };\n  harness?: {\n    name: string;\n    run: HarnessRun;\n  };\n};\n\ntype EvalTaskLike = {\n  meta: EvalTaskMeta;\n};\n\ntype RegisteredJudgeRunContext = {\n  harness: Harness<any, any, any>;\n  input: unknown;\n  judgeHarness?: JudgeHarness;\n  metadata: HarnessMetadata;\n  run: HarnessRun;\n  signal?: AbortSignal;\n};\n\ntype InternalEvalFixtures = {\n  harness: Harness<any, any, any>;\n  automaticJudges: Array<Judge<JudgeContext<any, any, any, any>>>;\n  judgeHarness?: JudgeHarness;\n  judgeThreshold: number | null | undefined;\n  explicitJudgeHarness?: JudgeHarness;\n  run: EvalRun<any, any, any>;\n};\n\ntype HarnessInput<THarness extends Harness<any, any, any>> =\n  THarness extends Harness<infer TInput, any, any> ? TInput : unknown;\n\ntype HarnessMetadataFor<THarness extends Harness<any, any, any>> =\n  THarness extends Harness<any, any, infer TMetadata>\n    ? TMetadata\n    : HarnessMetadata;\n\ntype HarnessOutput<THarness extends Harness<any, any, any>> =\n  THarness extends Harness<any, infer TOutput, any>\n    ? TOutput\n    : JsonValue | undefined;\n\ntype CreateJudgeConfig<\n  TOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n> = {\n  name: string;\n  judgeHarness?: JudgeHarness;\n  assess: JudgeAssessFn<TOptions>;\n};\n\ndeclare const evalHarnessRunBrand: unique symbol;\n\n/**\n * Harness run returned by the fixture-backed `run(...)` API.\n *\n * @example\n * ```ts\n * it(\"approves a refund\", async ({ run }) => {\n *   const result = await run(\"Refund invoice inv_123\");\n *\n *   expect(result.output.status).toBe(\"approved\");\n * });\n * ```\n */\nexport type EvalHarnessRun<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> = Harness<\n    TInput,\n    TOutput,\n    TMetadata\n  >,\n> = HarnessRun<TOutput> & {\n  readonly [evalHarnessRunBrand]: {\n    readonly input: TInput;\n    readonly metadata: TMetadata;\n    readonly output: TOutput;\n    readonly harness: THarness;\n  };\n};\n\n/**\n * Per-run metadata forwarded to the harness alongside the test input.\n *\n * @example\n * ```ts\n * await run(\"Refund invoice inv_123\", {\n *   metadata: {\n *     expected: { status: \"approved\" },\n *     expectedTools: [\"lookupInvoice\", \"createRefund\"],\n *   },\n * });\n * ```\n */\nexport interface EvalRunOptions<\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n> {\n  /** Per-run expectations or configuration forwarded to harnesses and judges. */\n  metadata?: TMetadata;\n}\n\n/**\n * Explicit harness execution primitive exposed to each eval test.\n *\n * @example\n * ```ts\n * const result = await run(\"Refund invoice inv_123\", {\n *   metadata: { expected: { status: \"approved\" } },\n * });\n * ```\n */\nexport type EvalRun<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> = Harness<\n    TInput,\n    TOutput,\n    TMetadata\n  >,\n> = (\n  input: TInput,\n  options?: EvalRunOptions<TMetadata>,\n) => Promise<EvalHarnessRun<TInput, TOutput, TMetadata, THarness>>;\n\n/**\n * Fixture-backed Vitest context exposed inside `describeEval(...)` tests.\n *\n * @example\n * ```ts\n * type RefundOutput = { status: \"approved\" | \"denied\" };\n *\n * it(\"approves a refund\", async ({ run }: EvalTestContext<string, RefundOutput>) => {\n *   const result = await run(\"Refund invoice inv_123\");\n *\n *   expect(result.output.status).toBe(\"approved\");\n * });\n * ```\n */\nexport interface EvalTestContext<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> = Harness<\n    TInput,\n    TOutput,\n    TMetadata\n  >,\n> {\n  run: EvalRun<TInput, TOutput, TMetadata, THarness>;\n}\n\n/** Fixture-backed Vitest test API exposed inside `describeEval(...)`. */\nexport type EvalTestAPI<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> = Harness<\n    TInput,\n    TOutput,\n    TMetadata\n  >,\n> = TestAPI<EvalTestContext<TInput, TOutput, TMetadata, THarness>>;\n\n/**\n * Suite-level configuration for a harness-backed eval block.\n *\n * @example\n * ```ts\n * const options: DescribeEvalOptions<\n *   string,\n *   { status: \"approved\" | \"denied\" },\n *   { expected: { status: \"approved\" | \"denied\" } }\n * > = {\n *   harness: refundHarness,\n *   judges: [ToolCallJudge(), StructuredOutputJudge()],\n *   judgeThreshold: 1,\n * };\n * ```\n */\nexport interface DescribeEvalOptions<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> = Harness<\n    TInput,\n    TOutput,\n    TMetadata\n  >,\n> {\n  /** Harness used for every explicit `run(...)` call in the suite. */\n  harness: THarness;\n  /** Automatic judges applied after each successful `run(...)`. */\n  judges?: Array<Judge<JudgeContext<TInput, TOutput, TMetadata, THarness>>>;\n  /** Optional judge-side harness used only by judges that call `ctx.runJudge(...)`. */\n  judgeHarness?: JudgeHarness;\n  /** Passing threshold for automatic suite-level judges. `null` disables fail-on-score. */\n  judgeThreshold?: number | null;\n  /** Skips the entire eval suite when the predicate returns true. */\n  skipIf?: () => boolean;\n}\n\ntype JudgeAssertionInput<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = TJudgeOptions extends { input: infer TInput } ? TInput : unknown;\n\ntype JudgeAssertionOutput<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = TJudgeOptions extends { output: infer TOutput }\n  ? TOutput\n  : JsonValue | undefined;\n\ntype JudgeAssertionMetadata<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = TJudgeOptions extends { metadata: infer TMetadata }\n  ? TMetadata\n  : HarnessMetadata;\n\ntype JudgeAssertionHarness<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = TJudgeOptions extends { harness: infer THarness }\n  ? Exclude<THarness, undefined>\n  : Harness<\n      JudgeAssertionInput<TJudgeOptions>,\n      JudgeAssertionOutput<TJudgeOptions>,\n      JudgeAssertionMetadata<TJudgeOptions>\n    >;\n\ntype JudgeAssertionReservedKey =\n  | keyof JudgeContext<any, any, any, any>\n  | \"judgeHarness\"\n  | \"signal\"\n  | \"threshold\";\n\ntype JudgeAssertionParams<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = Omit<TJudgeOptions, JudgeAssertionReservedKey>;\n\ntype RequiredKeys<T> = {\n  [K in keyof T]-?: Record<string, never> extends Pick<T, K> ? never : K;\n}[keyof T];\n\ntype JudgeAssertionArgs<\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = RequiredKeys<JudgeAssertionParams<TJudgeOptions>> extends never\n  ? [options?: JudgeAssertionOptions<TJudgeOptions>]\n  : [options: JudgeAssertionOptions<TJudgeOptions>];\n\ntype MatcherOutput<TReceived> = TReceived extends EvalHarnessRun<\n  any,\n  infer TOutput,\n  any,\n  any\n>\n  ? TOutput\n  : TReceived extends HarnessRun<infer TOutput>\n    ? TOutput\n    : TReceived extends NormalizedSession\n      ? JsonValue | undefined\n      : TReceived extends JsonValue\n        ? TReceived\n        : JsonValue | undefined;\n\ntype JudgeForReceived<\n  TReceived,\n  TJudgeOptions extends JudgeContext<any, any, any, any>,\n> = MatcherOutput<TReceived> extends JudgeAssertionOutput<TJudgeOptions>\n  ? Judge<TJudgeOptions>\n  : never;\n\n/**\n * Optional overrides passed to `expect(...).toSatisfyJudge(...)`.\n *\n * @example\n * ```ts\n * await expect(result).toSatisfyJudge(RefundStatusJudge, {\n *   threshold: null,\n * });\n * ```\n */\nexport type JudgeAssertionOptions<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n> = JudgeAssertionParams<TJudgeOptions> & {\n  /** Override or provide the original eval input for the judge. */\n  input?: JudgeAssertionInput<TJudgeOptions>;\n  /** Override or provide the app-facing output for the judge. */\n  output?: JudgeAssertionOutput<TJudgeOptions>;\n  /** Override or provide per-run judge metadata. */\n  metadata?: JudgeAssertionMetadata<TJudgeOptions>;\n  /** Override or provide flattened tool calls for the judge. */\n  toolCalls?: ToolCallRecord[];\n  /** Override or provide the complete normalized harness run. */\n  run?: HarnessRun<JudgeAssertionOutput<TJudgeOptions>>;\n  /** Override or provide the normalized session transcript. */\n  session?: HarnessRun[\"session\"];\n  /** Override or provide the harness associated with the judge context. */\n  harness?: JudgeAssertionHarness<TJudgeOptions>;\n  /** Override or provide the judge harness for judges that call `ctx.runJudge(...)`. */\n  judgeHarness?: JudgeHarness;\n  /** Passing threshold for the explicit matcher. `null` records the score without failing. */\n  threshold?: number | null;\n};\n\n/** Function type installed as the `toSatisfyJudge(...)` matcher. */\nexport type ToSatisfyJudge<TReceived = unknown> = <\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  judge: JudgeForReceived<TReceived, TJudgeOptions>,\n  ...args: JudgeAssertionArgs<TJudgeOptions>\n) => Promise<TReceived>;\n\n/**\n * Vitest matcher extension surface added by `vitest-evals`.\n *\n * @example\n * ```ts\n * await expect(result).toSatisfyJudge(RefundStatusJudge);\n * ```\n */\nexport interface EvalMatchers<R = unknown> {\n  toSatisfyJudge: ToSatisfyJudge<R>;\n}\n\ndeclare module \"vitest\" {\n  interface Assertion<T = any> extends EvalMatchers<T> {}\n  interface AsymmetricMatchersContaining extends EvalMatchers {}\n\n  interface TaskMeta extends EvalTaskMeta {}\n}\n\nconst judgeRunContextByObject = new WeakMap<\n  object,\n  RegisteredJudgeRunContext\n>();\n\nconst evalTest = test\n  .extend(\"harness\", async (): Promise<InternalEvalFixtures[\"harness\"]> => {\n    throw new Error(\n      \"describeEval must override the harness fixture before running tests.\",\n    );\n  })\n  .extend(\n    \"automaticJudges\",\n    [] as Array<Judge<JudgeContext<any, any, any, any>>>,\n  )\n  .extend(\"judgeThreshold\", undefined as number | null | undefined)\n  .extend(\"judgeHarness\", undefined as JudgeHarness | undefined)\n  .extend(\"explicitJudgeHarness\", undefined as JudgeHarness | undefined)\n  .extend(\n    \"run\",\n    async ({\n      automaticJudges,\n      explicitJudgeHarness,\n      harness,\n      judgeHarness,\n      judgeThreshold,\n      signal,\n      task,\n    }) => {\n      return async (input: unknown, options?: EvalRunOptions) => {\n        const resolvedHarness = harness as Harness<\n          unknown,\n          JsonValue | undefined,\n          HarnessMetadata\n        >;\n        const metadata = createMetadata(options?.metadata);\n        const artifacts: HarnessContext[\"artifacts\"] = {};\n        const context: HarnessContext<HarnessMetadata> = {\n          metadata,\n          signal,\n          artifacts,\n          setArtifact: (artifactName, value) => {\n            artifacts[artifactName] = value;\n          },\n        };\n\n        clearRecordedTaskMeta(task);\n\n        let run: HarnessRun;\n        const startedAt = new Date();\n        try {\n          run = await resolvedHarness.run(input, context);\n        } catch (error) {\n          const finishedAt = new Date();\n          const partialRun = getHarnessRunFromError(error);\n          if (partialRun) {\n            if (Object.keys(artifacts).length > 0 && !partialRun.artifacts) {\n              partialRun.artifacts = artifacts;\n            }\n\n            ensureRunTrace(partialRun, {\n              name: resolvedHarness.name,\n              startedAt,\n              finishedAt,\n            });\n            setHarnessMeta(task, resolvedHarness.name, partialRun);\n            recordJudgeRunContext(\n              partialRun,\n              resolvedHarness,\n              input,\n              explicitJudgeHarness,\n              metadata,\n              signal,\n            );\n          }\n\n          if (!partialRun) {\n            const failedRun = createFailedHarnessRun(input, error, {\n              artifacts,\n            });\n            ensureRunTrace(failedRun, {\n              name: resolvedHarness.name,\n              startedAt,\n              finishedAt,\n            });\n            setHarnessMeta(task, resolvedHarness.name, failedRun);\n            recordJudgeRunContext(\n              failedRun,\n              resolvedHarness,\n              input,\n              explicitJudgeHarness,\n              metadata,\n              signal,\n            );\n          }\n\n          throw error;\n        }\n\n        if (Object.keys(artifacts).length > 0 && !run.artifacts) {\n          run.artifacts = artifacts;\n        }\n\n        ensureRunTrace(run, {\n          name: resolvedHarness.name,\n          startedAt,\n          finishedAt: new Date(),\n        });\n        setHarnessMeta(task, resolvedHarness.name, run);\n        recordJudgeRunContext(\n          run,\n          resolvedHarness,\n          input,\n          explicitJudgeHarness,\n          metadata,\n          signal,\n        );\n\n        if (automaticJudges.length > 0) {\n          await applyAutomaticJudges(\n            task,\n            automaticJudges,\n            judgeThreshold,\n            resolvedHarness,\n            input,\n            judgeHarness,\n            metadata,\n            run,\n            signal,\n          );\n        }\n\n        return run as EvalHarnessRun<\n          unknown,\n          JsonValue | undefined,\n          HarnessMetadata,\n          typeof resolvedHarness\n        >;\n      };\n    },\n  ) as TestAPI<InternalEvalFixtures>;\n\nexpect.extend({\n  toSatisfyJudge: async function toSatisfyJudge<\n    TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n  >(\n    received: unknown,\n    judge: Judge<TJudgeOptions>,\n    options?: JudgeAssertionOptions<TJudgeOptions>,\n  ) {\n    const { threshold = 1.0, ...context } = (options ??\n      {}) as JudgeAssertionOptions<TJudgeOptions>;\n    const judgeOptions = buildJudgeAssertionOptions(\n      received,\n      judge,\n      context,\n      isEvalTaskLike(this.task) ? this.task : undefined,\n    );\n\n    const result = await judge.assess(judgeOptions);\n\n    const score = result.score ?? 0;\n    const pass = threshold === null ? true : score >= threshold;\n    const scoredJudge = {\n      ...result,\n      name: judge.name || \"AnonymousJudge\",\n    };\n\n    if (isEvalTaskLike(this.task)) {\n      appendJudgeScore(this.task, {\n        score: scoredJudge,\n        output: judgeOptions.output,\n        thresholdFailed: threshold !== null && !pass,\n        toolCalls: judgeOptions.toolCalls,\n      });\n    }\n\n    return {\n      pass,\n      message: () =>\n        [\n          threshold === null\n            ? `Score: ${score.toFixed(2)} recorded without a failure threshold`\n            : `Score: ${score.toFixed(2)} below threshold: ${threshold.toFixed(2)}`,\n          `Output: ${formatJudgeOutputForMessage(judgeOptions.output)}`,\n          formatScores([scoredJudge]),\n        ].join(\"\\n\\n\"),\n    };\n  },\n});\n\nfunction formatJudgeOutputForMessage(output: JsonValue | undefined) {\n  if (typeof output === \"string\") {\n    return wrapText(output);\n  }\n\n  if (output === undefined) {\n    return \"undefined\";\n  }\n\n  return wrapText(JSON.stringify(output, null, 2));\n}\n\n/**\n * Creates a harness-backed eval suite on top of a fixture-backed Vitest test API.\n *\n * @param name - Suite name shown by Vitest and reporters.\n * @param options - Harness, automatic judges, threshold, and suite skip settings.\n * @param define - Callback that receives the eval-aware `it` API.\n *\n * @example\n * ```ts\n * import { piAiHarness } from \"@vitest-evals/harness-pi-ai\";\n * import { getModel } from \"@mariozechner/pi-ai\";\n * import { piAiJudgeHarness } from \"@vitest-evals/harness-pi-ai\";\n * import { expect } from \"vitest\";\n * import {\n *   describeEval,\n *   FactualityJudge,\n *   ToolCallJudge,\n *   toolCalls,\n * } from \"vitest-evals\";\n * import { createRefundAgent } from \"../src/refundAgent\";\n *\n * const judgeHarness = piAiJudgeHarness({\n *   model: getModel(\"anthropic\", \"claude-sonnet-4-5\"),\n *   temperature: 0,\n * });\n *\n * describeEval(\"refund agent\", {\n *   harness: piAiHarness({\n *     agent: () => createRefundAgent(),\n *   }),\n *   judgeHarness,\n *   judges: [ToolCallJudge()],\n * }, (it) => {\n *   it(\"approves a refundable invoice\", async ({ run }) => {\n *     const result = await run(\"Refund invoice inv_123\", {\n *       metadata: {\n *         expected: \"Invoice inv_123 should be refunded.\",\n *       },\n *     });\n *\n *     expect(result.output).toMatchObject({ status: \"approved\" });\n *     expect(toolCalls(result.session)).toHaveLength(2);\n *     await expect(result).toSatisfyJudge(FactualityJudge(), {\n *       threshold: 0.6,\n *     });\n *   });\n * });\n * ```\n */\nexport function describeEval<THarness extends Harness<any, any, any>>(\n  name: string,\n  options: DescribeEvalOptions<\n    HarnessInput<THarness>,\n    HarnessOutput<THarness>,\n    HarnessMetadataFor<THarness>,\n    THarness\n  >,\n  define: (\n    it: EvalTestAPI<\n      HarnessInput<THarness>,\n      HarnessOutput<THarness>,\n      HarnessMetadataFor<THarness>,\n      THarness\n    >,\n  ) => void,\n) {\n  const suite = options.skipIf ? describe.skipIf(options.skipIf()) : describe;\n\n  return suite(name, () => {\n    const automaticJudges = (options.judges ?? []) as Array<\n      Judge<JudgeContext<any, any, any, any>>\n    >;\n    const explicitJudgeHarness =\n      options.judgeHarness ?? resolveDefaultJudgeHarness(automaticJudges);\n    const it = evalTest.override({\n      harness: options.harness,\n      automaticJudges,\n      judgeHarness: options.judgeHarness,\n      explicitJudgeHarness,\n      judgeThreshold: options.judgeThreshold,\n    }) as unknown as EvalTestAPI<\n      HarnessInput<THarness>,\n      HarnessOutput<THarness>,\n      HarnessMetadataFor<THarness>,\n      THarness\n    >;\n\n    define(it);\n  });\n}\n\nfunction createMetadata<TMetadata extends HarnessMetadata>(\n  metadata: EvalRunOptions<TMetadata>[\"metadata\"],\n) {\n  return { ...(metadata ?? {}) } as TMetadata;\n}\n\nasync function applyAutomaticJudges<\n  TInput,\n  TOutput extends JsonValue | undefined,\n  TMetadata extends HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata>,\n>(\n  task: EvalTaskLike,\n  judges: Array<Judge<JudgeContext<TInput, TOutput, TMetadata, THarness>>>,\n  threshold: number | null | undefined,\n  harness: THarness,\n  input: TInput,\n  judgeHarness: JudgeHarness | undefined,\n  metadata: TMetadata,\n  run: HarnessRun<TOutput>,\n  signal?: AbortSignal,\n) {\n  const runToolCalls = toolCalls(run.session);\n  const scores = await Promise.all(\n    judges.map((judge) => {\n      const runJudge = createRunJudge(\n        resolveJudgeHarnessForJudge(judge, judgeHarness),\n        signal,\n      );\n      const judgeOptions = {\n        input,\n        output: run.output,\n        toolCalls: runToolCalls,\n        metadata,\n        run,\n        session: run.session,\n        signal,\n        harness,\n        runJudge,\n      } as unknown as JudgeContext<TInput, TOutput, TMetadata, THarness>;\n\n      return Promise.resolve(judge.assess(judgeOptions));\n    }),\n  );\n\n  const scoresWithName = scores.map((score, index) => ({\n    ...score,\n    name: judges[index].name,\n  }));\n  const thresholdValue = threshold === undefined ? 1.0 : threshold;\n  const avgScore =\n    scores.reduce((acc, score) => acc + (score.score ?? 0), 0) / scores.length;\n  const thresholdFailed = thresholdValue !== null && avgScore < thresholdValue;\n\n  task.meta.eval = {\n    scores: scoresWithName,\n    avgScore,\n    output: run.output ?? formatJudgeTextOutput(run),\n    toolCalls: runToolCalls,\n    thresholdFailed,\n  };\n\n  if (thresholdFailed) {\n    assert(\n      avgScore >= thresholdValue,\n      [\n        `Score: ${avgScore.toFixed(2)} below threshold: ${thresholdValue.toFixed(2)}`,\n        `Output: ${wrapText(formatJudgeTextOutput(run))}`,\n        formatScores(scoresWithName),\n      ].join(\"\\n\\n\"),\n    );\n  }\n}\n\nfunction clearRecordedTaskMeta(task: EvalTaskLike) {\n  task.meta.eval = undefined;\n  task.meta.harness = undefined;\n}\n\nfunction setHarnessMeta(task: EvalTaskLike, name: string, run: HarnessRun) {\n  task.meta.harness = {\n    name,\n    run,\n  };\n}\n\nfunction recordJudgeRunContext<\n  TInput,\n  TMetadata extends HarnessMetadata,\n  TOutput extends JsonValue | undefined,\n>(\n  run: HarnessRun<TOutput>,\n  harness: Harness<TInput, TOutput, TMetadata>,\n  input: TInput,\n  judgeHarness: JudgeHarness | undefined,\n  metadata: TMetadata,\n  signal?: AbortSignal,\n) {\n  const context = {\n    harness,\n    input,\n    judgeHarness,\n    metadata,\n    run,\n    signal,\n  };\n\n  recordJudgeRunContextObject(run, context);\n  recordJudgeRunContextObject(run.session, context);\n  recordJudgeRunContextObject(run.output, context);\n}\n\nfunction recordJudgeRunContextObject(\n  value: unknown,\n  context: RegisteredJudgeRunContext,\n) {\n  if (isWeakMapKey(value)) {\n    judgeRunContextByObject.set(value, context);\n  }\n}\n\nfunction appendJudgeScore(\n  task: EvalTaskLike,\n  {\n    output,\n    score,\n    thresholdFailed,\n    toolCalls: judgeToolCalls,\n  }: {\n    score: JudgeResult & { name: string };\n    output?: unknown;\n    thresholdFailed: boolean;\n    toolCalls?: ToolCallRecord[];\n  },\n) {\n  const previousScores = task.meta.eval?.scores ?? [];\n  const scores = [...previousScores, score];\n  const avgScore =\n    scores.reduce((acc, item) => acc + (item.score ?? 0), 0) / scores.length;\n\n  task.meta.eval = {\n    scores,\n    avgScore,\n    output,\n    toolCalls: judgeToolCalls ?? task.meta.eval?.toolCalls,\n    thresholdFailed:\n      Boolean(task.meta.eval?.thresholdFailed) || thresholdFailed,\n  };\n}\n\nfunction isEvalTaskLike(task: unknown): task is EvalTaskLike {\n  if (!task || typeof task !== \"object\") {\n    return false;\n  }\n\n  return (\n    \"meta\" in task &&\n    typeof (task as { meta?: unknown }).meta === \"object\" &&\n    (task as { meta?: unknown }).meta !== null\n  );\n}\n\nfunction formatJudgeOutput(run: HarnessRun) {\n  if (typeof run.output === \"string\") {\n    return run.output;\n  }\n\n  if (run.output !== undefined) {\n    try {\n      return JSON.stringify(run.output);\n    } catch {\n      return String(run.output);\n    }\n  }\n\n  const assistantOutput = resolveAssistantOutput(run.session);\n  if (assistantOutput !== undefined) {\n    return typeof assistantOutput === \"string\"\n      ? assistantOutput\n      : JSON.stringify(assistantOutput);\n  }\n\n  return \"\";\n}\n\nfunction formatJudgeTextOutput(run: HarnessRun) {\n  const assistantOutput = resolveAssistantOutput(run.session);\n  if (assistantOutput === undefined) {\n    return formatJudgeOutput(run);\n  }\n\n  return typeof assistantOutput === \"string\"\n    ? assistantOutput\n    : JSON.stringify(assistantOutput);\n}\n\nfunction buildJudgeAssertionOptions<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  received: unknown,\n  judge: Judge<TJudgeOptions>,\n  options: Omit<JudgeAssertionOptions<TJudgeOptions>, \"threshold\">,\n  task?: EvalTaskLike,\n): TJudgeOptions {\n  const registeredContext = resolveRegisteredJudgeRunContext(\n    received,\n    options,\n    task,\n  );\n  const harness = options.harness ?? registeredContext?.harness;\n  const judgeHarness =\n    options.judgeHarness ??\n    resolveJudgeHarnessForJudge(judge, registeredContext?.judgeHarness);\n  const runJudge = createRunJudge(judgeHarness, registeredContext?.signal);\n  const signal = registeredContext?.signal;\n  const metadata = (options.metadata ??\n    registeredContext?.metadata ??\n    {}) as JudgeAssertionMetadata<TJudgeOptions>;\n  const input =\n    options.input ??\n    (registeredContext?.input as\n      | JudgeAssertionInput<TJudgeOptions>\n      | undefined) ??\n    undefined;\n  const contextualOptions = {\n    ...options,\n    ...(input !== undefined ? { input } : {}),\n  };\n  const run = resolveJudgeRun(\n    received,\n    contextualOptions,\n    registeredContext?.run,\n  );\n  const resolvedInput =\n    input ??\n    (userMessages(run.session)[0]?.content as\n      | JudgeAssertionInput<TJudgeOptions>\n      | undefined) ??\n    undefined;\n  const output = resolveJudgeAssertionOutput<TJudgeOptions>(\n    received,\n    run,\n    options.output,\n  );\n  const resolvedToolCalls = options.toolCalls ?? toolCalls(run.session);\n\n  const { judgeHarness: _judgeHarness, ...judgeParams } = options as Record<\n    string,\n    unknown\n  >;\n\n  return {\n    ...judgeParams,\n    input: resolvedInput,\n    output,\n    metadata,\n    run,\n    session: options.session ?? run.session,\n    signal,\n    toolCalls: resolvedToolCalls,\n    harness,\n    runJudge,\n  } as unknown as TJudgeOptions;\n}\n\nfunction resolveJudgeHarnessForJudge(\n  judge: Pick<Judge<any>, \"judgeHarness\">,\n  fallback: JudgeHarness | undefined,\n) {\n  return judge.judgeHarness ?? fallback;\n}\n\nfunction resolveDefaultJudgeHarness(\n  judges: Array<Pick<Judge<any>, \"judgeHarness\">>,\n) {\n  const configured = judges\n    .map((judge) => judge.judgeHarness)\n    .filter((judgeHarness): judgeHarness is JudgeHarness =>\n      Boolean(judgeHarness),\n    );\n  const [first] = configured;\n\n  if (!first || configured.some((judgeHarness) => judgeHarness !== first)) {\n    return undefined;\n  }\n\n  return first;\n}\n\nfunction resolveRegisteredJudgeRunContext<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  received: unknown,\n  options: Omit<JudgeAssertionOptions<TJudgeOptions>, \"threshold\">,\n  task?: EvalTaskLike,\n) {\n  if (options.run) {\n    return getRegisteredJudgeRunContext(options.run);\n  }\n\n  const receivedContext = getRegisteredJudgeRunContext(received);\n  if (receivedContext) {\n    return receivedContext;\n  }\n\n  if (task?.meta.harness?.run) {\n    return getRegisteredJudgeRunContext(task.meta.harness.run);\n  }\n\n  return undefined;\n}\n\nfunction getRegisteredJudgeRunContext(value: unknown) {\n  return isWeakMapKey(value) ? judgeRunContextByObject.get(value) : undefined;\n}\n\nfunction isWeakMapKey(value: unknown): value is object {\n  return (\n    value !== null && (typeof value === \"object\" || typeof value === \"function\")\n  );\n}\n\nfunction resolveJudgeRun<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  received: unknown,\n  options: Omit<JudgeAssertionOptions<TJudgeOptions>, \"threshold\">,\n  contextualRun?: HarnessRun,\n): HarnessRun {\n  const explicitRun = options.run as HarnessRun | undefined;\n  if (explicitRun) {\n    return options.session\n      ? {\n          ...explicitRun,\n          session: options.session,\n        }\n      : explicitRun;\n  }\n\n  if (isHarnessRun(received)) {\n    return options.session\n      ? {\n          ...received,\n          session: options.session,\n        }\n      : received;\n  }\n\n  if (contextualRun) {\n    return options.session\n      ? {\n          ...contextualRun,\n          session: options.session,\n        }\n      : contextualRun;\n  }\n\n  const session =\n    options.session ??\n    (isNormalizedSession(received)\n      ? received\n      : createSyntheticJudgeSession(received, options));\n\n  return {\n    session,\n    output: inferJudgeOutputValue(received, session),\n    usage: {},\n    errors: [],\n  };\n}\n\nfunction resolveJudgeAssertionOutput<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  received: unknown,\n  run: HarnessRun,\n  explicitOutput?: JudgeAssertionOutput<TJudgeOptions>,\n) {\n  if (explicitOutput !== undefined) {\n    return explicitOutput;\n  }\n\n  if (isHarnessRun(received)) {\n    return received.output as JudgeAssertionOutput<TJudgeOptions> | undefined;\n  }\n\n  if (isNormalizedSession(received)) {\n    return inferJudgeOutputValue(received, run.session) as\n      | JudgeAssertionOutput<TJudgeOptions>\n      | undefined;\n  }\n\n  return normalizeJudgeJsonValue(received) as\n    | JudgeAssertionOutput<TJudgeOptions>\n    | undefined;\n}\n\nfunction createSyntheticJudgeSession<\n  TJudgeOptions extends JudgeContext<any, any, any, any> = JudgeContext,\n>(\n  received: unknown,\n  options: Omit<JudgeAssertionOptions<TJudgeOptions>, \"threshold\">,\n): NormalizedSession {\n  const messages: NormalizedSession[\"messages\"] = [];\n  const userContent = normalizeJudgeJsonValue(options.input);\n  if (userContent !== undefined) {\n    messages.push({\n      role: \"user\",\n      content: userContent,\n    });\n  }\n\n  const assistantContent = normalizeJudgeJsonValue(received);\n  if (assistantContent !== undefined) {\n    messages.push({\n      role: \"assistant\",\n      content: assistantContent,\n    });\n  }\n\n  return {\n    messages,\n  };\n}\n\nfunction inferJudgeOutputValue(\n  received: unknown,\n  session: NormalizedSession,\n): JsonValue | undefined {\n  if (isHarnessRun(received)) {\n    return received.output;\n  }\n\n  if (isNormalizedSession(received)) {\n    return (\n      resolveAssistantOutput(session) ??\n      normalizeJudgeJsonValue(received.messages)\n    );\n  }\n\n  return normalizeJudgeJsonValue(received);\n}\n\nfunction resolveAssistantOutput(session: NormalizedSession) {\n  const assistantContent = latestAssistantMessageContent(session);\n  return assistantContent !== undefined\n    ? normalizeContent(assistantContent)\n    : undefined;\n}\n\nfunction normalizeJudgeJsonValue(value: unknown): JsonValue | undefined {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  return normalizeContent(value);\n}\n\n/**\n * Formats judge results for reporter and assertion output.\n *\n * @param scores - Named judge results to sort and format.\n *\n * @example\n * ```ts\n * const message = formatScores([\n *   {\n *     name: \"RefundStatusJudge\",\n *     score: 0,\n *     metadata: { rationale: \"Expected approved, got denied\" },\n *   },\n * ]);\n * ```\n */\nexport function formatScores(scores: (JudgeResult & { name: string })[]) {\n  return [...scores]\n    .sort((a, b) => (a.score ?? 0) - (b.score ?? 0))\n    .map((s) => {\n      const scoreLine = `${s.name || \"Unknown\"} [${(s.score ?? 0).toFixed(1)}]`;\n      if (\n        ((s.score ?? 0) < 1.0 && s.metadata?.rationale) ||\n        s.metadata?.output\n      ) {\n        let formattedOutput = \"\";\n        if (s.metadata?.output !== undefined) {\n          const output = s.metadata.output;\n          if (typeof output === \"string\") {\n            formattedOutput = `\\noutput  ${wrapText(output)}`;\n          } else {\n            formattedOutput = `\\noutput  ${wrapText(JSON.stringify(output, null, 2))}`;\n          }\n        }\n\n        return `${scoreLine}${\n          s.metadata?.rationale\n            ? `\\nreason  ${wrapText(s.metadata.rationale)}`\n            : \"\"\n        }${formattedOutput}`;\n      }\n      return scoreLine;\n    })\n    .join(\"\\n\\n\");\n}\n\n/**\n * Creates a named judge object from an assessment function.\n *\n * @param name - Stable judge name shown in assertion messages and reports.\n * @param assess - Function that scores one normalized judge context.\n *\n * @example\n * ```ts\n * import { createJudge, type JudgeContext } from \"vitest-evals\";\n *\n * type RefundOutput = { status: \"approved\" | \"denied\" };\n * type RefundMetadata = { expected: { status: RefundOutput[\"status\"] } };\n *\n * export const RefundStatusJudge = createJudge(\n *   \"RefundStatusJudge\",\n *   async ({ output, metadata }: JudgeContext<string, RefundOutput, RefundMetadata>) => ({\n *     score: output.status === metadata.expected.status ? 1 : 0,\n *     metadata: {\n *       rationale: `Expected ${metadata.expected.status}, got ${output.status}`,\n *     },\n *   }),\n * );\n * ```\n *\n * For LLM-backed judges, prefer the object form with `ctx.runJudge(...)` so\n * provider-specific model configuration stays in the judge harness.\n */\nexport function createJudge<TOptions extends JudgeContext<any, any, any, any>>(\n  name: string,\n  assess: JudgeAssessFn<TOptions>,\n): Judge<TOptions>;\nexport function createJudge<TOptions extends JudgeContext<any, any, any, any>>(\n  config: CreateJudgeConfig<TOptions>,\n): Judge<TOptions>;\n/**\n * @deprecated Prefer `createJudge({ name, judgeHarness, assess })` and call\n * `ctx.runJudge(...)` from LLM-backed judges.\n */\nexport function createJudge<\n  TOptions extends JudgeContext<any, any, any, any>,\n  TInput,\n  TOutput,\n>(\n  name: string,\n  assessor: JudgeAssessor<TInput, TOutput>,\n  assess: JudgeAssessWithAssessorFn<TOptions, TInput, TOutput>,\n): Judge<TOptions>;\nexport function createJudge<\n  TOptions extends JudgeContext<any, any, any, any>,\n  TInput,\n  TOutput,\n>(\n  nameOrConfig: string | CreateJudgeConfig<TOptions>,\n  assessOrAssessor?: JudgeAssessFn<TOptions> | JudgeAssessor<TInput, TOutput>,\n  assess?: JudgeAssessWithAssessorFn<TOptions, TInput, TOutput>,\n): Judge<TOptions> {\n  if (typeof nameOrConfig !== \"string\") {\n    return {\n      name: nameOrConfig.name,\n      judgeHarness: nameOrConfig.judgeHarness,\n      assess: nameOrConfig.assess,\n    };\n  }\n\n  const name = nameOrConfig;\n\n  if (!assess) {\n    return {\n      name,\n      assess: assessOrAssessor as JudgeAssessFn<TOptions>,\n    };\n  }\n\n  const assessor = assessOrAssessor as JudgeAssessor<TInput, TOutput>;\n\n  return {\n    name,\n    assess: (opts) =>\n      assess(opts, {\n        assess: (input) =>\n          Promise.resolve(\n            assessor.assess(input, {\n              signal: (opts as { signal?: AbortSignal }).signal,\n            }),\n          ),\n      }),\n  };\n}\n\nexport { wrapText } from \"./wrapText\";\nexport {\n  assistantMessages,\n  attachHarnessRunToError,\n  createFailedHarnessRun,\n  createGenAiUsageAttributes,\n  createHarness,\n  createToolCallSpans,\n  ensureRunTrace,\n  failedSpans,\n  getHarnessRunFromError,\n  latestAssistantMessageContent,\n  messagesByRole,\n  normalizeHarnessRun,\n  normalizeSpanAttributes,\n  normalizeSpanError,\n  spans,\n  spansByKind,\n  systemMessages,\n  toJsonValue,\n  toolCalls,\n  toolMessages,\n  userMessages,\n  type CreateToolCallSpansOptions,\n  type EnsureRunTraceOptions,\n  type CreateHarnessOptions,\n  type CreateHarnessRunArgs,\n  type Harness,\n  type HarnessContext,\n  type HarnessMetadata,\n  type HarnessResultLike,\n  type HarnessRun,\n  type HarnessRunError,\n  type GenAiOperationName,\n  type GenAiOutputType,\n  type GenAiProviderName,\n  type GenAiSemanticAttributeKey,\n  type GenAiSemanticAttributes,\n  type GenAiTokenType,\n  type GenAiToolType,\n  type JsonPrimitive,\n  type JsonValue,\n  type MaybePromise,\n  type NormalizedMessage,\n  type NormalizedSession,\n  type NormalizedSpan,\n  type NormalizedSpanAttributes,\n  type NormalizedSpanAttributeKey,\n  type NormalizedSpanEvent,\n  type NormalizedTrace,\n  type OpenTelemetrySemanticAttributeKey,\n  type OpenTelemetrySemanticAttributes,\n  type SimpleHarnessResult,\n  type SimpleSpanEvent,\n  type SimpleSpanRecord,\n  type SimpleTraceRecord,\n  type SimpleToolCallRecord,\n  type TimingSummary,\n  type ToolCallRecord,\n  type UsageSummary,\n} from \"./harness\";\n\nexport {\n  FactualityJudge,\n  type FactualityJudgeChoice,\n  type FactualityJudgeConfig,\n  type FactualityJudgeExpected,\n  type FactualityJudgeOptions,\n  type FactualityJudgePrompt,\n  type FactualityJudgeVerdict,\n  createJudgeHarness,\n  runJudgeHarness,\n  type CreateJudgeHarnessOptions,\n  type CreateJudgeHarnessRunOptions,\n  type JudgeHarness,\n  type JudgeHarnessInput,\n  type JudgeHarnessOutput,\n  type RunJudge,\n  type RunJudgeOptions,\n  StructuredOutputJudge,\n  type StructuredOutputJudgeConfig,\n  type StructuredOutputJudgeExpected,\n  type StructuredOutputJudgeOptions,\n  ToolCallJudge,\n  type ToolCallJudgeConfig,\n  type ToolCallJudgeExpectedTool,\n  type ToolCallJudgeOptions,\n} from \"./judges\";\nexport type {\n  BoundJudgeAssessor,\n  Judge,\n  JudgeAssessFn,\n  JudgeAssessWithAssessorFn,\n  JudgeAssessor,\n  JudgeAssessorOptions,\n  JudgeContext,\n  JudgeOptions,\n  JudgeResult,\n} from \"./judges/types\";\nexport type {\n  BaseMatcherConfig,\n  FuzzyMatchOptions,\n  MatchStrategy,\n} from \"./internal/matchers\";\n","import {\n  assistantMessages,\n  failedSpans,\n  latestAssistantMessageContent,\n  messagesByRole,\n  spans,\n  spansByKind,\n  systemMessages,\n  toolCalls,\n  toolMessages,\n  userMessages,\n} from \"@vitest-evals/core\";\nimport type {\n  GenAiOperationName,\n  HarnessRun,\n  HarnessRunError,\n  JsonPrimitive,\n  JsonValue,\n  NormalizedMessage,\n  NormalizedSession,\n  NormalizedSpan,\n  NormalizedSpanAttributes,\n  NormalizedSpanEvent,\n  NormalizedTrace,\n  TimingSummary,\n  ToolCallRecord,\n  UsageSummary,\n} from \"@vitest-evals/core\";\n\nexport {\n  assistantMessages,\n  failedSpans,\n  latestAssistantMessageContent,\n  messagesByRole,\n  spans,\n  spansByKind,\n  systemMessages,\n  toolCalls,\n  toolMessages,\n  userMessages,\n} from \"@vitest-evals/core\";\nexport type {\n  GenAiOperationName,\n  GenAiOutputType,\n  GenAiProviderName,\n  GenAiSemanticAttributeKey,\n  GenAiSemanticAttributes,\n  GenAiTokenType,\n  GenAiToolType,\n  HarnessRun,\n  HarnessRunError,\n  JsonPrimitive,\n  JsonValue,\n  NormalizedMessage,\n  NormalizedSession,\n  NormalizedSpan,\n  NormalizedSpanAttributeKey,\n  NormalizedSpanAttributes,\n  NormalizedSpanEvent,\n  NormalizedTrace,\n  OpenTelemetrySemanticAttributeKey,\n  OpenTelemetrySemanticAttributes,\n  TimingSummary,\n  ToolCallRecord,\n  UsageSummary,\n} from \"@vitest-evals/core\";\n\n/** Options for converting normalized tool calls into trace spans. */\nexport type CreateToolCallSpansOptions = {\n  /** Trace id to attach to each generated tool span. */\n  traceId?: string;\n  /** Parent span id to attach to each generated tool span. */\n  parentId?: string;\n  /** Prefix used to create internal span ids instead of reusing tool-call ids. */\n  spanIdPrefix?: string;\n};\n\n/** Options for attaching a fallback run trace to a harness result. */\nexport type EnsureRunTraceOptions = {\n  /** Human-readable run or harness name. */\n  name: string;\n  /** Wall-clock start time for the harness run. */\n  startedAt: Date;\n  /** Wall-clock finish time for the harness run. */\n  finishedAt: Date;\n  /** Optional trace id. A generated id is used when omitted. */\n  id?: string;\n  /** GenAI operation name to place on the root run span. */\n  operationName?: GenAiOperationName;\n  /** Optional JSON-safe source marker for the trace metadata. */\n  source?: string;\n};\n\ntype OutputField<TOutput extends JsonValue | undefined> =\n  undefined extends TOutput ? { output?: TOutput } : { output: TOutput };\n\n/** Per-run metadata shape accepted by harnesses and eval tests. */\nexport type HarnessMetadata = Record<string, unknown>;\n\n/**\n * Runtime context passed from the eval fixture into a harness run.\n *\n * @example\n * ```ts\n * const harness: Harness<string> = {\n *   name: \"refund-agent\",\n *   async run(input, context) {\n *     context.setArtifact(\"inputLength\", input.length);\n *\n *     return {\n *       output: undefined,\n *       session: { messages: [{ role: \"user\", content: input }] },\n *       usage: {},\n *       errors: [],\n *     };\n *   },\n * };\n * ```\n */\nexport type HarnessContext<\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n> = {\n  /** Per-run metadata passed through `run(input, { metadata })`. */\n  metadata: Readonly<TMetadata>;\n  /** Abort signal from Vitest when available. */\n  signal?: AbortSignal;\n  /** Mutable JSON-safe artifact bag shared with the harness. */\n  artifacts: Record<string, JsonValue>;\n  /** Stores one JSON-safe artifact on the current run. */\n  setArtifact: (name: string, value: JsonValue) => void;\n};\n\n/**\n * Adapter that executes the system under test and returns a normalized run.\n *\n * @example\n * ```ts\n * const harness: Harness<string, { status: \"approved\" | \"denied\" }> = {\n *   name: \"refund-agent\",\n *   async run(input, context) {\n *     return normalizeHarnessRun(input, await runRefundFlow(input), context);\n *   },\n * };\n * ```\n */\nexport type Harness<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n> = {\n  /** Stable harness name used in reports. */\n  name: string;\n  /** Executes the system under test and returns a normalized run. */\n  run: (\n    input: TInput,\n    context: HarnessContext<TMetadata>,\n  ) => Promise<HarnessRun<TOutput>>;\n};\n\n/** Value or promise accepted by lightweight harness callbacks. */\nexport type MaybePromise<T> = T | Promise<T>;\n\n/** Lightweight tool-call record accepted by `createHarness(...)` results. */\nexport type SimpleToolCallRecord = Omit<\n  ToolCallRecord,\n  \"arguments\" | \"result\" | \"error\" | \"metadata\"\n> & {\n  /** Raw tool arguments accepted by `createHarness(...)` before normalization. */\n  arguments?: unknown;\n  /** Raw tool result accepted by `createHarness(...)` before normalization. */\n  result?: unknown;\n  /** Raw tool error accepted by `createHarness(...)` before normalization. */\n  error?: unknown;\n  /** Raw tool metadata accepted by `createHarness(...)` before normalization. */\n  metadata?: Record<string, unknown>;\n};\n\n/** Lightweight span event accepted by `createHarness(...)` results. */\nexport type SimpleSpanEvent = Omit<NormalizedSpanEvent, \"attributes\"> & {\n  /** Raw event attributes accepted by `createHarness(...)` before normalization. */\n  attributes?: Record<string, unknown>;\n};\n\n/** Lightweight span record accepted by `createHarness(...)` results. */\nexport type SimpleSpanRecord = Omit<\n  NormalizedSpan,\n  \"attributes\" | \"error\" | \"events\"\n> & {\n  /** Raw span attributes accepted by `createHarness(...)` before normalization. */\n  attributes?: Record<string, unknown>;\n  /** Raw span error accepted by `createHarness(...)` before normalization. */\n  error?: unknown;\n  /** Raw span events accepted by `createHarness(...)` before normalization. */\n  events?: SimpleSpanEvent[];\n};\n\n/** Lightweight trace record accepted by `createHarness(...)` results. */\nexport type SimpleTraceRecord = Omit<NormalizedTrace, \"metadata\" | \"spans\"> & {\n  /** Raw trace metadata accepted by `createHarness(...)` before normalization. */\n  metadata?: Record<string, unknown>;\n  /** Lightweight spans to normalize into the trace. */\n  spans: SimpleSpanRecord[];\n};\n\n/**\n * Lightweight result shape normalized by `createHarness(...)`.\n *\n * @example\n * ```ts\n * const result: SimpleHarnessResult<{ status: \"approved\" }> = {\n *   output: { status: \"approved\" },\n *   toolCalls: [{ name: \"lookupInvoice\", arguments: { invoiceId: \"inv_123\" } }],\n *   usage: { totalTokens: 260 },\n * };\n * ```\n */\nexport type SimpleHarnessResult<\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n> = OutputField<TOutput> & {\n  /** Pre-normalized transcript messages. When omitted, a default user/assistant transcript is created. */\n  messages?: NormalizedMessage[];\n  /** Lightweight tool-call records to normalize into the session. */\n  toolCalls?: SimpleToolCallRecord[];\n  /** Usage summary to attach to the run. */\n  usage?: UsageSummary;\n  /** Timing summary to attach to the run. */\n  timings?: TimingSummary;\n  /** Raw artifact values to normalize and merge into the run. */\n  artifacts?: Record<string, unknown>;\n  /** Lightweight traces and spans to normalize into the run. */\n  traces?: SimpleTraceRecord[];\n  /** Raw session metadata to normalize into the session. */\n  metadata?: Record<string, unknown>;\n  /** Raw errors to normalize into the run. */\n  errors?: unknown[];\n};\n\n/** Either a complete normalized run or a lightweight result to normalize. */\nexport type HarnessResultLike<\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n> = HarnessRun<TOutput> | SimpleHarnessResult<TOutput>;\n\n/** Arguments passed to the `createHarness(...)` convenience callback. */\nexport type CreateHarnessRunArgs<TInput, TMetadata extends HarnessMetadata> = {\n  /** Original input passed to `run(input)`. */\n  input: TInput;\n  /** Read-only metadata passed to `run(input, { metadata })`. */\n  metadata: Readonly<TMetadata>;\n  /** Abort signal from Vitest when available. */\n  signal?: AbortSignal;\n  /** Mutable run artifact bag. */\n  artifacts: HarnessContext<TMetadata>[\"artifacts\"];\n  /** Stores one JSON-safe artifact on the current run. */\n  setArtifact: HarnessContext<TMetadata>[\"setArtifact\"];\n};\n\n/**\n * Options for creating a lightweight custom application harness.\n *\n * @example\n * ```ts\n * const options: CreateHarnessOptions<string, { status: \"approved\" }> = {\n *   name: \"refund-agent\",\n *   run: async ({ input }) => ({\n *     output: await classifyRefund(input),\n *   }),\n * };\n * ```\n */\nexport type CreateHarnessOptions<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n> = {\n  /** Stable harness name used in reports. */\n  name: string;\n  /** Executes application code and returns either a lightweight result or full `HarnessRun`. */\n  run: (\n    args: CreateHarnessRunArgs<TInput, TMetadata>,\n  ) => MaybePromise<HarnessResultLike<TOutput>>;\n};\n\nfunction isJsonPrimitive(value: unknown): value is JsonPrimitive {\n  return (\n    value === null ||\n    typeof value === \"string\" ||\n    typeof value === \"boolean\" ||\n    (typeof value === \"number\" && Number.isFinite(value))\n  );\n}\n\nfunction isJsonRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeJsonArray(value: unknown[], seen: WeakSet<object>) {\n  if (seen.has(value)) {\n    return undefined;\n  }\n\n  seen.add(value);\n  const normalized = value.map((item) => {\n    const normalized = toJsonValueInternal(item, seen);\n    return normalized === undefined ? null : normalized;\n  });\n  seen.delete(value);\n\n  return normalized;\n}\n\nfunction normalizeJsonObject(\n  value: Record<string, unknown>,\n  seen: WeakSet<object>,\n): Record<string, JsonValue> {\n  const normalized: Record<string, JsonValue> = {};\n\n  if (seen.has(value)) {\n    return normalized;\n  }\n\n  seen.add(value);\n  try {\n    for (const [key, entryValue] of Object.entries(value)) {\n      const entry = toJsonValueInternal(entryValue, seen);\n      if (entry !== undefined) {\n        normalized[key] = entry;\n      }\n    }\n  } finally {\n    seen.delete(value);\n  }\n\n  return normalized;\n}\n\n/** Returns true when a value exposes a callable method with the given name. */\nexport function hasCallableMethod(value: unknown, methodName: string) {\n  return (\n    value !== null &&\n    (typeof value === \"object\" || typeof value === \"function\") &&\n    methodName in value &&\n    typeof (value as Record<string, unknown>)[methodName] === \"function\"\n  );\n}\n\n/** Normalizes an unknown value into the JSON-safe shape used by harness runs. */\nexport function toJsonValue(value: unknown): JsonValue | undefined {\n  return toJsonValueInternal(value, new WeakSet());\n}\n\nfunction toJsonValueInternal(\n  value: unknown,\n  seen: WeakSet<object>,\n): JsonValue | undefined {\n  if (isJsonPrimitive(value)) {\n    return value;\n  }\n\n  if (\n    value !== null &&\n    typeof value === \"object\" &&\n    seen.has(value as object)\n  ) {\n    return undefined;\n  }\n\n  if (Array.isArray(value)) {\n    return normalizeJsonArray(value, seen);\n  }\n\n  if (isJsonRecord(value)) {\n    return normalizeJsonObject(value, seen);\n  }\n\n  return undefined;\n}\n\n/** Drops non-JSON properties from a record while preserving valid values. */\nexport function normalizeRecord(\n  value: Record<string, unknown>,\n): Record<string, JsonValue> {\n  return normalizeJsonObject(value, new WeakSet());\n}\n\n/** Normalizes metadata and omits the field entirely when nothing survives. */\nexport function normalizeMetadata(\n  value: Record<string, unknown>,\n): Record<string, JsonValue> | undefined {\n  const normalized = normalizeRecord(value);\n  return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/** Converts arbitrary content into the JSON-safe message content shape. */\nexport function normalizeContent(value: unknown): JsonValue {\n  const normalized = toJsonValue(value);\n  return normalized !== undefined ? normalized : String(value);\n}\n\n/**\n * Creates a harness from the common \"run app code and return output\" shape.\n *\n * @param options - Harness name plus the callback that executes app code.\n *\n * @example\n * ```ts\n * import { createHarness } from \"vitest-evals\";\n *\n * export const refundHarness = createHarness<\n *   string,\n *   { status: \"approved\" | \"denied\" },\n *   { expected: { status: \"approved\" | \"denied\" } }\n * >({\n *   name: \"refund-agent\",\n *   run: async ({ input, metadata, setArtifact }) => {\n *     const result = await runRefundFlow(input, metadata);\n *     const output = { status: result.status };\n *\n *     setArtifact(\"case\", { expected: metadata.expected.status });\n *\n *     return {\n *       output,\n *       toolCalls: result.toolCalls,\n *       usage: { provider: \"openai\", model: \"gpt-4o-mini\" },\n *     };\n *   },\n * });\n * ```\n */\nexport function createHarness<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n>(\n  options: CreateHarnessOptions<TInput, TOutput, TMetadata>,\n): Harness<TInput, TOutput, TMetadata>;\nexport function createHarness<\n  TInput = unknown,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n>(\n  options: CreateHarnessOptions<TInput, TOutput, TMetadata>,\n): Harness<TInput, TOutput, TMetadata> {\n  const harness: Harness<TInput, TOutput, TMetadata> = {\n    name: options.name,\n    run: async (input, context) => {\n      const startedAt = new Date();\n\n      try {\n        const result = await options.run({\n          input,\n          metadata: context.metadata,\n          signal: context.signal,\n          artifacts: context.artifacts,\n          setArtifact: context.setArtifact,\n        });\n        const run = normalizeHarnessRun(input, result, context);\n        ensureRunTrace(run, {\n          name: options.name,\n          startedAt,\n          finishedAt: new Date(),\n        });\n\n        return run;\n      } catch (error) {\n        const partialRun = getHarnessRunFromError(error);\n        if (partialRun) {\n          if (\n            Object.keys(context.artifacts).length > 0 &&\n            !partialRun.artifacts\n          ) {\n            partialRun.artifacts = context.artifacts;\n          }\n          ensureRunTrace(partialRun, {\n            name: options.name,\n            startedAt,\n            finishedAt: new Date(),\n          });\n          throw attachHarnessRunToError(error, partialRun);\n        }\n\n        const failedRun = createFailedHarnessRun(input, error, {\n          artifacts: context.artifacts,\n        });\n        ensureRunTrace(failedRun, {\n          name: options.name,\n          startedAt,\n          finishedAt: new Date(),\n        });\n\n        throw attachHarnessRunToError(error, failedRun);\n      }\n    },\n  };\n\n  return harness;\n}\n\n/**\n * Normalizes a lightweight harness result into the reporter-facing run shape.\n *\n * @param input - Original input passed to the harness.\n * @param result - Lightweight result or pre-normalized harness run.\n * @param context - Optional per-run context used to merge artifacts.\n *\n * @example\n * ```ts\n * const run = normalizeHarnessRun(\"Refund invoice inv_123\", {\n *   output: { status: \"approved\" },\n *   toolCalls: [{ name: \"lookupInvoice\", arguments: { invoiceId: \"inv_123\" } }],\n *   usage: { provider: \"openai\", model: \"gpt-4o-mini\" },\n * });\n *\n * expect(toolCalls(run.session)).toHaveLength(1);\n * ```\n */\nexport function normalizeHarnessRun<\n  TInput = unknown,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n>(\n  input: TInput,\n  result: HarnessResultLike<TOutput>,\n  context?: HarnessContext<TMetadata>,\n): HarnessRun<TOutput> {\n  if (isHarnessRun(result)) {\n    if (\n      context &&\n      Object.keys(context.artifacts).length > 0 &&\n      !result.artifacts\n    ) {\n      return {\n        ...result,\n        artifacts: context.artifacts,\n      };\n    }\n\n    return result;\n  }\n\n  const output = result.output;\n  const toolCalls = normalizeSimpleToolCalls(result.toolCalls);\n  const usage = result.usage ?? {};\n  const messages =\n    result.messages ??\n    createDefaultSessionMessages({\n      input,\n      output,\n      toolCalls,\n    });\n  const metadata = result.metadata\n    ? normalizeMetadata(result.metadata)\n    : undefined;\n  const artifacts = normalizeMergedArtifacts(\n    context?.artifacts,\n    result.artifacts,\n  );\n  const traces = normalizeSimpleTraces(result.traces);\n\n  return {\n    session: {\n      messages,\n      ...(usage.provider ? { provider: usage.provider } : {}),\n      ...(usage.model ? { model: usage.model } : {}),\n      ...(metadata ? { metadata } : {}),\n    },\n    ...(output !== undefined ? { output } : {}),\n    usage,\n    ...(result.timings ? { timings: result.timings } : {}),\n    ...(artifacts ? { artifacts } : {}),\n    ...(traces ? { traces } : {}),\n    errors: normalizeSimpleErrors(result.errors),\n  } as HarnessRun<TOutput>;\n}\n\n/**\n * Builds a JSON-safe failed run for errors that happen before a harness can return.\n *\n * @param input - Original input passed to the harness.\n * @param error - Error thrown by setup or execution.\n * @param options - Optional artifacts to preserve on the failed run.\n */\nexport function createFailedHarnessRun(\n  input: unknown,\n  error: unknown,\n  options: { artifacts?: Record<string, JsonValue> } = {},\n): HarnessRun {\n  const artifacts = options.artifacts;\n\n  return {\n    session: {\n      messages: [\n        {\n          role: \"user\",\n          content: normalizeContent(input),\n        },\n      ],\n    },\n    usage: {},\n    ...(artifacts && Object.keys(artifacts).length > 0 ? { artifacts } : {}),\n    errors: [serializeError(error)],\n  };\n}\n\nfunction createDefaultSessionMessages<TInput>({\n  input,\n  output,\n  toolCalls: normalizedToolCalls,\n}: {\n  input: TInput;\n  output: JsonValue | undefined;\n  toolCalls: ToolCallRecord[];\n}): NormalizedMessage[] {\n  const messages: NormalizedMessage[] = [\n    {\n      role: \"user\",\n      content: normalizeContent(input),\n    },\n  ];\n\n  if (output !== undefined || normalizedToolCalls.length > 0) {\n    messages.push({\n      role: \"assistant\",\n      ...(output !== undefined ? { content: normalizeContent(output) } : {}),\n      ...(normalizedToolCalls.length > 0\n        ? { toolCalls: normalizedToolCalls }\n        : {}),\n    });\n  }\n\n  return messages;\n}\n\nfunction normalizeSimpleToolCalls(\n  calls: SimpleToolCallRecord[] | undefined,\n): ToolCallRecord[] {\n  return (calls ?? []).map((call) => {\n    const {\n      arguments: rawArguments,\n      result: rawResult,\n      error: rawError,\n      metadata: rawMetadata,\n      ...toolCall\n    } = call;\n    const args = normalizeToolCallArguments(rawArguments);\n    const result = toJsonValue(rawResult);\n    const error = normalizeToolCallError(rawError);\n    const metadata = rawMetadata ? normalizeMetadata(rawMetadata) : undefined;\n\n    return {\n      ...toolCall,\n      ...(args ? { arguments: args } : {}),\n      ...(result !== undefined ? { result } : {}),\n      ...(error ? { error } : {}),\n      ...(metadata ? { metadata } : {}),\n    };\n  });\n}\n\nfunction normalizeToolCallArguments(\n  value: unknown,\n): Record<string, JsonValue> | undefined {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  const normalized = toJsonValue(value);\n  return normalized &&\n    typeof normalized === \"object\" &&\n    !Array.isArray(normalized)\n    ? normalized\n    : undefined;\n}\n\nfunction normalizeToolCallError(\n  value: unknown,\n): ToolCallRecord[\"error\"] | undefined {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  const serialized = serializeError(value);\n  const { message, type, ...details } = serialized;\n\n  return {\n    ...details,\n    message: typeof message === \"string\" ? message : String(message),\n    ...(typeof type === \"string\" ? { type } : {}),\n  };\n}\n\nfunction normalizeMergedArtifacts(\n  contextArtifacts: Record<string, JsonValue> | undefined,\n  resultArtifacts: Record<string, unknown> | undefined,\n) {\n  const artifacts = {\n    ...(contextArtifacts ?? {}),\n    ...(resultArtifacts ? normalizeRecord(resultArtifacts) : {}),\n  };\n\n  return Object.keys(artifacts).length > 0 ? artifacts : undefined;\n}\n\nfunction normalizeSimpleErrors(\n  errors: unknown[] | undefined,\n): Array<Record<string, JsonValue>> {\n  return (errors ?? []).map((error) => {\n    const normalized = toJsonValue(error);\n\n    if (\n      normalized &&\n      typeof normalized === \"object\" &&\n      !Array.isArray(normalized) &&\n      Object.keys(normalized).length > 0\n    ) {\n      return normalized;\n    }\n\n    return serializeError(error);\n  });\n}\n\nfunction normalizeSimpleTraces(\n  traces: SimpleTraceRecord[] | undefined,\n): NormalizedTrace[] | undefined {\n  if (!Array.isArray(traces)) {\n    return undefined;\n  }\n\n  const normalized = traces\n    .map(normalizeSimpleTrace)\n    .filter((trace): trace is NormalizedTrace => Boolean(trace));\n\n  return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction normalizeSimpleTrace(trace: unknown): NormalizedTrace | undefined {\n  if (!isJsonRecord(trace)) {\n    return undefined;\n  }\n\n  const {\n    metadata: rawMetadata,\n    spans: rawSpans,\n    ...traceFields\n  } = trace as Partial<SimpleTraceRecord>;\n  const spans = (Array.isArray(rawSpans) ? rawSpans : [])\n    .map((span) => normalizeSimpleSpan(span))\n    .filter((span): span is NormalizedSpan => Boolean(span));\n  const metadata = isJsonRecord(rawMetadata)\n    ? normalizeMetadata(rawMetadata)\n    : undefined;\n\n  if (spans.length === 0 && !traceFields.id && !traceFields.name) {\n    return undefined;\n  }\n\n  return {\n    ...traceFields,\n    ...(metadata ? { metadata } : {}),\n    spans,\n  };\n}\n\nfunction normalizeSimpleSpan(span: unknown): NormalizedSpan | undefined {\n  if (!isJsonRecord(span) || typeof span.name !== \"string\" || !span.name) {\n    return undefined;\n  }\n\n  const {\n    attributes: rawAttributes,\n    error: rawError,\n    events: rawEvents,\n    ...spanFields\n  } = span as Partial<SimpleSpanRecord> & { name: string };\n  const attributes = rawAttributes\n    ? isJsonRecord(rawAttributes)\n      ? normalizeMetadata(rawAttributes)\n      : undefined\n    : undefined;\n  const error = normalizeSpanError(rawError);\n  const events = normalizeSimpleSpanEvents(rawEvents);\n\n  return {\n    ...spanFields,\n    ...(attributes\n      ? { attributes: attributes as NormalizedSpanAttributes }\n      : {}),\n    ...(error ? { error } : {}),\n    ...(events ? { events } : {}),\n  };\n}\n\nfunction normalizeSimpleSpanEvents(\n  events: unknown,\n): NormalizedSpanEvent[] | undefined {\n  if (!Array.isArray(events)) {\n    return undefined;\n  }\n\n  const normalized = events\n    .map(normalizeSimpleSpanEvent)\n    .filter((event): event is NormalizedSpanEvent => Boolean(event));\n\n  return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction normalizeSimpleSpanEvent(\n  event: unknown,\n): NormalizedSpanEvent | undefined {\n  if (!isJsonRecord(event) || typeof event.name !== \"string\" || !event.name) {\n    return undefined;\n  }\n\n  const { attributes: rawAttributes, ...eventFields } =\n    event as Partial<SimpleSpanEvent> & { name: string };\n  const attributes = rawAttributes\n    ? isJsonRecord(rawAttributes)\n      ? normalizeMetadata(rawAttributes)\n      : undefined\n    : undefined;\n\n  return {\n    ...eventFields,\n    ...(attributes\n      ? { attributes: attributes as NormalizedSpanAttributes }\n      : {}),\n  };\n}\n\n/** Normalizes arbitrary span errors while preserving object-shaped messages. */\nexport function normalizeSpanError(\n  error: unknown,\n): NormalizedSpan[\"error\"] | undefined {\n  if (error === undefined) {\n    return undefined;\n  }\n\n  if (error instanceof Error) {\n    const details = normalizeMetadata(\n      error as unknown as Record<string, unknown>,\n    );\n\n    return {\n      ...(details ?? {}),\n      type: error.name,\n      message: error.message,\n    };\n  }\n\n  if (\n    error &&\n    typeof error === \"object\" &&\n    !Array.isArray(error) &&\n    typeof (error as { message?: unknown }).message === \"string\"\n  ) {\n    const normalized = normalizeMetadata(error as Record<string, unknown>);\n    const { message, type, ...details } = normalized ?? {};\n\n    return {\n      ...details,\n      message: message as string,\n      ...(typeof type === \"string\" ? { type } : {}),\n    };\n  }\n\n  const serialized = serializeError(error);\n  const { message, type, ...details } = serialized;\n\n  return {\n    ...details,\n    message: typeof message === \"string\" ? message : String(message),\n    ...(typeof type === \"string\" ? { type } : {}),\n  };\n}\n\n/** Normalizes raw span attributes into the JSON-safe span attribute shape. */\nexport function normalizeSpanAttributes(\n  attributes: Record<string, unknown>,\n): NormalizedSpanAttributes | undefined {\n  return normalizeMetadata(attributes) as NormalizedSpanAttributes | undefined;\n}\n\n/** Builds common OpenTelemetry GenAI usage attributes from a usage summary. */\nexport function createGenAiUsageAttributes(\n  usage: UsageSummary | undefined,\n  options: { provider?: string } = {},\n) {\n  return {\n    \"gen_ai.provider.name\": usage?.provider ?? options.provider,\n    \"gen_ai.request.model\": usage?.model,\n    \"gen_ai.response.model\": usage?.model,\n    \"gen_ai.usage.input_tokens\": usage?.inputTokens,\n    \"gen_ai.usage.output_tokens\": usage?.outputTokens,\n    \"gen_ai.usage.reasoning.output_tokens\": usage?.reasoningTokens,\n  } satisfies Record<string, unknown>;\n}\n\n/**\n * Converts normalized tool-call records into trace spans.\n *\n * Tool-call ids are preserved as GenAI attributes. Pass `spanIdPrefix` when the\n * spans belong to a known trace so span ids stay internally unique.\n */\nexport function createToolCallSpans(\n  calls: ToolCallRecord[],\n  options: CreateToolCallSpansOptions = {},\n): NormalizedSpan[] {\n  return calls.map((call, index) => {\n    const spanError = call.error ? normalizeSpanError(call.error) : undefined;\n    const spanId = options.spanIdPrefix\n      ? `${options.spanIdPrefix}:${index + 1}`\n      : call.id;\n\n    return {\n      ...(spanId ? { id: spanId } : {}),\n      ...(options.traceId ? { traceId: options.traceId } : {}),\n      ...(options.parentId ? { parentId: options.parentId } : {}),\n      name: call.name,\n      kind: \"tool\",\n      ...(call.startedAt ? { startedAt: call.startedAt } : {}),\n      ...(call.finishedAt ? { finishedAt: call.finishedAt } : {}),\n      ...(call.durationMs !== undefined ? { durationMs: call.durationMs } : {}),\n      status: spanError ? \"error\" : \"ok\",\n      ...(spanError ? { error: spanError } : {}),\n      attributes: normalizeSpanAttributes({\n        \"gen_ai.operation.name\": \"execute_tool\",\n        \"gen_ai.tool.name\": call.name,\n        \"gen_ai.tool.type\": \"function\",\n        ...(call.id ? { \"gen_ai.tool.call.id\": call.id } : {}),\n        ...(call.arguments !== undefined\n          ? { \"gen_ai.tool.call.arguments\": call.arguments }\n          : {}),\n        ...(call.result !== undefined\n          ? { \"gen_ai.tool.call.result\": call.result }\n          : {}),\n      }),\n    } satisfies NormalizedSpan;\n  });\n}\n\n/**\n * Attaches a fallback run trace when a harness result does not already contain spans.\n *\n * This keeps custom harnesses inspectable while first-party harness packages\n * remain free to attach richer native traces.\n */\nexport function ensureRunTrace(\n  run: HarnessRun,\n  options: EnsureRunTraceOptions,\n): NormalizedTrace | undefined {\n  if (spans(run).length > 0) {\n    return undefined;\n  }\n\n  const traceId = options.id ?? createGeneratedTraceId();\n  const rootSpanId = `${traceId}:run`;\n  const durationMs = options.finishedAt.getTime() - options.startedAt.getTime();\n  const rootError =\n    run.errors.length > 0 ? normalizeSpanError(run.errors[0]) : undefined;\n  const runSpan: NormalizedSpan = {\n    id: rootSpanId,\n    traceId,\n    name: options.name,\n    kind: \"run\",\n    startedAt: options.startedAt.toISOString(),\n    finishedAt: options.finishedAt.toISOString(),\n    durationMs,\n    status: rootError ? \"error\" : \"ok\",\n    ...(rootError ? { error: rootError } : {}),\n    attributes: normalizeSpanAttributes({\n      \"gen_ai.operation.name\": options.operationName ?? \"invoke_workflow\",\n      \"gen_ai.workflow.name\": options.name,\n      ...createGenAiUsageAttributes(run.usage),\n    }),\n  };\n  const toolSpans = createToolCallSpans(toolCalls(run.session), {\n    traceId,\n    parentId: rootSpanId,\n    spanIdPrefix: `${traceId}:tool`,\n  });\n  const trace: NormalizedTrace = {\n    id: traceId,\n    name: options.name,\n    startedAt: options.startedAt.toISOString(),\n    finishedAt: options.finishedAt.toISOString(),\n    durationMs,\n    ...(options.source ? { metadata: { source: options.source } } : {}),\n    spans: [runSpan, ...toolSpans],\n  };\n\n  run.traces = [trace];\n  return trace;\n}\n\nlet nextGeneratedTraceId = 0;\n\nfunction createGeneratedTraceId() {\n  nextGeneratedTraceId += 1;\n  return `trace_${nextGeneratedTraceId}`;\n}\n\n/**\n * Attaches a partial or complete harness run to an arbitrary thrown error.\n *\n * @param error - Thrown value to wrap.\n * @param run - Partial or complete normalized harness run to preserve.\n *\n * @example\n * ```ts\n * try {\n *   return await runAgent(input);\n * } catch (error) {\n *   throw attachHarnessRunToError(error, partialRun);\n * }\n * ```\n */\nexport function attachHarnessRunToError(\n  error: unknown,\n  run: HarnessRun,\n): HarnessRunError {\n  const baseError =\n    error instanceof Error\n      ? error\n      : new Error(String(error ?? \"Unknown error\"));\n  return Object.assign(baseError, {\n    vitestEvalsRun: run,\n  });\n}\n\n/**\n * Reads an attached harness run back off a previously wrapped error value.\n *\n * @param error - Unknown thrown value that may contain a harness run.\n *\n * @example\n * ```ts\n * const partialRun = getHarnessRunFromError(error);\n *\n * if (partialRun) {\n *   console.log(toolCalls(partialRun.session));\n * }\n * ```\n */\nexport function getHarnessRunFromError(error: unknown): HarnessRun | undefined {\n  if (\n    error &&\n    typeof error === \"object\" &&\n    \"vitestEvalsRun\" in error &&\n    isHarnessRun((error as { vitestEvalsRun?: unknown }).vitestEvalsRun)\n  ) {\n    return (error as { vitestEvalsRun: HarnessRun }).vitestEvalsRun;\n  }\n\n  return undefined;\n}\n\n/** Returns true when a value matches the normalized `HarnessRun` contract. */\nexport function isHarnessRun(value: unknown): value is HarnessRun {\n  if (!value || typeof value !== \"object\") {\n    return false;\n  }\n\n  const candidate = value as {\n    session?: unknown;\n    usage?: unknown;\n    errors?: unknown;\n  };\n\n  return (\n    isNormalizedSession(candidate.session) &&\n    Boolean(candidate.usage) &&\n    typeof candidate.usage === \"object\" &&\n    !Array.isArray(candidate.usage) &&\n    Array.isArray(candidate.errors)\n  );\n}\n\n/** Returns true when a value matches the normalized session contract. */\nexport function isNormalizedSession(\n  value: unknown,\n): value is NormalizedSession {\n  return (\n    Boolean(value) &&\n    typeof value === \"object\" &&\n    value !== null &&\n    \"messages\" in value &&\n    Array.isArray((value as { messages?: unknown }).messages)\n  );\n}\n\n/** Reuses pre-normalized harness errors when a runtime already returns them. */\nexport function resolveHarnessRunErrors(\n  result: unknown,\n): Array<Record<string, JsonValue>> {\n  if (\n    result &&\n    typeof result === \"object\" &&\n    Array.isArray((result as Record<string, unknown>).errors)\n  ) {\n    return (result as { errors: Array<Record<string, JsonValue>> }).errors;\n  }\n\n  return [];\n}\n\n/** Serializes an arbitrary thrown value into the normalized error shape. */\nexport function serializeError(error: unknown): Record<string, JsonValue> {\n  if (error instanceof Error) {\n    return {\n      type: error.name,\n      message: error.message,\n    };\n  }\n\n  return {\n    type: \"Error\",\n    message: String(error),\n  };\n}\n","import {\n  createHarness,\n  type Harness,\n  type HarnessContext,\n  type HarnessMetadata,\n  type HarnessResultLike,\n  type HarnessRun,\n  isHarnessRun,\n  latestAssistantMessageContent,\n  type JsonValue,\n  type MaybePromise,\n  normalizeContent,\n} from \"../harness\";\n\n/**\n * Provider-neutral prompt request issued by an LLM-backed judge.\n *\n * @example\n * ```ts\n * const input: JudgeHarnessInput = {\n *   system: \"Grade factual consistency.\",\n *   prompt: \"Compare the submitted answer with the reference answer.\",\n *   responseFormat: {\n *     type: \"json\",\n *   },\n * };\n * ```\n */\nexport type JudgeHarnessInput = {\n  /** Optional system prompt for the judge model. */\n  system?: string;\n  /** User prompt or instruction payload for the judge model. */\n  prompt: string;\n  /** Optional response-format hint for adapters that support structured output. */\n  responseFormat?: {\n    /** Requests a JSON-compatible response. */\n    type: \"json\";\n    /** Optional JSON Schema passed through to provider-specific adapters. */\n    schema?: JsonValue;\n  };\n};\n\n/** JSON-safe output returned by a judge harness. */\nexport type JudgeHarnessOutput = JsonValue | undefined;\n\n/**\n * Harness used by LLM-backed judges to issue judge-side prompts.\n *\n * This is separate from the application harness under test.\n *\n * @example\n * ```ts\n * const judgeHarness: JudgeHarness = createJudgeHarness({\n *   name: \"judge-model\",\n *   run: async ({ prompt }, { signal }) => {\n *     return callJudgeModel({ prompt, signal });\n *   },\n * });\n * ```\n */\nexport type JudgeHarness = Harness<\n  JudgeHarnessInput,\n  JudgeHarnessOutput,\n  HarnessMetadata\n>;\n\n/** Runtime options supplied when a judge calls `runJudge(...)`. */\nexport type RunJudgeOptions = {\n  /** Optional metadata forwarded to the judge harness run. */\n  metadata?: HarnessMetadata;\n};\n\n/**\n * Curried judge-harness runner available inside `JudgeContext`.\n *\n * @example\n * ```ts\n * const verdict = await ctx.runJudge?.({\n *   prompt: \"Return a JSON verdict.\",\n *   responseFormat: { type: \"json\" },\n * });\n * ```\n */\nexport type RunJudge = (\n  input: JudgeHarnessInput,\n  options?: RunJudgeOptions,\n) => Promise<JudgeHarnessOutput>;\n\n/** Runtime options passed to `createJudgeHarness(...)` callbacks. */\nexport type CreateJudgeHarnessRunOptions = {\n  /** Abort signal from the current eval run when available. */\n  signal?: AbortSignal;\n  /** Metadata for this judge-harness run. */\n  metadata: Readonly<HarnessMetadata>;\n};\n\n/**\n * Configuration for `createJudgeHarness(...)`.\n *\n * @example\n * ```ts\n * const judgeHarness = createJudgeHarness({\n *   name: \"custom-judge\",\n *   run: async ({ system, prompt }, { signal }) => {\n *     return callProvider({ system, prompt, signal });\n *   },\n * });\n * ```\n */\nexport type CreateJudgeHarnessOptions = {\n  /** Stable harness name used in diagnostics. */\n  name?: string;\n  /**\n   * Runs one provider-specific judge prompt.\n   *\n   * Return a JSON-safe value, a raw provider value to normalize, a lightweight\n   * `{ output }` result, or a full normalized `HarnessRun`.\n   */\n  run: (\n    input: JudgeHarnessInput,\n    options: CreateJudgeHarnessRunOptions,\n  ) => MaybePromise<unknown>;\n};\n\n/**\n * Creates a judge harness from a provider-specific prompt callback.\n *\n * @param options - Harness name plus the callback that issues the judge prompt.\n *\n * @example\n * ```ts\n * const judgeHarness = createJudgeHarness({\n *   run: async ({ prompt }) => callJudgeModel(prompt),\n * });\n * ```\n */\nexport function createJudgeHarness(\n  options: CreateJudgeHarnessOptions,\n): JudgeHarness {\n  return createHarness({\n    name: options.name ?? \"judge-harness\",\n    run: async ({ input, signal, metadata }) => {\n      return normalizeJudgeHarnessResult(\n        await options.run(input, { signal, metadata }),\n      );\n    },\n  });\n}\n\n/**\n * Runs a judge harness with eval-scoped context already supplied.\n *\n * @param judgeHarness - Judge-side harness configured on the matcher, judge, or suite.\n * @param input - Provider-neutral judge prompt request.\n * @param options - Run-scoped metadata and abort signal.\n */\nexport async function runJudgeHarness(\n  judgeHarness: JudgeHarness,\n  input: JudgeHarnessInput,\n  options: RunJudgeOptions & { signal?: AbortSignal } = {},\n): Promise<JudgeHarnessOutput> {\n  const artifacts: HarnessContext[\"artifacts\"] = {};\n  const run = await judgeHarness.run(input, {\n    metadata: options.metadata ?? {},\n    signal: options.signal,\n    artifacts,\n    setArtifact: (name, value) => {\n      artifacts[name] = value;\n    },\n  });\n\n  return run.output !== undefined\n    ? run.output\n    : resolveJudgeHarnessAssistantOutput(run);\n}\n\n/** Binds a judge harness to the current eval run context. */\nexport function createRunJudge(\n  judgeHarness: JudgeHarness | undefined,\n  signal?: AbortSignal,\n): RunJudge | undefined {\n  if (!judgeHarness) {\n    return undefined;\n  }\n\n  return (input, options) =>\n    runJudgeHarness(judgeHarness, input, {\n      metadata: options?.metadata,\n      signal,\n    });\n}\n\nfunction normalizeJudgeHarnessResult(\n  result: Awaited<ReturnType<CreateJudgeHarnessOptions[\"run\"]>>,\n): HarnessResultLike<JudgeHarnessOutput> {\n  if (isHarnessRun(result)) {\n    return result as HarnessRun<JudgeHarnessOutput>;\n  }\n\n  if (hasOutputField(result)) {\n    return {\n      output: normalizeJudgeHarnessOutput(result.output),\n    };\n  }\n\n  return {\n    output: normalizeJudgeHarnessOutput(result),\n  };\n}\n\nfunction hasOutputField(value: unknown): value is { output?: unknown } {\n  return (\n    value !== null &&\n    typeof value === \"object\" &&\n    !Array.isArray(value) &&\n    Object.keys(value).length === 1 &&\n    \"output\" in value\n  );\n}\n\nfunction normalizeJudgeHarnessOutput(value: unknown): JudgeHarnessOutput {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  return normalizeContent(value);\n}\n\nfunction resolveJudgeHarnessAssistantOutput(\n  run: HarnessRun<JudgeHarnessOutput>,\n): JudgeHarnessOutput {\n  return latestAssistantMessageContent(run.session) ?? \"\";\n}\n","/**\n * Wraps text to fit within a specified width, breaking at word boundaries.\n *\n * @param text - The text to wrap\n * @param width - The maximum width in characters (default: 80)\n * @returns The wrapped text with line breaks\n *\n * @example\n * ```javascript\n * const wrapped = wrapText(\"This is a very long text that needs to be wrapped to fit within an 80 character width.\", 20);\n * console.log(wrapped);\n * // Output:\n * // This is a very\n * // long text that\n * // needs to be\n * // wrapped to fit\n * // within an 80\n * // character width.\n * ```\n */\nexport function wrapText(text: string, width = 80): string {\n  if (!text || text.length <= width) {\n    return text;\n  }\n\n  const words = text.split(/\\s+/);\n  const lines: string[] = [];\n  let currentLine = \"\";\n\n  for (const word of words) {\n    // If adding this word would exceed the width, start a new line\n    if (currentLine.length + word.length + 1 > width) {\n      lines.push(currentLine.trim());\n      currentLine = word;\n    } else {\n      // Add the word to the current line\n      currentLine += (currentLine ? \" \" : \"\") + word;\n    }\n  }\n\n  // Add the last line if it's not empty\n  if (currentLine) {\n    lines.push(currentLine);\n  }\n\n  return lines.join(\"\\n\");\n}\n","import {\n  type Harness,\n  type HarnessMetadata,\n  latestAssistantMessageContent,\n} from \"../harness\";\nimport type { JsonValue } from \"../harness\";\nimport { createRunJudge } from \"./judgeHarness\";\nimport type { JudgeHarness } from \"./judgeHarness\";\nimport type { Judge, JudgeContext, JudgeResult } from \"./types\";\n\n/**\n * Rubric choice returned by a factuality judge model call.\n *\n * @example\n * ```ts\n * import type { FactualityJudgeChoice } from \"vitest-evals\";\n *\n * const choice: FactualityJudgeChoice = \"C\";\n * ```\n */\nexport type FactualityJudgeChoice = \"A\" | \"B\" | \"C\" | \"D\" | \"E\";\n\n/**\n * Prompt payload sent to the configured judge harness.\n *\n * @example\n * ```ts\n * import type { FactualityJudgePrompt } from \"vitest-evals\";\n *\n * const payload: FactualityJudgePrompt = {\n *   system: \"Grade factual consistency.\",\n *   prompt: \"Compare these answers.\",\n * };\n * ```\n */\nexport type FactualityJudgePrompt = {\n  /** System prompt for the judge model. */\n  system: string;\n  /** User prompt containing the question, expert answer, submitted answer, and rubric. */\n  prompt: string;\n};\n\n/**\n * Parsed verdict returned by a factuality judge model call.\n *\n * @example\n * ```ts\n * import type { FactualityJudgeVerdict } from \"vitest-evals\";\n *\n * const verdict: FactualityJudgeVerdict = {\n *   choice: \"C\",\n *   rationale: \"The submitted answer matches the expert answer.\",\n * };\n * ```\n */\nexport type FactualityJudgeVerdict = {\n  /** Rubric choice selected by the judge model. */\n  choice: FactualityJudgeChoice;\n  /** Human-readable explanation for the selected choice. */\n  rationale: string;\n};\n\nconst FACTUALITY_CHOICE_SCORES: Record<FactualityJudgeChoice, number> = {\n  A: 0.4,\n  B: 0.6,\n  C: 1,\n  D: 0,\n  E: 1,\n};\n\nconst FACTUALITY_SYSTEM =\n  \"You are comparing factual content. Ignore differences in style, grammar, punctuation, and formatting.\";\n\nconst FACTUALITY_RESPONSE_SCHEMA = {\n  type: \"object\",\n  additionalProperties: false,\n  required: [\"choice\", \"rationale\"],\n  properties: {\n    choice: {\n      enum: [\"A\", \"B\", \"C\", \"D\", \"E\"],\n    },\n    rationale: {\n      type: \"string\",\n    },\n  },\n} as const satisfies JsonValue;\n\n/**\n * Expert answer or reference facts accepted by `FactualityJudge()`.\n *\n * @example\n * ```ts\n * import type { FactualityJudgeExpected } from \"vitest-evals\";\n *\n * const expected: FactualityJudgeExpected =\n *   \"Paris is the capital of France.\";\n * ```\n */\nexport type FactualityJudgeExpected = JsonValue;\n\n/**\n * Configuration for the factuality judge.\n *\n * The judge harness can be supplied here, by `describeEval({ judgeHarness })`,\n * or by `expect(...).toSatisfyJudge(..., { judgeHarness })`. Passing it here\n * keeps the judge self-contained while preserving provider neutrality.\n *\n * @example\n * ```ts\n * import { FactualityJudge, type JudgeHarness } from \"vitest-evals\";\n *\n * declare const judgeHarness: JudgeHarness;\n *\n * const judge = FactualityJudge({ name: \"FactJudge\", judgeHarness });\n * ```\n */\nexport type FactualityJudgeConfig = {\n  /** Stable judge name used in assertion messages and reports. */\n  name?: string;\n  /** Default judge-side harness used when matcher options do not provide one. */\n  judgeHarness?: JudgeHarness;\n};\n\ntype FactualityJudgeMetadata = HarnessMetadata & {\n  expected?: FactualityJudgeExpected;\n};\n\n/**\n * Matcher context accepted by `FactualityJudge()`.\n *\n * @example\n * ```ts\n * import { aiSdkJudgeHarness } from \"@vitest-evals/harness-ai-sdk\";\n * import { openai } from \"@ai-sdk/openai\";\n * import { expect } from \"vitest\";\n * import { FactualityJudge } from \"vitest-evals\";\n *\n * const judgeHarness = aiSdkJudgeHarness({\n *   model: openai(\"gpt-4.1-mini\"),\n * });\n *\n * await expect(result).toSatisfyJudge(FactualityJudge(), {\n *   expected: \"Paris is the capital of France.\",\n *   judgeHarness,\n * });\n * ```\n */\nexport type FactualityJudgeOptions<\n  TInput = any,\n  TOutput extends JsonValue | undefined = JsonValue | undefined,\n  TMetadata extends HarnessMetadata = HarnessMetadata,\n  THarness extends Harness<TInput, TOutput, TMetadata> | undefined =\n    | Harness<TInput, TOutput, TMetadata>\n    | undefined,\n> = JudgeContext<TInput, TOutput, TMetadata, THarness> & {\n  /** Expert answer or reference facts. Defaults to `metadata.expected`. */\n  expected?: FactualityJudgeExpected;\n};\n\n/**\n * Creates a factuality judge over normalized harness output.\n *\n * `FactualityJudge()` compares `input`, `output`, and `expected` from the\n * current `JudgeContext`, so the same judge can run against any application\n * harness. Configure the LLM used for grading with `judgeHarness` on the\n * judge, suite, or matcher options.\n *\n * @param config - Optional judge name and reusable judge harness default.\n *\n * @example\n * ```ts\n * import { anthropic } from \"@ai-sdk/anthropic\";\n * import { aiSdkJudgeHarness } from \"@vitest-evals/harness-ai-sdk\";\n * import { describeEval, FactualityJudge } from \"vitest-evals\";\n * import { qaHarness } from \"./qaHarness\";\n *\n * const judgeHarness = aiSdkJudgeHarness({\n *   model: anthropic(\"claude-sonnet-4-5\"),\n *   temperature: 0,\n * });\n * const factualityJudge = FactualityJudge({ judgeHarness });\n *\n * describeEval(\"qa agent\", {\n *   harness: qaHarness,\n *   judges: [factualityJudge],\n * }, (it) => {\n *   it(\"answers a geography question\", async ({ run }) => {\n *     await run(\"What is the capital of France?\", {\n *       metadata: {\n *         expected: \"Paris is the capital of France.\",\n *       },\n *     });\n *   });\n * });\n * ```\n */\nexport function FactualityJudge(\n  config: FactualityJudgeConfig = {},\n): Judge<FactualityJudgeOptions> {\n  const judgeHarness = config.judgeHarness;\n\n  return {\n    name: config.name ?? \"FactualityJudge\",\n    judgeHarness,\n    assess: (opts) => assessFactuality(opts, judgeHarness),\n  };\n}\n\nasync function assessFactuality(\n  opts: FactualityJudgeOptions,\n  configuredJudgeHarness: JudgeHarness | undefined,\n) {\n  const metadata = opts.metadata as FactualityJudgeMetadata;\n  const expected =\n    opts.expected === undefined ? metadata.expected : opts.expected;\n\n  if (isMissingExpectedAnswer(expected)) {\n    return {\n      score: 0,\n      metadata: {\n        rationale:\n          \"FactualityJudge requires a non-empty expert answer in `expected` or `metadata.expected`.\",\n      },\n    };\n  }\n\n  const runJudge =\n    opts.runJudge ??\n    createRunJudge(\n      configuredJudgeHarness,\n      (opts as { signal?: AbortSignal }).signal,\n    );\n\n  if (!runJudge) {\n    throw new Error(\n      \"FactualityJudge requires a judgeHarness in FactualityJudge(...) config, describeEval(...) options, toSatisfyJudge(...) options, or JudgeContext.runJudge.\",\n    );\n  }\n\n  const verdict = await runJudge({\n    system: FACTUALITY_SYSTEM,\n    prompt: formatFactualityPrompt({\n      input: opts.input,\n      expected,\n      output: resolveJudgeOutput(opts),\n    }),\n    responseFormat: {\n      type: \"json\",\n      schema: FACTUALITY_RESPONSE_SCHEMA,\n    },\n  });\n\n  return formatJudgeResult(parseFactualityJudgeVerdict(verdict));\n}\n\nfunction isMissingExpectedAnswer(value: FactualityJudgeExpected | undefined) {\n  return (\n    value == null || (typeof value === \"string\" && value.trim().length === 0)\n  );\n}\n\nfunction resolveJudgeOutput(opts: FactualityJudgeOptions) {\n  if (opts.output !== undefined) {\n    return opts.output;\n  }\n\n  return latestAssistantMessageContent(opts.session) ?? \"\";\n}\n\nfunction parseFactualityJudgeVerdict(value: unknown): FactualityJudgeVerdict {\n  const parsed = typeof value === \"string\" ? parseJsonObject(value) : value;\n\n  if (!parsed || typeof parsed !== \"object\") {\n    throw new Error(\n      \"FactualityJudge judgeHarness must return an object with `choice` and `rationale`.\",\n    );\n  }\n\n  const verdict = parsed as Record<string, unknown>;\n  if (!isFactualityChoice(verdict.choice)) {\n    throw new Error(\n      \"FactualityJudge judgeHarness must return choice A, B, C, D, or E.\",\n    );\n  }\n\n  if (typeof verdict.rationale !== \"string\") {\n    throw new Error(\n      \"FactualityJudge judgeHarness must return a string `rationale`.\",\n    );\n  }\n\n  return {\n    choice: verdict.choice,\n    rationale: verdict.rationale,\n  };\n}\n\nfunction parseJsonObject(value: string) {\n  try {\n    return JSON.parse(value);\n  } catch {\n    const fencedJson = value.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n    if (!fencedJson) {\n      throw new Error(\n        \"FactualityJudge judgeHarness must return JSON with `choice` and `rationale`.\",\n      );\n    }\n\n    return JSON.parse(fencedJson[1]);\n  }\n}\n\nfunction isFactualityChoice(value: unknown): value is FactualityJudgeChoice {\n  return (\n    value === \"A\" ||\n    value === \"B\" ||\n    value === \"C\" ||\n    value === \"D\" ||\n    value === \"E\"\n  );\n}\n\nfunction formatFactualityPrompt({\n  input,\n  expected,\n  output,\n}: {\n  input: unknown;\n  expected: unknown;\n  output: unknown;\n}) {\n  const comparison = formatJudgeValue({\n    question: input ?? \"\",\n    expert_answer: expected,\n    submitted_answer: output ?? \"\",\n  });\n\n  return `Compare the submitted answer with the expert answer.\n\nComparison payload:\n${comparison}\n\nSelect exactly one option:\nA: The submission is a fully consistent subset of the expert answer.\nB: The submission is a fully consistent superset of the expert answer.\nC: The submission contains the same factual details as the expert answer.\nD: The submission disagrees with the expert answer.\nE: The answers differ only in ways that do not affect factuality.\n\nReturn JSON with exactly these fields:\n{\n  \"choice\": \"C\",\n  \"rationale\": \"Brief explanation for the selected choice\"\n}\n\nThe choice value must be one of A, B, C, D, or E.`;\n}\n\nfunction formatJudgeValue(value: unknown) {\n  if (typeof value === \"string\") {\n    return value;\n  }\n\n  if (value === undefined) {\n    return \"\";\n  }\n\n  try {\n    return JSON.stringify(value, null, 2) ?? String(value);\n  } catch {\n    return String(value);\n  }\n}\n\nfunction formatJudgeResult(object: FactualityJudgeVerdict): JudgeResult {\n  return {\n    score: FACTUALITY_CHOICE_SCORES[object.choice],\n    metadata: {\n      rationale: object.rationale,\n      choice: object.choice,\n    },\n  };\n}\n","/**\n * Shared configuration for built-in value matchers.\n *\n * @example\n * ```ts\n * const config: BaseMatcherConfig = {\n *   requireAll: true,\n *   allowExtras: false,\n * };\n * ```\n */\nexport interface BaseMatcherConfig {\n  /** Require every expected field or tool to match. */\n  requireAll?: boolean;\n  /** Allow actual output/tool calls to contain extra fields or calls. */\n  allowExtras?: boolean;\n  /** Emit matcher debug details to the console. */\n  debug?: boolean;\n}\n\n/**\n * Matching strategy used by structured-output and tool-call judges.\n *\n * @example\n * ```ts\n * const exact: MatchStrategy = \"strict\";\n * const custom: MatchStrategy = (expected, actual) =>\n *   String(actual).includes(String(expected));\n * ```\n */\nexport type MatchStrategy<T = unknown> =\n  | \"strict\"\n  | \"fuzzy\"\n  | ((expected: T, actual: T, context?: string) => boolean);\n\n/**\n * Options controlling fuzzy matcher behavior.\n *\n * @example\n * ```ts\n * const fuzzyOptions: FuzzyMatchOptions = {\n *   caseInsensitive: true,\n *   substring: true,\n *   numericTolerance: 0.01,\n * };\n * ```\n */\nexport interface FuzzyMatchOptions {\n  /** Compare strings without case sensitivity. */\n  caseInsensitive?: boolean;\n  /** Treat either string containing the other as a match. */\n  substring?: boolean;\n  /** Relative and absolute tolerance used for numeric comparisons. */\n  numericTolerance?: number;\n  /** Match arrays without requiring the same order. */\n  ignoreArrayOrder?: boolean;\n  /** Allow simple string/number/boolean coercions before failing. */\n  coerceTypes?: boolean;\n}\n\ntype Mismatch = {\n  key: string;\n  expected: unknown;\n  actual: unknown;\n};\n\n/** Debug logger interface accepted by matcher helpers. */\nexport interface Logger {\n  log: (message: string, ...args: unknown[]) => void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Compares two values with strict deep equality semantics. */\nexport function strictEquals(\n  expected: unknown,\n  actual: unknown,\n  context?: string,\n): boolean {\n  void context;\n\n  if (expected === actual) {\n    return true;\n  }\n\n  if (\n    expected === null ||\n    expected === undefined ||\n    actual === null ||\n    actual === undefined\n  ) {\n    return false;\n  }\n\n  if (typeof expected !== typeof actual) {\n    return false;\n  }\n\n  if (Array.isArray(expected)) {\n    return (\n      Array.isArray(actual) &&\n      expected.length === actual.length &&\n      expected.every((item, index) =>\n        strictEquals(item, actual[index], context),\n      )\n    );\n  }\n\n  if (isRecord(expected) && isRecord(actual)) {\n    const expectedKeys = Object.keys(expected);\n    const actualKeys = Object.keys(actual);\n\n    return (\n      expectedKeys.length === actualKeys.length &&\n      expectedKeys.every(\n        (key) =>\n          key in actual && strictEquals(expected[key], actual[key], context),\n      )\n    );\n  }\n\n  return false;\n}\n\nfunction fuzzyMatchString(\n  expected: string,\n  actual: string,\n  options: FuzzyMatchOptions,\n): boolean {\n  const { caseInsensitive = true, substring = false } = options;\n  const expectedText = caseInsensitive ? expected.toLowerCase() : expected;\n  const actualText = caseInsensitive ? actual.toLowerCase() : actual;\n\n  return substring\n    ? actualText.includes(expectedText) || expectedText.includes(actualText)\n    : expectedText === actualText;\n}\n\nfunction fuzzyMatchNumber(\n  expected: number,\n  actual: number,\n  options: FuzzyMatchOptions,\n): boolean {\n  const { numericTolerance = 0.001 } = options;\n  const tolerance = Math.max(\n    Math.abs(expected) * numericTolerance,\n    numericTolerance,\n  );\n\n  return Math.abs(expected - actual) <= tolerance;\n}\n\nfunction fuzzyMatchArray(\n  expected: unknown[],\n  actual: unknown[],\n  options: FuzzyMatchOptions,\n  context?: string,\n): boolean {\n  const { ignoreArrayOrder = true } = options;\n\n  if (!ignoreArrayOrder) {\n    return (\n      expected.length === actual.length &&\n      expected.every((item, index) =>\n        fuzzyMatch(item, actual[index], options, context),\n      )\n    );\n  }\n\n  const actualUsed = actual.map(() => false);\n  return expected.every((expectedItem) => {\n    for (const [index, actualItem] of actual.entries()) {\n      if (actualUsed[index]) {\n        continue;\n      }\n\n      if (fuzzyMatch(expectedItem, actualItem, options, context)) {\n        actualUsed[index] = true;\n        return true;\n      }\n    }\n\n    return false;\n  });\n}\n\nfunction fuzzyMatchObject(\n  expected: Record<string, unknown>,\n  actual: Record<string, unknown>,\n  options: FuzzyMatchOptions,\n  context?: string,\n): boolean {\n  return Object.entries(expected).every(\n    ([key, value]) =>\n      key in actual && fuzzyMatch(value, actual[key], options, context),\n  );\n}\n\nfunction fuzzyMatchWithCoercion(expected: unknown, actual: unknown): boolean {\n  if (typeof expected === \"boolean\" && typeof actual === \"string\") {\n    return expected === (actual.toLowerCase() === \"true\" || actual === \"1\");\n  }\n\n  if (typeof expected === \"string\" && typeof actual === \"number\") {\n    return Number.parseFloat(expected) === actual;\n  }\n\n  if (typeof expected === \"number\" && typeof actual === \"string\") {\n    return expected === Number.parseFloat(actual);\n  }\n\n  return false;\n}\n\n/** Compares two values with the configured fuzzy matching rules. */\nexport function fuzzyMatch(\n  expected: unknown,\n  actual: unknown,\n  options: FuzzyMatchOptions = {},\n  context?: string,\n): boolean {\n  const { coerceTypes = false } = options;\n\n  if (expected instanceof RegExp) {\n    return typeof actual === \"string\" && expected.test(actual);\n  }\n\n  if (typeof expected === \"function\") {\n    return Boolean((expected as (value: unknown) => unknown)(actual));\n  }\n\n  if (\n    expected === null ||\n    expected === undefined ||\n    actual === null ||\n    actual === undefined\n  ) {\n    return expected === actual;\n  }\n\n  if (typeof expected === \"string\" && typeof actual === \"string\") {\n    return fuzzyMatchString(expected, actual, options);\n  }\n\n  if (typeof expected === \"number\" && typeof actual === \"number\") {\n    return fuzzyMatchNumber(expected, actual, options);\n  }\n\n  if (Array.isArray(expected) && Array.isArray(actual)) {\n    return fuzzyMatchArray(expected, actual, options, context);\n  }\n\n  if (isRecord(expected) && isRecord(actual)) {\n    return fuzzyMatchObject(expected, actual, options, context);\n  }\n\n  if (coerceTypes && fuzzyMatchWithCoercion(expected, actual)) {\n    return true;\n  }\n\n  return expected === actual;\n}\n\n/** Builds a reusable matcher function from a strict, fuzzy, or custom strategy. */\nexport function createMatcher<T = unknown>(\n  strategy: MatchStrategy<T>,\n  options?: FuzzyMatchOptions,\n): (expected: T, actual: T, context?: string) => boolean {\n  if (typeof strategy === \"function\") {\n    return (expected, actual, context) => strategy(expected, actual, context);\n  }\n\n  if (strategy === \"strict\") {\n    return (expected, actual, context) =>\n      strictEquals(expected, actual, context);\n  }\n\n  return (expected, actual, context) =>\n    fuzzyMatch(expected, actual, options ?? {}, context);\n}\n\n/** Formats a value for scorer rationale and debug output. */\nexport function formatValue(value: unknown): string {\n  if (value === undefined) {\n    return \"undefined\";\n  }\n\n  if (value === null) {\n    return \"null\";\n  }\n\n  if (value instanceof RegExp) {\n    return value.toString();\n  }\n\n  if (typeof value === \"string\") {\n    return `\"${value}\"`;\n  }\n\n  if (typeof value === \"object\") {\n    try {\n      return JSON.stringify(value);\n    } catch {\n      return String(value);\n    }\n  }\n\n  return String(value);\n}\n\n/** Returns a normalized partial-credit score for match-based scorers. */\nexport function calculatePartialScore(\n  matched: number,\n  total: number,\n  requireAll: boolean,\n): number {\n  if (requireAll && matched < total) {\n    return 0;\n  }\n\n  return total > 0 ? matched / total : 1;\n}\n\nconst defaultLogger: Logger = {\n  log: (message: string, ...args: unknown[]) => {\n    if (\n      process.env.NODE_ENV === \"development\" ||\n      process.env.NODE_ENV === \"test\" ||\n      process.env.VITEST_EVALS_DEBUG === \"true\"\n    ) {\n      console.log(message, ...args);\n    }\n  },\n};\n\n/** Emits scorer debug details through the provided logger. */\nexport function debugLog(\n  context: string,\n  data: {\n    expected: unknown;\n    actual: unknown;\n    matches?: string[];\n    mismatches?: Mismatch[];\n    extras?: string[];\n  },\n  logger: Logger = defaultLogger,\n): void {\n  logger.log(`${context} debug:`);\n  logger.log(\"Expected:\", data.expected);\n  logger.log(\"Actual:\", data.actual);\n  if (data.matches) {\n    logger.log(\"Matches:\", data.matches);\n  }\n  if (data.mismatches) {\n    logger.log(\"Mismatches:\", data.mismatches);\n  }\n  if (data.extras) {\n    logger.log(\"Extras:\", data.extras);\n  }\n}\n","import type { BaseScorerOptions, ScoredResult } from \"./scoring\";\nimport {\n  createMatcher,\n  debugLog,\n  formatValue,\n  type BaseMatcherConfig,\n  type FuzzyMatchOptions,\n  type MatchStrategy,\n} from \"./matchers\";\n\nexport interface StructuredOutputScorerOptions extends BaseScorerOptions {\n  /** Expected structured output fields. */\n  expected?: Record<string, unknown>;\n}\n\nexport interface StructuredOutputScorerConfig extends BaseMatcherConfig {\n  /** Field matching strategy used for expected structured output values. */\n  match?: MatchStrategy;\n  /** Output field that indicates an error. Set to `null` to disable. */\n  errorField?: string | null;\n  /** Options used when `match` is `\"fuzzy\"`. */\n  fuzzyOptions?: FuzzyMatchOptions;\n}\n\nfunction formatMismatchDetails(\n  mismatches: Array<{ key: string; expected: unknown; actual: unknown }>,\n): string {\n  return mismatches\n    .map(\n      ({ key, expected, actual }) =>\n        `${key}: expected ${formatValue(expected)}, got ${formatValue(actual)}`,\n    )\n    .join(\"; \");\n}\n\n/** Creates a structured-output scorer used by both harness judges and legacy wrappers. */\nexport function StructuredOutputScorer(\n  config: StructuredOutputScorerConfig = {},\n) {\n  const {\n    match = \"strict\",\n    requireAll = true,\n    allowExtras = true,\n    debug = false,\n    errorField = \"error\",\n    fuzzyOptions = {},\n  } = config;\n\n  const fieldMatcher =\n    typeof match === \"function\" ? match : createMatcher(match, fuzzyOptions);\n\n  const scorer = async (\n    opts: StructuredOutputScorerOptions,\n  ): Promise<ScoredResult> => {\n    const expected = opts.expected ?? {};\n    let parsed: Record<string, unknown>;\n\n    try {\n      parsed = JSON.parse(opts.output) as Record<string, unknown>;\n    } catch (error) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Failed to parse output as JSON: ${error}`,\n          output: opts.output,\n        },\n      };\n    }\n\n    if (Object.keys(expected).length === 0) {\n      return {\n        score: 1,\n        metadata: {\n          rationale: \"Valid JSON output (no expected fields specified)\",\n        },\n      };\n    }\n\n    const errorValue = errorField !== null ? parsed[errorField] : undefined;\n    if (\n      errorField !== null &&\n      errorValue &&\n      errorValue !== \"\" &&\n      errorValue !== null\n    ) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Output contains error: ${String(errorValue)}`,\n          output: opts.output,\n        },\n      };\n    }\n\n    const matches: string[] = [];\n    const mismatches: Array<{\n      key: string;\n      expected: unknown;\n      actual: unknown;\n    }> = [];\n    const extras: string[] = [];\n\n    for (const [key, expectedValue] of Object.entries(expected)) {\n      const actualValue = parsed[key];\n      if (fieldMatcher(expectedValue, actualValue, key)) {\n        matches.push(key);\n      } else {\n        mismatches.push({\n          key,\n          expected: expectedValue,\n          actual: actualValue,\n        });\n      }\n    }\n\n    const expectedKeys = new Set(Object.keys(expected));\n    for (const key of Object.keys(parsed)) {\n      if (!expectedKeys.has(key)) {\n        extras.push(key);\n      }\n    }\n\n    if (debug) {\n      debugLog(\"StructuredOutputScorer\", {\n        expected,\n        actual: parsed,\n        matches,\n        mismatches,\n        extras,\n      });\n    }\n\n    const totalExpected = Object.keys(expected).length;\n    const totalMatched = matches.length;\n\n    if (requireAll && mismatches.length > 0) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Missing required fields: ${mismatches.map((mismatch) => mismatch.key).join(\", \")} - ${formatMismatchDetails(mismatches)}`,\n        },\n      };\n    }\n\n    if (!allowExtras && extras.length > 0) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Unexpected extra fields: ${extras.join(\", \")}`,\n        },\n      };\n    }\n\n    const score = totalExpected > 0 ? totalMatched / totalExpected : 1;\n    if (score === 1) {\n      const extraInfo =\n        extras.length > 0 ? ` (plus extra fields: ${extras.join(\", \")})` : \"\";\n\n      return {\n        score: 1,\n        metadata: {\n          rationale: `All expected fields match${extraInfo}`,\n        },\n      };\n    }\n\n    return {\n      score,\n      metadata: {\n        rationale: `Matched ${totalMatched}/${totalExpected} fields - ${formatMismatchDetails(mismatches)}`,\n        matched: totalMatched,\n        total: totalExpected,\n      },\n    };\n  };\n\n  Object.defineProperty(scorer, \"name\", {\n    value: \"StructuredOutputScorer\",\n  });\n\n  return scorer;\n}\n","import type { Judge, JudgeContext } from \"./types\";\nimport {\n  StructuredOutputScorer,\n  type StructuredOutputScorerConfig,\n  type StructuredOutputScorerOptions,\n} from \"../internal/structuredOutputScorer\";\nimport type { HarnessMetadata } from \"../harness\";\n\n/**\n * Expected structured fields accepted by `StructuredOutputJudge()`.\n *\n * @example\n * ```ts\n * const expected: StructuredOutputJudgeExpected = {\n *   status: \"approved\",\n *   risk: \"low\",\n * };\n * ```\n */\nexport type StructuredOutputJudgeExpected = Record<string, unknown>;\n\ntype StructuredOutputJudgeMetadata = HarnessMetadata & {\n  expected?: StructuredOutputJudgeExpected;\n};\n\n/**\n * Matcher context accepted by `StructuredOutputJudge()`.\n *\n * @example\n * ```ts\n * await expect(result).toSatisfyJudge(StructuredOutputJudge(), {\n *   expected: { status: \"approved\" },\n * });\n * ```\n */\nexport interface StructuredOutputJudgeOptions\n  extends JudgeContext<any, any, HarnessMetadata, any>,\n    Omit<StructuredOutputScorerOptions, \"input\" | \"output\" | \"toolCalls\"> {\n  expected?: StructuredOutputJudgeExpected;\n}\n\n/**\n * Configuration for the deterministic structured-output judge.\n *\n * @example\n * ```ts\n * const judge = StructuredOutputJudge({\n *   match: \"fuzzy\",\n *   fuzzyOptions: { caseInsensitive: true },\n * });\n * ```\n */\nexport interface StructuredOutputJudgeConfig\n  extends StructuredOutputScorerConfig {}\n\n/**\n * Creates a deterministic judge that compares structured output fields.\n *\n * @param config - Matching behavior shared by every assessment from this judge.\n *\n * @example\n * ```ts\n * describeEval(\"refund agent\", {\n *   harness: refundHarness,\n *   judges: [StructuredOutputJudge()],\n * }, (it) => {\n *   it(\"returns the expected decision\", async ({ run }) => {\n *     await run(\"Refund invoice inv_123\", {\n *       metadata: {\n *         expected: { status: \"approved\" },\n *       },\n *     });\n *   });\n * });\n * ```\n */\nexport function StructuredOutputJudge(\n  config: StructuredOutputJudgeConfig = {},\n): Judge<StructuredOutputJudgeOptions> {\n  const scorer = StructuredOutputScorer(config);\n  return {\n    name: \"StructuredOutputJudge\",\n    assess: (opts: StructuredOutputJudgeOptions) => {\n      const metadata = opts.metadata as StructuredOutputJudgeMetadata;\n\n      return scorer({\n        ...opts,\n        input: formatStructuredOutput(opts.input),\n        expected: opts.expected ?? metadata.expected,\n        output: formatStructuredOutput(opts.output),\n      });\n    },\n  };\n}\n\nfunction formatStructuredOutput(\n  output: StructuredOutputJudgeOptions[\"run\"][\"output\"],\n) {\n  if (typeof output === \"string\") {\n    return output;\n  }\n\n  if (output !== undefined) {\n    try {\n      return JSON.stringify(output);\n    } catch {\n      return String(output);\n    }\n  }\n\n  return \"\";\n}\n","import type { BaseScorerOptions, ScoredResult, ToolCallLike } from \"./scoring\";\nimport { normalizeContent } from \"../harness\";\nimport {\n  createMatcher,\n  type BaseMatcherConfig,\n  type FuzzyMatchOptions,\n  type MatchStrategy,\n} from \"./matchers\";\n\nexport type ExpectedTool = {\n  /** Expected tool name. */\n  name: string;\n  /** Expected tool arguments matched according to the configured strategy. */\n  arguments?: unknown;\n};\n\nexport interface ToolCallScorerOptions extends BaseScorerOptions {\n  /** Expected tool calls for the run. */\n  expectedTools?: ExpectedTool[];\n}\n\nexport interface ToolCallScorerConfig extends BaseMatcherConfig {\n  /** Require expected tools to appear in the configured order. */\n  ordered?: boolean;\n  /** Matching strategy for expected tool arguments. */\n  params?: MatchStrategy;\n  /** Options used when argument matching is fuzzy. */\n  fuzzyOptions?: FuzzyMatchOptions;\n}\n\n/** Creates a tool-call scorer used by both harness judges and legacy wrappers. */\nexport function ToolCallScorer(config: ToolCallScorerConfig = {}) {\n  const {\n    ordered = false,\n    requireAll = true,\n    allowExtras = true,\n    params = \"strict\",\n    fuzzyOptions: userFuzzyOptions,\n  } = config;\n\n  const fuzzyOptions: FuzzyMatchOptions = {\n    substring: true,\n    caseInsensitive: true,\n    ignoreArrayOrder: true,\n    numericTolerance: 0.001,\n    coerceTypes: false,\n    ...userFuzzyOptions,\n  };\n  const argMatcher = createMatcher(params, fuzzyOptions);\n\n  const scorer = async (opts: ToolCallScorerOptions): Promise<ScoredResult> => {\n    const expectedTools = opts.expectedTools ?? [];\n    const actualCalls = opts.toolCalls ?? [];\n\n    if (expectedTools.length === 0) {\n      return {\n        score: 1,\n        metadata: {\n          rationale: \"No tool calls expected\",\n        },\n      };\n    }\n\n    if (actualCalls.length === 0) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Expected ${expectedTools.length} tool(s) but none were called`,\n        },\n      };\n    }\n\n    return ordered\n      ? evaluateOrderedTools(expectedTools, actualCalls, {\n          argMatcher,\n          allowExtras,\n          requireAllTools: requireAll,\n        })\n      : evaluateUnorderedTools(expectedTools, actualCalls, {\n          argMatcher,\n          requireAllTools: requireAll,\n          allowExtras,\n        });\n  };\n\n  Object.defineProperty(scorer, \"name\", {\n    value: \"ToolCallScorer\",\n  });\n\n  return scorer;\n}\n\nfunction evaluateOrderedTools(\n  expected: ExpectedTool[],\n  actual: ToolCallLike[],\n  options: {\n    argMatcher: (expected: unknown, actual: unknown) => boolean;\n    allowExtras: boolean;\n    requireAllTools: boolean;\n  },\n): ScoredResult {\n  let expectedIndex = 0;\n  let actualIndex = 0;\n\n  while (expectedIndex < expected.length && actualIndex < actual.length) {\n    const expectedTool = expected[expectedIndex];\n    const actualTool = actual[actualIndex];\n\n    if (expectedTool.name === actualTool.name) {\n      if (\n        expectedTool.arguments !== undefined &&\n        !options.argMatcher(expectedTool.arguments, actualTool.arguments ?? {})\n      ) {\n        return {\n          score: expectedIndex / expected.length,\n          metadata: {\n            rationale: `Tool '${expectedTool.name}' called with incorrect arguments at position ${expectedIndex + 1} (${expectedIndex}/${expected.length} tools matched correctly)`,\n            expected: normalizeContent(expectedTool.arguments),\n            actual:\n              actualTool.arguments === undefined\n                ? undefined\n                : normalizeContent(actualTool.arguments),\n            matched: expectedIndex,\n            total: expected.length,\n          },\n        };\n      }\n\n      expectedIndex++;\n      actualIndex++;\n      continue;\n    }\n\n    if (options.allowExtras) {\n      actualIndex++;\n      continue;\n    }\n\n    return {\n      score: 0,\n      metadata: {\n        rationale: `Expected '${expectedTool.name}' at position ${expectedIndex + 1} but found '${actualTool.name}'`,\n      },\n    };\n  }\n\n  if (expectedIndex < expected.length) {\n    const missing = expected.slice(expectedIndex).map((tool) => tool.name);\n    if (options.requireAllTools) {\n      return {\n        score: 0,\n        metadata: {\n          rationale: `Missing required tools in sequence: ${missing.join(\", \")}`,\n        },\n      };\n    }\n\n    const matchedCount = expectedIndex;\n    const totalCount = expected.length;\n    return {\n      score: totalCount > 0 ? matchedCount / totalCount : 1,\n      metadata: {\n        rationale: `Partial match: ${matchedCount}/${totalCount} tools called in order (missing: ${missing.join(\", \")})`,\n        matched: matchedCount,\n        total: totalCount,\n      },\n    };\n  }\n\n  if (!options.allowExtras && actualIndex < actual.length) {\n    const extra = actual.slice(actualIndex).map((tool) => tool.name);\n    return {\n      score: 0,\n      metadata: {\n        rationale: `Unexpected extra tools: ${extra.join(\", \")}`,\n      },\n    };\n  }\n\n  return {\n    score: 1,\n    metadata: {\n      rationale: \"All tools called in expected order with correct arguments\",\n    },\n  };\n}\n\nfunction evaluateUnorderedTools(\n  expected: ExpectedTool[],\n  actual: ToolCallLike[],\n  options: {\n    argMatcher: (expected: unknown, actual: unknown) => boolean;\n    requireAllTools: boolean;\n    allowExtras: boolean;\n  },\n): ScoredResult {\n  const remainingExpected = [...expected];\n  const remainingActual = [...actual];\n  const issues: string[] = [];\n\n  for (let index = remainingExpected.length - 1; index >= 0; index--) {\n    const expectedTool = remainingExpected[index];\n    const matchIndex = remainingActual.findIndex((actualTool) => {\n      if (expectedTool.name !== actualTool.name) {\n        return false;\n      }\n\n      return expectedTool.arguments === undefined\n        ? true\n        : options.argMatcher(\n            expectedTool.arguments,\n            actualTool.arguments ?? {},\n          );\n    });\n\n    if (matchIndex !== -1) {\n      remainingExpected.splice(index, 1);\n      remainingActual.splice(matchIndex, 1);\n    }\n  }\n\n  for (const missingTool of remainingExpected) {\n    if (missingTool.arguments !== undefined) {\n      const wrongArgsCalls = actual.filter(\n        (call) => call.name === missingTool.name,\n      );\n      issues.push(\n        wrongArgsCalls.length > 0\n          ? `Tool '${missingTool.name}' called but with incorrect arguments`\n          : `Missing required tool: ${missingTool.name}`,\n      );\n    } else {\n      issues.push(`Missing required tool: ${missingTool.name}`);\n    }\n  }\n\n  const extraTools = remainingActual.map((tool) => tool.name);\n  if (!options.allowExtras && extraTools.length > 0) {\n    issues.push(`Unexpected extra tools: ${extraTools.join(\", \")}`);\n  }\n\n  const expectedMatched = expected.length - remainingExpected.length;\n  const score = expected.length > 0 ? expectedMatched / expected.length : 1;\n  if (issues.length > 0 && (options.requireAllTools || !options.allowExtras)) {\n    return {\n      score: 0,\n      metadata: {\n        rationale: issues.join(\"; \"),\n      },\n    };\n  }\n\n  if (score === 1) {\n    const extraInfo =\n      extraTools.length > 0 ? ` (plus extra: ${extraTools.join(\", \")})` : \"\";\n\n    return {\n      score: 1,\n      metadata: {\n        rationale: `All expected tools were called${extraInfo}`,\n      },\n    };\n  }\n\n  return {\n    score,\n    metadata: {\n      rationale: issues.join(\"; \"),\n      matched: expectedMatched,\n      total: expected.length,\n    },\n  };\n}\n","import type { Judge, JudgeContext } from \"./types\";\nimport {\n  ToolCallScorer,\n  type ToolCallScorerConfig,\n  type ToolCallScorerOptions,\n} from \"../internal/toolCallScorer\";\nimport type { HarnessMetadata } from \"../harness\";\n\n/**\n * Expected tool-call shape accepted by `ToolCallJudge()`.\n *\n * @example\n * ```ts\n * const expectedTools: ToolCallJudgeExpectedTool[] = [\n *   \"lookupInvoice\",\n *   { name: \"createRefund\", arguments: { invoiceId: \"inv_123\" } },\n * ];\n * ```\n */\nexport type ToolCallJudgeExpectedTool =\n  | string\n  | {\n      name: string;\n      arguments?: unknown;\n    };\n\n/**\n * Configuration for the deterministic tool-call judge.\n *\n * @example\n * ```ts\n * const judge = ToolCallJudge({\n *   ordered: true,\n *   allowExtra: false,\n * });\n * ```\n */\nexport interface ToolCallJudgeConfig extends ToolCallScorerConfig {}\n\ntype ToolCallJudgeMetadata = HarnessMetadata & {\n  expectedTools?: ToolCallJudgeExpectedTool[];\n};\n\n/**\n * Matcher context accepted by `ToolCallJudge()`.\n *\n * @example\n * ```ts\n * await expect(result).toSatisfyJudge(ToolCallJudge(), {\n *   expectedTools: [\"lookupInvoice\", \"createRefund\"],\n * });\n * ```\n */\nexport interface ToolCallJudgeOptions\n  extends JudgeContext<any, any, HarnessMetadata, any>,\n    Omit<\n      ToolCallScorerOptions,\n      \"input\" | \"output\" | \"toolCalls\" | \"expectedTools\"\n    > {\n  expectedTools?: ToolCallJudgeExpectedTool[];\n}\n\n/**\n * Creates a deterministic judge that checks expected tool calls.\n *\n * @param config - Matching behavior shared by every assessment from this judge.\n *\n * @example\n * ```ts\n * describeEval(\"refund agent\", {\n *   harness: refundHarness,\n *   judges: [ToolCallJudge({ ordered: true })],\n * }, (it) => {\n *   it(\"creates a refund after lookup\", async ({ run }) => {\n *     await run(\"Refund invoice inv_123\", {\n *       metadata: {\n *         expectedTools: [\"lookupInvoice\", \"createRefund\"],\n *       },\n *     });\n *   });\n * });\n * ```\n */\nexport function ToolCallJudge(\n  config: ToolCallJudgeConfig = {},\n): Judge<ToolCallJudgeOptions> {\n  const scorer = ToolCallScorer(config);\n  return {\n    name: \"ToolCallJudge\",\n    assess: (opts: ToolCallJudgeOptions) => {\n      const metadata = opts.metadata as ToolCallJudgeMetadata;\n\n      return scorer({\n        ...opts,\n        input: formatJudgeValue(opts.input),\n        output: formatJudgeValue(opts.output),\n        expectedTools: normalizeExpectedTools(\n          opts.expectedTools ?? metadata.expectedTools,\n        ),\n      });\n    },\n  };\n}\n\nfunction normalizeExpectedTools(\n  expectedTools: ToolCallJudgeExpectedTool[] | undefined,\n) {\n  return expectedTools?.map((tool) =>\n    typeof tool === \"string\" ? { name: tool } : tool,\n  );\n}\n\nfunction formatJudgeValue(value: unknown) {\n  if (typeof value === \"string\") {\n    return value;\n  }\n\n  if (value !== undefined) {\n    try {\n      return JSON.stringify(value) ?? String(value);\n    } catch {\n      return String(value);\n    }\n  }\n\n  return \"\";\n}\n"],"mappings":"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","names":["assistantMessages","failedSpans","latestAssistantMessageContent","messagesByRole","spans","spansByKind","systemMessages","toolCalls","toolMessages","userMessages","normalized","toolCalls","spans","details","message","type","latestAssistantMessageContent","latestAssistantMessageContent","formatJudgeValue","toolCalls","userMessages","latestAssistantMessageContent"]}