@gnsx/genesys.agent.eval 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/cli.js.map +1 -1
- package/dist/src/args.js +1 -1
- package/dist/src/args.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/bundle/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli.ts","../../../../../cli-utils/src/self-update.ts","../../src/args.ts","../../src/embedding-judge.ts","../../src/judge.ts","../../src/reporter.ts","../../src/cli-runner.ts","../../src/test-loader.ts","../../src/runner.ts","../../src/utils/package.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Genesys Agent Eval CLI launcher.\n *\n * Entry point for the evaluation harness. Spawns pi or genesys CLI\n * processes to run tests and evaluates the results.\n */\n\nimport { resolve } from 'node:path';\n\nimport { parseArgs } from './args.js';\nimport { EmbeddingJudge } from './embedding-judge.js';\nimport { Judge } from './judge.js';\nimport { Reporter } from './reporter.js';\nimport { type ProgressCallback, runEvaluation } from './runner.js';\nimport { getPackageJson } from './utils/package.js';\n\nimport type { RunnerConfig, TestResult } from './types.js';\n\n/**\n * ANSI color codes for console output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n};\n\n/**\n * Progress callback implementation for console output.\n */\nfunction createProgressCallback(verbose: boolean): ProgressCallback {\n return {\n onTestStart(testId: string, index: number, total: number): void {\n if (verbose) {\n console.log(`[${index + 1}/${total}] Running: ${testId}`);\n }\n },\n onTestComplete(result: TestResult, index: number, total: number): void {\n const status = result.passed ? 'PASS' : 'FAIL';\n const score = `${(result.judgeScore * 100).toFixed(0)}%`;\n const statusColor = result.passed ? colors.green : colors.red;\n console.log(`${statusColor}${status}${colors.reset}`);\n },\n onTestError(testId: string, error: string, index: number, total: number): void {\n console.error(`[${index + 1}/${total}] ERROR - ${testId}: ${error}`);\n },\n };\n}\n\n/**\n * Main entry point.\n */\nasync function main(argv: string[]): Promise<void> {\n const pkg = getPackageJson();\n const args = parseArgs(argv, pkg.version, pkg.name);\n\n const cwd = resolve(args.cwd);\n\n // Build configuration\n const config: RunnerConfig = {\n testsPath: args.tests,\n agent: args.agent,\n cwd,\n timeout: args.timeout * 1000, // Convert to milliseconds\n outputPath: args.output,\n format: args.format,\n parallel: args.parallel,\n judge: {\n provider: args.judgeProvider,\n model: args.judgeModel,\n },\n };\n\n console.log(`${colors.cyan}Agent:${colors.reset} ${colors.bright}${args.agent}${colors.reset}`);\n console.log(`${colors.cyan}Judge:${colors.reset} ${args.judgeType}`);\n console.log(`${colors.cyan}Working directory:${colors.reset} ${cwd}`);\n console.log(`${colors.cyan}Test file:${colors.reset} ${args.tests}`);\n console.log(`${colors.cyan}Timeout:${colors.reset} ${args.timeout}s per test`);\n console.log(`${colors.cyan}Parallelism:${colors.reset} ${args.parallel}`);\n console.log('');\n\n // Create judge based on type\n let judgeEvaluator: ReturnType<EmbeddingJudge['createEvaluator']> | ReturnType<Judge['createEvaluator']>;\n\n if (args.judgeType === 'embedding') {\n const judge = new EmbeddingJudge({ passThreshold: 0.6 });\n judgeEvaluator = judge.createEvaluator();\n } else {\n const judge = new Judge({\n provider: args.judgeProvider,\n model: args.judgeModel,\n passThreshold: 0.7,\n });\n judgeEvaluator = judge.createEvaluator();\n }\n\n // Run evaluation\n const progress = createProgressCallback(args.parallel > 1 || args.format === 'console');\n\n try {\n const results = await runEvaluation(config, judgeEvaluator, progress);\n\n // Report results\n const reporter = new Reporter({\n format: args.format,\n outputPath: args.output,\n });\n\n await reporter.reportAndSave(results);\n\n // Exit with appropriate code\n process.exit(results.summary.failed > 0 ? 1 : 0);\n } catch (error) {\n console.error(`Evaluation failed: ${error instanceof Error ? error.message : String(error)}`);\n\n // Provide more context for common errors\n if (error instanceof Error) {\n if (error.message.includes('ENOENT')) {\n console.error(`Make sure the ${args.agent} CLI is installed and in your PATH.`);\n }\n if (error.message.includes('ANTHROPIC_API_KEY') || error.message.includes('OPENAI_API_KEY')) {\n console.error('Set the appropriate API key environment variable for the LLM judge.');\n }\n }\n\n process.exit(1);\n }\n}\n\n// Run main\nmain(process.argv.slice(2)).catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","/**\n * Self-update functionality for Genesys CLI tools.\n *\n * Provides utilities for checking and performing CLI updates\n * via npm or pnpm package managers.\n */\n\nimport { execSync } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport type { Command } from 'commander';\n\n/**\n * Check if running from an installed package (not local development).\n * Returns true if the current file is inside node_modules.\n */\nexport function isInstalledPackage(): boolean {\n try {\n const currentFile = fileURLToPath(import.meta.url);\n return currentFile.includes('node_modules');\n } catch {\n return false;\n }\n}\n\n/**\n * Detect which package manager was used to install the CLI.\n * Checks environment variables and execution path.\n *\n * @returns 'pnpm', 'npm', or 'unknown'\n */\nexport function detectPackageManager(): 'pnpm' | 'npm' | 'unknown' {\n // Check environment variables\n if (process.env.PNPM_PACKAGE_NAME) return 'pnpm';\n if (process.env.npm_execpath?.includes('pnpm')) return 'pnpm';\n\n // Check exec path\n const execPath = process.argv[1] || '';\n if (execPath.includes('pnpm')) return 'pnpm';\n if (execPath.includes('npm')) return 'npm';\n\n // Default to pnpm (monorepo preference)\n return 'pnpm';\n}\n\n/**\n * Compare semantic versions.\n * Returns true if latest is newer than current.\n */\nfunction isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const latestPart = latestParts[i] || 0;\n const currentPart = currentParts[i] || 0;\n if (latestPart > currentPart) return true;\n if (latestPart < currentPart) return false;\n }\n\n return false;\n}\n\n/**\n * Check npm registry for the latest version of a package.\n *\n * @param packageName - The npm package name\n * @param currentVersion - The currently installed version\n * @returns Latest version string, or null if up-to-date or error\n */\nexport async function checkForUpdates(\n packageName: string,\n currentVersion: string\n): Promise<string | null> {\n try {\n if (!isInstalledPackage()) return null;\n\n const encodedName = encodeURIComponent(packageName);\n const response = await fetch(`https://registry.npmjs.org/${encodedName}/latest`, {\n signal: AbortSignal.timeout(10000),\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n const latestVersion = data.version;\n\n if (!latestVersion || latestVersion === currentVersion) return null;\n if (!isNewerVersion(latestVersion, currentVersion)) return null;\n\n return latestVersion;\n } catch {\n return null;\n }\n}\n\n/**\n * Perform the update using the detected package manager.\n *\n * @param packageName - The npm package name\n * @param packageManager - The package manager to use ('pnpm' or 'npm')\n * @param currentVersion - The current installed version\n * @param latestVersion - The latest available version\n * @returns true on success, false on failure\n */\nexport function performUpdate(\n packageName: string,\n packageManager: 'pnpm' | 'npm',\n currentVersion: string,\n latestVersion: string\n): boolean {\n console.log(`\\nUpdating ${packageName}...`);\n console.log(` Current: v${currentVersion}`);\n console.log(` Latest: v${latestVersion}\\n`);\n\n try {\n const updateCommand = packageManager === 'pnpm'\n ? `pnpm remove -g ${packageName} && pnpm add -g ${packageName}@latest`\n : `npm uninstall -g ${packageName} && npm install -g ${packageName}@latest`;\n\n // Run in shell for cross-platform compatibility (&& works on Unix, needs shell on Windows)\n execSync(updateCommand, { stdio: 'inherit' } as import('child_process').ExecSyncOptions);\n\n console.log(`\\n✅ Update complete! ${packageName} has been updated to v${latestVersion}.`);\n return true;\n } catch (error) {\n console.error(`\\n❌ Update failed. Please try running the commands manually:`);\n if (packageManager === 'pnpm') {\n console.error(` pnpm remove -g ${packageName}`);\n console.error(` pnpm add -g ${packageName}@latest`);\n } else {\n console.error(` npm uninstall -g ${packageName}`);\n console.error(` npm install -g ${packageName}@latest`);\n }\n return false;\n }\n}\n\n/**\n * Add 'update' subcommand to a Commander.js program.\n *\n * @param program - The Commander.js program\n * @param packageName - The npm package name\n * @param currentVersion - The current installed version\n */\nexport function addUpdateCommand(\n program: Command,\n packageName: string,\n currentVersion: string\n): void {\n program\n .command('update')\n .description('Check for updates and install the latest version')\n .action(async () => {\n // Skip if running from local development\n if (!isInstalledPackage()) {\n console.log('Skipping update check - running from local development.');\n process.exit(0);\n }\n\n console.log('Checking for updates...');\n\n const latestVersion = await checkForUpdates(packageName, currentVersion);\n\n if (!latestVersion) {\n console.log(`You are already using the latest version (v${currentVersion}).`);\n process.exit(0);\n }\n\n console.log(`\\n📦 Update available: v${currentVersion} → v${latestVersion}`);\n\n const packageManager = detectPackageManager();\n\n if (packageManager === 'unknown') {\n console.error('\\n❌ Could not detect package manager. Please update manually:');\n console.error(` pnpm remove -g ${packageName} && pnpm add -g ${packageName}@latest`);\n console.error(` or`);\n console.error(` npm uninstall -g ${packageName} && npm install -g ${packageName}@latest`);\n process.exit(1);\n }\n\n const success = performUpdate(packageName, packageManager, currentVersion, latestVersion);\n process.exit(success ? 0 : 1);\n });\n}\n","/**\n * CLI argument definitions and parsing for the eval harness using Commander.js.\n *\n * @module args\n */\n\nimport { addUpdateCommand } from '@gnsx/cli-utils/self-update';\nimport { Command } from 'commander';\n\nimport type { Args } from './types.js';\n\nconst VALID_FORMATS = ['console', 'json', 'html'] as const;\nconst VALID_JUDGE_TYPES = ['embedding', 'llm'] as const;\n\ntype ValidFormat = (typeof VALID_FORMATS)[number];\ntype ValidJudgeType = (typeof VALID_JUDGE_TYPES)[number];\n\nfunction isValidFormat(value: string): value is ValidFormat {\n return VALID_FORMATS.includes(value as ValidFormat);\n}\n\nfunction isValidJudgeType(value: string): value is ValidJudgeType {\n return VALID_JUDGE_TYPES.includes(value as ValidJudgeType);\n}\n\nexport function parseArgs(argv: string[], version: string, packageName: string): Args {\n const program = new Command();\n\n program\n .name('genesys-eval')\n .description('Agent evaluation harness for benchmarking AI agents')\n .version(version, '-v, --version');\n\n // Add update command\n addUpdateCommand(program, packageName, version);\n\n program\n .option('--tests <path>', 'path to YAML test file', './eval-tests.yaml')\n .option('-a, --agent <command>', 'agent CLI command to test', 'genesys')\n .option('--cwd <dir>', 'working directory for test context', process.cwd())\n .option('-t, --timeout <secs>', 'timeout per test in seconds', '120')\n .option('-o, --output <path>', 'output file for results')\n .option('--format <format>', 'output format: console, json, html', 'console')\n .option('-p, --parallel <n>', 'number of parallel test executions', '1')\n .option('--judge-type <type>', 'judge type: embedding, llm', 'embedding')\n .option('--judge-model <model>', 'model for LLM judge', 'claude-3-5-sonnet-20241022')\n .option('--judge-provider <provider>', 'provider for LLM judge', 'anthropic')\n .parse(argv, { from: 'user' });\n\n const opts = program.opts();\n\n // Validate format\n if (!isValidFormat(opts.format)) {\n console.error(`--format must be one of: ${VALID_FORMATS.join(', ')}`);\n process.exit(1);\n }\n\n // Validate judge type\n if (!isValidJudgeType(opts.judgeType)) {\n console.error(`--judge-type must be one of: ${VALID_JUDGE_TYPES.join(', ')}`);\n process.exit(1);\n }\n\n // Validate and parse timeout\n const timeout = parseInt(opts.timeout, 10);\n if (isNaN(timeout) || timeout < 1) {\n console.error('--timeout must be a positive integer');\n process.exit(1);\n }\n\n // Validate and parse parallel\n const parallel = parseInt(opts.parallel, 10);\n if (isNaN(parallel) || parallel < 1) {\n console.error('--parallel must be a positive integer');\n process.exit(1);\n }\n\n return {\n tests: opts.tests,\n agent: opts.agent,\n cwd: opts.cwd,\n timeout,\n output: opts.output,\n format: opts.format,\n parallel,\n judgeType: opts.judgeType,\n judgeModel: opts.judgeModel,\n judgeProvider: opts.judgeProvider,\n help: false,\n version: false,\n };\n}\n","/**\n * Embedding-based cosine similarity judge using an actual embedding model.\n *\n * Uses @huggingface/transformers with a lightweight local model for semantic similarity.\n *\n * @module embedding-judge\n */\n\nimport { type FeatureExtractionPipeline, pipeline } from '@huggingface/transformers';\n\nimport type { TestCase } from './types.js';\n\n/**\n * Result of judging a test case.\n */\nexport interface JudgeResult {\n /** Score from 0 to 1 */\n score: number;\n\n /** Reasoning for the score */\n reasoning: string;\n\n /** Whether the test passed (score >= threshold) */\n passed: boolean;\n}\n\n/**\n * Configuration for the embedding judge.\n */\nexport interface EmbeddingJudgeConfig {\n /** Score threshold for passing (0-1, default: 0.7) */\n passThreshold?: number;\n\n /** Embedding model to use (default: Xenova/all-MiniLM-L6-v2 via Hugging Face) */\n model?: string;\n}\n\n/**\n * Judge that evaluates agent outputs using embedding cosine similarity.\n *\n * Uses a local transformer model for semantic similarity comparison.\n * The model is downloaded on first use and cached locally.\n */\nexport class EmbeddingJudge {\n private _config: Required<EmbeddingJudgeConfig>;\n private _pipeline: FeatureExtractionPipeline | null = null;\n private _modelLoading: Promise<FeatureExtractionPipeline> | null = null;\n\n constructor(config: EmbeddingJudgeConfig = {}) {\n this._config = {\n passThreshold: 0.7,\n model: 'Xenova/all-MiniLM-L6-v2',\n ...config,\n };\n }\n\n /**\n * Get or create the embedding pipeline.\n * Lazy loads the model on first use.\n */\n private async getPipeline(): Promise<FeatureExtractionPipeline> {\n if (this._pipeline) {\n return this._pipeline;\n }\n\n if (this._modelLoading) {\n return this._modelLoading;\n }\n\n\n this._modelLoading = pipeline(\n 'feature-extraction',\n this._config.model,\n\n ) as unknown as Promise<FeatureExtractionPipeline>;\n\n this._pipeline = await this._modelLoading;\n return this._pipeline;\n }\n\n /**\n * Generate embeddings for text.\n *\n * @param text - Text to embed\n * @returns Embedding vector\n */\n private async generateEmbedding(text: string): Promise<number[]> {\n const pipe = await this.getPipeline();\n\n const output = await pipe(text, {\n pooling: 'mean',\n normalize: true,\n });\n\n // Convert to array\n return Array.from(output.data as Float32Array);\n }\n\n /**\n * Calculate cosine similarity between two vectors.\n */\n private cosineSimilarity(a: number[], b: number[]): number {\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n // Vectors are already normalized, but calculate just in case\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n\n if (magnitude === 0) {\n return 0;\n }\n\n return Math.max(0, Math.min(1, dotProduct / magnitude));\n }\n\n /**\n * Evaluate a test case against the actual output.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The judge result with score and reasoning\n */\n async evaluate(test: TestCase, actualOutput: string): Promise<JudgeResult> {\n try {\n // Generate embeddings for both expected and actual output\n const expectedEmbedding = await this.generateEmbedding(test.expectedOutput);\n const actualEmbedding = await this.generateEmbedding(actualOutput);\n\n // Calculate similarity\n const score = this.cosineSimilarity(expectedEmbedding, actualEmbedding);\n\n // Generate reasoning\n let reasoning: string;\n if (score >= 0.9) {\n reasoning = 'Very high semantic similarity - output closely matches expected content.';\n } else if (score >= 0.75) {\n reasoning = 'Good semantic similarity with minor differences in meaning or detail.';\n } else if (score >= this._config.passThreshold) {\n reasoning = 'Moderate similarity - core concepts match but notable differences exist.';\n } else if (score >= 0.4) {\n reasoning = 'Low semantic similarity - significant differences in meaning.';\n } else {\n reasoning = 'Very low similarity - output does not match expected content.';\n }\n\n const passed = score >= this._config.passThreshold;\n\n return {\n score,\n reasoning,\n passed,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n score: 0,\n reasoning: `Embedding evaluation failed: ${errorMessage}`,\n passed: false,\n };\n }\n }\n\n /**\n * Create a judge function compatible with the TestRunner.\n *\n * @returns A function that can be passed to the runner\n */\n createEvaluator(): (\n test: TestCase,\n actualOutput: string\n ) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }> {\n return async (test, actualOutput) => {\n const result = await this.evaluate(test, actualOutput);\n return {\n score: result.score,\n reasoning: result.reasoning,\n passed: result.passed,\n };\n };\n }\n\n /**\n * Get the judge configuration.\n */\n get config(): EmbeddingJudgeConfig {\n return this._config;\n }\n}\n\n/**\n * Create an embedding judge with the given configuration.\n *\n * @param config - Judge configuration\n * @returns A new EmbeddingJudge instance\n *\n * @example\n * ```typescript\n * const judge = createEmbeddingJudge({ passThreshold: 0.75 });\n * const result = await judge.evaluate(test, output);\n * console.log(`Score: ${result.score}, Passed: ${result.passed}`);\n * ```\n */\nexport function createEmbeddingJudge(config?: EmbeddingJudgeConfig): EmbeddingJudge {\n return new EmbeddingJudge(config);\n}\n","/**\n * LLM-based judge for evaluating agent outputs against expected results.\n *\n * The judge uses a separate LLM to score how well the agent's output matches\n * the expected output description on a scale of 0-1.\n *\n * @module judge\n */\n\nimport { anthropic } from '@ai-sdk/anthropic';\nimport { google } from '@ai-sdk/google';\nimport { openai } from '@ai-sdk/openai';\nimport { generateObject } from 'ai';\nimport { z } from 'zod';\n\nimport type { JudgeConfig, TestCase } from './types.js';\n\n/**\n * Result of judging a test case.\n */\nexport interface JudgeResult {\n /** Score from 0 to 1 */\n score: number;\n\n /** Reasoning for the score */\n reasoning: string;\n\n /** Whether the test passed (score >= threshold) */\n passed: boolean;\n}\n\n/**\n * Zod schema for the judge's structured output.\n */\nconst judgeOutputSchema = z.object({\n score: z.number().min(0).max(1).describe('Score from 0 to 1 where 1 is perfect'),\n reasoning: z.string().describe('Explanation for the score'),\n});\n\n/**\n * Type for judge output.\n */\ntype JudgeOutput = z.infer<typeof judgeOutputSchema>;\n\n/**\n * Judge that evaluates agent outputs using an LLM.\n *\n * The judge prompts a separate LLM to compare the actual output against the\n * expected output description and score it on a scale of 0-1.\n */\nexport class Judge {\n private _config: JudgeConfig;\n\n constructor(config: JudgeConfig) {\n this._config = {\n passThreshold: 0.7,\n temperature: 0,\n ...config,\n };\n }\n\n /**\n * Build the judge prompt.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The prompt to send to the judge LLM\n */\n private buildPrompt(test: TestCase, actualOutput: string): string {\n return `You are an expert evaluator assessing the quality of AI responses.\n\nYour task is to evaluate how well the ACTUAL OUTPUT matches the EXPECTED OUTPUT description.\n\n## Test Input\n${test.input}\n\n## Expected Output Description\n${test.expectedOutput}\n\n${test.context ? `## Additional Context\\n${test.context}\\n\\n` : ''}## Actual Output\n${actualOutput}\n\n## Evaluation Instructions\n\n1. Carefully read the expected output description and the actual output\n2. Score the actual output on a scale of 0.0 to 1.0 where:\n - 1.0 = Perfect match, fully satisfies the expected output\n - 0.8-0.9 = Good match, minor issues or omissions\n - 0.6-0.7 = Partial match, significant issues but some correct elements\n - 0.4-0.5 = Poor match, mostly incorrect or incomplete\n - 0.0-0.3 = Very poor match, completely wrong or irrelevant\n\n3. Provide clear reasoning for your score\n\nRespond with a structured object containing:\n- score: number from 0 to 1\n- reasoning: string explaining your evaluation`;\n }\n\n /**\n * Get the model instance based on provider.\n *\n * @returns Model instance for the Vercel AI SDK\n */\n private getModel() {\n const { provider, model } = this._config;\n\n switch (provider) {\n case 'anthropic': {\n return anthropic(model);\n }\n case 'openai': {\n return openai(model);\n }\n case 'google':\n case 'gemini': {\n return google(model);\n }\n default: {\n throw new Error(`Unsupported judge provider: ${provider}`);\n }\n }\n }\n\n /**\n * Evaluate a test case against the actual output.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The judge result with score and reasoning\n */\n async evaluate(test: TestCase, actualOutput: string): Promise<JudgeResult> {\n const prompt = this.buildPrompt(test, actualOutput);\n\n try {\n const { object } = await generateObject({\n model: this.getModel() as unknown as Parameters<typeof generateObject>[0]['model'],\n schema: judgeOutputSchema,\n messages: [\n {\n role: 'user',\n content: prompt,\n },\n ],\n temperature: this._config.temperature,\n });\n\n const passed = object.score >= (this._config.passThreshold ?? 0.7);\n\n return {\n score: object.score,\n reasoning: object.reasoning,\n passed,\n };\n } catch (error) {\n // If structured generation fails, return a failed result\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n score: 0,\n reasoning: `Judge evaluation failed: ${errorMessage}`,\n passed: false,\n };\n }\n }\n\n /**\n * Create a judge function compatible with the TestRunner.\n *\n * @returns A function that can be passed to the runner\n */\n createEvaluator(): (\n test: TestCase,\n actualOutput: string\n ) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }> {\n return async (test, actualOutput) => {\n const result = await this.evaluate(test, actualOutput);\n return {\n score: result.score,\n reasoning: result.reasoning,\n passed: result.passed,\n };\n };\n }\n\n /**\n * Get the judge configuration.\n */\n get config(): JudgeConfig {\n return this._config;\n }\n}\n\n/**\n * Create a judge with the given configuration.\n *\n * @param config - Judge configuration\n * @returns A new Judge instance\n *\n * @example\n * ```typescript\n * const judge = createJudge({\n * provider: 'anthropic',\n * model: 'claude-3-5-sonnet-20241022',\n * passThreshold: 0.8\n * });\n *\n * const result = await judge.evaluate(test, output);\n * console.log(`Score: ${result.score}, Passed: ${result.passed}`);\n * ```\n */\nexport function createJudge(config: JudgeConfig): Judge {\n return new Judge(config);\n}\n\n/**\n * Quick evaluate function for one-off judgments.\n *\n * @param config - Judge configuration\n * @param test - Test case\n * @param actualOutput - Actual output to evaluate\n * @returns Judge result\n */\nexport async function evaluate(\n config: JudgeConfig,\n test: TestCase,\n actualOutput: string\n): Promise<JudgeResult> {\n const judge = createJudge(config);\n return judge.evaluate(test, actualOutput);\n}\n","/**\n * Reporter for formatting and outputting evaluation results.\n *\n * Supports multiple output formats:\n * - console: Rich text table output to stdout\n * - json: Machine-readable JSON output\n * - html: Rich HTML report with styling\n *\n * @module reporter\n */\n\nimport { writeFile } from 'node:fs/promises';\n\nimport type { EvalResults, TestResult } from './types.js';\n\n/**\n * Output format options.\n */\nexport type OutputFormat = 'console' | 'json' | 'html';\n\n/**\n * Reporter configuration.\n */\nexport interface ReporterConfig {\n /** Output format */\n format: OutputFormat;\n\n /** Output file path (optional, defaults to stdout) */\n outputPath?: string;\n}\n\n/**\n * Format duration in milliseconds to human-readable string.\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\n/**\n * Truncate string to max length with ellipsis.\n */\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) {\n return str;\n }\n return str.slice(0, maxLength - 3) + '...';\n}\n\n/**\n * Format test result for console output.\n */\nfunction formatResultForConsole(result: TestResult, maxWidth: number): string {\n const status = result.passed ? 'PASS' : 'FAIL';\n const score = `${(result.judgeScore * 100).toFixed(0)}%`;\n const duration = formatDuration(result.durationMs);\n const id = truncate(result.testId, 20);\n\n return ` ${status.padEnd(4)} | ${id.padEnd(20)} | ${score.padEnd(4)} | ${duration}`;\n}\n\n/**\n * ANSI color codes for console output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n};\n\n/**\n * Reporter class for formatting evaluation results.\n */\nexport class Reporter {\n private _config: ReporterConfig;\n\n constructor(config: ReporterConfig) {\n this._config = config;\n }\n\n /**\n * Format results as a console table.\n *\n * @param results - Evaluation results\n * @returns Formatted string for console output\n */\n private formatConsole(results: EvalResults): string {\n const lines: string[] = [];\n\n // Header\n lines.push('');\n lines.push(`${colors.bright}Evaluation Results${colors.reset}`);\n lines.push(`${colors.dim}${'='.repeat(60)}${colors.reset}`);\n lines.push('');\n\n // Suite info\n lines.push(`${colors.cyan}Suite:${colors.reset} ${results.suite.name}`);\n if (results.suite.description) {\n lines.push(`${colors.cyan}Description:${colors.reset} ${results.suite.description}`);\n }\n lines.push(`${colors.cyan}Agent:${colors.reset} ${results.agent}`);\n lines.push(`${colors.cyan}Timestamp:${colors.reset} ${new Date(results.timestamp).toLocaleString()}`);\n lines.push('');\n\n // Summary\n const { summary } = results;\n const statusColor = summary.failed === 0 ? colors.green : colors.red;\n lines.push(`${colors.bright}Summary:${colors.reset}`);\n lines.push(` ${colors.cyan}Total:${colors.reset} ${summary.total}`);\n lines.push(` ${colors.green}Passed:${colors.reset} ${summary.passed}`);\n lines.push(` ${colors.red}Failed:${colors.reset} ${summary.failed}`);\n lines.push(` ${colors.yellow}Avg Score:${colors.reset} ${(summary.avgScore * 100).toFixed(1)}%`);\n lines.push(` ${colors.dim}Duration:${colors.reset} ${formatDuration(summary.totalDurationMs)}`);\n lines.push('');\n\n // Test results table\n lines.push(`${colors.bright}Test Results:${colors.reset}`);\n lines.push(` ${colors.dim}Status | ID | Score | Duration${colors.reset}`);\n lines.push(` ${colors.dim}${'-'.repeat(55)}${colors.reset}`);\n\n const failedResults: TestResult[] = [];\n\n for (const result of results.results) {\n const color = result.passed ? colors.green : colors.red;\n lines.push(`${color}${formatResultForConsole(result, 80)}${colors.reset}`);\n if (!result.passed) {\n failedResults.push(result);\n }\n }\n\n lines.push('');\n\n // Show details for failed tests\n if (failedResults.length > 0) {\n lines.push(`${colors.bright}Failed Test Details:${colors.reset}`);\n lines.push(`${colors.dim}${'='.repeat(60)}${colors.reset}`);\n\n for (const result of failedResults) {\n lines.push('');\n lines.push(`${colors.red}${colors.bright}Test: ${result.testId}${colors.reset}`);\n lines.push(`${colors.dim}Input:${colors.reset} ${result.input}`);\n lines.push(`${colors.yellow}Expected:${colors.reset} ${result.expectedOutput}`);\n lines.push(`${colors.cyan}Actual:${colors.reset} ${result.actualOutput}`);\n if (result.judgeReasoning) {\n lines.push(`${colors.dim}Reasoning: ${result.judgeReasoning}${colors.reset}`);\n }\n lines.push(`${colors.dim}${'-'.repeat(40)}${colors.reset}`);\n }\n\n lines.push('');\n }\n\n // Footer\n if (summary.failed > 0) {\n lines.push(`${colors.yellow}Some tests failed. Review the results above.${colors.reset}`);\n } else {\n lines.push(`${colors.green}All tests passed!${colors.reset}`);\n }\n\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Format results as JSON.\n *\n * @param results - Evaluation results\n * @returns JSON string\n */\n private formatJson(results: EvalResults): string {\n return JSON.stringify(results, null, 2);\n }\n\n /**\n * Format results as HTML.\n *\n * @param results - Evaluation results\n * @returns HTML string\n */\n private formatHtml(results: EvalResults): string {\n const { summary } = results;\n const allPassed = summary.failed === 0;\n\n const testRows = results.results.map(result => `\n <tr class=\"${result.passed ? 'passed' : 'failed'}\">\n <td class=\"status\">${result.passed ? 'PASS' : 'FAIL'}</td>\n <td class=\"id\">${escapeHtml(result.testId)}</td>\n <td class=\"score\">${(result.judgeScore * 100).toFixed(0)}%</td>\n <td class=\"duration\">${formatDuration(result.durationMs)}</td>\n <td class=\"reasoning\">${escapeHtml(truncate(result.judgeReasoning, 100))}</td>\n </tr>\n `).join('\\n');\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Eval Results: ${escapeHtml(results.suite.name)}</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n line-height: 1.6;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n .container {\n background: white;\n border-radius: 8px;\n padding: 2rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n h1 { margin-top: 0; color: #333; }\n h2 { color: #555; border-bottom: 2px solid #eee; padding-bottom: 0.5rem; }\n .meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin-bottom: 2rem;\n }\n .meta-item {\n background: #f8f9fa;\n padding: 1rem;\n border-radius: 4px;\n }\n .meta-label { font-weight: 600; color: #666; font-size: 0.875rem; }\n .meta-value { color: #333; }\n .summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .summary-card {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 1.5rem;\n border-radius: 8px;\n text-align: center;\n }\n .summary-card.passed { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); }\n .summary-card.failed { background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%); }\n .summary-card.warning { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }\n .summary-value { font-size: 2rem; font-weight: bold; }\n .summary-label { font-size: 0.875rem; opacity: 0.9; }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 1rem;\n }\n th, td {\n padding: 0.75rem;\n text-align: left;\n border-bottom: 1px solid #eee;\n }\n th {\n font-weight: 600;\n color: #555;\n background: #f8f9fa;\n }\n tr.passed .status { color: #11998e; font-weight: 600; }\n tr.failed .status { color: #eb3349; font-weight: 600; }\n .footer {\n margin-top: 2rem;\n padding-top: 1rem;\n border-top: 1px solid #eee;\n text-align: center;\n color: #666;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h1>Evaluation Results</h1>\n\n <div class=\"meta\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite</div>\n <div class=\"meta-value\">${escapeHtml(results.suite.name)}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Agent</div>\n <div class=\"meta-value\">${escapeHtml(results.agent)}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Timestamp</div>\n <div class=\"meta-value\">${new Date(results.timestamp).toLocaleString()}</div>\n </div>\n </div>\n\n <h2>Summary</h2>\n <div class=\"summary\">\n <div class=\"summary-card\">\n <div class=\"summary-value\">${summary.total}</div>\n <div class=\"summary-label\">Total Tests</div>\n </div>\n <div class=\"summary-card ${summary.passed === summary.total ? 'passed' : summary.passed === 0 ? 'failed' : 'warning'}\">\n <div class=\"summary-value\">${summary.passed}</div>\n <div class=\"summary-label\">Passed</div>\n </div>\n <div class=\"summary-card ${summary.failed === 0 ? 'passed' : 'failed'}\">\n <div class=\"summary-value\">${summary.failed}</div>\n <div class=\"summary-label\">Failed</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"summary-value\">${(summary.avgScore * 100).toFixed(1)}%</div>\n <div class=\"summary-label\">Avg Score</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"summary-value\">${formatDuration(summary.totalDurationMs)}</div>\n <div class=\"summary-label\">Duration</div>\n </div>\n </div>\n\n <h2>Test Results</h2>\n <table>\n <thead>\n <tr>\n <th>Status</th>\n <th>ID</th>\n <th>Score</th>\n <th>Duration</th>\n <th>Reasoning</th>\n </tr>\n </thead>\n <tbody>\n ${testRows}\n </tbody>\n </table>\n\n <div class=\"footer\">\n <p>Generated by genesys-eval</p>\n </div>\n </div>\n</body>\n</html>`;\n }\n\n /**\n * Report evaluation results.\n *\n * @param results - Evaluation results\n * @returns The formatted output string\n */\n report(results: EvalResults): string {\n switch (this._config.format) {\n case 'json': {\n return this.formatJson(results);\n }\n case 'html': {\n return this.formatHtml(results);\n }\n case 'console':\n default: {\n return this.formatConsole(results);\n }\n }\n }\n\n /**\n * Report results and optionally write to file.\n *\n * @param results - Evaluation results\n */\n async reportAndSave(results: EvalResults): Promise<void> {\n const output = this.report(results);\n\n if (this._config.outputPath) {\n await writeFile(this._config.outputPath, output, 'utf-8');\n }\n\n // Always print to console if format is console, or if no output file\n if (this._config.format === 'console' || !this._config.outputPath) {\n console.log(output);\n } else {\n console.log(`Results written to: ${this._config.outputPath}`);\n }\n }\n\n /**\n * Get the reporter configuration.\n */\n get config(): ReporterConfig {\n return this._config;\n }\n}\n\n/**\n * Escape HTML special characters.\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Quick report function.\n *\n * @param results - Evaluation results\n * @param format - Output format\n * @returns Formatted string\n */\nexport function formatResults(results: EvalResults, format: OutputFormat): string {\n const reporter = new Reporter({ format });\n return reporter.report(results);\n}\n\n/**\n * Report and save results.\n *\n * @param results - Evaluation results\n * @param format - Output format\n * @param outputPath - Optional output file path\n */\nexport async function reportResults(\n results: EvalResults,\n format: OutputFormat,\n outputPath?: string\n): Promise<void> {\n const reporter = new Reporter({ format, outputPath });\n await reporter.reportAndSave(results);\n}\n","/**\n * Simple CLI runner for executing pi, genesys, or any custom agent CLI.\n *\n * Prompt is passed via stdin for all agents.\n *\n * @module cli-runner\n */\n\nimport { spawn } from 'node:child_process';\n\nimport type { AgentResponse } from './types.js';\n\n/**\n * Options for running a CLI command.\n */\nexport interface RunOptions {\n /** Working directory for the command */\n cwd: string;\n\n /** Timeout in milliseconds */\n timeout: number;\n}\n\n/**\n * Error thrown when CLI execution fails.\n */\nexport class CLIError extends Error {\n constructor(\n message: string,\n public readonly command: string,\n public readonly exitCode: number,\n public readonly stderr: string\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\n/**\n * Parse an agent command string into command and arguments.\n *\n * Simple commands like \"genesys\" or \"pi\" return [cmd, []].\n * Compound commands like \"tsx src/launcher.ts\" return [cmd, args].\n *\n * @param agentCommand - The agent command string\n * @returns Tuple of [command, arguments]\n */\nfunction parseAgentCommand(agentCommand: string): [string, string[]] {\n const trimmed = agentCommand.trim();\n\n // If no spaces, it's a simple command\n if (!trimmed.includes(' ')) {\n return [trimmed, []];\n }\n\n // Parse compound command (basic space-splitting, no quote handling needed for our use case)\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0];\n const args = parts.slice(1);\n\n return [cmd, args];\n}\n\n/**\n * Run a prompt through a CLI agent.\n *\n * The prompt is passed via stdin to avoid shell escaping issues\n * with multiline strings on Windows.\n *\n * @param agent - The agent command to use (e.g., 'pi', 'genesys', 'tsx src/launcher.ts')\n * @param prompt - The prompt to send\n * @param options - Execution options\n * @returns The agent response\n */\nexport async function runAgent(\n agent: string,\n prompt: string,\n options: RunOptions\n): Promise<AgentResponse> {\n const startTime = Date.now();\n\n // console.log(`Running ${agent} with prompt: [${prompt.substring(0, 100)}${prompt.length > 100 ? '...' : ''}]`);\n\n return new Promise((resolve, reject) => {\n let stdout = '';\n let stderr = '';\n\n const [cmd, cmdArgs] = parseAgentCommand(agent);\n\n // Use shell mode for compound commands or on Windows for .cmd/.ps1 support\n const isCompoundCommand = cmdArgs.length > 0;\n const useShell = isCompoundCommand || process.platform === 'win32';\n\n // Build spawn arguments: command plus -p flag and any original args\n const spawnArgs = [...cmdArgs, '-p'];\n\n const child = spawn(cmd, spawnArgs, {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n shell: useShell,\n });\n\n // Write prompt to stdin and close it\n if (child.stdin) {\n child.stdin.write(prompt, 'utf-8');\n child.stdin.end();\n }\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new CLIError(\n `Command timed out after ${options.timeout}ms`,\n `${agent} -p`,\n -1,\n stderr\n ));\n }, options.timeout);\n\n child.on('error', (error) => {\n clearTimeout(timeout);\n reject(new CLIError(\n `Failed to spawn ${agent}: ${error.message}. Make sure the command is installed and in PATH.`,\n `${agent} -p`,\n -1,\n stderr\n ));\n });\n\n child.on('close', (code) => {\n clearTimeout(timeout);\n const durationMs = Date.now() - startTime;\n\n resolve({\n output: stdout.trim(),\n exitCode: code ?? 0,\n stderr: stderr.trim(),\n durationMs,\n });\n });\n });\n}\n","/**\n * Test suite loading and validation from YAML files.\n *\n * @module test-loader\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\n\nimport YAML from 'yaml';\nimport { z } from 'zod';\n\nimport type { TestCase, TestSuite } from './types.js';\n\n/**\n * Zod schema for validating a test case.\n */\nconst testCaseSchema = z.object({\n id: z.string().min(1, 'Test case ID is required'),\n input: z.string().min(1, 'Test case input is required'),\n context: z.string().optional(),\n expectedOutput: z.string().min(1, 'Test case expectedOutput is required'),\n});\n\n/**\n * Zod schema for validating a test suite.\n */\nconst testSuiteSchema = z.object({\n name: z.string().min(1, 'Test suite name is required'),\n description: z.string().optional(),\n context: z.string().optional(),\n tests: z.array(testCaseSchema).min(1, 'At least one test case is required'),\n});\n\n/**\n * Result of loading a test suite.\n */\nexport interface LoadResult {\n /** The loaded test suite */\n suite: TestSuite;\n\n /** Absolute path to the test file */\n path: string;\n}\n\n/**\n * Error thrown when test file validation fails.\n */\nexport class TestValidationError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly issues: z.ZodIssue[]\n ) {\n super(message);\n this.name = 'TestValidationError';\n }\n}\n\n/**\n * Error thrown when a test file cannot be read.\n */\nexport class TestLoadError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'TestLoadError';\n }\n}\n\n/**\n * Load and validate a test suite from a YAML file.\n *\n * @param filePath - Path to the YAML test file (relative or absolute)\n * @param cwd - Working directory for resolving relative paths\n * @returns The loaded and validated test suite\n * @throws TestLoadError if the file cannot be read\n * @throws TestValidationError if the YAML content is invalid\n *\n * @example\n * ```typescript\n * const { suite, path } = await loadTestSuite('./tests.yaml', process.cwd());\n * console.log(`Loaded ${suite.tests.length} tests from ${path}`);\n * ```\n */\nexport async function loadTestSuite(\n filePath: string,\n cwd: string = process.cwd()\n): Promise<LoadResult> {\n const absolutePath = resolve(cwd, filePath);\n\n let content: string;\n try {\n content = await readFile(absolutePath, 'utf-8');\n } catch (error) {\n throw new TestLoadError(\n `Failed to read test file: ${absolutePath}`,\n absolutePath,\n error\n );\n }\n\n let parsed: unknown;\n try {\n parsed = YAML.parse(content);\n } catch (error) {\n throw new TestLoadError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n absolutePath,\n error\n );\n }\n\n const result = testSuiteSchema.safeParse(parsed);\n if (!result.success) {\n throw new TestValidationError(\n `Test suite validation failed: ${result.error.message}`,\n absolutePath,\n result.error.issues\n );\n }\n\n const validated = result.data;\n\n // Check for duplicate test IDs\n const ids = validated.tests.map((t: TestCase) => t.id);\n const duplicates = ids.filter((id: string, index: number) => ids.indexOf(id) !== index);\n if (duplicates.length > 0) {\n throw new TestValidationError(\n `Duplicate test IDs found: ${[...new Set(duplicates)].join(', ')}`,\n absolutePath,\n []\n );\n }\n\n return {\n suite: validated,\n path: absolutePath,\n };\n}\n\n/**\n * Validate a test suite object without loading from file.\n *\n * @param data - The data to validate\n * @returns The validated test suite\n * @throws TestValidationError if validation fails\n */\nexport function validateTestSuite(data: unknown): TestSuite {\n const result = testSuiteSchema.safeParse(data);\n if (!result.success) {\n throw new TestValidationError(\n `Test suite validation failed: ${result.error.message}`,\n '<inline>',\n result.error.issues\n );\n }\n\n const validated = result.data;\n\n // Check for duplicate test IDs\n const ids = validated.tests.map((t: TestCase) => t.id);\n const duplicates = ids.filter((id: string, index: number) => ids.indexOf(id) !== index);\n if (duplicates.length > 0) {\n throw new TestValidationError(\n `Duplicate test IDs found: ${[...new Set(duplicates)].join(', ')}`,\n '<inline>',\n []\n );\n }\n\n return validated;\n}\n\n/**\n * Parse a test suite from a YAML string.\n *\n * @param yamlString - YAML content to parse\n * @returns The parsed and validated test suite\n * @throws TestLoadError if YAML parsing fails\n * @throws TestValidationError if validation fails\n */\nexport function parseTestSuite(yamlString: string): TestSuite {\n let parsed: unknown;\n try {\n parsed = YAML.parse(yamlString);\n } catch (error) {\n throw new TestLoadError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n '<string>',\n error\n );\n }\n\n return validateTestSuite(parsed);\n}\n","/**\n * Test runner orchestrates loading, execution, and judging of test cases.\n *\n * @module runner\n */\n\nimport { runAgent } from './cli-runner.js';\nimport { loadTestSuite } from './test-loader.js';\n\nimport type {\n EvalResults,\n RunnerConfig,\n TestCase,\n TestResult,\n TestSuite,\n} from './types.js';\n\n/**\n * Progress callback for test execution.\n */\nexport interface ProgressCallback {\n /**\n * Called when a test starts.\n *\n * @param testId - The test ID\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestStart(testId: string, index: number, total: number): void;\n\n /**\n * Called when a test completes.\n *\n * @param result - The test result\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestComplete(result: TestResult, index: number, total: number): void;\n\n /**\n * Called when a test fails with an error.\n *\n * @param testId - The test ID\n * @param error - The error that occurred\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestError(testId: string, error: string, index: number, total: number): void;\n}\n\n/**\n * Run a single test case.\n *\n * @param test - The test case to run\n * @param suite - The test suite\n * @param agent - The agent to use\n * @param timeout - Timeout in milliseconds\n * @param judge - Function to judge the response\n * @param progress - Optional progress callback\n * @param index - Test index\n * @param total - Total tests\n * @returns The test result\n */\nasync function runTest(\n test: TestCase,\n suite: TestSuite,\n agent: string,\n timeout: number,\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress: ProgressCallback | undefined,\n index: number,\n total: number\n): Promise<TestResult> {\n progress?.onTestStart(test.id, index, total);\n\n const startTime = Date.now();\n\n // Build the full prompt with context\n const parts: string[] = [];\n if (suite.context) {\n parts.push('Context:', suite.context, '');\n }\n if (test.context) {\n parts.push('Specific Context:', test.context, '');\n }\n parts.push('Task:', test.input);\n const prompt = parts.join('\\n');\n\n try {\n // Run the agent\n const response = await runAgent(\n agent as 'pi' | 'genesys',\n prompt,\n { cwd: process.cwd(), timeout }\n );\n\n // Judge the response\n const { score, reasoning, passed } = await judge(test, response.output);\n\n const result: TestResult = {\n testId: test.id,\n input: test.input,\n expectedOutput: test.expectedOutput,\n actualOutput: response.output,\n judgeScore: score,\n judgeReasoning: reasoning,\n durationMs: response.durationMs,\n passed,\n };\n\n progress?.onTestComplete(result, index, total);\n return result;\n } catch (error) {\n const durationMs = Date.now() - startTime;\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n progress?.onTestError(test.id, errorMessage, index, total);\n\n return {\n testId: test.id,\n input: test.input,\n expectedOutput: test.expectedOutput,\n actualOutput: '',\n judgeScore: 0,\n judgeReasoning: `Error: ${errorMessage}`,\n durationMs,\n passed: false,\n error: errorMessage,\n };\n }\n}\n\n/**\n * Run tests in parallel with a concurrency limit.\n *\n * @param tests - Tests to run\n * @param concurrency - Number of concurrent executions\n * @param runner - Function to run a single test\n * @returns Array of results in the same order as tests\n */\nasync function runInParallel<T, R>(\n items: T[],\n concurrency: number,\n runner: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n if (concurrency <= 1) {\n // Sequential execution\n const results: R[] = [];\n for (let i = 0; i < items.length; i++) {\n results.push(await runner(items[i], i));\n }\n return results;\n }\n\n // Parallel execution with concurrency limit\n const results = new Array<R>(items.length);\n let index = 0;\n\n async function worker(): Promise<void> {\n while (index < items.length) {\n const currentIndex = index++;\n results[currentIndex] = await runner(items[currentIndex], currentIndex);\n }\n }\n\n // Start workers\n const workers = Array(Math.min(concurrency, items.length))\n .fill(null)\n .map(() => worker());\n\n await Promise.all(workers);\n\n return results;\n}\n\n/**\n * TestRunner orchestrates the evaluation process.\n */\nexport class TestRunner {\n private _config: RunnerConfig;\n\n constructor(config: RunnerConfig) {\n this._config = config;\n }\n\n /**\n * Run the evaluation.\n *\n * @param judge - Function to evaluate agent outputs\n * @param progress - Optional progress callback\n * @returns The evaluation results\n */\n async run(\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress?: ProgressCallback\n ): Promise<EvalResults> {\n // Load the test suite\n const { suite } = await loadTestSuite(this._config.testsPath, this._config.cwd);\n\n // Run all tests\n const results = await runInParallel(\n suite.tests,\n this._config.parallel,\n async (test, index) => {\n return runTest(\n test,\n suite,\n this._config.agent,\n this._config.timeout,\n judge,\n progress,\n index,\n suite.tests.length\n );\n }\n );\n\n // Calculate summary\n const totalDurationMs = results.reduce((sum, r) => sum + r.durationMs, 0);\n const passed = results.filter(r => r.passed).length;\n const failed = results.length - passed;\n const avgScore = results.reduce((sum, r) => sum + r.judgeScore, 0) / results.length;\n\n const evalResults: EvalResults = {\n suite,\n agent: this._config.agent,\n timestamp: new Date().toISOString(),\n results,\n summary: {\n total: results.length,\n passed,\n failed,\n avgScore,\n totalDurationMs,\n },\n };\n\n return evalResults;\n }\n\n /**\n * Get the runner configuration.\n */\n get config(): RunnerConfig {\n return this._config;\n }\n}\n\n/**\n * Run an evaluation with the given configuration.\n *\n * Convenience function that creates a TestRunner and executes it.\n *\n * @param config - Runner configuration\n * @param judge - Judge function for evaluating responses\n * @param progress - Optional progress callback\n * @returns Evaluation results\n */\nexport async function runEvaluation(\n config: RunnerConfig,\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress?: ProgressCallback\n): Promise<EvalResults> {\n const runner = new TestRunner(config);\n return runner.run(judge, progress);\n}\n","/**\n * Package metadata utilities.\n *\n * @module utils/package\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get package.json contents.\n *\n * @returns Package.json as an object\n */\nexport function getPackageJson(): { version: string; name: string; [key: string]: unknown } {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packagePath = join(__dirname, '..', '..', 'package.json');\n\n try {\n const content = readFileSync(packagePath, 'utf-8');\n return JSON.parse(content) as { version: string; name: string; [key: string]: unknown };\n } catch {\n // Fallback if package.json can't be read\n return {\n version: '1.0.0',\n name: '@gnsx/genesys.agent.eval',\n };\n }\n}\n"],"mappings":"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","names":["resolve","resolve","z","results","fileURLToPath","colors","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli.ts","../../../../../cli-utils/src/self-update.ts","../../src/args.ts","../../src/embedding-judge.ts","../../src/judge.ts","../../src/reporter.ts","../../src/cli-runner.ts","../../src/test-loader.ts","../../src/runner.ts","../../src/utils/package.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Genesys Agent Eval CLI launcher.\n *\n * Entry point for the evaluation harness. Spawns pi or genesys CLI\n * processes to run tests and evaluates the results.\n */\n\nimport { resolve } from 'node:path';\n\nimport { parseArgs } from './args.js';\nimport { EmbeddingJudge } from './embedding-judge.js';\nimport { Judge } from './judge.js';\nimport { Reporter } from './reporter.js';\nimport { type ProgressCallback, runEvaluation } from './runner.js';\nimport { getPackageJson } from './utils/package.js';\n\nimport type { RunnerConfig, TestResult } from './types.js';\n\n/**\n * ANSI color codes for console output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n};\n\n/**\n * Progress callback implementation for console output.\n */\nfunction createProgressCallback(verbose: boolean): ProgressCallback {\n return {\n onTestStart(testId: string, index: number, total: number): void {\n if (verbose) {\n console.log(`[${index + 1}/${total}] Running: ${testId}`);\n }\n },\n onTestComplete(result: TestResult, index: number, total: number): void {\n const status = result.passed ? 'PASS' : 'FAIL';\n const score = `${(result.judgeScore * 100).toFixed(0)}%`;\n const statusColor = result.passed ? colors.green : colors.red;\n console.log(`${statusColor}${status}${colors.reset}`);\n },\n onTestError(testId: string, error: string, index: number, total: number): void {\n console.error(`[${index + 1}/${total}] ERROR - ${testId}: ${error}`);\n },\n };\n}\n\n/**\n * Main entry point.\n */\nasync function main(argv: string[]): Promise<void> {\n const pkg = getPackageJson();\n const args = parseArgs(argv, pkg.version, pkg.name);\n\n const cwd = resolve(args.cwd);\n\n // Build configuration\n const config: RunnerConfig = {\n testsPath: args.tests,\n agent: args.agent,\n cwd,\n timeout: args.timeout * 1000, // Convert to milliseconds\n outputPath: args.output,\n format: args.format,\n parallel: args.parallel,\n judge: {\n provider: args.judgeProvider,\n model: args.judgeModel,\n },\n };\n\n console.log(`${colors.cyan}Agent:${colors.reset} ${colors.bright}${args.agent}${colors.reset}`);\n console.log(`${colors.cyan}Judge:${colors.reset} ${args.judgeType}`);\n console.log(`${colors.cyan}Working directory:${colors.reset} ${cwd}`);\n console.log(`${colors.cyan}Test file:${colors.reset} ${args.tests}`);\n console.log(`${colors.cyan}Timeout:${colors.reset} ${args.timeout}s per test`);\n console.log(`${colors.cyan}Parallelism:${colors.reset} ${args.parallel}`);\n console.log('');\n\n // Create judge based on type\n let judgeEvaluator: ReturnType<EmbeddingJudge['createEvaluator']> | ReturnType<Judge['createEvaluator']>;\n\n if (args.judgeType === 'embedding') {\n const judge = new EmbeddingJudge({ passThreshold: 0.6 });\n judgeEvaluator = judge.createEvaluator();\n } else {\n const judge = new Judge({\n provider: args.judgeProvider,\n model: args.judgeModel,\n passThreshold: 0.7,\n });\n judgeEvaluator = judge.createEvaluator();\n }\n\n // Run evaluation\n const progress = createProgressCallback(args.parallel > 1 || args.format === 'console');\n\n try {\n const results = await runEvaluation(config, judgeEvaluator, progress);\n\n // Report results\n const reporter = new Reporter({\n format: args.format,\n outputPath: args.output,\n });\n\n await reporter.reportAndSave(results);\n\n // Exit with appropriate code\n process.exit(results.summary.failed > 0 ? 1 : 0);\n } catch (error) {\n console.error(`Evaluation failed: ${error instanceof Error ? error.message : String(error)}`);\n\n // Provide more context for common errors\n if (error instanceof Error) {\n if (error.message.includes('ENOENT')) {\n console.error(`Make sure the ${args.agent} CLI is installed and in your PATH.`);\n }\n if (error.message.includes('ANTHROPIC_API_KEY') || error.message.includes('OPENAI_API_KEY')) {\n console.error('Set the appropriate API key environment variable for the LLM judge.');\n }\n }\n\n process.exit(1);\n }\n}\n\n// Run main\nmain(process.argv.slice(2)).catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","/**\n * Self-update functionality for Genesys CLI tools.\n *\n * Provides utilities for checking and performing CLI updates\n * via npm or pnpm package managers.\n */\n\nimport { execSync } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport type { Command } from 'commander';\n\n/**\n * Check if running from an installed package (not local development).\n * Returns true if the current file is inside node_modules.\n */\nexport function isInstalledPackage(): boolean {\n try {\n const currentFile = fileURLToPath(import.meta.url);\n return currentFile.includes('node_modules');\n } catch {\n return false;\n }\n}\n\n/**\n * Detect which package manager was used to install the CLI.\n * Checks environment variables and execution path.\n *\n * @returns 'pnpm', 'npm', or 'unknown'\n */\nexport function detectPackageManager(): 'pnpm' | 'npm' | 'unknown' {\n // Check environment variables\n if (process.env.PNPM_PACKAGE_NAME) return 'pnpm';\n if (process.env.npm_execpath?.includes('pnpm')) return 'pnpm';\n\n // Check exec path\n const execPath = process.argv[1] || '';\n if (execPath.includes('pnpm')) return 'pnpm';\n if (execPath.includes('npm')) return 'npm';\n\n // Default to pnpm (monorepo preference)\n return 'pnpm';\n}\n\n/**\n * Compare semantic versions.\n * Returns true if latest is newer than current.\n */\nfunction isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const latestPart = latestParts[i] || 0;\n const currentPart = currentParts[i] || 0;\n if (latestPart > currentPart) return true;\n if (latestPart < currentPart) return false;\n }\n\n return false;\n}\n\n/**\n * Check npm registry for the latest version of a package.\n *\n * @param packageName - The npm package name\n * @param currentVersion - The currently installed version\n * @returns Latest version string, or null if up-to-date or error\n */\nexport async function checkForUpdates(\n packageName: string,\n currentVersion: string\n): Promise<string | null> {\n try {\n if (!isInstalledPackage()) return null;\n\n const encodedName = encodeURIComponent(packageName);\n const response = await fetch(`https://registry.npmjs.org/${encodedName}/latest`, {\n signal: AbortSignal.timeout(10000),\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n const latestVersion = data.version;\n\n if (!latestVersion || latestVersion === currentVersion) return null;\n if (!isNewerVersion(latestVersion, currentVersion)) return null;\n\n return latestVersion;\n } catch {\n return null;\n }\n}\n\n/**\n * Perform the update using the detected package manager.\n *\n * @param packageName - The npm package name\n * @param packageManager - The package manager to use ('pnpm' or 'npm')\n * @param currentVersion - The current installed version\n * @param latestVersion - The latest available version\n * @returns true on success, false on failure\n */\nexport function performUpdate(\n packageName: string,\n packageManager: 'pnpm' | 'npm',\n currentVersion: string,\n latestVersion: string\n): boolean {\n console.log(`\\nUpdating ${packageName}...`);\n console.log(` Current: v${currentVersion}`);\n console.log(` Latest: v${latestVersion}\\n`);\n\n try {\n const updateCommand = packageManager === 'pnpm'\n ? `pnpm remove -g ${packageName} && pnpm add -g ${packageName}@latest`\n : `npm uninstall -g ${packageName} && npm install -g ${packageName}@latest`;\n\n // Run in shell for cross-platform compatibility (&& works on Unix, needs shell on Windows)\n execSync(updateCommand, { stdio: 'inherit' } as import('child_process').ExecSyncOptions);\n\n console.log(`\\n✅ Update complete! ${packageName} has been updated to v${latestVersion}.`);\n return true;\n } catch (error) {\n console.error(`\\n❌ Update failed. Please try running the commands manually:`);\n if (packageManager === 'pnpm') {\n console.error(` pnpm remove -g ${packageName}`);\n console.error(` pnpm add -g ${packageName}@latest`);\n } else {\n console.error(` npm uninstall -g ${packageName}`);\n console.error(` npm install -g ${packageName}@latest`);\n }\n return false;\n }\n}\n\n/**\n * Add 'update' subcommand to a Commander.js program.\n *\n * @param program - The Commander.js program\n * @param packageName - The npm package name\n * @param currentVersion - The current installed version\n */\nexport function addUpdateCommand(\n program: Command,\n packageName: string,\n currentVersion: string\n): void {\n program\n .command('update')\n .description('Check for updates and install the latest version')\n .action(async () => {\n // Skip if running from local development\n if (!isInstalledPackage()) {\n console.log('Skipping update check - running from local development.');\n process.exit(0);\n }\n\n console.log('Checking for updates...');\n\n const latestVersion = await checkForUpdates(packageName, currentVersion);\n\n if (!latestVersion) {\n console.log(`You are already using the latest version (v${currentVersion}).`);\n process.exit(0);\n }\n\n console.log(`\\n📦 Update available: v${currentVersion} → v${latestVersion}`);\n\n const packageManager = detectPackageManager();\n\n if (packageManager === 'unknown') {\n console.error('\\n❌ Could not detect package manager. Please update manually:');\n console.error(` pnpm remove -g ${packageName} && pnpm add -g ${packageName}@latest`);\n console.error(` or`);\n console.error(` npm uninstall -g ${packageName} && npm install -g ${packageName}@latest`);\n process.exit(1);\n }\n\n const success = performUpdate(packageName, packageManager, currentVersion, latestVersion);\n process.exit(success ? 0 : 1);\n });\n}\n","/**\n * CLI argument definitions and parsing for the eval harness using Commander.js.\n *\n * @module args\n */\n\nimport { addUpdateCommand } from '@gnsx/cli-utils';\nimport { Command } from 'commander';\n\nimport type { Args } from './types.js';\n\nconst VALID_FORMATS = ['console', 'json', 'html'] as const;\nconst VALID_JUDGE_TYPES = ['embedding', 'llm'] as const;\n\ntype ValidFormat = (typeof VALID_FORMATS)[number];\ntype ValidJudgeType = (typeof VALID_JUDGE_TYPES)[number];\n\nfunction isValidFormat(value: string): value is ValidFormat {\n return VALID_FORMATS.includes(value as ValidFormat);\n}\n\nfunction isValidJudgeType(value: string): value is ValidJudgeType {\n return VALID_JUDGE_TYPES.includes(value as ValidJudgeType);\n}\n\nexport function parseArgs(argv: string[], version: string, packageName: string): Args {\n const program = new Command();\n\n program\n .name('genesys-eval')\n .description('Agent evaluation harness for benchmarking AI agents')\n .version(version, '-v, --version');\n\n // Add update command\n addUpdateCommand(program, packageName, version);\n\n program\n .option('--tests <path>', 'path to YAML test file', './eval-tests.yaml')\n .option('-a, --agent <command>', 'agent CLI command to test', 'genesys')\n .option('--cwd <dir>', 'working directory for test context', process.cwd())\n .option('-t, --timeout <secs>', 'timeout per test in seconds', '120')\n .option('-o, --output <path>', 'output file for results')\n .option('--format <format>', 'output format: console, json, html', 'console')\n .option('-p, --parallel <n>', 'number of parallel test executions', '1')\n .option('--judge-type <type>', 'judge type: embedding, llm', 'embedding')\n .option('--judge-model <model>', 'model for LLM judge', 'claude-3-5-sonnet-20241022')\n .option('--judge-provider <provider>', 'provider for LLM judge', 'anthropic')\n .parse(argv, { from: 'user' });\n\n const opts = program.opts();\n\n // Validate format\n if (!isValidFormat(opts.format)) {\n console.error(`--format must be one of: ${VALID_FORMATS.join(', ')}`);\n process.exit(1);\n }\n\n // Validate judge type\n if (!isValidJudgeType(opts.judgeType)) {\n console.error(`--judge-type must be one of: ${VALID_JUDGE_TYPES.join(', ')}`);\n process.exit(1);\n }\n\n // Validate and parse timeout\n const timeout = parseInt(opts.timeout, 10);\n if (isNaN(timeout) || timeout < 1) {\n console.error('--timeout must be a positive integer');\n process.exit(1);\n }\n\n // Validate and parse parallel\n const parallel = parseInt(opts.parallel, 10);\n if (isNaN(parallel) || parallel < 1) {\n console.error('--parallel must be a positive integer');\n process.exit(1);\n }\n\n return {\n tests: opts.tests,\n agent: opts.agent,\n cwd: opts.cwd,\n timeout,\n output: opts.output,\n format: opts.format,\n parallel,\n judgeType: opts.judgeType,\n judgeModel: opts.judgeModel,\n judgeProvider: opts.judgeProvider,\n help: false,\n version: false,\n };\n}\n","/**\n * Embedding-based cosine similarity judge using an actual embedding model.\n *\n * Uses @huggingface/transformers with a lightweight local model for semantic similarity.\n *\n * @module embedding-judge\n */\n\nimport { type FeatureExtractionPipeline, pipeline } from '@huggingface/transformers';\n\nimport type { TestCase } from './types.js';\n\n/**\n * Result of judging a test case.\n */\nexport interface JudgeResult {\n /** Score from 0 to 1 */\n score: number;\n\n /** Reasoning for the score */\n reasoning: string;\n\n /** Whether the test passed (score >= threshold) */\n passed: boolean;\n}\n\n/**\n * Configuration for the embedding judge.\n */\nexport interface EmbeddingJudgeConfig {\n /** Score threshold for passing (0-1, default: 0.7) */\n passThreshold?: number;\n\n /** Embedding model to use (default: Xenova/all-MiniLM-L6-v2 via Hugging Face) */\n model?: string;\n}\n\n/**\n * Judge that evaluates agent outputs using embedding cosine similarity.\n *\n * Uses a local transformer model for semantic similarity comparison.\n * The model is downloaded on first use and cached locally.\n */\nexport class EmbeddingJudge {\n private _config: Required<EmbeddingJudgeConfig>;\n private _pipeline: FeatureExtractionPipeline | null = null;\n private _modelLoading: Promise<FeatureExtractionPipeline> | null = null;\n\n constructor(config: EmbeddingJudgeConfig = {}) {\n this._config = {\n passThreshold: 0.7,\n model: 'Xenova/all-MiniLM-L6-v2',\n ...config,\n };\n }\n\n /**\n * Get or create the embedding pipeline.\n * Lazy loads the model on first use.\n */\n private async getPipeline(): Promise<FeatureExtractionPipeline> {\n if (this._pipeline) {\n return this._pipeline;\n }\n\n if (this._modelLoading) {\n return this._modelLoading;\n }\n\n\n this._modelLoading = pipeline(\n 'feature-extraction',\n this._config.model,\n\n ) as unknown as Promise<FeatureExtractionPipeline>;\n\n this._pipeline = await this._modelLoading;\n return this._pipeline;\n }\n\n /**\n * Generate embeddings for text.\n *\n * @param text - Text to embed\n * @returns Embedding vector\n */\n private async generateEmbedding(text: string): Promise<number[]> {\n const pipe = await this.getPipeline();\n\n const output = await pipe(text, {\n pooling: 'mean',\n normalize: true,\n });\n\n // Convert to array\n return Array.from(output.data as Float32Array);\n }\n\n /**\n * Calculate cosine similarity between two vectors.\n */\n private cosineSimilarity(a: number[], b: number[]): number {\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n // Vectors are already normalized, but calculate just in case\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n\n if (magnitude === 0) {\n return 0;\n }\n\n return Math.max(0, Math.min(1, dotProduct / magnitude));\n }\n\n /**\n * Evaluate a test case against the actual output.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The judge result with score and reasoning\n */\n async evaluate(test: TestCase, actualOutput: string): Promise<JudgeResult> {\n try {\n // Generate embeddings for both expected and actual output\n const expectedEmbedding = await this.generateEmbedding(test.expectedOutput);\n const actualEmbedding = await this.generateEmbedding(actualOutput);\n\n // Calculate similarity\n const score = this.cosineSimilarity(expectedEmbedding, actualEmbedding);\n\n // Generate reasoning\n let reasoning: string;\n if (score >= 0.9) {\n reasoning = 'Very high semantic similarity - output closely matches expected content.';\n } else if (score >= 0.75) {\n reasoning = 'Good semantic similarity with minor differences in meaning or detail.';\n } else if (score >= this._config.passThreshold) {\n reasoning = 'Moderate similarity - core concepts match but notable differences exist.';\n } else if (score >= 0.4) {\n reasoning = 'Low semantic similarity - significant differences in meaning.';\n } else {\n reasoning = 'Very low similarity - output does not match expected content.';\n }\n\n const passed = score >= this._config.passThreshold;\n\n return {\n score,\n reasoning,\n passed,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n score: 0,\n reasoning: `Embedding evaluation failed: ${errorMessage}`,\n passed: false,\n };\n }\n }\n\n /**\n * Create a judge function compatible with the TestRunner.\n *\n * @returns A function that can be passed to the runner\n */\n createEvaluator(): (\n test: TestCase,\n actualOutput: string\n ) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }> {\n return async (test, actualOutput) => {\n const result = await this.evaluate(test, actualOutput);\n return {\n score: result.score,\n reasoning: result.reasoning,\n passed: result.passed,\n };\n };\n }\n\n /**\n * Get the judge configuration.\n */\n get config(): EmbeddingJudgeConfig {\n return this._config;\n }\n}\n\n/**\n * Create an embedding judge with the given configuration.\n *\n * @param config - Judge configuration\n * @returns A new EmbeddingJudge instance\n *\n * @example\n * ```typescript\n * const judge = createEmbeddingJudge({ passThreshold: 0.75 });\n * const result = await judge.evaluate(test, output);\n * console.log(`Score: ${result.score}, Passed: ${result.passed}`);\n * ```\n */\nexport function createEmbeddingJudge(config?: EmbeddingJudgeConfig): EmbeddingJudge {\n return new EmbeddingJudge(config);\n}\n","/**\n * LLM-based judge for evaluating agent outputs against expected results.\n *\n * The judge uses a separate LLM to score how well the agent's output matches\n * the expected output description on a scale of 0-1.\n *\n * @module judge\n */\n\nimport { anthropic } from '@ai-sdk/anthropic';\nimport { google } from '@ai-sdk/google';\nimport { openai } from '@ai-sdk/openai';\nimport { generateObject } from 'ai';\nimport { z } from 'zod';\n\nimport type { JudgeConfig, TestCase } from './types.js';\n\n/**\n * Result of judging a test case.\n */\nexport interface JudgeResult {\n /** Score from 0 to 1 */\n score: number;\n\n /** Reasoning for the score */\n reasoning: string;\n\n /** Whether the test passed (score >= threshold) */\n passed: boolean;\n}\n\n/**\n * Zod schema for the judge's structured output.\n */\nconst judgeOutputSchema = z.object({\n score: z.number().min(0).max(1).describe('Score from 0 to 1 where 1 is perfect'),\n reasoning: z.string().describe('Explanation for the score'),\n});\n\n/**\n * Type for judge output.\n */\ntype JudgeOutput = z.infer<typeof judgeOutputSchema>;\n\n/**\n * Judge that evaluates agent outputs using an LLM.\n *\n * The judge prompts a separate LLM to compare the actual output against the\n * expected output description and score it on a scale of 0-1.\n */\nexport class Judge {\n private _config: JudgeConfig;\n\n constructor(config: JudgeConfig) {\n this._config = {\n passThreshold: 0.7,\n temperature: 0,\n ...config,\n };\n }\n\n /**\n * Build the judge prompt.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The prompt to send to the judge LLM\n */\n private buildPrompt(test: TestCase, actualOutput: string): string {\n return `You are an expert evaluator assessing the quality of AI responses.\n\nYour task is to evaluate how well the ACTUAL OUTPUT matches the EXPECTED OUTPUT description.\n\n## Test Input\n${test.input}\n\n## Expected Output Description\n${test.expectedOutput}\n\n${test.context ? `## Additional Context\\n${test.context}\\n\\n` : ''}## Actual Output\n${actualOutput}\n\n## Evaluation Instructions\n\n1. Carefully read the expected output description and the actual output\n2. Score the actual output on a scale of 0.0 to 1.0 where:\n - 1.0 = Perfect match, fully satisfies the expected output\n - 0.8-0.9 = Good match, minor issues or omissions\n - 0.6-0.7 = Partial match, significant issues but some correct elements\n - 0.4-0.5 = Poor match, mostly incorrect or incomplete\n - 0.0-0.3 = Very poor match, completely wrong or irrelevant\n\n3. Provide clear reasoning for your score\n\nRespond with a structured object containing:\n- score: number from 0 to 1\n- reasoning: string explaining your evaluation`;\n }\n\n /**\n * Get the model instance based on provider.\n *\n * @returns Model instance for the Vercel AI SDK\n */\n private getModel() {\n const { provider, model } = this._config;\n\n switch (provider) {\n case 'anthropic': {\n return anthropic(model);\n }\n case 'openai': {\n return openai(model);\n }\n case 'google':\n case 'gemini': {\n return google(model);\n }\n default: {\n throw new Error(`Unsupported judge provider: ${provider}`);\n }\n }\n }\n\n /**\n * Evaluate a test case against the actual output.\n *\n * @param test - The test case\n * @param actualOutput - The actual output from the agent\n * @returns The judge result with score and reasoning\n */\n async evaluate(test: TestCase, actualOutput: string): Promise<JudgeResult> {\n const prompt = this.buildPrompt(test, actualOutput);\n\n try {\n const { object } = await generateObject({\n model: this.getModel() as unknown as Parameters<typeof generateObject>[0]['model'],\n schema: judgeOutputSchema,\n messages: [\n {\n role: 'user',\n content: prompt,\n },\n ],\n temperature: this._config.temperature,\n });\n\n const passed = object.score >= (this._config.passThreshold ?? 0.7);\n\n return {\n score: object.score,\n reasoning: object.reasoning,\n passed,\n };\n } catch (error) {\n // If structured generation fails, return a failed result\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n score: 0,\n reasoning: `Judge evaluation failed: ${errorMessage}`,\n passed: false,\n };\n }\n }\n\n /**\n * Create a judge function compatible with the TestRunner.\n *\n * @returns A function that can be passed to the runner\n */\n createEvaluator(): (\n test: TestCase,\n actualOutput: string\n ) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }> {\n return async (test, actualOutput) => {\n const result = await this.evaluate(test, actualOutput);\n return {\n score: result.score,\n reasoning: result.reasoning,\n passed: result.passed,\n };\n };\n }\n\n /**\n * Get the judge configuration.\n */\n get config(): JudgeConfig {\n return this._config;\n }\n}\n\n/**\n * Create a judge with the given configuration.\n *\n * @param config - Judge configuration\n * @returns A new Judge instance\n *\n * @example\n * ```typescript\n * const judge = createJudge({\n * provider: 'anthropic',\n * model: 'claude-3-5-sonnet-20241022',\n * passThreshold: 0.8\n * });\n *\n * const result = await judge.evaluate(test, output);\n * console.log(`Score: ${result.score}, Passed: ${result.passed}`);\n * ```\n */\nexport function createJudge(config: JudgeConfig): Judge {\n return new Judge(config);\n}\n\n/**\n * Quick evaluate function for one-off judgments.\n *\n * @param config - Judge configuration\n * @param test - Test case\n * @param actualOutput - Actual output to evaluate\n * @returns Judge result\n */\nexport async function evaluate(\n config: JudgeConfig,\n test: TestCase,\n actualOutput: string\n): Promise<JudgeResult> {\n const judge = createJudge(config);\n return judge.evaluate(test, actualOutput);\n}\n","/**\n * Reporter for formatting and outputting evaluation results.\n *\n * Supports multiple output formats:\n * - console: Rich text table output to stdout\n * - json: Machine-readable JSON output\n * - html: Rich HTML report with styling\n *\n * @module reporter\n */\n\nimport { writeFile } from 'node:fs/promises';\n\nimport type { EvalResults, TestResult } from './types.js';\n\n/**\n * Output format options.\n */\nexport type OutputFormat = 'console' | 'json' | 'html';\n\n/**\n * Reporter configuration.\n */\nexport interface ReporterConfig {\n /** Output format */\n format: OutputFormat;\n\n /** Output file path (optional, defaults to stdout) */\n outputPath?: string;\n}\n\n/**\n * Format duration in milliseconds to human-readable string.\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\n/**\n * Truncate string to max length with ellipsis.\n */\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) {\n return str;\n }\n return str.slice(0, maxLength - 3) + '...';\n}\n\n/**\n * Format test result for console output.\n */\nfunction formatResultForConsole(result: TestResult, maxWidth: number): string {\n const status = result.passed ? 'PASS' : 'FAIL';\n const score = `${(result.judgeScore * 100).toFixed(0)}%`;\n const duration = formatDuration(result.durationMs);\n const id = truncate(result.testId, 20);\n\n return ` ${status.padEnd(4)} | ${id.padEnd(20)} | ${score.padEnd(4)} | ${duration}`;\n}\n\n/**\n * ANSI color codes for console output.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n};\n\n/**\n * Reporter class for formatting evaluation results.\n */\nexport class Reporter {\n private _config: ReporterConfig;\n\n constructor(config: ReporterConfig) {\n this._config = config;\n }\n\n /**\n * Format results as a console table.\n *\n * @param results - Evaluation results\n * @returns Formatted string for console output\n */\n private formatConsole(results: EvalResults): string {\n const lines: string[] = [];\n\n // Header\n lines.push('');\n lines.push(`${colors.bright}Evaluation Results${colors.reset}`);\n lines.push(`${colors.dim}${'='.repeat(60)}${colors.reset}`);\n lines.push('');\n\n // Suite info\n lines.push(`${colors.cyan}Suite:${colors.reset} ${results.suite.name}`);\n if (results.suite.description) {\n lines.push(`${colors.cyan}Description:${colors.reset} ${results.suite.description}`);\n }\n lines.push(`${colors.cyan}Agent:${colors.reset} ${results.agent}`);\n lines.push(`${colors.cyan}Timestamp:${colors.reset} ${new Date(results.timestamp).toLocaleString()}`);\n lines.push('');\n\n // Summary\n const { summary } = results;\n const statusColor = summary.failed === 0 ? colors.green : colors.red;\n lines.push(`${colors.bright}Summary:${colors.reset}`);\n lines.push(` ${colors.cyan}Total:${colors.reset} ${summary.total}`);\n lines.push(` ${colors.green}Passed:${colors.reset} ${summary.passed}`);\n lines.push(` ${colors.red}Failed:${colors.reset} ${summary.failed}`);\n lines.push(` ${colors.yellow}Avg Score:${colors.reset} ${(summary.avgScore * 100).toFixed(1)}%`);\n lines.push(` ${colors.dim}Duration:${colors.reset} ${formatDuration(summary.totalDurationMs)}`);\n lines.push('');\n\n // Test results table\n lines.push(`${colors.bright}Test Results:${colors.reset}`);\n lines.push(` ${colors.dim}Status | ID | Score | Duration${colors.reset}`);\n lines.push(` ${colors.dim}${'-'.repeat(55)}${colors.reset}`);\n\n const failedResults: TestResult[] = [];\n\n for (const result of results.results) {\n const color = result.passed ? colors.green : colors.red;\n lines.push(`${color}${formatResultForConsole(result, 80)}${colors.reset}`);\n if (!result.passed) {\n failedResults.push(result);\n }\n }\n\n lines.push('');\n\n // Show details for failed tests\n if (failedResults.length > 0) {\n lines.push(`${colors.bright}Failed Test Details:${colors.reset}`);\n lines.push(`${colors.dim}${'='.repeat(60)}${colors.reset}`);\n\n for (const result of failedResults) {\n lines.push('');\n lines.push(`${colors.red}${colors.bright}Test: ${result.testId}${colors.reset}`);\n lines.push(`${colors.dim}Input:${colors.reset} ${result.input}`);\n lines.push(`${colors.yellow}Expected:${colors.reset} ${result.expectedOutput}`);\n lines.push(`${colors.cyan}Actual:${colors.reset} ${result.actualOutput}`);\n if (result.judgeReasoning) {\n lines.push(`${colors.dim}Reasoning: ${result.judgeReasoning}${colors.reset}`);\n }\n lines.push(`${colors.dim}${'-'.repeat(40)}${colors.reset}`);\n }\n\n lines.push('');\n }\n\n // Footer\n if (summary.failed > 0) {\n lines.push(`${colors.yellow}Some tests failed. Review the results above.${colors.reset}`);\n } else {\n lines.push(`${colors.green}All tests passed!${colors.reset}`);\n }\n\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Format results as JSON.\n *\n * @param results - Evaluation results\n * @returns JSON string\n */\n private formatJson(results: EvalResults): string {\n return JSON.stringify(results, null, 2);\n }\n\n /**\n * Format results as HTML.\n *\n * @param results - Evaluation results\n * @returns HTML string\n */\n private formatHtml(results: EvalResults): string {\n const { summary } = results;\n const allPassed = summary.failed === 0;\n\n const testRows = results.results.map(result => `\n <tr class=\"${result.passed ? 'passed' : 'failed'}\">\n <td class=\"status\">${result.passed ? 'PASS' : 'FAIL'}</td>\n <td class=\"id\">${escapeHtml(result.testId)}</td>\n <td class=\"score\">${(result.judgeScore * 100).toFixed(0)}%</td>\n <td class=\"duration\">${formatDuration(result.durationMs)}</td>\n <td class=\"reasoning\">${escapeHtml(truncate(result.judgeReasoning, 100))}</td>\n </tr>\n `).join('\\n');\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Eval Results: ${escapeHtml(results.suite.name)}</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n line-height: 1.6;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n .container {\n background: white;\n border-radius: 8px;\n padding: 2rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n h1 { margin-top: 0; color: #333; }\n h2 { color: #555; border-bottom: 2px solid #eee; padding-bottom: 0.5rem; }\n .meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin-bottom: 2rem;\n }\n .meta-item {\n background: #f8f9fa;\n padding: 1rem;\n border-radius: 4px;\n }\n .meta-label { font-weight: 600; color: #666; font-size: 0.875rem; }\n .meta-value { color: #333; }\n .summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .summary-card {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 1.5rem;\n border-radius: 8px;\n text-align: center;\n }\n .summary-card.passed { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); }\n .summary-card.failed { background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%); }\n .summary-card.warning { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }\n .summary-value { font-size: 2rem; font-weight: bold; }\n .summary-label { font-size: 0.875rem; opacity: 0.9; }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 1rem;\n }\n th, td {\n padding: 0.75rem;\n text-align: left;\n border-bottom: 1px solid #eee;\n }\n th {\n font-weight: 600;\n color: #555;\n background: #f8f9fa;\n }\n tr.passed .status { color: #11998e; font-weight: 600; }\n tr.failed .status { color: #eb3349; font-weight: 600; }\n .footer {\n margin-top: 2rem;\n padding-top: 1rem;\n border-top: 1px solid #eee;\n text-align: center;\n color: #666;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h1>Evaluation Results</h1>\n\n <div class=\"meta\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite</div>\n <div class=\"meta-value\">${escapeHtml(results.suite.name)}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Agent</div>\n <div class=\"meta-value\">${escapeHtml(results.agent)}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Timestamp</div>\n <div class=\"meta-value\">${new Date(results.timestamp).toLocaleString()}</div>\n </div>\n </div>\n\n <h2>Summary</h2>\n <div class=\"summary\">\n <div class=\"summary-card\">\n <div class=\"summary-value\">${summary.total}</div>\n <div class=\"summary-label\">Total Tests</div>\n </div>\n <div class=\"summary-card ${summary.passed === summary.total ? 'passed' : summary.passed === 0 ? 'failed' : 'warning'}\">\n <div class=\"summary-value\">${summary.passed}</div>\n <div class=\"summary-label\">Passed</div>\n </div>\n <div class=\"summary-card ${summary.failed === 0 ? 'passed' : 'failed'}\">\n <div class=\"summary-value\">${summary.failed}</div>\n <div class=\"summary-label\">Failed</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"summary-value\">${(summary.avgScore * 100).toFixed(1)}%</div>\n <div class=\"summary-label\">Avg Score</div>\n </div>\n <div class=\"summary-card\">\n <div class=\"summary-value\">${formatDuration(summary.totalDurationMs)}</div>\n <div class=\"summary-label\">Duration</div>\n </div>\n </div>\n\n <h2>Test Results</h2>\n <table>\n <thead>\n <tr>\n <th>Status</th>\n <th>ID</th>\n <th>Score</th>\n <th>Duration</th>\n <th>Reasoning</th>\n </tr>\n </thead>\n <tbody>\n ${testRows}\n </tbody>\n </table>\n\n <div class=\"footer\">\n <p>Generated by genesys-eval</p>\n </div>\n </div>\n</body>\n</html>`;\n }\n\n /**\n * Report evaluation results.\n *\n * @param results - Evaluation results\n * @returns The formatted output string\n */\n report(results: EvalResults): string {\n switch (this._config.format) {\n case 'json': {\n return this.formatJson(results);\n }\n case 'html': {\n return this.formatHtml(results);\n }\n case 'console':\n default: {\n return this.formatConsole(results);\n }\n }\n }\n\n /**\n * Report results and optionally write to file.\n *\n * @param results - Evaluation results\n */\n async reportAndSave(results: EvalResults): Promise<void> {\n const output = this.report(results);\n\n if (this._config.outputPath) {\n await writeFile(this._config.outputPath, output, 'utf-8');\n }\n\n // Always print to console if format is console, or if no output file\n if (this._config.format === 'console' || !this._config.outputPath) {\n console.log(output);\n } else {\n console.log(`Results written to: ${this._config.outputPath}`);\n }\n }\n\n /**\n * Get the reporter configuration.\n */\n get config(): ReporterConfig {\n return this._config;\n }\n}\n\n/**\n * Escape HTML special characters.\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Quick report function.\n *\n * @param results - Evaluation results\n * @param format - Output format\n * @returns Formatted string\n */\nexport function formatResults(results: EvalResults, format: OutputFormat): string {\n const reporter = new Reporter({ format });\n return reporter.report(results);\n}\n\n/**\n * Report and save results.\n *\n * @param results - Evaluation results\n * @param format - Output format\n * @param outputPath - Optional output file path\n */\nexport async function reportResults(\n results: EvalResults,\n format: OutputFormat,\n outputPath?: string\n): Promise<void> {\n const reporter = new Reporter({ format, outputPath });\n await reporter.reportAndSave(results);\n}\n","/**\n * Simple CLI runner for executing pi, genesys, or any custom agent CLI.\n *\n * Prompt is passed via stdin for all agents.\n *\n * @module cli-runner\n */\n\nimport { spawn } from 'node:child_process';\n\nimport type { AgentResponse } from './types.js';\n\n/**\n * Options for running a CLI command.\n */\nexport interface RunOptions {\n /** Working directory for the command */\n cwd: string;\n\n /** Timeout in milliseconds */\n timeout: number;\n}\n\n/**\n * Error thrown when CLI execution fails.\n */\nexport class CLIError extends Error {\n constructor(\n message: string,\n public readonly command: string,\n public readonly exitCode: number,\n public readonly stderr: string\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\n/**\n * Parse an agent command string into command and arguments.\n *\n * Simple commands like \"genesys\" or \"pi\" return [cmd, []].\n * Compound commands like \"tsx src/launcher.ts\" return [cmd, args].\n *\n * @param agentCommand - The agent command string\n * @returns Tuple of [command, arguments]\n */\nfunction parseAgentCommand(agentCommand: string): [string, string[]] {\n const trimmed = agentCommand.trim();\n\n // If no spaces, it's a simple command\n if (!trimmed.includes(' ')) {\n return [trimmed, []];\n }\n\n // Parse compound command (basic space-splitting, no quote handling needed for our use case)\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0];\n const args = parts.slice(1);\n\n return [cmd, args];\n}\n\n/**\n * Run a prompt through a CLI agent.\n *\n * The prompt is passed via stdin to avoid shell escaping issues\n * with multiline strings on Windows.\n *\n * @param agent - The agent command to use (e.g., 'pi', 'genesys', 'tsx src/launcher.ts')\n * @param prompt - The prompt to send\n * @param options - Execution options\n * @returns The agent response\n */\nexport async function runAgent(\n agent: string,\n prompt: string,\n options: RunOptions\n): Promise<AgentResponse> {\n const startTime = Date.now();\n\n // console.log(`Running ${agent} with prompt: [${prompt.substring(0, 100)}${prompt.length > 100 ? '...' : ''}]`);\n\n return new Promise((resolve, reject) => {\n let stdout = '';\n let stderr = '';\n\n const [cmd, cmdArgs] = parseAgentCommand(agent);\n\n // Use shell mode for compound commands or on Windows for .cmd/.ps1 support\n const isCompoundCommand = cmdArgs.length > 0;\n const useShell = isCompoundCommand || process.platform === 'win32';\n\n // Build spawn arguments: command plus -p flag and any original args\n const spawnArgs = [...cmdArgs, '-p'];\n\n const child = spawn(cmd, spawnArgs, {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n shell: useShell,\n });\n\n // Write prompt to stdin and close it\n if (child.stdin) {\n child.stdin.write(prompt, 'utf-8');\n child.stdin.end();\n }\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new CLIError(\n `Command timed out after ${options.timeout}ms`,\n `${agent} -p`,\n -1,\n stderr\n ));\n }, options.timeout);\n\n child.on('error', (error) => {\n clearTimeout(timeout);\n reject(new CLIError(\n `Failed to spawn ${agent}: ${error.message}. Make sure the command is installed and in PATH.`,\n `${agent} -p`,\n -1,\n stderr\n ));\n });\n\n child.on('close', (code) => {\n clearTimeout(timeout);\n const durationMs = Date.now() - startTime;\n\n resolve({\n output: stdout.trim(),\n exitCode: code ?? 0,\n stderr: stderr.trim(),\n durationMs,\n });\n });\n });\n}\n","/**\n * Test suite loading and validation from YAML files.\n *\n * @module test-loader\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\n\nimport YAML from 'yaml';\nimport { z } from 'zod';\n\nimport type { TestCase, TestSuite } from './types.js';\n\n/**\n * Zod schema for validating a test case.\n */\nconst testCaseSchema = z.object({\n id: z.string().min(1, 'Test case ID is required'),\n input: z.string().min(1, 'Test case input is required'),\n context: z.string().optional(),\n expectedOutput: z.string().min(1, 'Test case expectedOutput is required'),\n});\n\n/**\n * Zod schema for validating a test suite.\n */\nconst testSuiteSchema = z.object({\n name: z.string().min(1, 'Test suite name is required'),\n description: z.string().optional(),\n context: z.string().optional(),\n tests: z.array(testCaseSchema).min(1, 'At least one test case is required'),\n});\n\n/**\n * Result of loading a test suite.\n */\nexport interface LoadResult {\n /** The loaded test suite */\n suite: TestSuite;\n\n /** Absolute path to the test file */\n path: string;\n}\n\n/**\n * Error thrown when test file validation fails.\n */\nexport class TestValidationError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly issues: z.ZodIssue[]\n ) {\n super(message);\n this.name = 'TestValidationError';\n }\n}\n\n/**\n * Error thrown when a test file cannot be read.\n */\nexport class TestLoadError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'TestLoadError';\n }\n}\n\n/**\n * Load and validate a test suite from a YAML file.\n *\n * @param filePath - Path to the YAML test file (relative or absolute)\n * @param cwd - Working directory for resolving relative paths\n * @returns The loaded and validated test suite\n * @throws TestLoadError if the file cannot be read\n * @throws TestValidationError if the YAML content is invalid\n *\n * @example\n * ```typescript\n * const { suite, path } = await loadTestSuite('./tests.yaml', process.cwd());\n * console.log(`Loaded ${suite.tests.length} tests from ${path}`);\n * ```\n */\nexport async function loadTestSuite(\n filePath: string,\n cwd: string = process.cwd()\n): Promise<LoadResult> {\n const absolutePath = resolve(cwd, filePath);\n\n let content: string;\n try {\n content = await readFile(absolutePath, 'utf-8');\n } catch (error) {\n throw new TestLoadError(\n `Failed to read test file: ${absolutePath}`,\n absolutePath,\n error\n );\n }\n\n let parsed: unknown;\n try {\n parsed = YAML.parse(content);\n } catch (error) {\n throw new TestLoadError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n absolutePath,\n error\n );\n }\n\n const result = testSuiteSchema.safeParse(parsed);\n if (!result.success) {\n throw new TestValidationError(\n `Test suite validation failed: ${result.error.message}`,\n absolutePath,\n result.error.issues\n );\n }\n\n const validated = result.data;\n\n // Check for duplicate test IDs\n const ids = validated.tests.map((t: TestCase) => t.id);\n const duplicates = ids.filter((id: string, index: number) => ids.indexOf(id) !== index);\n if (duplicates.length > 0) {\n throw new TestValidationError(\n `Duplicate test IDs found: ${[...new Set(duplicates)].join(', ')}`,\n absolutePath,\n []\n );\n }\n\n return {\n suite: validated,\n path: absolutePath,\n };\n}\n\n/**\n * Validate a test suite object without loading from file.\n *\n * @param data - The data to validate\n * @returns The validated test suite\n * @throws TestValidationError if validation fails\n */\nexport function validateTestSuite(data: unknown): TestSuite {\n const result = testSuiteSchema.safeParse(data);\n if (!result.success) {\n throw new TestValidationError(\n `Test suite validation failed: ${result.error.message}`,\n '<inline>',\n result.error.issues\n );\n }\n\n const validated = result.data;\n\n // Check for duplicate test IDs\n const ids = validated.tests.map((t: TestCase) => t.id);\n const duplicates = ids.filter((id: string, index: number) => ids.indexOf(id) !== index);\n if (duplicates.length > 0) {\n throw new TestValidationError(\n `Duplicate test IDs found: ${[...new Set(duplicates)].join(', ')}`,\n '<inline>',\n []\n );\n }\n\n return validated;\n}\n\n/**\n * Parse a test suite from a YAML string.\n *\n * @param yamlString - YAML content to parse\n * @returns The parsed and validated test suite\n * @throws TestLoadError if YAML parsing fails\n * @throws TestValidationError if validation fails\n */\nexport function parseTestSuite(yamlString: string): TestSuite {\n let parsed: unknown;\n try {\n parsed = YAML.parse(yamlString);\n } catch (error) {\n throw new TestLoadError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n '<string>',\n error\n );\n }\n\n return validateTestSuite(parsed);\n}\n","/**\n * Test runner orchestrates loading, execution, and judging of test cases.\n *\n * @module runner\n */\n\nimport { runAgent } from './cli-runner.js';\nimport { loadTestSuite } from './test-loader.js';\n\nimport type {\n EvalResults,\n RunnerConfig,\n TestCase,\n TestResult,\n TestSuite,\n} from './types.js';\n\n/**\n * Progress callback for test execution.\n */\nexport interface ProgressCallback {\n /**\n * Called when a test starts.\n *\n * @param testId - The test ID\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestStart(testId: string, index: number, total: number): void;\n\n /**\n * Called when a test completes.\n *\n * @param result - The test result\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestComplete(result: TestResult, index: number, total: number): void;\n\n /**\n * Called when a test fails with an error.\n *\n * @param testId - The test ID\n * @param error - The error that occurred\n * @param index - The test index (0-based)\n * @param total - Total number of tests\n */\n onTestError(testId: string, error: string, index: number, total: number): void;\n}\n\n/**\n * Run a single test case.\n *\n * @param test - The test case to run\n * @param suite - The test suite\n * @param agent - The agent to use\n * @param timeout - Timeout in milliseconds\n * @param judge - Function to judge the response\n * @param progress - Optional progress callback\n * @param index - Test index\n * @param total - Total tests\n * @returns The test result\n */\nasync function runTest(\n test: TestCase,\n suite: TestSuite,\n agent: string,\n timeout: number,\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress: ProgressCallback | undefined,\n index: number,\n total: number\n): Promise<TestResult> {\n progress?.onTestStart(test.id, index, total);\n\n const startTime = Date.now();\n\n // Build the full prompt with context\n const parts: string[] = [];\n if (suite.context) {\n parts.push('Context:', suite.context, '');\n }\n if (test.context) {\n parts.push('Specific Context:', test.context, '');\n }\n parts.push('Task:', test.input);\n const prompt = parts.join('\\n');\n\n try {\n // Run the agent\n const response = await runAgent(\n agent as 'pi' | 'genesys',\n prompt,\n { cwd: process.cwd(), timeout }\n );\n\n // Judge the response\n const { score, reasoning, passed } = await judge(test, response.output);\n\n const result: TestResult = {\n testId: test.id,\n input: test.input,\n expectedOutput: test.expectedOutput,\n actualOutput: response.output,\n judgeScore: score,\n judgeReasoning: reasoning,\n durationMs: response.durationMs,\n passed,\n };\n\n progress?.onTestComplete(result, index, total);\n return result;\n } catch (error) {\n const durationMs = Date.now() - startTime;\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n progress?.onTestError(test.id, errorMessage, index, total);\n\n return {\n testId: test.id,\n input: test.input,\n expectedOutput: test.expectedOutput,\n actualOutput: '',\n judgeScore: 0,\n judgeReasoning: `Error: ${errorMessage}`,\n durationMs,\n passed: false,\n error: errorMessage,\n };\n }\n}\n\n/**\n * Run tests in parallel with a concurrency limit.\n *\n * @param tests - Tests to run\n * @param concurrency - Number of concurrent executions\n * @param runner - Function to run a single test\n * @returns Array of results in the same order as tests\n */\nasync function runInParallel<T, R>(\n items: T[],\n concurrency: number,\n runner: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n if (concurrency <= 1) {\n // Sequential execution\n const results: R[] = [];\n for (let i = 0; i < items.length; i++) {\n results.push(await runner(items[i], i));\n }\n return results;\n }\n\n // Parallel execution with concurrency limit\n const results = new Array<R>(items.length);\n let index = 0;\n\n async function worker(): Promise<void> {\n while (index < items.length) {\n const currentIndex = index++;\n results[currentIndex] = await runner(items[currentIndex], currentIndex);\n }\n }\n\n // Start workers\n const workers = Array(Math.min(concurrency, items.length))\n .fill(null)\n .map(() => worker());\n\n await Promise.all(workers);\n\n return results;\n}\n\n/**\n * TestRunner orchestrates the evaluation process.\n */\nexport class TestRunner {\n private _config: RunnerConfig;\n\n constructor(config: RunnerConfig) {\n this._config = config;\n }\n\n /**\n * Run the evaluation.\n *\n * @param judge - Function to evaluate agent outputs\n * @param progress - Optional progress callback\n * @returns The evaluation results\n */\n async run(\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress?: ProgressCallback\n ): Promise<EvalResults> {\n // Load the test suite\n const { suite } = await loadTestSuite(this._config.testsPath, this._config.cwd);\n\n // Run all tests\n const results = await runInParallel(\n suite.tests,\n this._config.parallel,\n async (test, index) => {\n return runTest(\n test,\n suite,\n this._config.agent,\n this._config.timeout,\n judge,\n progress,\n index,\n suite.tests.length\n );\n }\n );\n\n // Calculate summary\n const totalDurationMs = results.reduce((sum, r) => sum + r.durationMs, 0);\n const passed = results.filter(r => r.passed).length;\n const failed = results.length - passed;\n const avgScore = results.reduce((sum, r) => sum + r.judgeScore, 0) / results.length;\n\n const evalResults: EvalResults = {\n suite,\n agent: this._config.agent,\n timestamp: new Date().toISOString(),\n results,\n summary: {\n total: results.length,\n passed,\n failed,\n avgScore,\n totalDurationMs,\n },\n };\n\n return evalResults;\n }\n\n /**\n * Get the runner configuration.\n */\n get config(): RunnerConfig {\n return this._config;\n }\n}\n\n/**\n * Run an evaluation with the given configuration.\n *\n * Convenience function that creates a TestRunner and executes it.\n *\n * @param config - Runner configuration\n * @param judge - Judge function for evaluating responses\n * @param progress - Optional progress callback\n * @returns Evaluation results\n */\nexport async function runEvaluation(\n config: RunnerConfig,\n judge: (test: TestCase, actualOutput: string) => Promise<{\n score: number;\n reasoning: string;\n passed: boolean;\n }>,\n progress?: ProgressCallback\n): Promise<EvalResults> {\n const runner = new TestRunner(config);\n return runner.run(judge, progress);\n}\n","/**\n * Package metadata utilities.\n *\n * @module utils/package\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get package.json contents.\n *\n * @returns Package.json as an object\n */\nexport function getPackageJson(): { version: string; name: string; [key: string]: unknown } {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packagePath = join(__dirname, '..', '..', 'package.json');\n\n try {\n const content = readFileSync(packagePath, 'utf-8');\n return JSON.parse(content) as { version: string; name: string; [key: string]: unknown };\n } catch {\n // Fallback if package.json can't be read\n return {\n version: '1.0.0',\n name: '@gnsx/genesys.agent.eval',\n };\n }\n}\n"],"mappings":"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","names":["resolve","resolve","z","results","fileURLToPath","colors","resolve"]}
|
package/dist/src/args.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module args
|
|
5
5
|
*/
|
|
6
|
-
import { addUpdateCommand } from '@gnsx/cli-utils
|
|
6
|
+
import { addUpdateCommand } from '@gnsx/cli-utils';
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
const VALID_FORMATS = ['console', 'json', 'html'];
|
|
9
9
|
const VALID_JUDGE_TYPES = ['embedding', 'llm'];
|
package/dist/src/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"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"}
|