{"version":3,"sources":["/Users/Raffael.Prem/WebstormProjects/agentest/dist/vitest.cjs","../src/vitest.ts"],"names":[],"mappings":"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","file":"/Users/Raffael.Prem/WebstormProjects/agentest/dist/vitest.cjs","sourcesContent":[null,"import { describe, it, expect, beforeAll } from 'vitest'\nimport type { AgentestConfig, AgentestConfigInput } from './config/schema.js'\nimport { defineConfig } from './config/defineConfig.js'\nimport { discoverAndLoad } from './runner/discovery.js'\nimport { Runner } from './runner/runner.js'\nimport type { ScenarioResult } from './runner/runner.js'\nimport type { DiscoveryResult } from './runner/discovery.js'\nimport { computeMetricAverages } from './evaluator/scoring.js'\n\nexport interface SimSuiteOptions {\n  /** Filter scenarios by name (case-insensitive substring match) */\n  scenario?: string\n  /** Timeout per scenario in milliseconds (default: 120000) */\n  timeout?: number\n  /** Working directory for scenario discovery (default: process.cwd()) */\n  cwd?: string\n}\n\nconst DEFAULT_TIMEOUT = 120_000\n\n/**\n * Define an Agentest test suite inside a vitest test file.\n *\n * Each scenario becomes an individual `it()` test case.\n *\n * ```ts\n * import { defineSimSuite } from '@agentesting/agentest/vitest'\n *\n * defineSimSuite({\n *   agent: { name: 'my-agent', endpoint: 'http://localhost:3000/api/chat' },\n * })\n * ```\n */\nexport function defineSimSuite(\n  configInput: AgentestConfig | AgentestConfigInput,\n  options: SimSuiteOptions = {},\n) {\n  const config = defineConfig(configInput as AgentestConfigInput)\n\n  const timeout = options.timeout ?? DEFAULT_TIMEOUT\n  const cwd = options.cwd ?? process.cwd()\n\n  describe('Agentest', () => {\n    let runner: Runner\n    let allScenarios: DiscoveryResult[]\n\n    beforeAll(async () => {\n      const discoveries = await discoverAndLoad(config, cwd)\n\n      // Filter by scenario name if specified\n      if (options.scenario) {\n        for (const d of discoveries) {\n          d.scenarios = d.scenarios.filter((s) =>\n            s.name.toLowerCase().includes(options.scenario!.toLowerCase()),\n          )\n        }\n      }\n\n      allScenarios = discoveries.filter((d) => d.scenarios.length > 0)\n\n      // Create runner with no reporters (vitest handles output)\n      runner = new Runner(config, [])\n    }, timeout)\n\n    // We need to register tests synchronously, but scenarios are loaded async.\n    // Use a deferred pattern: register a single test that runs all scenarios,\n    // or use vitest's concurrent test generation.\n    //\n    // Since vitest needs tests registered synchronously at describe time,\n    // we use a wrapper that discovers scenarios first, then creates the suite.\n    // This is handled by the alternative `defineSimSuite` approach below.\n\n    it(\n      'runs all scenarios',\n      async () => {\n        if (!allScenarios || allScenarios.length === 0) {\n          throw new Error('No scenarios found. Check your include/exclude patterns.')\n        }\n\n        const result = await runner.run(allScenarios)\n\n        if (!result.passed) {\n          const failureDetails = result.scenarioResults\n            .filter((sr) => !sr.passed)\n            .map((sr) => formatScenarioFailure(sr))\n            .join('\\n\\n')\n\n          expect.fail(\n            `${result.failedScenarios}/${result.totalScenarios} scenarios failed\\n\\n${failureDetails}`,\n          )\n        }\n      },\n      timeout,\n    )\n  })\n}\n\n/**\n * Run a single scenario as a vitest test. Gives more granular control\n * than `defineSimSuite` — import your scenario file directly and test it.\n *\n * ```ts\n * import { runScenario } from '@agentesting/agentest/vitest'\n * import config from '../agentest.config.js'\n * import '../scenarios/booking.sim.js'\n *\n * it('booking flow', async () => {\n *   const result = await runScenario(config, 'user books a morning slot')\n *   expect(result.passed).toBe(true)\n * })\n * ```\n */\nexport async function runScenario(\n  configInput: AgentestConfig | AgentestConfigInput,\n  scenarioName: string,\n  options: { cwd?: string } = {},\n): Promise<ScenarioResult> {\n  const config = defineConfig(configInput as AgentestConfigInput)\n\n  const cwd = options.cwd ?? process.cwd()\n  const discoveries = await discoverAndLoad(config, cwd)\n\n  // Find the matching scenario\n  const allScenarios = discoveries.flatMap((d) => d.scenarios)\n  const match = allScenarios.find((s) => s.name.toLowerCase() === scenarioName.toLowerCase())\n\n  if (!match) {\n    const available = allScenarios.map((s) => s.name).join(', ')\n    throw new Error(`Scenario \"${scenarioName}\" not found. Available: ${available}`)\n  }\n\n  // Run with a single-scenario discovery\n  const runner = new Runner(config, [])\n  const result = await runner.run([{ file: 'vitest', scenarios: [match] }])\n\n  return result.scenarioResults[0]\n}\n\nfunction formatScenarioFailure(sr: ScenarioResult): string {\n  const lines: string[] = [`--- ${sr.scenario.name} ---`]\n\n  // Errored conversations\n  const errored = sr.simulation.conversations.filter((c) => c.error)\n  for (const conv of errored) {\n    lines.push(`  ${conv.conversationId}: error — ${conv.error}`)\n  }\n\n  // Trajectory failures\n  for (const [convId, traj] of sr.trajectoryResults) {\n    if (!traj.matched) {\n      const details: string[] = []\n      if (traj.missingCalls.length > 0) details.push(`missing: ${traj.missingCalls.join(', ')}`)\n      if (traj.extraCalls.length > 0) details.push(`extra: ${traj.extraCalls.join(', ')}`)\n      if (traj.forbiddenCalls.length > 0)\n        details.push(`forbidden: ${traj.forbiddenCalls.join(', ')}`)\n      lines.push(`  ${convId}: trajectory failed — ${details.join('; ')}`)\n    }\n  }\n\n  // Per-turn trajectory failures\n  for (const [convId, turnResults] of sr.perTurnTrajectoryResults) {\n    for (const tr of turnResults) {\n      if (!tr.result.matched) {\n        const details: string[] = []\n        if (tr.result.missingCalls.length > 0)\n          details.push(`missing: ${tr.result.missingCalls.join(', ')}`)\n        if (tr.result.extraCalls.length > 0)\n          details.push(`extra: ${tr.result.extraCalls.join(', ')}`)\n        if (tr.result.forbiddenCalls.length > 0)\n          details.push(`forbidden: ${tr.result.forbiddenCalls.join(', ')}`)\n        lines.push(`  ${convId}: turn ${tr.turnIndex} trajectory failed — ${details.join('; ')}`)\n      }\n    }\n  }\n\n  // Metric averages\n  const averages = computeMetricAverages(sr.evaluations.values())\n  if (Object.keys(averages).length > 0) {\n    const scores = Object.entries(averages)\n      .map(([name, avg]) => `${name}: ${avg.toFixed(1)}`)\n      .join(', ')\n    lines.push(`  Metrics: ${scores}`)\n  }\n\n  // Errors\n  for (const err of sr.errors) {\n    lines.push(`  [${err.severity}] ${err.label} (${err.occurrences.length}x)`)\n  }\n\n  return lines.join('\\n')\n}\n"]}