@agtlantis/eval 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs","../src/cli/config/types.ts","../src/cli/config/schema.ts","../src/core/errors.ts","../src/cli/config/loader.ts","../src/cli/yaml/schema.ts","../src/cli/yaml/loader.ts","../src/multi-turn/types.ts","../src/multi-turn/termination.ts","../src/utils/json.ts","../src/multi-turn/conditions.ts","../src/multi-turn/runner.ts","../src/multi-turn/ai-user.ts","../src/cli/utils/env.ts","../src/cli/utils/provider-factory.ts","../src/cli/constants.ts","../src/cli/output/colors.ts","../src/cli/output/console.ts","../src/cli/output/report.ts","../src/reporter/markdown.ts","../src/core/runner.ts","../src/utils/semaphore.ts","../src/core/constants.ts","../src/core/types.ts","../src/core/iteration.ts","../src/core/suite.ts","../src/index.ts","../src/judge/llm-judge.ts","../src/judge/prompts/default.ts","../src/reporter/json-reporter.ts","../src/reporter/cost-helpers.ts","../src/reporter/format-utils.ts","../src/reporter/markdown-reporter.ts","../src/reporter/cycle-json.ts","../src/reporter/cycle-markdown.ts","../src/improver/utils.ts","../src/improver/llm-improver.ts","../src/improver/prompts/default.ts","../src/improvement-cycle/types.ts","../src/improvement-cycle/conditions.ts","../src/improvement-cycle/runner.ts","../src/improvement-cycle/history.ts","../src/cli/commands/run.ts","../src/cli/output/improve-report.ts","../src/cli/commands/improve.ts","../src/cli/commands/rollback.ts","../src/cli/index.ts"],"sourcesContent":["import { EventEmitter } from 'events';\n\nfunction toArr(any) {\n\treturn any == null ? [] : Array.isArray(any) ? any : [any];\n}\n\nfunction toVal(out, key, val, opts) {\n\tvar x, old=out[key], nxt=(\n\t\t!!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val))\n\t\t: typeof val === 'boolean' ? val\n\t\t: !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val))\n\t\t: (x = +val,x * 0 === 0) ? x : val\n\t);\n\tout[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]);\n}\n\nfunction mri2 (args, opts) {\n\targs = args || [];\n\topts = opts || {};\n\n\tvar k, arr, arg, name, val, out={ _:[] };\n\tvar i=0, j=0, idx=0, len=args.length;\n\n\tconst alibi = opts.alias !== void 0;\n\tconst strict = opts.unknown !== void 0;\n\tconst defaults = opts.default !== void 0;\n\n\topts.alias = opts.alias || {};\n\topts.string = toArr(opts.string);\n\topts.boolean = toArr(opts.boolean);\n\n\tif (alibi) {\n\t\tfor (k in opts.alias) {\n\t\t\tarr = opts.alias[k] = toArr(opts.alias[k]);\n\t\t\tfor (i=0; i < arr.length; i++) {\n\t\t\t\t(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i=opts.boolean.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.boolean[i]] || [];\n\t\tfor (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]);\n\t}\n\n\tfor (i=opts.string.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.string[i]] || [];\n\t\tfor (j=arr.length; j-- > 0;) opts.string.push(arr[j]);\n\t}\n\n\tif (defaults) {\n\t\tfor (k in opts.default) {\n\t\t\tname = typeof opts.default[k];\n\t\t\tarr = opts.alias[k] = opts.alias[k] || [];\n\t\t\tif (opts[name] !== void 0) {\n\t\t\t\topts[name].push(k);\n\t\t\t\tfor (i=0; i < arr.length; i++) {\n\t\t\t\t\topts[name].push(arr[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst keys = strict ? Object.keys(opts.alias) : [];\n\n\tfor (i=0; i < len; i++) {\n\t\targ = args[i];\n\n\t\tif (arg === '--') {\n\t\t\tout._ = out._.concat(args.slice(++i));\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (j=0; j < arg.length; j++) {\n\t\t\tif (arg.charCodeAt(j) !== 45) break; // \"-\"\n\t\t}\n\n\t\tif (j === 0) {\n\t\t\tout._.push(arg);\n\t\t} else if (arg.substring(j, j + 3) === 'no-') {\n\t\t\tname = arg.substring(j + 3);\n\t\t\tif (strict && !~keys.indexOf(name)) {\n\t\t\t\treturn opts.unknown(arg);\n\t\t\t}\n\t\t\tout[name] = false;\n\t\t} else {\n\t\t\tfor (idx=j+1; idx < arg.length; idx++) {\n\t\t\t\tif (arg.charCodeAt(idx) === 61) break; // \"=\"\n\t\t\t}\n\n\t\t\tname = arg.substring(j, idx);\n\t\t\tval = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]);\n\t\t\tarr = (j === 2 ? [name] : name);\n\n\t\t\tfor (idx=0; idx < arr.length; idx++) {\n\t\t\t\tname = arr[idx];\n\t\t\t\tif (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);\n\t\t\t\ttoVal(out, name, (idx + 1 < arr.length) || val, opts);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (defaults) {\n\t\tfor (k in opts.default) {\n\t\t\tif (out[k] === void 0) {\n\t\t\t\tout[k] = opts.default[k];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (alibi) {\n\t\tfor (k in out) {\n\t\t\tarr = opts.alias[k] || [];\n\t\t\twhile (arr.length > 0) {\n\t\t\t\tout[arr.shift()] = out[k];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn out;\n}\n\nconst removeBrackets = (v) => v.replace(/[<[].+/, \"\").trim();\nconst findAllBrackets = (v) => {\n const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;\n const SQUARE_BRACKET_RE_GLOBAL = /\\[([^\\]]+)\\]/g;\n const res = [];\n const parse = (match) => {\n let variadic = false;\n let value = match[1];\n if (value.startsWith(\"...\")) {\n value = value.slice(3);\n variadic = true;\n }\n return {\n required: match[0].startsWith(\"<\"),\n value,\n variadic\n };\n };\n let angledMatch;\n while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {\n res.push(parse(angledMatch));\n }\n let squareMatch;\n while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {\n res.push(parse(squareMatch));\n }\n return res;\n};\nconst getMriOptions = (options) => {\n const result = {alias: {}, boolean: []};\n for (const [index, option] of options.entries()) {\n if (option.names.length > 1) {\n result.alias[option.names[0]] = option.names.slice(1);\n }\n if (option.isBoolean) {\n if (option.negated) {\n const hasStringTypeOption = options.some((o, i) => {\n return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === \"boolean\";\n });\n if (!hasStringTypeOption) {\n result.boolean.push(option.names[0]);\n }\n } else {\n result.boolean.push(option.names[0]);\n }\n }\n }\n return result;\n};\nconst findLongest = (arr) => {\n return arr.sort((a, b) => {\n return a.length > b.length ? -1 : 1;\n })[0];\n};\nconst padRight = (str, length) => {\n return str.length >= length ? str : `${str}${\" \".repeat(length - str.length)}`;\n};\nconst camelcase = (input) => {\n return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {\n return p1 + p2.toUpperCase();\n });\n};\nconst setDotProp = (obj, keys, val) => {\n let i = 0;\n let length = keys.length;\n let t = obj;\n let x;\n for (; i < length; ++i) {\n x = t[keys[i]];\n t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(\".\") || !(+keys[i + 1] > -1) ? {} : [];\n }\n};\nconst setByType = (obj, transforms) => {\n for (const key of Object.keys(transforms)) {\n const transform = transforms[key];\n if (transform.shouldTransform) {\n obj[key] = Array.prototype.concat.call([], obj[key]);\n if (typeof transform.transformFunction === \"function\") {\n obj[key] = obj[key].map(transform.transformFunction);\n }\n }\n }\n};\nconst getFileName = (input) => {\n const m = /([^\\\\\\/]+)$/.exec(input);\n return m ? m[1] : \"\";\n};\nconst camelcaseOptionName = (name) => {\n return name.split(\".\").map((v, i) => {\n return i === 0 ? camelcase(v) : v;\n }).join(\".\");\n};\nclass CACError extends Error {\n constructor(message) {\n super(message);\n this.name = this.constructor.name;\n if (typeof Error.captureStackTrace === \"function\") {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = new Error(message).stack;\n }\n }\n}\n\nclass Option {\n constructor(rawName, description, config) {\n this.rawName = rawName;\n this.description = description;\n this.config = Object.assign({}, config);\n rawName = rawName.replace(/\\.\\*/g, \"\");\n this.negated = false;\n this.names = removeBrackets(rawName).split(\",\").map((v) => {\n let name = v.trim().replace(/^-{1,2}/, \"\");\n if (name.startsWith(\"no-\")) {\n this.negated = true;\n name = name.replace(/^no-/, \"\");\n }\n return camelcaseOptionName(name);\n }).sort((a, b) => a.length > b.length ? 1 : -1);\n this.name = this.names[this.names.length - 1];\n if (this.negated && this.config.default == null) {\n this.config.default = true;\n }\n if (rawName.includes(\"<\")) {\n this.required = true;\n } else if (rawName.includes(\"[\")) {\n this.required = false;\n } else {\n this.isBoolean = true;\n }\n }\n}\n\nconst processArgs = process.argv;\nconst platformInfo = `${process.platform}-${process.arch} node-${process.version}`;\n\nclass Command {\n constructor(rawName, description, config = {}, cli) {\n this.rawName = rawName;\n this.description = description;\n this.config = config;\n this.cli = cli;\n this.options = [];\n this.aliasNames = [];\n this.name = removeBrackets(rawName);\n this.args = findAllBrackets(rawName);\n this.examples = [];\n }\n usage(text) {\n this.usageText = text;\n return this;\n }\n allowUnknownOptions() {\n this.config.allowUnknownOptions = true;\n return this;\n }\n ignoreOptionDefaultValue() {\n this.config.ignoreOptionDefaultValue = true;\n return this;\n }\n version(version, customFlags = \"-v, --version\") {\n this.versionNumber = version;\n this.option(customFlags, \"Display version number\");\n return this;\n }\n example(example) {\n this.examples.push(example);\n return this;\n }\n option(rawName, description, config) {\n const option = new Option(rawName, description, config);\n this.options.push(option);\n return this;\n }\n alias(name) {\n this.aliasNames.push(name);\n return this;\n }\n action(callback) {\n this.commandAction = callback;\n return this;\n }\n isMatched(name) {\n return this.name === name || this.aliasNames.includes(name);\n }\n get isDefaultCommand() {\n return this.name === \"\" || this.aliasNames.includes(\"!\");\n }\n get isGlobalCommand() {\n return this instanceof GlobalCommand;\n }\n hasOption(name) {\n name = name.split(\".\")[0];\n return this.options.find((option) => {\n return option.names.includes(name);\n });\n }\n outputHelp() {\n const {name, commands} = this.cli;\n const {\n versionNumber,\n options: globalOptions,\n helpCallback\n } = this.cli.globalCommand;\n let sections = [\n {\n body: `${name}${versionNumber ? `/${versionNumber}` : \"\"}`\n }\n ];\n sections.push({\n title: \"Usage\",\n body: ` $ ${name} ${this.usageText || this.rawName}`\n });\n const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;\n if (showCommands) {\n const longestCommandName = findLongest(commands.map((command) => command.rawName));\n sections.push({\n title: \"Commands\",\n body: commands.map((command) => {\n return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;\n }).join(\"\\n\")\n });\n sections.push({\n title: `For more info, run any command with the \\`--help\\` flag`,\n body: commands.map((command) => ` $ ${name}${command.name === \"\" ? \"\" : ` ${command.name}`} --help`).join(\"\\n\")\n });\n }\n let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];\n if (!this.isGlobalCommand && !this.isDefaultCommand) {\n options = options.filter((option) => option.name !== \"version\");\n }\n if (options.length > 0) {\n const longestOptionName = findLongest(options.map((option) => option.rawName));\n sections.push({\n title: \"Options\",\n body: options.map((option) => {\n return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? \"\" : `(default: ${option.config.default})`}`;\n }).join(\"\\n\")\n });\n }\n if (this.examples.length > 0) {\n sections.push({\n title: \"Examples\",\n body: this.examples.map((example) => {\n if (typeof example === \"function\") {\n return example(name);\n }\n return example;\n }).join(\"\\n\")\n });\n }\n if (helpCallback) {\n sections = helpCallback(sections) || sections;\n }\n console.log(sections.map((section) => {\n return section.title ? `${section.title}:\n${section.body}` : section.body;\n }).join(\"\\n\\n\"));\n }\n outputVersion() {\n const {name} = this.cli;\n const {versionNumber} = this.cli.globalCommand;\n if (versionNumber) {\n console.log(`${name}/${versionNumber} ${platformInfo}`);\n }\n }\n checkRequiredArgs() {\n const minimalArgsCount = this.args.filter((arg) => arg.required).length;\n if (this.cli.args.length < minimalArgsCount) {\n throw new CACError(`missing required args for command \\`${this.rawName}\\``);\n }\n }\n checkUnknownOptions() {\n const {options, globalCommand} = this.cli;\n if (!this.config.allowUnknownOptions) {\n for (const name of Object.keys(options)) {\n if (name !== \"--\" && !this.hasOption(name) && !globalCommand.hasOption(name)) {\n throw new CACError(`Unknown option \\`${name.length > 1 ? `--${name}` : `-${name}`}\\``);\n }\n }\n }\n }\n checkOptionValue() {\n const {options: parsedOptions, globalCommand} = this.cli;\n const options = [...globalCommand.options, ...this.options];\n for (const option of options) {\n const value = parsedOptions[option.name.split(\".\")[0]];\n if (option.required) {\n const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));\n if (value === true || value === false && !hasNegated) {\n throw new CACError(`option \\`${option.rawName}\\` value is missing`);\n }\n }\n }\n }\n}\nclass GlobalCommand extends Command {\n constructor(cli) {\n super(\"@@global@@\", \"\", {}, cli);\n }\n}\n\nvar __assign = Object.assign;\nclass CAC extends EventEmitter {\n constructor(name = \"\") {\n super();\n this.name = name;\n this.commands = [];\n this.rawArgs = [];\n this.args = [];\n this.options = {};\n this.globalCommand = new GlobalCommand(this);\n this.globalCommand.usage(\"<command> [options]\");\n }\n usage(text) {\n this.globalCommand.usage(text);\n return this;\n }\n command(rawName, description, config) {\n const command = new Command(rawName, description || \"\", config, this);\n command.globalCommand = this.globalCommand;\n this.commands.push(command);\n return command;\n }\n option(rawName, description, config) {\n this.globalCommand.option(rawName, description, config);\n return this;\n }\n help(callback) {\n this.globalCommand.option(\"-h, --help\", \"Display this message\");\n this.globalCommand.helpCallback = callback;\n this.showHelpOnExit = true;\n return this;\n }\n version(version, customFlags = \"-v, --version\") {\n this.globalCommand.version(version, customFlags);\n this.showVersionOnExit = true;\n return this;\n }\n example(example) {\n this.globalCommand.example(example);\n return this;\n }\n outputHelp() {\n if (this.matchedCommand) {\n this.matchedCommand.outputHelp();\n } else {\n this.globalCommand.outputHelp();\n }\n }\n outputVersion() {\n this.globalCommand.outputVersion();\n }\n setParsedInfo({args, options}, matchedCommand, matchedCommandName) {\n this.args = args;\n this.options = options;\n if (matchedCommand) {\n this.matchedCommand = matchedCommand;\n }\n if (matchedCommandName) {\n this.matchedCommandName = matchedCommandName;\n }\n return this;\n }\n unsetMatchedCommand() {\n this.matchedCommand = void 0;\n this.matchedCommandName = void 0;\n }\n parse(argv = processArgs, {\n run = true\n } = {}) {\n this.rawArgs = argv;\n if (!this.name) {\n this.name = argv[1] ? getFileName(argv[1]) : \"cli\";\n }\n let shouldParse = true;\n for (const command of this.commands) {\n const parsed = this.mri(argv.slice(2), command);\n const commandName = parsed.args[0];\n if (command.isMatched(commandName)) {\n shouldParse = false;\n const parsedInfo = __assign(__assign({}, parsed), {\n args: parsed.args.slice(1)\n });\n this.setParsedInfo(parsedInfo, command, commandName);\n this.emit(`command:${commandName}`, command);\n }\n }\n if (shouldParse) {\n for (const command of this.commands) {\n if (command.name === \"\") {\n shouldParse = false;\n const parsed = this.mri(argv.slice(2), command);\n this.setParsedInfo(parsed, command);\n this.emit(`command:!`, command);\n }\n }\n }\n if (shouldParse) {\n const parsed = this.mri(argv.slice(2));\n this.setParsedInfo(parsed);\n }\n if (this.options.help && this.showHelpOnExit) {\n this.outputHelp();\n run = false;\n this.unsetMatchedCommand();\n }\n if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {\n this.outputVersion();\n run = false;\n this.unsetMatchedCommand();\n }\n const parsedArgv = {args: this.args, options: this.options};\n if (run) {\n this.runMatchedCommand();\n }\n if (!this.matchedCommand && this.args[0]) {\n this.emit(\"command:*\");\n }\n return parsedArgv;\n }\n mri(argv, command) {\n const cliOptions = [\n ...this.globalCommand.options,\n ...command ? command.options : []\n ];\n const mriOptions = getMriOptions(cliOptions);\n let argsAfterDoubleDashes = [];\n const doubleDashesIndex = argv.indexOf(\"--\");\n if (doubleDashesIndex > -1) {\n argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);\n argv = argv.slice(0, doubleDashesIndex);\n }\n let parsed = mri2(argv, mriOptions);\n parsed = Object.keys(parsed).reduce((res, name) => {\n return __assign(__assign({}, res), {\n [camelcaseOptionName(name)]: parsed[name]\n });\n }, {_: []});\n const args = parsed._;\n const options = {\n \"--\": argsAfterDoubleDashes\n };\n const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;\n let transforms = Object.create(null);\n for (const cliOption of cliOptions) {\n if (!ignoreDefault && cliOption.config.default !== void 0) {\n for (const name of cliOption.names) {\n options[name] = cliOption.config.default;\n }\n }\n if (Array.isArray(cliOption.config.type)) {\n if (transforms[cliOption.name] === void 0) {\n transforms[cliOption.name] = Object.create(null);\n transforms[cliOption.name][\"shouldTransform\"] = true;\n transforms[cliOption.name][\"transformFunction\"] = cliOption.config.type[0];\n }\n }\n }\n for (const key of Object.keys(parsed)) {\n if (key !== \"_\") {\n const keys = key.split(\".\");\n setDotProp(options, keys, parsed[key]);\n setByType(options, transforms);\n }\n }\n return {\n args,\n options\n };\n }\n runMatchedCommand() {\n const {args, options, matchedCommand: command} = this;\n if (!command || !command.commandAction)\n return;\n command.checkUnknownOptions();\n command.checkOptionValue();\n command.checkRequiredArgs();\n const actionArgs = [];\n command.args.forEach((arg, index) => {\n if (arg.variadic) {\n actionArgs.push(args.slice(index));\n } else {\n actionArgs.push(args[index]);\n }\n });\n actionArgs.push(options);\n return command.commandAction.apply(this, actionArgs);\n }\n}\n\nconst cac = (name = \"\") => new CAC(name);\n\nexport default cac;\nexport { CAC, Command, cac };\n","/**\n * CLI Configuration Types\n *\n * Defines the configuration schema for `agent-eval.config.ts` files.\n * Use `defineConfig()` helper for type inference and IDE autocompletion.\n */\n\nimport type {\n EvalAgent,\n TestCase,\n Criterion,\n ValidatorCriterion,\n FileContent,\n} from '@/core/types'\nimport type { JudgePrompt } from '@/judge/types'\nimport type { ImproverPrompt } from '@/improver/types'\nimport type { EvalPricingConfig } from '@/reporter/cost-helpers'\nimport type {\n MultiTurnTestCase,\n TerminationCondition,\n FollowUpInput,\n} from '@/multi-turn/types'\n\n/**\n * LLM provider configuration.\n * API keys fall back to OPENAI_API_KEY or GOOGLE_API_KEY env vars.\n */\nexport interface LLMConfig {\n /** LLM provider */\n provider: 'openai' | 'gemini'\n /** API key (optional - falls back to environment variable) */\n apiKey?: string\n /** Default model to use */\n defaultModel?: string\n /**\n * OpenAI reasoning effort (o1/o3 models only)\n * @see https://platform.openai.com/docs/guides/reasoning\n */\n reasoningEffort?: 'minimal' | 'low' | 'medium' | 'high'\n /**\n * Default response format\n * @see https://platform.openai.com/docs/guides/structured-outputs\n */\n defaultResponseFormat?: { type: 'json_object' | 'text' }\n}\n\nexport interface CLIJudgeConfig {\n /**\n * LLM configuration for judge.\n * If not specified, uses the main `llm` config.\n */\n llm?: LLMConfig\n /**\n * Evaluation criteria.\n * Use built-in criteria factories like `accuracy()`, `relevance()`,\n * or define custom criteria objects.\n */\n criteria: Array<Criterion | ValidatorCriterion>\n /**\n * Score threshold for passing (0-100).\n * @default 70\n */\n passThreshold?: number\n /**\n * Custom judge prompt.\n * If not specified, uses the default judge prompt.\n */\n prompt?: JudgePrompt\n}\n\nexport interface CLIImproverConfig {\n /**\n * LLM configuration for improver.\n * If not specified, uses the main `llm` config.\n */\n llm?: LLMConfig\n /**\n * Custom improver prompt.\n * If not specified, uses the default improver prompt.\n */\n prompt?: ImproverPrompt\n}\n\nexport interface OutputConfig {\n /**\n * Directory for report output.\n * @default './reports'\n */\n dir?: string\n /**\n * Custom filename pattern.\n * Supports `{timestamp}` placeholder.\n * @default 'eval-{timestamp}.md'\n */\n filename?: string\n /**\n * Include verbose details in console output.\n * @default false\n */\n verbose?: boolean\n}\n\nexport interface RunConfig {\n /**\n * Number of concurrent test executions.\n * @default 1\n */\n concurrency?: number\n /**\n * Number of iterations per test case (for statistical analysis).\n * @default 1\n */\n iterations?: number\n /**\n * Stop execution on first test failure.\n * @default false\n */\n stopOnFirstFailure?: boolean\n}\n\nexport interface CLISingleTurnTestCase<TInput> extends TestCase<TInput> {\n /** Test case must NOT have multiTurn field */\n multiTurn?: never\n}\n\nexport interface CLIMultiTurnTestCase<TInput, TOutput = unknown>\n extends TestCase<TInput> {\n /** Multi-turn configuration */\n multiTurn: {\n /**\n * Inputs for 2nd turn onwards.\n * First turn uses `input` field.\n */\n followUpInputs?: FollowUpInput<TInput, TOutput>[]\n /**\n * Termination conditions (OR relationship).\n * Any one triggers termination.\n */\n terminateWhen: TerminationCondition<TInput, TOutput>[]\n /**\n * Safety limit: maximum turns.\n * @default 10\n */\n maxTurns?: number\n /**\n * Outcome when termination condition is met.\n * @default 'pass'\n */\n onConditionMet?: 'pass' | 'fail'\n /**\n * Outcome when maxTurns is reached.\n * @default 'fail'\n */\n onMaxTurnsReached?: 'pass' | 'fail'\n }\n}\n\nexport type CLITestCase<TInput, TOutput = unknown> =\n | CLISingleTurnTestCase<TInput>\n | CLIMultiTurnTestCase<TInput, TOutput>\n\n/**\n * Main evaluation configuration for CLI.\n * @typeParam TInput - Agent input type\n * @typeParam TOutput - Agent output type\n */\nexport interface EvalConfig<TInput = unknown, TOutput = unknown> {\n /**\n * Human-readable name for this evaluation.\n */\n name?: string\n\n /**\n * Description of what the agent does.\n * Used by Judge for evaluation context.\n */\n agentDescription?: string\n\n /**\n * The agent to evaluate.\n */\n agent: EvalAgent<TInput, TOutput>\n\n /**\n * LLM configuration (shared by Judge and Improver unless overridden).\n */\n llm: LLMConfig\n\n /**\n * Judge configuration for evaluating agent outputs.\n */\n judge: CLIJudgeConfig\n\n /**\n * Improver configuration for prompt improvement suggestions.\n * Optional - if not specified, no improvements are generated.\n */\n improver?: CLIImproverConfig\n\n /**\n * Test cases to run (inline TypeScript definition).\n * Can mix single-turn and multi-turn test cases.\n *\n * Either `testCases` or `include` must be provided.\n * - Use `testCases` for inline TypeScript test case definitions\n * - Use `include` for YAML-based test case files\n */\n testCases?: CLITestCase<TInput, TOutput>[]\n\n /**\n * Output configuration for reports.\n */\n output?: OutputConfig\n\n /**\n * Run configuration for test execution.\n */\n run?: RunConfig\n\n /**\n * Pricing configuration for cost calculation.\n * If provided, cost breakdown will be included in test metrics.\n *\n * @example\n * ```typescript\n * pricing: {\n * openai: { 'gpt-4o': { inputPricePerMillion: 2.5, outputPricePerMillion: 10 } },\n * fallback: { inputPricePerMillion: 1.0, outputPricePerMillion: 3.0 },\n * }\n * ```\n */\n pricing?: EvalPricingConfig\n\n /**\n * Glob patterns to discover YAML eval files.\n * Required when using YAML-based test cases instead of inline testCases.\n *\n * @example\n * ```typescript\n * include: ['evals/booking/*.eval.yaml']\n * ```\n */\n include?: string[]\n\n /**\n * Agent registry for YAML file references.\n * YAML files reference agents by name (e.g., `agent: booking-agent`).\n *\n * @example\n * ```typescript\n * agents: {\n * 'booking-agent': bookingAgent,\n * 'qa-agent': qaAgent,\n * }\n * ```\n */\n agents?: Record<string, EvalAgent<unknown, unknown>>\n}\n\n/** Identity function for type inference and IDE autocompletion. */\nexport function defineConfig<TInput = unknown, TOutput = unknown>(\n config: EvalConfig<TInput, TOutput>\n): EvalConfig<TInput, TOutput> {\n return config\n}\n\nexport function isMultiTurnConfig<TInput, TOutput>(\n testCase: CLITestCase<TInput, TOutput>\n): testCase is CLIMultiTurnTestCase<TInput, TOutput> {\n return 'multiTurn' in testCase && testCase.multiTurn !== undefined\n}\n","import { z } from 'zod';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors';\n\nexport const llmConfigSchema = z.object({\n provider: z.enum(['openai', 'gemini'], {\n errorMap: () => ({\n message: \"provider must be 'openai' or 'gemini'\",\n }),\n }),\n apiKey: z.string().optional(),\n defaultModel: z.string().optional(),\n reasoningEffort: z.enum(['minimal', 'low', 'medium', 'high']).optional(),\n defaultResponseFormat: z\n .object({\n type: z.enum(['json_object', 'text']),\n })\n .optional(),\n});\n\nexport const criterionSchema = z.object({\n id: z.string().min(1, 'Criterion id is required'),\n name: z.string().min(1, 'Criterion name is required'),\n description: z.string().min(1, 'Criterion description is required'),\n weight: z.number().positive().optional(),\n validator: z.function().optional(),\n});\n\nexport const judgeConfigSchema = z.object({\n llm: llmConfigSchema.optional(),\n criteria: z.array(criterionSchema).min(1, 'At least one criterion is required'),\n passThreshold: z.number().min(0).max(100).optional(),\n prompt: z.any().optional(),\n});\n\nexport const improverConfigSchema = z\n .object({\n llm: llmConfigSchema.optional(),\n prompt: z.any().optional(),\n })\n .optional();\n\nexport const outputConfigSchema = z\n .object({\n dir: z.string().optional(),\n filename: z.string().optional(),\n verbose: z.boolean().optional(),\n })\n .optional();\n\nexport const runConfigSchema = z\n .object({\n concurrency: z.number().int().positive().optional(),\n iterations: z.number().int().positive().optional(),\n stopOnFirstFailure: z.boolean().optional(),\n })\n .optional();\n\nconst maxTurnsConditionSchema = z.object({\n type: z.literal('maxTurns'),\n count: z.number().int().positive(),\n});\n\nconst fieldSetConditionSchema = z.object({\n type: z.literal('fieldSet'),\n fieldPath: z.string().min(1),\n});\n\nconst fieldValueConditionSchema = z.object({\n type: z.literal('fieldValue'),\n fieldPath: z.string().min(1),\n expectedValue: z.unknown(),\n});\n\nconst customConditionSchema = z.object({\n type: z.literal('custom'),\n check: z.function(),\n description: z.string().optional(),\n});\n\nexport const terminationConditionSchema = z.union([\n maxTurnsConditionSchema,\n fieldSetConditionSchema,\n fieldValueConditionSchema,\n customConditionSchema,\n]);\n\nexport const followUpInputSchema = z.object({\n input: z.unknown(),\n description: z.string().optional(),\n turns: z.number().optional(),\n});\n\nexport const multiTurnConfigSchema = z.object({\n followUpInputs: z.array(followUpInputSchema).optional(),\n terminateWhen: z\n .array(terminationConditionSchema)\n .min(1, 'At least one termination condition is required'),\n maxTurns: z.number().int().positive().optional(),\n onConditionMet: z.enum(['pass', 'fail']).optional(),\n onMaxTurnsReached: z.enum(['pass', 'fail']).optional(),\n});\n\nexport const testCaseSchema = z.object({\n id: z.string().optional(),\n input: z.unknown(),\n tags: z.array(z.string()).optional(),\n description: z.string().optional(),\n expectedOutput: z.unknown().optional(),\n files: z.array(z.any()).optional(),\n multiTurn: multiTurnConfigSchema.optional(),\n});\n\nexport const agentSchema = z.object({\n config: z.object({\n name: z.string(),\n description: z.string().optional(),\n }),\n prompt: z.object({\n id: z.string(),\n version: z.string(),\n system: z.string(),\n renderUserPrompt: z.function(),\n }),\n execute: z.function(),\n});\n\nexport const evalConfigSchema = z\n .object({\n name: z.string().optional(),\n agentDescription: z.string().optional(),\n agent: agentSchema,\n llm: llmConfigSchema,\n judge: judgeConfigSchema,\n improver: improverConfigSchema,\n testCases: z.array(testCaseSchema).optional(),\n output: outputConfigSchema,\n run: runConfigSchema,\n include: z\n .array(z.string().min(1, 'Include pattern cannot be empty'))\n .min(1, 'Include array must have at least one pattern')\n .optional(),\n agents: z.record(z.string(), agentSchema).optional(),\n })\n .refine(\n (data) => {\n const hasTestCases = (data.testCases?.length ?? 0) > 0;\n const hasInclude = (data.include?.length ?? 0) > 0;\n return hasTestCases || hasInclude;\n },\n {\n message:\n 'Either testCases or include must be provided. ' +\n 'Use testCases for inline TypeScript tests, or include for YAML file discovery.',\n path: ['testCases'],\n }\n );\n\nexport type ValidatedLLMConfig = z.infer<typeof llmConfigSchema>;\nexport type ValidatedJudgeConfig = z.infer<typeof judgeConfigSchema>;\nexport type ValidatedImproverConfig = z.infer<typeof improverConfigSchema>;\nexport type ValidatedOutputConfig = z.infer<typeof outputConfigSchema>;\nexport type ValidatedRunConfig = z.infer<typeof runConfigSchema>;\nexport type ValidatedTestCase = z.infer<typeof testCaseSchema>;\nexport type ValidatedEvalConfig = z.infer<typeof evalConfigSchema>;\n\nexport function validateConfig(config: unknown): ValidatedEvalConfig {\n const result = evalConfigSchema.safeParse(config);\n\n if (!result.success) {\n const errors = result.error.issues\n .map((issue) => {\n const path = issue.path.join('.');\n return path ? ` - ${path}: ${issue.message}` : ` - ${issue.message}`;\n })\n .join('\\n');\n\n throw new EvalError(`Invalid configuration:\\n${errors}`, {\n code: EvalErrorCode.INVALID_CONFIG,\n });\n }\n\n return result.data;\n}\n\nexport function validateConfigPartial(config: unknown): {\n success: boolean;\n errors?: string[];\n} {\n const result = evalConfigSchema.safeParse(config);\n\n if (result.success) {\n return { success: true };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => {\n const path = issue.path.join('.');\n return path ? `${path}: ${issue.message}` : issue.message;\n }),\n };\n}\n","/**\n * Error codes for agent-eval operations\n */\nexport enum EvalErrorCode {\n // LLM errors\n LLM_API_ERROR = 'LLM_API_ERROR',\n LLM_RATE_LIMIT = 'LLM_RATE_LIMIT',\n LLM_TIMEOUT = 'LLM_TIMEOUT',\n\n // Parsing errors\n JSON_PARSE_ERROR = 'JSON_PARSE_ERROR',\n VERDICT_PARSE_ERROR = 'VERDICT_PARSE_ERROR',\n TEMPLATE_COMPILE_ERROR = 'TEMPLATE_COMPILE_ERROR',\n\n // Agent errors\n AGENT_EXECUTION_ERROR = 'AGENT_EXECUTION_ERROR',\n\n // Configuration errors\n INVALID_CONFIG = 'INVALID_CONFIG',\n MISSING_API_KEY = 'MISSING_API_KEY',\n\n // Prompt Repository errors\n PROMPT_NOT_FOUND = 'PROMPT_NOT_FOUND',\n PROMPT_INVALID_FORMAT = 'PROMPT_INVALID_FORMAT',\n PROMPT_WRITE_ERROR = 'PROMPT_WRITE_ERROR',\n PROMPT_READ_ERROR = 'PROMPT_READ_ERROR',\n\n // Suggestion apply errors\n SUGGESTION_APPLY_ERROR = 'SUGGESTION_APPLY_ERROR',\n\n // Schema validation errors\n SCHEMA_VALIDATION_ERROR = 'SCHEMA_VALIDATION_ERROR',\n SCHEMA_GENERATION_ERROR = 'SCHEMA_GENERATION_ERROR',\n\n // File context errors (Phase 5.3)\n FILE_READ_ERROR = 'FILE_READ_ERROR',\n FILE_WRITE_ERROR = 'FILE_WRITE_ERROR',\n FILE_TOO_LARGE = 'FILE_TOO_LARGE',\n\n // Concurrency errors\n CONCURRENT_MODIFICATION = 'CONCURRENT_MODIFICATION',\n\n // General errors\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\nexport interface EvalErrorOptions {\n code: EvalErrorCode\n cause?: Error\n context?: Record<string, unknown>\n}\n\n/**\n * Custom error class for agent-eval operations.\n * Provides structured error information including error code and optional context.\n */\nexport class EvalError extends Error {\n readonly code: EvalErrorCode\n readonly cause?: Error\n readonly context?: Record<string, unknown>\n\n constructor(message: string, options: EvalErrorOptions) {\n super(message)\n this.name = 'EvalError'\n this.code = options.code\n this.cause = options.cause\n this.context = options.context\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, EvalError)\n }\n }\n\n /**\n * Creates an EvalError from an unknown error with a specific code.\n */\n static from(error: unknown, code: EvalErrorCode, context?: Record<string, unknown>): EvalError {\n if (error instanceof EvalError) {\n return error\n }\n\n const cause = error instanceof Error ? error : new Error(String(error))\n return new EvalError(cause.message, { code, cause, context })\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n context: this.context,\n cause: this.cause?.message,\n }\n }\n}\n","import { existsSync } from 'node:fs'\nimport { resolve, extname } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { bundleRequire } from 'bundle-require'\nimport fg from 'fast-glob'\nimport { validateConfig, type ValidatedEvalConfig } from './schema.js'\nimport type { EvalConfig } from './types.js'\n\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public readonly code: ConfigErrorCode,\n public readonly context?: Record<string, unknown>\n ) {\n super(message)\n this.name = 'ConfigError'\n }\n}\n\nexport type ConfigErrorCode =\n | 'CONFIG_NOT_FOUND'\n | 'CONFIG_LOAD_ERROR'\n | 'CONFIG_NO_DEFAULT_EXPORT'\n | 'CONFIG_VALIDATION_ERROR'\n | 'CONFIG_NO_INCLUDE_PATTERN'\n\nexport const DEFAULT_CONFIG_FILE = 'agent-eval.config.ts'\n\nexport const SUPPORTED_EXTENSIONS = ['.ts', '.mts', '.cts', '.js', '.mjs', '.cjs']\n\nexport function resolveConfigPath(\n configPath: string = DEFAULT_CONFIG_FILE,\n cwd: string = process.cwd()\n): string {\n return resolve(cwd, configPath)\n}\n\nexport async function loadConfig(configPath: string): Promise<EvalConfig> {\n const absolutePath = resolve(process.cwd(), configPath)\n\n if (!existsSync(absolutePath)) {\n throw new ConfigError(\n `Config file not found: ${configPath}\\n\\n` +\n `Create an ${DEFAULT_CONFIG_FILE} file or specify a path:\\n` +\n ` npx agent-eval run ./path/to/config.ts`,\n 'CONFIG_NOT_FOUND',\n { path: absolutePath }\n )\n }\n\n const ext = extname(absolutePath).toLowerCase()\n if (!SUPPORTED_EXTENSIONS.includes(ext)) {\n throw new ConfigError(\n `Unsupported config file extension: ${ext}\\n` +\n `Supported extensions: ${SUPPORTED_EXTENSIONS.join(', ')}`,\n 'CONFIG_LOAD_ERROR',\n { path: absolutePath, extension: ext }\n )\n }\n\n let mod: { default?: EvalConfig } | EvalConfig\n\n try {\n if (ext === '.ts' || ext === '.mts' || ext === '.cts') {\n const result = await bundleRequire({\n filepath: absolutePath,\n format: 'esm',\n esbuildOptions: { sourcemap: 'inline' },\n })\n mod = result.mod\n } else {\n const fileUrl = pathToFileURL(absolutePath).href\n mod = await import(fileUrl)\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new ConfigError(\n `Failed to load config file: ${configPath}\\n\\n` +\n `Error: ${message}\\n\\n` +\n `Make sure the file is valid TypeScript/JavaScript and has no syntax errors.`,\n 'CONFIG_LOAD_ERROR',\n { path: absolutePath, originalError: message }\n )\n }\n\n const config = 'default' in mod ? mod.default : mod\n\n if (!config || typeof config !== 'object') {\n throw new ConfigError(\n `Config file must export a default configuration object.\\n\\n` +\n `Example:\\n` +\n ` import { defineConfig } from '@agtlantis/eval'\\n` +\n ` export default defineConfig({ ... })`,\n 'CONFIG_NO_DEFAULT_EXPORT',\n { path: absolutePath }\n )\n }\n\n try {\n validateConfig(config)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new ConfigError(\n message,\n 'CONFIG_VALIDATION_ERROR',\n { path: absolutePath }\n )\n }\n\n return config as EvalConfig\n}\n\nexport async function loadConfigWithDefaults(\n configPath?: string,\n cwd?: string\n): Promise<EvalConfig> {\n const resolvedPath = resolveConfigPath(configPath, cwd)\n return loadConfig(resolvedPath)\n}\n\nexport interface DiscoverOptions {\n /** Override config include patterns (CLI --include) */\n include?: string[]\n /** Base directory for glob patterns (defaults to process.cwd()) */\n cwd?: string\n /** Ignore patterns (default excludes node_modules) */\n ignore?: string[]\n}\n\n/** Discover YAML eval files matching glob patterns. CLI patterns override config. */\nexport async function discoverEvalFiles(\n config: Pick<EvalConfig, 'include'>,\n options: DiscoverOptions = {}\n): Promise<string[]> {\n const patterns = options.include ?? config.include\n\n if (!patterns || patterns.length === 0) {\n throw new ConfigError(\n 'No include patterns specified.\\n\\n' +\n 'Add an include field to your config:\\n' +\n \" include: ['evals/**/*.eval.yaml']\\n\\n\" +\n 'Or use the --include CLI option:\\n' +\n ' npx agent-eval --include \"evals/**/*.eval.yaml\"',\n 'CONFIG_NO_INCLUDE_PATTERN'\n )\n }\n\n const cwd = options.cwd ?? process.cwd()\n const ignore = options.ignore ?? ['**/node_modules/**']\n\n const files = await fg(patterns, {\n absolute: true,\n cwd,\n ignore,\n onlyFiles: true,\n dot: false,\n followSymbolicLinks: false,\n unique: true,\n suppressErrors: false,\n })\n\n return files.sort()\n}\n","import { z } from 'zod';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors.js';\n\nimport type { YamlEvalFile } from './types.js';\n\nexport const yamlExpectationSchema = z.object({\n minTurns: z.number().int().positive().optional(),\n maxTurns: z.number().int().positive().optional(),\n minScore: z.number().min(0).max(100).optional(),\n});\n\nexport const yamlTerminationConditionSchema = z\n .object({\n field: z.string().min(1).optional(),\n equals: z.unknown().optional(),\n naturalLanguage: z.string().min(1).optional(),\n })\n .refine((data) => data.field !== undefined || data.naturalLanguage !== undefined, {\n message: 'Either field or naturalLanguage must be specified',\n });\n\nexport const yamlPersonaSchema = z.object({\n name: z.string().min(1, 'Persona name is required'),\n description: z.string().optional(),\n systemPrompt: z.string().min(1, 'Persona systemPrompt is required'),\n});\n\nexport const yamlTestCaseDefaultsSchema = z.object({\n maxTurns: z.number().int().positive().optional(),\n endWhen: yamlTerminationConditionSchema.optional(),\n onConditionMet: z.enum(['pass', 'fail']).optional(),\n onMaxTurnsReached: z.enum(['pass', 'fail']).optional(),\n tags: z.array(z.string()).optional(),\n});\n\nexport const yamlTestCaseSchema = z.object({\n id: z.string().min(1, 'Test case id is required'),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n input: z.record(z.unknown()),\n persona: z.union([z.string().min(1), yamlPersonaSchema]).optional(),\n maxTurns: z.number().int().positive().optional(),\n endWhen: yamlTerminationConditionSchema.optional(),\n onConditionMet: z.enum(['pass', 'fail']).optional(),\n onMaxTurnsReached: z.enum(['pass', 'fail']).optional(),\n expectedOutput: z.record(z.unknown()).optional(),\n expect: yamlExpectationSchema.optional(),\n});\n\nexport const yamlEvalFileSchema = z.object({\n agent: z.string().min(1, 'Agent name is required'),\n name: z.string().optional(),\n description: z.string().optional(),\n defaults: yamlTestCaseDefaultsSchema.optional(),\n personas: z.record(yamlPersonaSchema).optional(),\n cases: z.array(yamlTestCaseSchema).min(1, 'At least one test case is required'),\n});\n\nexport type ValidatedYamlEvalFile = z.infer<typeof yamlEvalFileSchema>;\nexport type ValidatedYamlTestCase = z.infer<typeof yamlTestCaseSchema>;\nexport type ValidatedYamlPersona = z.infer<typeof yamlPersonaSchema>;\nexport type ValidatedYamlExpectation = z.infer<typeof yamlExpectationSchema>;\nexport type ValidatedYamlTerminationCondition = z.infer<typeof yamlTerminationConditionSchema>;\nexport type ValidatedYamlTestCaseDefaults = z.infer<typeof yamlTestCaseDefaultsSchema>;\n\nexport function validateYamlEvalFile(content: unknown): YamlEvalFile {\n const result = yamlEvalFileSchema.safeParse(content);\n\n if (!result.success) {\n const errors = result.error.issues\n .map((issue) => {\n const path = issue.path.join('.');\n return path ? ` - ${path}: ${issue.message}` : ` - ${issue.message}`;\n })\n .join('\\n');\n\n throw new EvalError(`Invalid YAML eval file:\\n${errors}`, {\n code: EvalErrorCode.INVALID_CONFIG,\n });\n }\n\n return result.data as YamlEvalFile;\n}\n\nexport function validateYamlEvalFileSourceial(content: unknown): {\n success: boolean;\n data?: YamlEvalFile;\n errors?: string[];\n} {\n const result = yamlEvalFileSchema.safeParse(content);\n\n if (result.success) {\n return { success: true, data: result.data as YamlEvalFile };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => {\n const path = issue.path.join('.');\n return path ? `${path}: ${issue.message}` : issue.message;\n }),\n };\n}\n","/**\n * YAML Eval File Loader\n *\n * Two-phase architecture:\n * 1. Load: Read YAML file, validate, return YamlEvalFile\n * 2. Convert: YamlEvalFile + context -> TestCase[] / MultiTurnTestCase[]\n */\n\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { isAbsolute, resolve } from 'node:path'\nimport { parse as parseYaml } from 'yaml'\nimport { EvalError, EvalErrorCode } from '@/core/errors.js'\nimport type { TestCase } from '@/core/types.js'\nimport type { Provider } from '@agtlantis/core'\nimport {\n aiUser,\n fieldEquals,\n fieldIsSet,\n naturalLanguage,\n type ConversationContext,\n type FollowUpInput,\n type MultiTurnTestCase,\n type TerminationCondition,\n} from '@/multi-turn/index.js'\nimport { validateYamlEvalFile } from './schema.js'\nimport type {\n DiscoveredEvalFile,\n YamlEvalFile,\n YamlLoadOptions,\n YamlPersona,\n YamlTerminationCondition,\n YamlTestCase,\n YamlTestCaseDefaults,\n} from './types.js'\n\nexport async function loadYamlEvalFile(\n path: string,\n options: YamlLoadOptions = {}\n): Promise<YamlEvalFile> {\n const { basePath = process.cwd(), skipValidation = false } = options\n\n const absolutePath = isAbsolute(path) ? path : resolve(basePath, path)\n\n if (!existsSync(absolutePath)) {\n throw new EvalError(`YAML eval file not found: ${absolutePath}`, {\n code: EvalErrorCode.FILE_READ_ERROR,\n context: { path, absolutePath },\n })\n }\n\n let content: string\n try {\n content = await readFile(absolutePath, 'utf-8')\n } catch (error) {\n throw EvalError.from(error, EvalErrorCode.FILE_READ_ERROR, {\n path,\n absolutePath,\n })\n }\n\n let parsed: unknown\n try {\n parsed = parseYaml(content)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new EvalError(`Failed to parse YAML: ${message}`, {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { path, absolutePath },\n cause: error instanceof Error ? error : undefined,\n })\n }\n\n if (skipValidation) {\n return parsed as YamlEvalFile\n }\n\n return validateYamlEvalFile(parsed)\n}\n\nexport async function loadYamlEvalFiles(\n paths: string[],\n options: YamlLoadOptions = {}\n): Promise<DiscoveredEvalFile[]> {\n const results: DiscoveredEvalFile[] = []\n\n for (const path of paths) {\n const content = await loadYamlEvalFile(path, options)\n results.push({ path, content })\n }\n\n return results\n}\n\nexport interface YamlConversionContext<TInput = unknown, TOutput = unknown> {\n provider: Provider\n /** Custom buildInput for aiUser. Default: wraps response in { message: response } */\n buildInput?: (response: string, ctx: ConversationContext<TInput, TOutput>) => TInput\n formatHistory?: (ctx: ConversationContext<TInput, TOutput>) => string\n}\n\n/**\n * Convert YamlEvalFile to TestCase or MultiTurnTestCase array.\n * Cases with persona or endWhen become MultiTurnTestCase, others become TestCase.\n */\nexport function convertToTestCases<\n TInput = Record<string, unknown>,\n TOutput = unknown,\n>(\n yaml: YamlEvalFile,\n context: YamlConversionContext<TInput, TOutput>\n): Array<TestCase<TInput> | MultiTurnTestCase<TInput, TOutput>> {\n const { defaults, personas, cases } = yaml\n\n return cases.map((testCase) => {\n const merged = mergeWithDefaults(testCase, defaults)\n\n if (isMultiTurnCase(merged)) {\n return convertToMultiTurnTestCase(merged, personas, context)\n }\n\n return convertToSimpleTestCase<TInput>(merged)\n })\n}\n\ninterface MergedTestCase {\n id: string\n name?: string\n description?: string\n tags?: string[]\n input: Record<string, unknown>\n persona?: string | YamlPersona\n maxTurns?: number\n endWhen?: YamlTerminationCondition\n onConditionMet?: 'pass' | 'fail'\n onMaxTurnsReached?: 'pass' | 'fail'\n expectedOutput?: Record<string, unknown>\n}\n\nfunction mergeWithDefaults(\n testCase: YamlTestCase,\n defaults: YamlTestCaseDefaults | undefined\n): MergedTestCase {\n if (!defaults) {\n return testCase\n }\n\n return {\n ...testCase,\n maxTurns: testCase.maxTurns ?? defaults.maxTurns,\n endWhen: testCase.endWhen ?? defaults.endWhen,\n onConditionMet: testCase.onConditionMet ?? defaults.onConditionMet,\n onMaxTurnsReached: testCase.onMaxTurnsReached ?? defaults.onMaxTurnsReached,\n tags: [...(defaults.tags ?? []), ...(testCase.tags ?? [])],\n }\n}\n\nfunction isMultiTurnCase(testCase: MergedTestCase): boolean {\n return testCase.persona !== undefined || testCase.endWhen !== undefined\n}\n\nfunction resolvePersona(\n ref: string | YamlPersona | undefined,\n personas: Record<string, YamlPersona> | undefined\n): YamlPersona | undefined {\n if (ref === undefined) {\n return undefined\n }\n\n if (typeof ref === 'object') {\n return ref\n }\n\n if (!personas || !(ref in personas)) {\n throw new EvalError(`Persona not found: \"${ref}\"`, {\n code: EvalErrorCode.INVALID_CONFIG,\n context: {\n personaRef: ref,\n availablePersonas: personas ? Object.keys(personas) : [],\n },\n })\n }\n\n return personas[ref]\n}\n\nfunction convertTerminationCondition<TInput, TOutput>(\n condition: YamlTerminationCondition,\n provider: Provider\n): TerminationCondition<TInput, TOutput> {\n if (condition.naturalLanguage) {\n return naturalLanguage<TInput, TOutput>({\n provider,\n prompt: condition.naturalLanguage,\n })\n }\n\n if (condition.field) {\n if (condition.equals !== undefined) {\n return fieldEquals<TInput, TOutput>(condition.field, condition.equals)\n }\n return fieldIsSet<TInput, TOutput>(condition.field)\n }\n\n throw new EvalError('Invalid termination condition: no field or naturalLanguage specified', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { condition },\n })\n}\n\nfunction convertToSimpleTestCase<TInput>(merged: MergedTestCase): TestCase<TInput> {\n return {\n id: merged.id,\n description: merged.name ?? merged.description,\n tags: merged.tags,\n input: merged.input as TInput,\n expectedOutput: merged.expectedOutput,\n }\n}\n\nfunction convertToMultiTurnTestCase<TInput, TOutput>(\n merged: MergedTestCase,\n personas: Record<string, YamlPersona> | undefined,\n context: YamlConversionContext<TInput, TOutput>\n): MultiTurnTestCase<TInput, TOutput> {\n const { provider, buildInput, formatHistory } = context\n\n const persona = resolvePersona(merged.persona, personas)\n\n const terminateWhen: TerminationCondition<TInput, TOutput>[] = []\n if (merged.endWhen) {\n terminateWhen.push(convertTerminationCondition<TInput, TOutput>(merged.endWhen, provider))\n }\n\n const followUpInputs: FollowUpInput<TInput, TOutput>[] = []\n if (persona) {\n const defaultBuildInput = (response: string): TInput => ({ message: response }) as TInput\n\n const aiUserInput = aiUser<TInput, TOutput>({\n provider,\n systemPrompt: persona.systemPrompt,\n formatHistory,\n buildInput: buildInput ?? defaultBuildInput,\n })\n\n const maxTurns = merged.maxTurns ?? 10\n for (let i = 0; i < maxTurns - 1; i++) {\n followUpInputs.push({\n input: aiUserInput,\n description: `AI User (${persona.name}) - Turn ${i + 2}`,\n })\n }\n }\n\n return {\n id: merged.id,\n description: merged.name ?? merged.description,\n tags: merged.tags,\n input: merged.input as TInput,\n expectedOutput: merged.expectedOutput,\n multiTurn: {\n followUpInputs,\n terminateWhen,\n maxTurns: merged.maxTurns ?? 10,\n onConditionMet: merged.onConditionMet ?? 'pass',\n onMaxTurnsReached: merged.onMaxTurnsReached ?? 'fail',\n },\n }\n}\n","import type { AgentMetadata, TestCase, TestResultWithVerdict } from '@/core/types'\n\nexport type TerminationCondition<TInput = unknown, TOutput = unknown> =\n | MaxTurnsCondition\n | FieldSetCondition\n | FieldValueCondition\n | CustomCondition<TInput, TOutput>\n\nexport interface MaxTurnsCondition {\n type: 'maxTurns'\n /** Safety limit - terminates after this many turns */\n count: number\n}\n\nexport interface FieldsCondition {\n /** Dot notation for nested access (e.g., \"result.recommendation\") */\n fieldPath: string\n}\n\nexport interface FieldSetCondition extends FieldsCondition {\n type: 'fieldSet'\n}\n\nexport interface FieldValueCondition extends FieldsCondition {\n type: 'fieldValue'\n expectedValue: unknown\n}\n\nexport interface CustomCondition<TInput = unknown, TOutput = unknown> {\n type: 'custom'\n /** Sync or async check function (e.g., for LLM-based conditions) */\n check: (\n context: ConversationContext<TInput, TOutput>\n ) => boolean | Promise<boolean>\n /** For debugging/logging */\n description?: string\n}\n\nexport type TerminationType = 'condition' | 'maxTurns' | 'error' | 'exhausted'\n\nexport interface ContinueResult {\n terminated: false\n reason: string\n terminationType?: never\n matchedCondition?: never\n}\n\nexport interface TerminatedResult {\n terminated: true\n terminationType: TerminationType\n matchedCondition?: TerminationCondition<unknown, unknown>\n reason: string\n}\n\nexport type TerminationCheckResult = ContinueResult | TerminatedResult\n\nexport interface ConversationContext<TInput, TOutput = unknown> {\n currentTurn: number\n history: Array<{\n turn: number\n input: TInput\n output: TOutput | undefined\n metadata?: AgentMetadata\n }>\n lastOutput?: TOutput\n}\n\nexport interface FollowUpInput<TInput, TOutput = unknown> {\n /**\n * Input for this follow-up turn.\n * Can be static, dynamic (sync), or async (for AI-generated inputs via aiUser()).\n */\n input:\n | TInput\n | ((context: ConversationContext<TInput, TOutput>) => TInput)\n | ((context: ConversationContext<TInput, TOutput>) => Promise<TInput>)\n\n /** For debugging/reports */\n description?: string\n\n /**\n * Repeat count (default: 1).\n * Use Infinity to repeat until termination (must be last followUpInput).\n */\n turns?: number\n}\n\nexport interface MultiTurnTestCase<TInput, TOutput = unknown>\n extends TestCase<TInput> {\n multiTurn: {\n /** Inputs for 2nd turn onwards (first turn uses TestCase.input) */\n followUpInputs?: FollowUpInput<TInput, TOutput>[]\n\n /** Any condition triggers termination (OR logic) */\n terminateWhen: TerminationCondition<TInput, TOutput>[]\n\n /** Safety limit (default: 10). Uses min of this and any maxTurns condition. */\n maxTurns?: number\n\n /** Pass/fail when condition met (default: 'pass') */\n onConditionMet?: 'pass' | 'fail'\n\n /** Pass/fail when maxTurns reached (default: 'fail') */\n onMaxTurnsReached?: 'pass' | 'fail'\n }\n}\n\nexport interface MultiTurnTestResult<TInput, TOutput>\n extends Omit<TestResultWithVerdict<TInput, TOutput>, 'output'> {\n output: TOutput | undefined\n conversationHistory: Array<{\n turn: number\n input: TInput\n output: TOutput | undefined\n metadata?: AgentMetadata\n }>\n termination: TerminationCheckResult\n totalTurns: number\n}\n\nexport function isMaxTurnsCondition<TInput, TOutput>(\n condition: TerminationCondition<TInput, TOutput>\n): condition is MaxTurnsCondition {\n return condition.type === 'maxTurns'\n}\n\nexport function isFieldSetCondition<TInput, TOutput>(\n condition: TerminationCondition<TInput, TOutput>\n): condition is FieldSetCondition {\n return condition.type === 'fieldSet'\n}\n\nexport function isFieldValueCondition<TInput, TOutput>(\n condition: TerminationCondition<TInput, TOutput>\n): condition is FieldValueCondition {\n return condition.type === 'fieldValue'\n}\n\nexport function isCustomCondition<TInput, TOutput>(\n condition: TerminationCondition<TInput, TOutput>\n): condition is CustomCondition<TInput, TOutput> {\n return condition.type === 'custom'\n}\n\nexport function isMultiTurnTestCase<TInput, TOutput = unknown>(\n testCase: TestCase<TInput>\n): testCase is MultiTurnTestCase<TInput, TOutput> {\n return 'multiTurn' in testCase\n}\n\nexport function isTerminated(\n result: TerminationCheckResult\n): result is TerminatedResult {\n return result.terminated === true\n}\n","import type {\n ConversationContext,\n CustomCondition,\n FieldSetCondition,\n FieldValueCondition,\n MaxTurnsCondition,\n TerminationCheckResult,\n TerminationCondition,\n} from './types'\nimport {\n isCustomCondition,\n isFieldSetCondition,\n isFieldValueCondition,\n isMaxTurnsCondition,\n} from './types'\nimport { EvalError, EvalErrorCode } from '@/core/errors'\n\n/** Access a nested field value using dot notation (e.g., \"result.recommendation\"). */\nexport function getFieldValue(obj: unknown, fieldPath: string): unknown {\n if (obj === null || obj === undefined) {\n return undefined\n }\n\n const parts = fieldPath.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined\n }\n\n if (typeof current !== 'object') {\n return undefined\n }\n\n current = (current as Record<string, unknown>)[part]\n }\n\n return current\n}\n\nfunction isSet(value: unknown): boolean {\n return value !== null && value !== undefined\n}\n\nfunction checkMaxTurns<TInput, TOutput>(\n condition: MaxTurnsCondition,\n context: ConversationContext<TInput, TOutput>\n): TerminationCheckResult {\n const shouldTerminate = context.currentTurn >= condition.count\n\n if (shouldTerminate) {\n return {\n terminated: true,\n terminationType: 'maxTurns',\n matchedCondition: condition,\n reason: `Maximum turns reached (${condition.count})`,\n }\n }\n\n return {\n terminated: false,\n reason: `Turn ${context.currentTurn} of ${condition.count}`,\n }\n}\n\nfunction checkFieldSet<TInput, TOutput>(\n condition: FieldSetCondition,\n context: ConversationContext<TInput, TOutput>\n): TerminationCheckResult {\n const fieldValue = getFieldValue(context.lastOutput, condition.fieldPath)\n const fieldIsSet = isSet(fieldValue)\n\n if (fieldIsSet) {\n return {\n terminated: true,\n terminationType: 'condition',\n matchedCondition: condition,\n reason: `Field \"${condition.fieldPath}\" is set (value: ${JSON.stringify(fieldValue)})`,\n }\n }\n\n return {\n terminated: false,\n reason: `Field \"${condition.fieldPath}\" is not set`,\n }\n}\n\nfunction checkFieldValue<TInput, TOutput>(\n condition: FieldValueCondition,\n context: ConversationContext<TInput, TOutput>\n): TerminationCheckResult {\n const fieldValue = getFieldValue(context.lastOutput, condition.fieldPath)\n const matches = fieldValue === condition.expectedValue\n\n if (matches) {\n return {\n terminated: true,\n terminationType: 'condition',\n matchedCondition: condition,\n reason: `Field \"${condition.fieldPath}\" equals expected value`,\n }\n }\n\n return {\n terminated: false,\n reason: `Field \"${condition.fieldPath}\" does not equal expected value (got: ${JSON.stringify(fieldValue)})`,\n }\n}\n\nasync function checkCustom<TInput, TOutput>(\n condition: CustomCondition<TInput, TOutput>,\n context: ConversationContext<TInput, TOutput>\n): Promise<TerminationCheckResult> {\n const description = condition.description ?? 'Custom condition'\n\n try {\n const shouldTerminate = await condition.check(context)\n\n if (shouldTerminate) {\n return {\n terminated: true,\n terminationType: 'condition',\n matchedCondition: condition as TerminationCondition<unknown, unknown>,\n reason: `${description} met`,\n }\n }\n\n return {\n terminated: false,\n reason: `${description} not met`,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n return {\n terminated: false,\n reason: `${description} failed: ${errorMessage}`,\n }\n }\n}\n\nexport async function checkCondition<TInput, TOutput>(\n condition: TerminationCondition<TInput, TOutput>,\n context: ConversationContext<TInput, TOutput>\n): Promise<TerminationCheckResult> {\n if (isMaxTurnsCondition(condition)) {\n return checkMaxTurns(condition, context)\n }\n\n if (isFieldValueCondition(condition)) {\n return checkFieldValue(condition, context)\n }\n\n if (isFieldSetCondition(condition)) {\n return checkFieldSet(condition, context)\n }\n\n if (isCustomCondition(condition)) {\n return checkCustom(condition, context)\n }\n\n const _exhaustive: never = condition\n throw new EvalError(`Unknown condition type: ${JSON.stringify(_exhaustive)}`, {\n code: EvalErrorCode.UNKNOWN_ERROR,\n context: { condition: _exhaustive },\n })\n}\n\n/** Check all termination conditions (OR relationship). Returns on first termination. */\nexport async function checkTermination<TInput, TOutput>(\n conditions: TerminationCondition<TInput, TOutput>[],\n context: ConversationContext<TInput, TOutput>\n): Promise<TerminationCheckResult> {\n if (conditions.length === 0) {\n return {\n terminated: false,\n reason: 'No termination conditions specified',\n }\n }\n\n for (const condition of conditions) {\n const result = await checkCondition(condition, context)\n if (result.terminated) {\n return result\n }\n }\n\n return {\n terminated: false,\n reason: 'No termination conditions met',\n }\n}\n","/**\n * Extracts JSON from LLM response, handling markdown code blocks.\n *\n * Supports:\n * - Raw JSON: `{\"key\": \"value\"}`\n * - Markdown code block: ```json\\n{...}\\n```\n * - Code block without annotation: ```\\n{...}\\n```\n * - JSON embedded in text: \"Here is my answer: {...} Hope this helps\"\n *\n * @example\n * ```typescript\n * const json = extractJson('```json\\n{\"foo\": \"bar\"}\\n```')\n * console.log(json) // '{\"foo\": \"bar\"}'\n * ```\n */\nexport function extractJson(content: string): string {\n const markdownCodeBlockMatch = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n if (markdownCodeBlockMatch) {\n return markdownCodeBlockMatch[1].trim()\n }\n\n const jsonObjectMatch = content.match(/\\{[\\s\\S]*\\}/)\n if (jsonObjectMatch) {\n return jsonObjectMatch[0]\n }\n\n return content.trim()\n}\n\n/**\n * Truncates a string to a maximum length with ellipsis.\n * Only adds \"...\" if the string was actually truncated.\n *\n * @example\n * ```typescript\n * truncate('hello', 10) // 'hello'\n * truncate('hello world', 5) // 'hello...'\n * ```\n */\nexport function truncate(str: string | undefined | null, maxLength: number): string {\n if (!str) {\n return ''\n }\n if (str.length <= maxLength) {\n return str\n }\n return str.slice(0, maxLength) + '...'\n}\n","import type { Provider } from '@agtlantis/core';\nimport { truncate } from '@/utils/json';\nimport { checkCondition } from './termination';\nimport type { ConversationContext, CustomCondition, TerminationCondition } from './types';\n\nimport {\n createAndCheck,\n createOrCheck,\n createNotCheck,\n formatCompositeDescription,\n} from '../utils/condition-composites';\n\nexport interface NaturalLanguageConditionOptions {\n /** Provider to use for evaluation */\n provider: Provider;\n /** Prompt describing the termination criteria (e.g., \"Has the user's question been fully answered?\") */\n prompt: string;\n /** Optional system prompt override */\n systemPrompt?: string;\n}\n\n/** LLM-based termination condition. Asks the LLM to evaluate the termination criteria. */\nexport function naturalLanguage<TInput = unknown, TOutput = unknown>(\n options: NaturalLanguageConditionOptions\n): CustomCondition<TInput, TOutput> {\n const { provider, prompt, systemPrompt } = options;\n\n const defaultSystemPrompt = `You are an assistant that evaluates whether a conversation should terminate.\nAnalyze the conversation history and determine if the specified condition is met.\nRespond with ONLY \"yes\" or \"no\" - nothing else.`;\n\n return {\n type: 'custom',\n check: async (context: ConversationContext<TInput, TOutput>) => {\n const historyText = context.history\n .map(\n (h) =>\n `Turn ${h.turn}:\\nInput: ${JSON.stringify(h.input)}\\nOutput: ${JSON.stringify(h.output)}`\n )\n .join('\\n\\n');\n\n const userPrompt = `## Termination Condition\n${prompt}\n\n## Conversation History\n${historyText || '(No history yet)'}\n\n## Current Turn\nTurn: ${context.currentTurn}\nLast Output: ${JSON.stringify(context.lastOutput)}\n\nShould the conversation terminate based on the condition above? Answer \"yes\" or \"no\" only.`;\n\n const execution = provider.simpleExecution(async (session) => {\n const result = await session.generateText({\n messages: [\n { role: 'system', content: systemPrompt ?? defaultSystemPrompt },\n { role: 'user', content: userPrompt },\n ],\n });\n return result.text;\n });\n\n const executionResult = await execution.result();\n\n if (executionResult.status !== 'succeeded') {\n throw executionResult.status === 'failed'\n ? executionResult.error\n : new Error('Execution was canceled');\n }\n\n const responseText = executionResult.value;\n const answer = responseText.toLowerCase().trim();\n return answer === 'yes' || answer.startsWith('yes');\n },\n description: `NL: ${truncate(prompt, 50)}`,\n };\n}\n\n/** Terminates when ALL sub-conditions are met (AND logic). */\nexport function and<TInput = unknown, TOutput = unknown>(\n ...conditions: TerminationCondition<TInput, TOutput>[]\n): CustomCondition<TInput, TOutput> {\n if (conditions.length === 0) {\n return {\n type: 'custom',\n check: () => false,\n description: formatCompositeDescription('and', []),\n };\n }\n\n return {\n type: 'custom',\n check: createAndCheck(conditions, checkCondition),\n description: formatCompositeDescription('and', conditions),\n };\n}\n\n/** Terminates when ANY sub-condition is met (OR logic). Useful for nested composites. */\nexport function or<TInput = unknown, TOutput = unknown>(\n ...conditions: TerminationCondition<TInput, TOutput>[]\n): CustomCondition<TInput, TOutput> {\n if (conditions.length === 0) {\n return {\n type: 'custom',\n check: () => false,\n description: formatCompositeDescription('or', []),\n };\n }\n\n return {\n type: 'custom',\n check: createOrCheck(conditions, checkCondition),\n description: formatCompositeDescription('or', conditions),\n };\n}\n\n/** Inverts another condition (NOT logic). */\nexport function not<TInput = unknown, TOutput = unknown>(\n condition: TerminationCondition<TInput, TOutput>\n): CustomCondition<TInput, TOutput> {\n return {\n type: 'custom',\n check: createNotCheck(condition, checkCondition),\n description: `not(${condition.type})`,\n };\n}\n\n/** Terminates after a specified number of turns. Convenience wrapper for use in composites. */\nexport function afterTurns<TInput = unknown, TOutput = unknown>(\n count: number\n): CustomCondition<TInput, TOutput> {\n return {\n type: 'custom',\n check: (context) => context.currentTurn >= count,\n description: `afterTurns(${count})`,\n };\n}\n\n/** Terminates when a field matches a specific value. Convenience wrapper for composites. */\nexport function fieldEquals<TInput = unknown, TOutput = unknown>(\n fieldPath: string,\n expectedValue: unknown\n): CustomCondition<TInput, TOutput> {\n return {\n type: 'custom',\n check: async (context) => {\n const result = await checkCondition(\n { type: 'fieldValue', fieldPath, expectedValue },\n context\n );\n return result.terminated;\n },\n description: `fieldEquals(${fieldPath}, ${JSON.stringify(expectedValue)})`,\n };\n}\n\n/** Terminates when a field is set (not null/undefined). Convenience wrapper for composites. */\nexport function fieldIsSet<TInput = unknown, TOutput = unknown>(\n fieldPath: string\n): CustomCondition<TInput, TOutput> {\n return {\n type: 'custom',\n check: async (context) => {\n const result = await checkCondition({ type: 'fieldSet', fieldPath }, context);\n return result.terminated;\n },\n description: `fieldIsSet(${fieldPath})`,\n };\n}\n","import { resolveFileSourcesInInput } from '@agtlantis/core';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors';\nimport type { AgentMetadata, EvalAgent, EvalTokenUsage, MetricsResult } from '@/core/types';\nimport type { Judge } from '@/judge/types';\n\nimport { checkTermination } from './termination';\nimport type {\n ConversationContext,\n FollowUpInput,\n MultiTurnTestCase,\n MultiTurnTestResult,\n TerminationCheckResult,\n TerminationCondition,\n} from './types';\nimport { isTerminated } from './types';\n\nexport interface MultiTurnExecuteContext<TInput, TOutput> {\n agent: EvalAgent<TInput, TOutput>;\n judge: Judge;\n agentDescription: string;\n}\n\nexport interface MultiTurnExecuteOptions {\n signal?: AbortSignal;\n}\n\nconst DEFAULT_MAX_TURNS = 10;\nconst DEFAULT_ON_CONDITION_MET: 'pass' | 'fail' = 'pass';\nconst DEFAULT_ON_MAX_TURNS_REACHED: 'pass' | 'fail' = 'fail';\n\nfunction aggregateTokenUsage(usages: EvalTokenUsage[]): EvalTokenUsage {\n return usages.reduce(\n (acc, usage) => ({\n inputTokens: acc.inputTokens + usage.inputTokens,\n outputTokens: acc.outputTokens + usage.outputTokens,\n totalTokens: acc.totalTokens + usage.totalTokens,\n }),\n { inputTokens: 0, outputTokens: 0, totalTokens: 0 }\n );\n}\n\nfunction getEffectiveMaxTurns<TInput, TOutput>(\n conditions: TerminationCondition<TInput, TOutput>[],\n safetyLimit: number\n): number {\n const maxTurnsCondition = conditions.find((c) => c.type === 'maxTurns');\n if (maxTurnsCondition && maxTurnsCondition.type === 'maxTurns') {\n return Math.min(maxTurnsCondition.count, safetyLimit);\n }\n return safetyLimit;\n}\n\nasync function resolveInput<TInput, TOutput>(\n followUpInput: FollowUpInput<TInput, TOutput>,\n context: ConversationContext<TInput, TOutput>\n): Promise<TInput> {\n const inputValue = followUpInput.input;\n if (typeof inputValue === 'function') {\n const result = (\n inputValue as (ctx: ConversationContext<TInput, TOutput>) => TInput | Promise<TInput>\n )(context);\n return result instanceof Promise ? await result : result;\n }\n return inputValue as TInput;\n}\n\nfunction buildContext<TInput, TOutput>(\n currentTurn: number,\n history: Array<{\n turn: number;\n input: TInput;\n output: TOutput | undefined;\n metadata?: AgentMetadata;\n }>\n): ConversationContext<TInput, TOutput> {\n return {\n currentTurn,\n history,\n lastOutput: history.length > 0 ? history[history.length - 1].output : undefined,\n };\n}\n\nfunction getFollowUpInput<TInput, TOutput>(\n followUpInputs: FollowUpInput<TInput, TOutput>[],\n followUpIndex: number\n): FollowUpInput<TInput, TOutput> | null {\n let currentIndex = 0;\n\n for (const followUp of followUpInputs) {\n const repeatCount = followUp.turns ?? 1;\n\n if (!Number.isFinite(repeatCount) && followUpIndex >= currentIndex) {\n return followUp;\n }\n\n if (followUpIndex < currentIndex + repeatCount) {\n return followUp;\n }\n\n currentIndex += repeatCount;\n }\n\n return null;\n}\n\nfunction validateFollowUpInputs<TInput, TOutput>(\n followUpInputs: FollowUpInput<TInput, TOutput>[]\n): void {\n for (let i = 0; i < followUpInputs.length; i++) {\n const followUp = followUpInputs[i];\n\n if (followUp.turns === undefined) {\n continue;\n }\n\n if (typeof followUp.turns !== 'number' || followUp.turns < 1) {\n throw new EvalError('turns must be a positive number or Infinity', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: {\n description: followUp.description,\n turns: followUp.turns,\n },\n });\n }\n\n if (!Number.isFinite(followUp.turns) && i < followUpInputs.length - 1) {\n throw new EvalError(\n 'turns: Infinity must be the last followUpInput (subsequent items would be unreachable)',\n {\n code: EvalErrorCode.INVALID_CONFIG,\n context: {\n description: followUp.description,\n position: i,\n totalItems: followUpInputs.length,\n },\n }\n );\n }\n }\n}\n\ntype GetTurnInputResult<TInput> = { type: 'success'; input: TInput } | { type: 'exhausted' };\n\nasync function getTurnInput<TInput, TOutput>(\n turn: number,\n testCaseInput: TInput,\n followUpInputs: FollowUpInput<TInput, TOutput>[],\n conversationHistory: Array<{\n turn: number;\n input: TInput;\n output: TOutput | undefined;\n metadata?: AgentMetadata;\n }>\n): Promise<GetTurnInputResult<TInput>> {\n if (turn === 1) {\n return { type: 'success', input: testCaseInput };\n }\n\n const followUpIndex = turn - 2;\n const followUp = getFollowUpInput(followUpInputs, followUpIndex);\n\n if (!followUp) {\n return { type: 'exhausted' };\n }\n\n const ctx = buildContext(turn, conversationHistory);\n const input = await resolveInput(followUp, ctx);\n return { type: 'success', input };\n}\n\ninterface TurnExecutionResult<TOutput> {\n output: TOutput | undefined;\n metadata: AgentMetadata | undefined;\n latencyMs: number;\n error?: Error;\n}\n\nfunction isFileResolutionError<TOutput>(\n result: TurnExecutionResult<TOutput> | { type: 'fileResolutionError'; reason: string }\n): result is { type: 'fileResolutionError'; reason: string } {\n return 'type' in result && result.type === 'fileResolutionError';\n}\n\nasync function executeSingleTurn<TInput, TOutput>(\n input: TInput,\n agent: EvalAgent<TInput, TOutput>,\n testCaseId: string,\n turn: number\n): Promise<TurnExecutionResult<TOutput> | { type: 'fileResolutionError'; reason: string }> {\n let resolvedInput: TInput;\n try {\n resolvedInput = await resolveFileSourcesInInput(input, {\n basePath: process.cwd(),\n });\n } catch (e) {\n return {\n type: 'fileResolutionError',\n reason: `FileSource resolution failed on turn ${turn}: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n\n const startTime = performance.now();\n let output: TOutput | undefined;\n let metadata: AgentMetadata | undefined;\n let error: Error | undefined;\n\n try {\n const agentResult = await agent.execute(resolvedInput);\n output = agentResult.result;\n metadata = agentResult.metadata;\n } catch (e) {\n error = EvalError.from(e, EvalErrorCode.AGENT_EXECUTION_ERROR, {\n testCaseId,\n turn,\n agentName: agent.config.name,\n });\n }\n\n const latencyMs = performance.now() - startTime;\n return { output, metadata, latencyMs, error };\n}\n\nfunction determinePassFromTermination(\n termination: TerminationCheckResult,\n onConditionMet: 'pass' | 'fail',\n onMaxTurnsReached: 'pass' | 'fail'\n): boolean {\n if (!isTerminated(termination)) {\n return true;\n }\n\n switch (termination.terminationType) {\n case 'error':\n case 'exhausted':\n return false;\n case 'maxTurns':\n return onMaxTurnsReached === 'pass';\n case 'condition':\n return onConditionMet === 'pass';\n default:\n return true;\n }\n}\n\nexport async function executeMultiTurnTestCase<TInput, TOutput>(\n testCase: MultiTurnTestCase<TInput, TOutput>,\n context: MultiTurnExecuteContext<TInput, TOutput>,\n options?: MultiTurnExecuteOptions\n): Promise<MultiTurnTestResult<TInput, TOutput>> {\n const { agent, judge, agentDescription } = context;\n const { multiTurn } = testCase;\n const signal = options?.signal;\n\n const maxTurns = getEffectiveMaxTurns(\n multiTurn.terminateWhen,\n multiTurn.maxTurns ?? DEFAULT_MAX_TURNS\n );\n const onConditionMet = multiTurn.onConditionMet ?? DEFAULT_ON_CONDITION_MET;\n const onMaxTurnsReached = multiTurn.onMaxTurnsReached ?? DEFAULT_ON_MAX_TURNS_REACHED;\n const followUpInputs = multiTurn.followUpInputs ?? [];\n\n validateFollowUpInputs(followUpInputs);\n\n const conversationHistory: Array<{\n turn: number;\n input: TInput;\n output: TOutput | undefined;\n metadata?: AgentMetadata;\n }> = [];\n const tokenUsages: EvalTokenUsage[] = [];\n let totalLatencyMs = 0;\n let termination: TerminationCheckResult = {\n terminated: false,\n reason: 'Execution not started',\n };\n\n for (let turn = 1; turn <= maxTurns; turn++) {\n if (signal?.aborted) {\n throw new EvalError('Multi-turn test execution aborted', {\n code: EvalErrorCode.AGENT_EXECUTION_ERROR,\n context: { testCaseId: testCase.id, turn, reason: 'aborted' },\n });\n }\n\n const inputResult = await getTurnInput(\n turn,\n testCase.input,\n followUpInputs,\n conversationHistory\n );\n if (inputResult.type === 'exhausted') {\n termination = {\n terminated: true,\n terminationType: 'exhausted',\n reason: 'All follow-up inputs exhausted',\n };\n break;\n }\n const input = inputResult.input;\n\n const turnResult = await executeSingleTurn(input, agent, testCase.id ?? 'unknown', turn);\n if (isFileResolutionError(turnResult)) {\n termination = {\n terminated: true,\n terminationType: 'error',\n reason: turnResult.reason,\n };\n break;\n }\n\n const {\n output: agentOutput,\n metadata: agentMetadata,\n latencyMs,\n error: agentError,\n } = turnResult;\n totalLatencyMs += latencyMs;\n\n const turnUsage = agentMetadata?.tokenUsage ?? {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n tokenUsages.push(turnUsage);\n\n conversationHistory.push({\n turn,\n input,\n output: agentOutput,\n metadata: agentMetadata,\n });\n\n if (agentError) {\n termination = {\n terminated: true,\n terminationType: 'error',\n reason: `Agent execution failed on turn ${turn}: ${agentError.message}`,\n };\n break;\n }\n\n const ctx = buildContext(turn, conversationHistory);\n termination = await checkTermination(multiTurn.terminateWhen, ctx);\n\n if (termination.terminated) {\n break;\n }\n\n if (turn >= maxTurns) {\n termination = {\n terminated: true,\n terminationType: 'maxTurns',\n matchedCondition: { type: 'maxTurns', count: maxTurns },\n reason: `Maximum turns reached (${maxTurns})`,\n };\n break;\n }\n }\n\n const aggregatedTokenUsage = aggregateTokenUsage(tokenUsages);\n const metrics: MetricsResult = {\n latencyMs: totalLatencyMs,\n tokenUsage: aggregatedTokenUsage,\n };\n\n const lastTurn = conversationHistory[conversationHistory.length - 1];\n const finalOutput = lastTurn?.output;\n\n const judgeResult = await judge.evaluate({\n input: testCase.input,\n output: finalOutput,\n agentDescription,\n files: testCase.files,\n });\n\n const passedTermination = determinePassFromTermination(\n termination,\n onConditionMet,\n onMaxTurnsReached\n );\n const passed = passedTermination && judgeResult.passed;\n\n return {\n testCase,\n output: finalOutput,\n metrics,\n verdicts: judgeResult.verdicts,\n overallScore: judgeResult.overallScore,\n passed,\n judgeMetadata: judgeResult.metadata,\n conversationHistory,\n termination,\n totalTurns: conversationHistory.length,\n };\n}\n","import type { Provider } from '@agtlantis/core';\nimport type { ConversationContext } from './types';\n\nexport interface AIUserOptions<TInput, TOutput> {\n /** Provider for generating user responses */\n provider: Provider;\n\n /** System prompt (string or function for dynamic personas). Uses default if not provided. */\n systemPrompt?: string | ((context: ConversationContext<TInput, TOutput>) => string);\n\n /** Custom history formatter. Default: JSON-based \"User: {input}\\nAssistant: {output}\" format. */\n formatHistory?: (context: ConversationContext<TInput, TOutput>) => string;\n\n /** Convert LLM text response to TInput. Has access to full context for structured input building. */\n buildInput: (llmResponse: string, context: ConversationContext<TInput, TOutput>) => TInput;\n}\n\nconst DEFAULT_SYSTEM_PROMPT = `You are simulating a realistic user in a conversation with an AI assistant.\n\n## Your Role\nGenerate natural, context-appropriate user messages based on the conversation history.\n\n## Guidelines\n\n1. **Stay in Character**: Respond as a real user would - with natural language, occasional typos, or casual phrasing when appropriate.\n\n2. **Be Goal-Oriented**: Users have objectives. Pursue them logically based on the conversation context:\n - If the assistant asks a question, provide a reasonable answer\n - If clarification is needed, ask for it naturally\n - If a task is progressing, guide it toward completion\n\n3. **React Appropriately**: Respond to what the assistant says:\n - Acknowledge when the assistant is helpful\n - Express confusion if the response is unclear\n - Correct misunderstandings if they occur\n\n4. **Keep It Realistic**: Real users:\n - Don't always provide perfect information upfront\n - May change their mind or add requirements\n - Sometimes need time to think or decide\n\n## Output Format\nRespond with ONLY the user's message. No additional formatting, explanation, or meta-commentary.`;\n\n/**\n * Creates an async function that generates user inputs using an LLM for multi-turn testing.\n *\n * @example\n * ```typescript\n * aiUser({\n * provider: openai,\n * systemPrompt: 'You are a friendly customer.',\n * buildInput: (response, ctx) => ({ message: response }),\n * })\n * ```\n */\nexport function aiUser<TInput, TOutput>(\n options: AIUserOptions<TInput, TOutput>\n): (context: ConversationContext<TInput, TOutput>) => Promise<TInput> {\n const { provider, systemPrompt, formatHistory, buildInput } = options;\n\n const defaultFormatHistory = (ctx: ConversationContext<TInput, TOutput>): string =>\n ctx.history\n .map(\n (h, i) =>\n `[Turn ${i + 1}]\\nUser: ${JSON.stringify(h.input)}\\nAssistant: ${JSON.stringify(h.output)}`\n )\n .join('\\n\\n');\n\n return async (context: ConversationContext<TInput, TOutput>): Promise<TInput> => {\n const historyText = (formatHistory ?? defaultFormatHistory)(context);\n\n const resolvedSystemPrompt =\n typeof systemPrompt === 'function'\n ? systemPrompt(context)\n : (systemPrompt ?? DEFAULT_SYSTEM_PROMPT);\n\n const userPrompt = historyText\n ? `## Conversation History\\n${historyText}\\n\\n## Your Task\\nGenerate the next user message based on the conversation above:`\n : `## Your Task\\nThis is the start of a new conversation. Generate an appropriate opening message from the user:`;\n\n const execution = provider.simpleExecution(async (session) => {\n const result = await session.generateText({\n messages: [\n { role: 'system', content: resolvedSystemPrompt },\n { role: 'user', content: userPrompt },\n ],\n });\n return result.text;\n });\n\n const executionResult = await execution.result();\n\n if (executionResult.status !== 'succeeded') {\n throw executionResult.status === 'failed'\n ? executionResult.error\n : new Error('Execution was canceled');\n }\n\n const responseText = executionResult.value;\n return buildInput(responseText, context);\n };\n}\n","import { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\n\nexport async function loadEnvFile(\n filePath: string = '.env',\n cwd: string = process.cwd()\n): Promise<void> {\n const absolutePath = resolve(cwd, filePath)\n\n if (!existsSync(absolutePath)) {\n return\n }\n\n try {\n const content = await readFile(absolutePath, 'utf-8')\n const vars = parseEnvFile(content)\n\n for (const [key, value] of Object.entries(vars)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n } catch {\n // Silently ignore read errors\n }\n}\n\n/**\n * Parses .env content. Supports KEY=value, quoted values, comments, and escape sequences.\n */\nfunction parseEnvFile(content: string): Record<string, string> {\n const result: Record<string, string> = {}\n const lines = content.split('\\n')\n\n for (const line of lines) {\n const trimmed = line.trim()\n\n if (!trimmed || trimmed.startsWith('#')) {\n continue\n }\n\n const eqIndex = trimmed.indexOf('=')\n if (eqIndex === -1) {\n continue\n }\n\n const key = trimmed.slice(0, eqIndex).trim()\n let value = trimmed.slice(eqIndex + 1).trim()\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1)\n }\n\n if (value.includes('\\\\')) {\n value = value\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\\\\/g, '\\\\')\n }\n\n if (key) {\n result[key] = value\n }\n }\n\n return result\n}\n","import {\n createOpenAIProvider,\n createGoogleProvider,\n type Provider,\n} from '@agtlantis/core'\nimport { mock } from '@agtlantis/core/testing'\nimport { ConfigError } from '../config/index.js'\nimport type { EvalConfig } from '../config/types.js'\nimport { CLI_DEFAULTS } from '../constants.js'\nimport { printProgress } from '../output/console.js'\n\n/**\n * Get API key from environment variable based on provider type.\n */\nexport function getApiKeyFromEnv(provider: 'openai' | 'gemini' | 'google'): string | undefined {\n if (provider === 'openai') {\n return process.env.OPENAI_API_KEY\n }\n // Both 'gemini' (legacy eval config) and 'google' (core provider) use the same env var\n return process.env.GOOGLE_API_KEY\n}\n\n/**\n * Create a Provider instance from EvalConfig.\n *\n * @throws {ConfigError} If API key is not found\n */\nexport function createProviderFromConfig(config: EvalConfig): Provider {\n const { llm } = config\n const apiKey = llm.apiKey ?? getApiKeyFromEnv(llm.provider)\n\n if (!apiKey) {\n const envVar = llm.provider === 'openai' ? 'OPENAI_API_KEY' : 'GOOGLE_API_KEY'\n throw new ConfigError(\n `API key not found for ${llm.provider}.\\n\\n` +\n `Set the ${envVar} environment variable or provide apiKey in config.`,\n 'CONFIG_VALIDATION_ERROR'\n )\n }\n\n if (llm.provider === 'openai') {\n return createOpenAIProvider({\n apiKey,\n }).withDefaultModel(llm.defaultModel ?? 'gpt-4o-mini')\n }\n\n // Note: eval config uses 'gemini' but core uses 'google' provider\n return createGoogleProvider({\n apiKey,\n }).withDefaultModel(llm.defaultModel ?? 'gemini-1.5-flash')\n}\n\n/**\n * Provider instances for evaluation.\n */\nexport interface Providers {\n mainProvider: Provider\n judgeProvider: Provider\n improverProvider: Provider\n}\n\n/**\n * Options for provider initialization (minimal interface for type compatibility).\n */\nexport interface InitializeProvidersOptions {\n mock?: boolean\n}\n\n/**\n * Initialize providers for evaluation.\n * Creates mock providers in test mode, or real providers from config.\n */\nexport function initializeProviders(\n config: EvalConfig,\n options: InitializeProvidersOptions\n): Providers {\n if (options.mock) {\n printProgress('Using mock Provider (--mock mode)')\n\n const mockVerdicts = config.judge.criteria.map((criterion) => ({\n criterionId: criterion.id,\n score: CLI_DEFAULTS.MOCK_DEFAULT_SCORE,\n reasoning: 'Mock evaluation - test mode',\n passed: true,\n }))\n\n const mockProvider = mock.provider(mock.json({ verdicts: mockVerdicts }))\n\n return { mainProvider: mockProvider, judgeProvider: mockProvider, improverProvider: mockProvider }\n }\n\n const mainProvider = createProviderFromConfig(config)\n const judgeProvider = config.judge.llm\n ? createProviderFromConfig({ ...config, llm: config.judge.llm })\n : mainProvider\n const improverProvider = config.improver?.llm\n ? createProviderFromConfig({ ...config, llm: config.improver.llm })\n : mainProvider\n\n return { mainProvider, judgeProvider, improverProvider }\n}\n","export const CLI_DEFAULTS = {\n /** Width for console dividers (═ characters) */\n DIVIDER_WIDTH: 60,\n /** Default score used in mock mode for testing */\n MOCK_DEFAULT_SCORE: 85,\n} as const\n","/**\n * Terminal Color Utilities\n *\n * Shared ANSI color codes and helpers for CLI output formatting.\n */\n\nexport const colors = {\n reset: '\\x1b[0m',\n bold: '\\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 gray: '\\x1b[90m',\n} as const\n\nexport const isColorSupported = process.stdout.isTTY && !process.env.NO_COLOR\n\n/**\n * Apply color to text if terminal supports colors.\n */\nexport function c(color: keyof typeof colors, text: string): string {\n return isColorSupported ? `${colors[color]}${text}${colors.reset}` : text\n}\n","import type { EvalReport } from '@/reporter/types'\nimport { CLI_DEFAULTS } from '../constants.js'\nimport { c } from './colors.js'\n\nexport function printBanner(): void {\n console.log()\n console.log(c('cyan', ' agent-eval'))\n console.log(c('dim', ' LLM-as-Judge AI Agent Evaluation'))\n console.log()\n}\n\nexport function printProgress(message: string): void {\n console.log(c('dim', ` ${message}`))\n}\n\ninterface PrintSummaryOptions {\n verbose?: boolean\n duration?: number\n}\n\nexport function printSummary(\n report: EvalReport<unknown, unknown>,\n options: PrintSummaryOptions = {}\n): void {\n const { summary, results } = report\n const { verbose, duration } = options\n\n const passRate = summary.totalTests > 0\n ? ((summary.passed / summary.totalTests) * 100).toFixed(1)\n : '0.0'\n\n const divider = '═'.repeat(CLI_DEFAULTS.DIVIDER_WIDTH)\n\n console.log()\n console.log(c('cyan', divider))\n console.log(c('bold', ' Evaluation Results'))\n console.log(c('cyan', divider))\n console.log()\n\n // Summary stats\n console.log(` ${c('bold', 'Total Tests:')} ${summary.totalTests}`)\n console.log(\n ` ${c('bold', 'Passed:')} ${c('green', String(summary.passed))} (${passRate}%)`\n )\n console.log(\n ` ${c('bold', 'Failed:')} ${summary.failed > 0 ? c('red', String(summary.failed)) : '0'}`\n )\n console.log(\n ` ${c('bold', 'Average Score:')} ${summary.avgScore.toFixed(1)}/100`\n )\n\n console.log()\n\n // Metrics\n console.log(\n ` ${c('bold', 'Total Tokens:')} ${formatNumber(summary.metrics.totalTokens)}`\n )\n console.log(\n ` ${c('bold', 'Avg Latency:')} ${formatMs(summary.metrics.avgLatencyMs)}`\n )\n\n if (duration !== undefined) {\n console.log()\n console.log(` ${c('bold', 'Duration:')} ${formatMs(duration)}`)\n }\n\n console.log()\n console.log(c('cyan', divider))\n\n if (verbose && results.length > 0) {\n printVerboseResults(results)\n }\n}\n\nfunction printVerboseResults(\n results: EvalReport<unknown, unknown>['results']\n): void {\n console.log()\n console.log(c('bold', ' Test Results:'))\n console.log()\n\n for (const result of results) {\n const status = result.passed ? c('green', '✓ PASS') : c('red', '✗ FAIL')\n const testId =\n 'testCase' in result && result.testCase?.id ? result.testCase.id : 'unknown'\n\n console.log(` ${status} ${testId}`)\n console.log(` Score: ${result.overallScore.toFixed(1)}/100`)\n\n if ('criteriaScores' in result && result.criteriaScores) {\n const scores = result.criteriaScores as Array<{ criterionId: string; score: number }>\n for (const score of scores) {\n console.log(` ${c('dim', score.criterionId)}: ${score.score.toFixed(1)}`)\n }\n }\n\n console.log()\n }\n}\n\nexport function printError(error: Error): void {\n console.error()\n console.error(c('red', ' ✗ Error:'))\n console.error()\n console.error(` ${error.message}`)\n console.error()\n}\n\nfunction formatNumber(num: number): string {\n return num.toLocaleString('en-US')\n}\n\nfunction formatMs(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(0)}ms`\n }\n return `${(ms / 1000).toFixed(2)}s`\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { reportToMarkdown } from '@/reporter/markdown'\nimport type { EvalReport, ReportMarkdownOptions } from '@/reporter/types'\n\nexport interface GenerateReportOptions {\n /** Output directory (default: './reports') */\n dir?: string\n /** Filename (default: 'eval-{timestamp}.md') */\n filename?: string\n /** Markdown options */\n markdown?: ReportMarkdownOptions\n}\n\nexport async function generateReport<TInput, TOutput>(\n report: EvalReport<TInput, TOutput>,\n options: GenerateReportOptions = {}\n): Promise<string> {\n const {\n dir = './reports',\n filename = generateFilename(),\n markdown,\n } = options\n\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true })\n }\n\n const content = reportToMarkdown(report, markdown)\n const outputPath = join(dir, filename)\n await writeFile(outputPath, content, 'utf-8')\n\n return outputPath\n}\n\nfunction generateFilename(): string {\n const timestamp = new Date()\n .toISOString()\n .replace(/:/g, '-')\n .replace(/\\.\\d{3}Z$/, '')\n\n return `eval-${timestamp}.md`\n}\n","import { writeFile } from 'node:fs/promises';\n\nimport { getFileSourcesDisplayInfo } from '@agtlantis/core';\n\nimport { truncate } from '@/utils/json';\n\nimport type { EvalReport, ReportComparison, ReportMarkdownOptions } from './types';\n\nconst PASS_ICON = '✅';\nconst FAIL_ICON = '❌';\n\nconst PRIORITY_ORDER: Record<string, number> = { high: 0, medium: 1, low: 2 };\n\n/**\n * Converts an evaluation report to Markdown format.\n *\n * @example\n * ```typescript\n * const report = await suite.run(testCases)\n * const markdown = reportToMarkdown(report)\n * console.log(markdown)\n * ```\n */\nexport function reportToMarkdown<TInput, TOutput>(\n report: EvalReport<TInput, TOutput>,\n options: ReportMarkdownOptions = {}\n): string {\n const {\n expandPassedTests = false,\n includeRawOutput = false,\n outputPreviewLength = 200,\n } = options;\n\n const { summary, results, suggestions, generatedAt, promptVersion } = report;\n const passRate =\n summary.totalTests > 0 ? ((summary.passed / summary.totalTests) * 100).toFixed(1) : '0.0';\n\n const lines: string[] = [];\n\n lines.push('# Evaluation Report');\n lines.push('');\n lines.push(`> Generated: ${generatedAt.toISOString()}`);\n lines.push(`> Prompt Version: ${promptVersion}`);\n lines.push('');\n\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Total Tests | ${summary.totalTests} |`);\n if (summary.iterations && summary.iterations > 1) {\n lines.push(`| **Iterations** | **${summary.iterations}** |`);\n }\n lines.push(`| Passed | ${summary.passed} (${passRate}%) |`);\n lines.push(`| Failed | ${summary.failed} |`);\n if (summary.avgStdDev !== undefined) {\n lines.push(\n `| Average Score | ${summary.avgScore.toFixed(1)} ± ${summary.avgStdDev.toFixed(1)} |`\n );\n } else {\n lines.push(`| Average Score | ${summary.avgScore.toFixed(1)} |`);\n }\n if (summary.avgPassRate !== undefined) {\n lines.push(`| Avg Pass Rate | ${(summary.avgPassRate * 100).toFixed(1)}% |`);\n }\n lines.push(`| Avg Latency | ${summary.metrics.avgLatencyMs.toFixed(0)}ms |`);\n lines.push(`| Total Tokens | ${summary.metrics.totalTokens} |`);\n if (summary.costSummary?.total !== undefined) {\n lines.push(`| Est. Cost | $${summary.costSummary.total.toFixed(4)} |`);\n }\n lines.push('');\n\n const failedResults = results.filter((r) => !r.passed);\n if (failedResults.length > 0) {\n lines.push(`## ${FAIL_ICON} Failed Tests`);\n lines.push('');\n for (const result of failedResults) {\n lines.push(formatTestResult(result, outputPreviewLength, includeRawOutput));\n }\n }\n\n const passedResults = results.filter((r) => r.passed);\n if (passedResults.length > 0) {\n lines.push(`## ${PASS_ICON} Passed Tests`);\n lines.push('');\n if (expandPassedTests) {\n for (const result of passedResults) {\n lines.push(formatTestResult(result, outputPreviewLength, includeRawOutput));\n }\n } else {\n lines.push('<details>');\n lines.push('<summary>Click to expand passed tests</summary>');\n lines.push('');\n for (const result of passedResults) {\n lines.push(formatTestResult(result, outputPreviewLength, includeRawOutput));\n }\n lines.push('</details>');\n lines.push('');\n }\n }\n\n if (suggestions.length > 0) {\n lines.push('## 💡 Improvement Suggestions');\n lines.push('');\n const sortedSuggestions = [...suggestions].sort(\n (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]\n );\n\n for (const suggestion of sortedSuggestions) {\n lines.push(formatSuggestion(suggestion));\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Saves an evaluation report as a Markdown file.\n *\n * @example\n * ```typescript\n * const report = await suite.run(testCases)\n * await saveReportMarkdown(report, './reports/eval-2024-01.md')\n * ```\n */\nexport async function saveReportMarkdown<TInput, TOutput>(\n report: EvalReport<TInput, TOutput>,\n path: string,\n options?: ReportMarkdownOptions\n): Promise<void> {\n const markdown = reportToMarkdown(report, options);\n await writeFile(path, markdown, 'utf-8');\n}\n\nfunction jsonCodeBlock(value: unknown, maxLength?: number): string[] {\n const json = JSON.stringify(value, null, 2);\n const content = maxLength !== undefined ? truncate(json, maxLength) : json;\n return ['```json', content, '```'];\n}\n\nfunction passFailIcon(passed: boolean): string {\n return passed ? PASS_ICON : FAIL_ICON;\n}\n\ninterface TestResultForFormat<TInput, TOutput> {\n testCase: { id?: string; input: TInput; description?: string };\n output: TOutput;\n overallScore: number;\n passed: boolean;\n verdicts: Array<{ criterionId: string; score: number; reasoning: string; passed: boolean }>;\n iterationStats?: {\n iterations: number;\n scores: number[];\n mean: number;\n stdDev: number;\n min: number;\n max: number;\n passRate: number;\n passCount: number;\n };\n iterationResults?: Array<{\n overallScore: number;\n passed: boolean;\n metrics: { latencyMs: number };\n }>;\n conversationHistory?: Array<{ turn: number; input: TInput; output: TOutput | undefined }>;\n totalTurns?: number;\n terminationReason?: string;\n multiTurnIterationStats?: {\n avgTurns: number;\n minTurns: number;\n maxTurns: number;\n terminationCounts: Record<string, number>;\n };\n}\n\nfunction formatTestResult<TInput, TOutput>(\n result: TestResultForFormat<TInput, TOutput>,\n previewLength: number,\n includeRaw: boolean\n): string {\n const lines: string[] = [];\n const testId = result.testCase.id ?? 'unnamed';\n\n const scoreDisplay = result.iterationStats\n ? `${result.overallScore.toFixed(1)} ± ${result.iterationStats.stdDev.toFixed(1)}`\n : result.overallScore.toFixed(1);\n lines.push(`### ${testId} (Score: ${scoreDisplay})`);\n lines.push('');\n\n if (result.testCase.description) {\n lines.push(`> ${result.testCase.description}`);\n lines.push('');\n }\n\n const fileDisplayInfos = getFileSourcesDisplayInfo(result.testCase.input);\n if (fileDisplayInfos.length > 0) {\n lines.push('**Files:**');\n for (const info of fileDisplayInfos) {\n const namePrefix = info.filename ? `${info.filename} - ` : '';\n lines.push(`- ${namePrefix}${info.source}: ${info.description} (${info.mediaType})`);\n }\n lines.push('');\n }\n\n if (result.totalTurns !== undefined) {\n lines.push(\n `**Multi-turn:** ${result.totalTurns} turns | Termination: ${result.terminationReason ?? 'unknown'}`\n );\n lines.push('');\n }\n\n if (result.multiTurnIterationStats) {\n lines.push(...formatMultiTurnIterationStats(result.multiTurnIterationStats));\n }\n\n if (result.iterationStats && result.iterationResults) {\n lines.push(...formatIterationResults(result.iterationStats, result.iterationResults));\n }\n\n if (result.conversationHistory && result.conversationHistory.length > 0) {\n lines.push(...formatConversationHistory(result.conversationHistory, previewLength));\n } else {\n lines.push(\n ...formatSingleTurnInputOutput(result.testCase.input, result.output, previewLength)\n );\n }\n\n lines.push('**Verdicts:**');\n for (const verdict of result.verdicts) {\n lines.push(\n `- ${passFailIcon(verdict.passed)} **${verdict.criterionId}**: ${verdict.score} - ${verdict.reasoning}`\n );\n }\n lines.push('');\n\n if (includeRaw) {\n lines.push('<details>');\n lines.push('<summary>Raw Output</summary>');\n lines.push('');\n lines.push(...jsonCodeBlock(result.output));\n lines.push('</details>');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nfunction formatMultiTurnIterationStats(\n stats: NonNullable<TestResultForFormat<unknown, unknown>['multiTurnIterationStats']>\n): string[] {\n const terminationSummary =\n Object.entries(stats.terminationCounts)\n .map(([type, count]) => `${type}: ${count}`)\n .join(', ') || 'none';\n\n return [\n '**Multi-turn Iteration Statistics:**',\n '',\n '| Metric | Value |',\n '|--------|-------|',\n `| Avg Turns | ${stats.avgTurns.toFixed(1)} |`,\n `| Min/Max Turns | ${stats.minTurns} / ${stats.maxTurns} |`,\n `| Termination Distribution | ${terminationSummary} |`,\n '',\n ];\n}\n\nfunction formatIterationResults(\n stats: NonNullable<TestResultForFormat<unknown, unknown>['iterationStats']>,\n results: NonNullable<TestResultForFormat<unknown, unknown>['iterationResults']>\n): string[] {\n const lines: string[] = [\n '**Iteration Results:**',\n '',\n '| # | Score | Passed | Latency |',\n '|---|-------|--------|---------|',\n ];\n\n results.forEach((iter, idx) => {\n lines.push(\n `| ${idx + 1} | ${iter.overallScore.toFixed(1)} | ${passFailIcon(iter.passed)} | ${iter.metrics.latencyMs.toFixed(0)}ms |`\n );\n });\n\n lines.push('');\n lines.push(\n `**Stats:** ${stats.mean.toFixed(1)} ± ${stats.stdDev.toFixed(1)} (min: ${stats.min.toFixed(0)}, max: ${stats.max.toFixed(0)}, pass rate: ${(stats.passRate * 100).toFixed(0)}%)`\n );\n lines.push('');\n\n return lines;\n}\n\nfunction formatConversationHistory<TInput, TOutput>(\n history: Array<{ turn: number; input: TInput; output: TOutput | undefined }>,\n previewLength: number\n): string[] {\n const lines: string[] = ['**Conversation History:**', ''];\n\n for (const turn of history) {\n lines.push('<details>');\n lines.push(`<summary>Turn ${turn.turn}</summary>`);\n lines.push('');\n lines.push('**Input:**');\n lines.push(...jsonCodeBlock(turn.input, previewLength));\n lines.push('');\n lines.push('**Output:**');\n lines.push(...jsonCodeBlock(turn.output, previewLength));\n lines.push('</details>');\n lines.push('');\n }\n\n return lines;\n}\n\nfunction formatSingleTurnInputOutput<TInput, TOutput>(\n input: TInput,\n output: TOutput,\n previewLength: number\n): string[] {\n return [\n '**Input:**',\n ...jsonCodeBlock(input, previewLength),\n '',\n '**Output:**',\n ...jsonCodeBlock(output, previewLength),\n '',\n ];\n}\n\nfunction formatSuggestion(suggestion: {\n type: string;\n priority: string;\n currentValue: string;\n suggestedValue: string;\n reasoning: string;\n expectedImprovement: string;\n}): string {\n const lines: string[] = [];\n const priorityIcon = { high: '🔴', medium: '🟡', low: '🟢' }[suggestion.priority] ?? '⚪';\n\n lines.push(`### ${priorityIcon} [${suggestion.priority.toUpperCase()}] ${suggestion.type}`);\n lines.push('');\n lines.push(`**Reasoning:** ${suggestion.reasoning}`);\n lines.push('');\n lines.push(`**Expected Improvement:** ${suggestion.expectedImprovement}`);\n lines.push('');\n lines.push('**Diff:**');\n lines.push('```diff');\n lines.push(`- ${suggestion.currentValue.split('\\n').join('\\n- ')}`);\n lines.push(`+ ${suggestion.suggestedValue.split('\\n').join('\\n+ ')}`);\n lines.push('```');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Compares two evaluation reports and returns the differences.\n * Useful for tracking improvements across prompt versions.\n *\n * @example\n * ```typescript\n * const beforeReport = await suite.run(testCases)\n * // ... apply improvements ...\n * const afterReport = await suite.withAgent(improvedAgent).run(testCases)\n *\n * const comparison = compareReports(beforeReport, afterReport)\n * console.log(`Score improved by ${comparison.scoreDelta} points`)\n * console.log(`Tests improved: ${comparison.improved.join(', ')}`)\n * console.log(`Tests regressed: ${comparison.regressed.join(', ')}`)\n * ```\n */\nexport function compareReports<TInput, TOutput>(\n before: EvalReport<TInput, TOutput>,\n after: EvalReport<TInput, TOutput>\n): ReportComparison {\n const scoreDelta = after.summary.avgScore - before.summary.avgScore;\n\n const beforePassRate =\n before.summary.totalTests > 0 ? before.summary.passed / before.summary.totalTests : 0;\n const afterPassRate =\n after.summary.totalTests > 0 ? after.summary.passed / after.summary.totalTests : 0;\n const passRateDelta = afterPassRate - beforePassRate;\n\n const metricsDelta = {\n latencyMs: after.summary.metrics.avgLatencyMs - before.summary.metrics.avgLatencyMs,\n tokenUsage: after.summary.metrics.totalTokens - before.summary.metrics.totalTokens,\n };\n\n const beforeScores = buildScoreMap(before.results);\n const afterScores = buildScoreMap(after.results);\n\n const improved: string[] = [];\n const regressed: string[] = [];\n\n for (const [id, afterScore] of afterScores) {\n const beforeScore = beforeScores.get(id);\n if (beforeScore === undefined) continue;\n if (afterScore > beforeScore) {\n improved.push(id);\n } else if (afterScore < beforeScore) {\n regressed.push(id);\n }\n }\n\n const removed = [...beforeScores.keys()].filter((id) => !afterScores.has(id));\n\n return {\n scoreDelta,\n passRateDelta,\n metricsDelta,\n improved,\n regressed,\n removed,\n };\n}\n\nfunction buildScoreMap<TInput, TOutput>(\n results: Array<{ testCase: { id?: string }; overallScore: number }>\n): Map<string, number> {\n const scoreMap = new Map<string, number>();\n for (const result of results) {\n scoreMap.set(result.testCase.id ?? 'unnamed', result.overallScore);\n }\n return scoreMap;\n}\n","import { resolveFileSourcesInInput } from '@agtlantis/core';\n\nimport type { Judge } from '@/judge/types';\nimport {\n type MultiTurnTestResult,\n executeMultiTurnTestCase,\n isMultiTurnTestCase,\n} from '@/multi-turn';\nimport { createSemaphore } from '@/utils/semaphore';\n\nimport { ZERO_TOKEN_USAGE } from './constants';\nimport { EvalError, EvalErrorCode } from './errors';\nimport type {\n EvalAgent,\n EvalTestResult,\n EvalTokenUsage,\n MetricsResult,\n MultiTurnResult,\n SingleTurnResult,\n TestCase,\n TestResult,\n TestResultWithVerdict,\n} from './types';\n\n/**\n * Options for running test cases.\n */\nexport interface RunOptions {\n /** Maximum number of concurrent test case executions. Defaults to 1 (sequential). */\n concurrency?: number;\n\n /** Stop execution after the first test failure. Defaults to false. */\n stopOnFirstFailure?: boolean;\n\n /** AbortSignal for cancelling execution */\n signal?: AbortSignal;\n\n /**\n * Number of times to run each test case. Defaults to 1.\n * When > 1, results include iteration statistics (mean, stdDev, passRate).\n */\n iterations?: number;\n}\n\n/**\n * Context required for executing a single test case.\n * @internal\n */\nexport interface ExecuteContext<TInput, TOutput> {\n agent: EvalAgent<TInput, TOutput>;\n judge: Judge;\n agentDescription: string;\n}\n\n/**\n * Executes a single test case and returns the result with verdict.\n *\n * Flow:\n * 1. Execute agent with test input\n * 2. Measure execution latency\n * 3. Collect token usage from agent metadata\n * 4. Evaluate output using Judge\n * 5. Return combined result with verdicts\n *\n * @example\n * ```typescript\n * const result = await executeTestCase(\n * { id: 'test-1', input: { query: 'Hello' } },\n * { agent: myAgent, judge: myJudge, agentDescription: 'A friendly bot' }\n * )\n *\n * console.log(result.passed) // true/false\n * console.log(result.overallScore) // 0-100\n * console.log(result.verdicts) // Verdict[]\n * ```\n */\nexport async function executeTestCase<TInput, TOutput>(\n testCase: TestCase<TInput>,\n context: ExecuteContext<TInput, TOutput>,\n signal?: AbortSignal\n): Promise<SingleTurnResult<TInput, TOutput>> {\n const { agent, judge, agentDescription } = context;\n\n if (signal?.aborted) {\n throw new EvalError('Test execution aborted', {\n code: EvalErrorCode.AGENT_EXECUTION_ERROR,\n context: { testCaseId: testCase.id, reason: 'aborted' },\n });\n }\n\n let resolvedInput: TInput;\n try {\n resolvedInput = await resolveFileSourcesInInput(testCase.input, {\n basePath: process.cwd(),\n });\n } catch (e) {\n const error = EvalError.from(e, EvalErrorCode.FILE_READ_ERROR, {\n testCaseId: testCase.id,\n agentName: agent.config.name,\n });\n return createFailedResult(testCase, error);\n }\n\n const startTime = performance.now();\n let output: TOutput;\n let tokenUsage: EvalTokenUsage = ZERO_TOKEN_USAGE;\n let error: Error | undefined;\n\n try {\n const agentResult = await agent.execute(resolvedInput);\n output = agentResult.result;\n if (agentResult.metadata?.tokenUsage) {\n tokenUsage = agentResult.metadata.tokenUsage;\n }\n } catch (e) {\n error = EvalError.from(e, EvalErrorCode.AGENT_EXECUTION_ERROR, {\n testCaseId: testCase.id,\n agentName: agent.config.name,\n });\n output = undefined as TOutput;\n }\n\n const latencyMs = performance.now() - startTime;\n\n const metrics: MetricsResult = { latencyMs, tokenUsage };\n const testResult: TestResult<TInput, TOutput> = { testCase, output, metrics, error };\n\n if (error) {\n return {\n kind: 'single-turn',\n ...testResult,\n verdicts: [],\n overallScore: 0,\n passed: false,\n judgeMetadata: undefined,\n };\n }\n\n if (signal?.aborted) {\n throw new EvalError('Test execution aborted before evaluation', {\n code: EvalErrorCode.AGENT_EXECUTION_ERROR,\n context: { testCaseId: testCase.id, reason: 'aborted' },\n });\n }\n\n const judgeResult = await judge.evaluate({\n input: testCase.input,\n output,\n agentDescription,\n files: testCase.files,\n });\n\n return {\n kind: 'single-turn',\n ...testResult,\n verdicts: judgeResult.verdicts,\n overallScore: judgeResult.overallScore,\n passed: judgeResult.passed,\n judgeMetadata: judgeResult.metadata,\n };\n}\n\nfunction createFailedResult<TInput, TOutput>(\n testCase: TestCase<TInput>,\n error: Error\n): SingleTurnResult<TInput, TOutput> {\n return {\n kind: 'single-turn',\n testCase,\n output: undefined as TOutput,\n metrics: { latencyMs: 0, tokenUsage: ZERO_TOKEN_USAGE },\n error,\n verdicts: [],\n overallScore: 0,\n passed: false,\n judgeMetadata: undefined,\n };\n}\n\n/**\n * Converts a MultiTurnTestResult to MultiTurnResult format.\n * This allows multi-turn results to flow through the same aggregation pipeline\n * as single-turn results while preserving multi-turn specific data.\n *\n * @internal\n */\nfunction toMultiTurnResult<TInput, TOutput>(\n result: MultiTurnTestResult<TInput, TOutput>\n): MultiTurnResult<TInput, TOutput> {\n return {\n kind: 'multi-turn',\n testCase: result.testCase,\n output: result.output as TOutput,\n metrics: result.metrics,\n verdicts: result.verdicts,\n overallScore: result.overallScore,\n passed: result.passed,\n judgeMetadata: result.judgeMetadata,\n conversationHistory: result.conversationHistory,\n totalTurns: result.totalTurns,\n terminationReason: result.termination.reason,\n termination: result.termination,\n };\n}\n\n/**\n * Runs multiple test cases with configurable concurrency.\n *\n * Features:\n * - Parallel execution with concurrency limit\n * - Stop on first failure option\n * - AbortSignal support for cancellation\n *\n * @example\n * ```typescript\n * const results = await runWithConcurrency(\n * testCases,\n * { agent: myAgent, judge: myJudge, agentDescription: 'Test agent' },\n * { concurrency: 5, stopOnFirstFailure: false }\n * )\n *\n * console.log(`Passed: ${results.filter(r => r.passed).length}`)\n * console.log(`Failed: ${results.filter(r => !r.passed).length}`)\n * ```\n */\nexport async function runWithConcurrency<TInput, TOutput>(\n testCases: TestCase<TInput>[],\n context: ExecuteContext<TInput, TOutput>,\n options: RunOptions = {}\n): Promise<EvalTestResult<TInput, TOutput>[]> {\n const { concurrency = 1, stopOnFirstFailure = false, signal } = options;\n\n if (concurrency < 1) {\n throw new EvalError('Concurrency must be at least 1', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { concurrency },\n });\n }\n\n if (testCases.length === 0) {\n return [];\n }\n\n const semaphore = createSemaphore(concurrency);\n const results: EvalTestResult<TInput, TOutput>[] = [];\n let shouldStop = false;\n let firstError: Error | undefined;\n const internalAbort = new AbortController();\n\n const propagateExternalAbort = () => {\n shouldStop = true;\n internalAbort.abort();\n };\n signal?.addEventListener('abort', propagateExternalAbort);\n\n if (signal?.aborted) {\n shouldStop = true;\n }\n\n try {\n const executeOne = async (testCase: TestCase<TInput>, index: number): Promise<void> => {\n if (shouldStop) return;\n\n await semaphore.acquire();\n\n try {\n if (shouldStop) return;\n\n const result = await executeTestCaseByType(testCase, context, internalAbort.signal);\n results[index] = result;\n\n if (stopOnFirstFailure && !result.passed) {\n shouldStop = true;\n internalAbort.abort();\n }\n } catch (e) {\n if (!firstError && !isAbortError(e)) {\n firstError = e instanceof Error ? e : new Error(String(e));\n }\n shouldStop = true;\n internalAbort.abort();\n } finally {\n semaphore.release();\n }\n };\n\n const promises = testCases.map((tc, i) => executeOne(tc, i));\n await Promise.allSettled(promises);\n\n if (firstError) {\n throw firstError;\n }\n\n return results.filter((r): r is EvalTestResult<TInput, TOutput> => r !== undefined);\n } finally {\n signal?.removeEventListener('abort', propagateExternalAbort);\n }\n}\n\nfunction isAbortError(e: unknown): boolean {\n return (\n (e instanceof DOMException && e.name === 'AbortError') ||\n (e instanceof EvalError && e.context?.reason === 'aborted')\n );\n}\n\nasync function executeTestCaseByType<TInput, TOutput>(\n testCase: TestCase<TInput>,\n context: ExecuteContext<TInput, TOutput>,\n signal: AbortSignal\n): Promise<EvalTestResult<TInput, TOutput>> {\n if (isMultiTurnTestCase<TInput, TOutput>(testCase)) {\n const multiTurnResult = await executeMultiTurnTestCase(testCase, context, { signal });\n return toMultiTurnResult(multiTurnResult);\n }\n return executeTestCase(testCase, context, signal);\n}\n","/**\n * A simple semaphore for limiting concurrent operations.\n *\n * @example\n * ```typescript\n * const semaphore = createSemaphore(3) // Allow 3 concurrent operations\n *\n * async function doWork(id: number) {\n * await semaphore.acquire()\n * try {\n * console.log(`Starting work ${id}`)\n * await someAsyncOperation()\n * } finally {\n * semaphore.release()\n * }\n * }\n *\n * // Launch 10 tasks, but only 3 run at a time\n * await Promise.all(Array.from({ length: 10 }, (_, i) => doWork(i)))\n * ```\n */\nexport interface Semaphore {\n /**\n * Acquires a slot from the semaphore.\n * If no slots are available, waits until one is released.\n */\n acquire(): Promise<void>\n\n /**\n * Releases a slot back to the semaphore.\n * Must be called after acquire() completes, typically in a finally block.\n */\n release(): void\n}\n\n/**\n * Creates a semaphore with the specified concurrency limit.\n *\n * @param limit - Maximum number of concurrent operations allowed\n * @returns A Semaphore instance\n */\nexport function createSemaphore(limit: number): Semaphore {\n let running = 0\n const waiting: Array<() => void> = []\n\n return {\n async acquire(): Promise<void> {\n if (running < limit) {\n running++\n return\n }\n return new Promise<void>((resolve) => {\n waiting.push(resolve)\n })\n },\n\n release(): void {\n running--\n const next = waiting.shift()\n if (next) {\n running++\n next()\n }\n },\n }\n}\n","/**\n * Evaluation Constants\n *\n * Centralized constants used across the evaluation system.\n * Eliminates magic numbers and provides semantic names.\n */\n\n/**\n * Score-related constants.\n */\nexport const SCORE = {\n /** Minimum possible score */\n MIN: 0,\n /** Maximum possible score */\n MAX: 100,\n /** Default threshold for passing evaluation */\n DEFAULT_PASS_THRESHOLD: 70,\n /** Threshold for majority-based pass determination (50%) */\n MAJORITY_PASS_THRESHOLD: 0.5,\n} as const\n\n/**\n * Default configuration values.\n */\nexport const DEFAULTS = {\n /** Default maximum turns for multi-turn conversations */\n MAX_TURNS: 10,\n /** Default concurrency for parallel execution */\n CONCURRENCY: 1,\n} as const\n\n\n/**\n * Zero token usage - used for error cases or initialization.\n */\nexport const ZERO_TOKEN_USAGE = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n} as const\n\n/**\n * Type for score values (0-100).\n */\nexport type Score = number\n","/**\n * Simplified token usage type for eval package.\n *\n * This is a subset of AI SDK's LanguageModelUsage that only includes\n * the properties eval actually tracks. The cost-helpers module handles\n * conversion when calling @agtlantis/core's pricing calculator.\n *\n * @example\n * ```typescript\n * const usage: EvalTokenUsage = {\n * inputTokens: 100,\n * outputTokens: 50,\n * totalTokens: 150,\n * }\n * ```\n */\nexport interface EvalTokenUsage {\n /** Number of input (prompt) tokens */\n inputTokens: number;\n /** Number of output (completion) tokens */\n outputTokens: number;\n /** Total tokens (input + output) */\n totalTokens: number;\n}\n\n/**\n * Simplified agent configuration for evaluation.\n * Only requires fields needed for eval purposes.\n *\n * For agents from `ai-agents` package with full AgentConfig,\n * use `toEvalAgent()` adapter to convert them.\n */\nexport interface EvalAgentConfig {\n /** Agent name for identification */\n name: string;\n /** Agent description (used by Judge for context) */\n description?: string;\n /** Additional custom fields */\n [key: string]: unknown;\n}\n\n/**\n * Agent prompt template.\n */\nexport interface AgentPrompt<TInput> {\n /** Prompt unique ID for version tracking */\n id: string;\n /** Version string (e.g., \"1.0.0\") */\n version: string;\n /** System prompt */\n system: string;\n /** User template string (for serialization/history) */\n userTemplate?: string;\n /** User prompt builder function */\n renderUserPrompt: (input: TInput) => string;\n /** Additional custom fields */\n [key: string]: unknown;\n}\n\n/**\n * Base metadata type shared by all LLM-using components (Agent, Judge, Improver).\n * Provides consistent structure for tracking token usage and model information.\n *\n * @example\n * ```typescript\n * const metadata: ComponentMetadata = {\n * tokenUsage: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },\n * model: 'gpt-4o',\n * }\n * ```\n */\nexport interface ComponentMetadata {\n /** Token usage from the LLM call (AI SDK LanguageModelUsage format) */\n tokenUsage?: EvalTokenUsage;\n /** Model identifier used for the LLM call */\n model?: string;\n /** Additional custom fields */\n [key: string]: unknown;\n}\n\n/**\n * Agent execution result metadata.\n * Extends ComponentMetadata with agent-specific fields.\n */\nexport interface AgentMetadata extends ComponentMetadata {\n /** Prompt version used for execution */\n promptVersion?: string;\n /** Execution duration in milliseconds */\n duration?: number;\n}\n\n/**\n * Judge evaluation metadata.\n * Tracks token usage and model for cost calculation.\n */\nexport interface JudgeMetadata extends ComponentMetadata {}\n\n/**\n * Improver analysis metadata.\n * Tracks token usage and model for cost calculation.\n */\nexport interface ImproverMetadata extends ComponentMetadata {}\n\n/**\n * Agent execution result.\n */\nexport interface AgentResult<TOutput> {\n result: TOutput;\n metadata?: AgentMetadata;\n}\n\n/**\n * Simplified Agent interface for evaluation.\n *\n * @example\n * ```typescript\n * // Direct implementation\n * const myAgent: EvalAgent<string, string> = {\n * config: { name: 'MyAgent', description: 'A simple agent' },\n * prompt: { id: 'prompt-1', version: '1.0.0', system: '...', renderUserPrompt: (input) => input },\n * execute: async (input) => ({ result: `Processed: ${input}` })\n * }\n *\n * // Or adapt from full ai-agents Agent\n * const evalAgent = toEvalAgent(fullAgent)\n * ```\n */\nexport interface EvalAgent<TInput, TOutput> {\n readonly config: EvalAgentConfig;\n readonly prompt: AgentPrompt<TInput>;\n execute(input: TInput, options?: unknown): Promise<AgentResult<TOutput>>;\n}\n\n/**\n * Full AgentConfig interface (compatible with ai-agents package).\n * Used for type-safe adaptation.\n */\nexport interface FullAgentConfig {\n name: string;\n role: 'generator' | 'analyzer' | 'validator' | 'enhancer';\n streaming: 'required' | 'optional' | 'none';\n execution: 'batch' | 'realtime';\n conversation?: 'single-turn' | 'multi-turn';\n description?: string;\n [key: string]: unknown;\n}\n\n/**\n * Full Agent interface (compatible with ai-agents package).\n * Used for type-safe adaptation.\n */\nexport interface FullAgent<TInput, TOutput> {\n readonly config: FullAgentConfig;\n readonly prompt: AgentPrompt<TInput>;\n execute(\n input: TInput,\n options?: unknown\n ): Promise<{\n result: TOutput;\n metadata: {\n duration: number;\n promptVersion: string;\n tokenUsage?: EvalTokenUsage;\n model?: string;\n retryCount?: number;\n traceId?: string;\n [key: string]: unknown;\n };\n }>;\n}\n\n/**\n * Adapts a full Agent (from ai-agents) to EvalAgent for evaluation.\n * Extracts only the fields needed for evaluation.\n *\n * @example\n * ```typescript\n * import { scenarioGenerator } from './agents/mce'\n *\n * const evalAgent = toEvalAgent(scenarioGenerator)\n * const suite = createEvalSuite({ agent: evalAgent, ... })\n * ```\n */\nexport function toEvalAgent<TInput, TOutput>(\n agent: FullAgent<TInput, TOutput>\n): EvalAgent<TInput, TOutput> {\n return {\n config: {\n name: agent.config.name,\n description: agent.config.description,\n },\n prompt: agent.prompt,\n execute: async (input, options) => {\n const result = await agent.execute(input, options);\n return {\n result: result.result,\n metadata: result.metadata,\n };\n },\n };\n}\n\n/**\n * Metadata for file content.\n */\nexport interface FileContentMetadata {\n /** File size in bytes */\n size?: number;\n /** Full resolved path (for loaded files) */\n fullPath?: string;\n /** Whether the content was created inline (not from disk) */\n inline?: boolean;\n /** Additional custom metadata */\n [key: string]: unknown;\n}\n\nexport interface FileContent {\n /** File path (relative or absolute) - used as identifier */\n path: string;\n /** File content as string (text files only for Phase 5.3) */\n content: string;\n /** Optional MIME type hint (defaults to 'text/plain') */\n mediaType?: string;\n /** Optional encoding (defaults to 'utf-8') */\n encoding?: BufferEncoding;\n /** Optional metadata (e.g., original size, full path, etc.) */\n metadata?: FileContentMetadata;\n}\n\nexport interface TestCase<TInput> {\n id?: string;\n input: TInput;\n tags?: string[];\n description?: string;\n expectedOutput?: unknown; // Optional reference for checking\n /**\n * Optional file context for agent and judge (Phase 5.3).\n * Files are passed to Judge for evaluation context.\n * For Agent access, include files in the input type directly.\n *\n * @deprecated Use FileSource in input directly for flexible file handling\n */\n files?: FileContent[];\n}\n\nexport interface MetricsResult {\n latencyMs: number;\n tokenUsage: EvalTokenUsage;\n}\n\nexport interface Criterion {\n id: string;\n name: string;\n description: string;\n weight?: number;\n}\n\n/**\n * Zod error issue - minimal type compatible with ZodError.errors.\n * Using `readonly` and rest index to be compatible with Zod's discriminated union.\n */\nexport type ZodIssue = {\n readonly code: string;\n readonly path: readonly (string | number)[];\n readonly message: string;\n};\n\n/**\n * Result of programmatic schema validation.\n */\nexport interface SchemaValidationResult {\n /** Whether the output matches the schema */\n valid: boolean;\n /** Validation errors if invalid (Zod issue format) */\n errors?: readonly ZodIssue[];\n /** Human-readable error summary */\n errorSummary?: string;\n}\n\n/**\n * Validator function type for programmatic validation.\n * Returns validation result with binary pass/fail outcome.\n */\nexport type ValidatorFn = (output: unknown) => SchemaValidationResult;\n\n/**\n * Extended criterion with optional programmatic validator.\n * Validators run before LLM evaluation with binary scoring (0 or 100).\n *\n * @example\n * ```typescript\n * import { z } from 'zod'\n * import { schema } from '@agtlantis/eval'\n *\n * const criterion = schema({\n * schema: z.object({ name: z.string() }),\n * weight: 2,\n * })\n * ```\n */\nexport interface ValidatorCriterion extends Criterion {\n /**\n * Optional programmatic validator.\n * If provided and fails, score is automatically 0.\n * If provided and passes, score is automatically 100.\n */\n validator?: ValidatorFn;\n}\n\nexport interface Verdict {\n criterionId: string;\n score: number; // 0-100\n reasoning: string;\n passed: boolean;\n}\n\nexport interface TestResult<TInput, TOutput> {\n testCase: TestCase<TInput>;\n output: TOutput;\n metrics: MetricsResult;\n error?: Error;\n}\n\nexport interface TestResultWithVerdict<TInput, TOutput> extends TestResult<TInput, TOutput> {\n verdicts: Verdict[];\n overallScore: number;\n passed: boolean;\n /** Judge metadata for cost tracking */\n judgeMetadata?: JudgeMetadata;\n}\n\n/**\n * Statistics from running the same test multiple times.\n * Used to measure consistency and reliability of LLM-based agents.\n */\nexport interface IterationStats {\n /** Total number of iterations run */\n iterations: number;\n /** Score from each iteration */\n scores: number[];\n /** Average score across all iterations */\n mean: number;\n /** Standard deviation (lower = more consistent) */\n stdDev: number;\n /** Lowest score achieved */\n min: number;\n /** Highest score achieved */\n max: number;\n /** Pass rate as decimal (0-1, e.g., 0.67 = 67%) */\n passRate: number;\n /** Number of iterations that passed */\n passCount: number;\n}\n\n/**\n * Extended iteration statistics for multi-turn tests.\n * Includes turn-count metrics and termination type distribution.\n *\n * @example\n * ```typescript\n * if (hasMultiTurnIterationData(result)) {\n * console.log(`Average turns: ${result.multiTurnIterationStats.avgTurns}`)\n * console.log(`Termination types: ${JSON.stringify(result.multiTurnIterationStats.terminationCounts)}`)\n * }\n * ```\n */\nexport interface MultiTurnIterationStats extends IterationStats {\n /** Average number of turns across all iterations */\n avgTurns: number;\n /** Minimum turns in any iteration */\n minTurns: number;\n /** Maximum turns in any iteration */\n maxTurns: number;\n /** Distribution of termination types across iterations (e.g., { condition: 2, maxTurns: 1 }) */\n terminationCounts: Record<string, number>;\n}\n\n/**\n * Discriminator for eval result types.\n * Used for exhaustive pattern matching on result variants.\n */\nexport type EvalResultKind =\n | 'single-turn'\n | 'single-turn-iterated'\n | 'multi-turn'\n | 'multi-turn-iterated';\n\n/**\n * Properties present when test ran with multiple iterations.\n * Extracted as a separate interface for composition.\n */\nexport interface IterationData<TInput, TOutput> {\n /** Aggregated statistics across all iterations */\n iterationStats: IterationStats;\n /** Individual results from each iteration */\n iterationResults: TestResultWithVerdict<TInput, TOutput>[];\n}\n\n/**\n * Single conversation entry in multi-turn tests.\n */\nexport interface ConversationEntry<TInput, TOutput> {\n /** Turn number (1-based) */\n turn: number;\n /** Input provided for this turn */\n input: TInput;\n /** Output from agent (undefined if execution failed) */\n output: TOutput | undefined;\n /** Agent execution metadata */\n metadata?: AgentMetadata;\n}\n\n/**\n * Termination info for multi-turn tests.\n * Compatible with TerminationCheckResult from multi-turn module.\n */\nexport interface TerminationInfo {\n /** Whether the conversation terminated */\n terminated: boolean;\n /** Human-readable reason for termination */\n reason: string;\n /** Type of termination (condition, maxTurns, error, exhausted) */\n terminationType?: string;\n /** The condition that caused termination (if applicable) */\n matchedCondition?: unknown;\n}\n\n/**\n * Properties present for multi-turn test results.\n * Extracted as a separate interface for composition.\n */\nexport interface MultiTurnData<TInput, TOutput> {\n /** Full conversation history */\n conversationHistory: ConversationEntry<TInput, TOutput>[];\n /** Total turns executed */\n totalTurns: number;\n /** Human-readable termination reason */\n terminationReason: string;\n /** Full termination check result */\n termination: TerminationInfo;\n}\n\n/**\n * Single-turn test result with single iteration (base case).\n * No iteration stats, no multi-turn data.\n */\nexport interface SingleTurnResult<TInput, TOutput> extends TestResultWithVerdict<TInput, TOutput> {\n readonly kind: 'single-turn';\n}\n\n/**\n * Single-turn test result with multiple iterations.\n * Has iteration stats but no multi-turn data.\n */\nexport interface SingleTurnIteratedResult<TInput, TOutput>\n extends TestResultWithVerdict<TInput, TOutput>, IterationData<TInput, TOutput> {\n readonly kind: 'single-turn-iterated';\n}\n\n/**\n * Multi-turn test result with single iteration.\n * Has multi-turn data but no iteration stats.\n */\nexport interface MultiTurnResult<TInput, TOutput>\n extends TestResultWithVerdict<TInput, TOutput>, MultiTurnData<TInput, TOutput> {\n readonly kind: 'multi-turn';\n}\n\n/**\n * Multi-turn test result with multiple iterations.\n * Has both multi-turn data and iteration stats.\n */\nexport interface MultiTurnIteratedResult<TInput, TOutput>\n extends\n TestResultWithVerdict<TInput, TOutput>,\n IterationData<TInput, TOutput>,\n MultiTurnData<TInput, TOutput> {\n readonly kind: 'multi-turn-iterated';\n /** Multi-turn specific iteration statistics */\n multiTurnIterationStats: MultiTurnIterationStats;\n}\n\n/**\n * Unified eval result type - discriminated union of all result kinds.\n *\n * Use pattern matching on `kind` for exhaustive handling:\n * @example\n * ```typescript\n * switch (result.kind) {\n * case 'single-turn':\n * // No iteration stats, no multi-turn data\n * break\n * case 'single-turn-iterated':\n * console.log(result.iterationStats.mean) // Type-safe\n * break\n * case 'multi-turn':\n * console.log(result.conversationHistory) // Type-safe\n * break\n * case 'multi-turn-iterated':\n * console.log(result.multiTurnIterationStats.avgTurns) // Type-safe\n * break\n * }\n * ```\n */\nexport type EvalTestResult<TInput, TOutput> =\n | SingleTurnResult<TInput, TOutput>\n | SingleTurnIteratedResult<TInput, TOutput>\n | MultiTurnResult<TInput, TOutput>\n | MultiTurnIteratedResult<TInput, TOutput>;\n\n/**\n * Check if result is from a single-turn test (either iterated or not).\n *\n * @example\n * ```typescript\n * if (isSingleTurnResult(result)) {\n * // result is SingleTurnResult | SingleTurnIteratedResult\n * console.log('Single turn test')\n * }\n * ```\n */\nexport function isSingleTurnResult<TInput, TOutput>(\n result: EvalTestResult<TInput, TOutput>\n): result is SingleTurnResult<TInput, TOutput> | SingleTurnIteratedResult<TInput, TOutput> {\n return result.kind === 'single-turn' || result.kind === 'single-turn-iterated';\n}\n\n/**\n * Check if result is from a multi-turn test (either iterated or not).\n *\n * @example\n * ```typescript\n * if (isMultiTurnResult(result)) {\n * // result is MultiTurnResult | MultiTurnIteratedResult\n * console.log(`Turns: ${result.totalTurns}`) // Type-safe\n * for (const entry of result.conversationHistory) { // Type-safe\n * console.log(`Turn ${entry.turn}: ${entry.input}`)\n * }\n * }\n * ```\n */\nexport function isMultiTurnResult<TInput, TOutput>(\n result: EvalTestResult<TInput, TOutput>\n): result is MultiTurnResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput> {\n return result.kind === 'multi-turn' || result.kind === 'multi-turn-iterated';\n}\n\n/**\n * Check if result has iteration data (multiple iterations ran).\n *\n * @example\n * ```typescript\n * if (isIteratedResult(result)) {\n * // result is SingleTurnIteratedResult | MultiTurnIteratedResult\n * console.log(`Mean score: ${result.iterationStats.mean}`) // Type-safe\n * console.log(`Pass rate: ${result.iterationStats.passRate}`) // Type-safe\n * }\n * ```\n */\nexport function isIteratedResult<TInput, TOutput>(\n result: EvalTestResult<TInput, TOutput>\n): result is SingleTurnIteratedResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput> {\n return result.kind === 'single-turn-iterated' || result.kind === 'multi-turn-iterated';\n}\n","/**\n * Iteration statistics utilities for repeated test execution.\n *\n * These functions aggregate results from running the same test multiple times,\n * providing statistical metrics like mean, standard deviation, and pass rate.\n */\n\nimport type {\n EvalTestResult,\n IterationStats,\n MultiTurnIteratedResult,\n MultiTurnResult,\n MultiTurnIterationStats,\n SingleTurnIteratedResult,\n SingleTurnResult,\n TestResultWithVerdict,\n} from './types.js'\nimport { isMultiTurnResult } from './types.js'\nimport { EvalError, EvalErrorCode } from './errors'\nimport { SCORE } from './constants'\n\n/**\n * Calculate iteration statistics from multiple test results.\n *\n * @param results - Results from running the same test multiple times\n * @returns Aggregated statistics including mean, stdDev, and passRate\n *\n * @example\n * ```typescript\n * const stats = calculateIterationStats([\n * { overallScore: 85, passed: true, ... },\n * { overallScore: 90, passed: true, ... },\n * { overallScore: 80, passed: true, ... },\n * ])\n * // stats.mean = 85\n * // stats.stdDev ≈ 4.08\n * // stats.passRate = 1.0\n * ```\n */\nexport function calculateIterationStats(\n results: TestResultWithVerdict<unknown, unknown>[]\n): IterationStats {\n if (results.length === 0) {\n return {\n iterations: 0,\n scores: [],\n mean: 0,\n stdDev: 0,\n min: 0,\n max: 0,\n passRate: 0,\n passCount: 0,\n }\n }\n\n const scores = results.map((r) => r.overallScore)\n const passCount = results.filter((r) => r.passed).length\n\n const mean = scores.reduce((sum, s) => sum + s, 0) / scores.length\n\n // Population standard deviation (not sample)\n const variance =\n scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length\n const stdDev = Math.sqrt(variance)\n\n return {\n iterations: results.length,\n scores,\n mean,\n stdDev,\n min: Math.min(...scores),\n max: Math.max(...scores),\n passRate: passCount / results.length,\n passCount,\n }\n}\n\n/**\n * Calculate multi-turn specific iteration statistics.\n *\n * Extends base iteration stats with turn counts and termination type distribution.\n * Used when aggregating multiple iterations of multi-turn tests.\n *\n * @param results - Results from running the same multi-turn test multiple times\n * @returns Extended statistics including avgTurns, min/max turns, and terminationCounts\n *\n * @example\n * ```typescript\n * const stats = calculateMultiTurnIterationStats(results)\n * // stats.avgTurns = 4.2\n * // stats.minTurns = 3\n * // stats.maxTurns = 6\n * // stats.terminationCounts = { condition: 2, maxTurns: 1 }\n * ```\n */\nexport function calculateMultiTurnIterationStats<TInput, TOutput>(\n results: (MultiTurnResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput>)[]\n): MultiTurnIterationStats {\n const baseStats = calculateIterationStats(results)\n\n // Extract turns from results (all multi-turn results have totalTurns)\n const turns = results.map((r) => r.totalTurns)\n\n // Count termination types from termination.terminationType\n const terminationCounts: Record<string, number> = {}\n for (const r of results) {\n const type = r.termination.terminationType\n if (type) {\n terminationCounts[type] = (terminationCounts[type] || 0) + 1\n }\n }\n\n return {\n ...baseStats,\n avgTurns: turns.length > 0 ? turns.reduce((a, b) => a + b, 0) / turns.length : 0,\n minTurns: turns.length > 0 ? Math.min(...turns) : 0,\n maxTurns: turns.length > 0 ? Math.max(...turns) : 0,\n terminationCounts,\n }\n}\n\n/**\n * Select the result closest to the mean score.\n * Used to pick a \"representative\" result for displaying verdicts/reasoning.\n *\n * The function preserves the full type of the input array, so if you pass\n * `TestResultWithIteration[]`, you get back `TestResultWithIteration`.\n *\n * @param results - Array of results to choose from (must not be empty)\n * @param mean - The mean score to compare against\n * @returns The result with overallScore closest to mean\n * @throws Error if results array is empty\n */\nexport function selectRepresentativeResult<\n TInput,\n TOutput,\n T extends TestResultWithVerdict<TInput, TOutput> = TestResultWithVerdict<TInput, TOutput>,\n>(results: T[], mean: number): T {\n if (results.length === 0) {\n throw new EvalError('Cannot select representative result from empty array', {\n code: EvalErrorCode.UNKNOWN_ERROR,\n })\n }\n\n return results.reduce((closest, current) => {\n const closestDiff = Math.abs(closest.overallScore - mean)\n const currentDiff = Math.abs(current.overallScore - mean)\n return currentDiff < closestDiff ? current : closest\n })\n}\n\n/**\n * Aggregate results from multiple iteration runs into iterated result types.\n *\n * Takes N arrays of results (one per iteration) and groups them by test case,\n * calculating iteration statistics for each test case.\n *\n * For multi-turn tests, returns MultiTurnIteratedResult with multi-turn specific\n * statistics like average turns, min/max turns, and termination type distribution.\n *\n * For single-turn tests, returns SingleTurnIteratedResult with base iteration stats.\n *\n * @param allIterationResults - Array of arrays: outer = iterations, inner = test cases\n * @returns Aggregated results with iteration statistics\n *\n * @example\n * ```typescript\n * // 3 iterations, 2 test cases each\n * const allResults = [\n * [testCase1_iter1, testCase2_iter1], // iteration 1\n * [testCase1_iter2, testCase2_iter2], // iteration 2\n * [testCase1_iter3, testCase2_iter3], // iteration 3\n * ]\n *\n * const aggregated = aggregateIterationResults(allResults)\n * // aggregated[0] = testCase1 with stats from iter1, iter2, iter3\n * // aggregated[1] = testCase2 with stats from iter1, iter2, iter3\n *\n * // For multi-turn tests:\n * // aggregated[0].kind === 'multi-turn-iterated'\n * // aggregated[0].multiTurnIterationStats = { avgTurns, minTurns, maxTurns, terminationCounts }\n * ```\n */\nexport function aggregateIterationResults<TInput, TOutput>(\n allIterationResults: EvalTestResult<TInput, TOutput>[][]\n): (SingleTurnIteratedResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput>)[] {\n if (allIterationResults.length === 0) {\n return []\n }\n\n const testCount = allIterationResults[0].length\n const aggregated: (SingleTurnIteratedResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput>)[] = []\n\n for (let i = 0; i < testCount; i++) {\n const resultsForTestCase = allIterationResults.map((iteration) => iteration[i])\n const stats = calculateIterationStats(resultsForTestCase)\n const representative = selectRepresentativeResult(resultsForTestCase, stats.mean)\n const isMultiTurn = resultsForTestCase.some((r) => isMultiTurnResult(r))\n const passedByMajority = stats.passRate >= SCORE.MAJORITY_PASS_THRESHOLD\n\n if (isMultiTurn) {\n const multiTurnResults = resultsForTestCase.filter(\n (r): r is MultiTurnResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput> =>\n isMultiTurnResult(r)\n )\n const multiTurnRep = representative as MultiTurnResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput>\n\n const aggregatedResult: MultiTurnIteratedResult<TInput, TOutput> = {\n kind: 'multi-turn-iterated',\n testCase: multiTurnRep.testCase,\n output: multiTurnRep.output,\n metrics: multiTurnRep.metrics,\n verdicts: multiTurnRep.verdicts,\n error: multiTurnRep.error,\n overallScore: stats.mean,\n passed: passedByMajority,\n iterationStats: stats,\n iterationResults: resultsForTestCase,\n conversationHistory: multiTurnRep.conversationHistory,\n totalTurns: multiTurnRep.totalTurns,\n terminationReason: multiTurnRep.terminationReason,\n termination: multiTurnRep.termination,\n multiTurnIterationStats: calculateMultiTurnIterationStats(multiTurnResults),\n }\n aggregated.push(aggregatedResult)\n } else {\n const aggregatedResult: SingleTurnIteratedResult<TInput, TOutput> = {\n kind: 'single-turn-iterated',\n testCase: representative.testCase,\n output: representative.output,\n metrics: representative.metrics,\n verdicts: representative.verdicts,\n error: representative.error,\n overallScore: stats.mean,\n passed: passedByMajority,\n iterationStats: stats,\n iterationResults: resultsForTestCase,\n }\n aggregated.push(aggregatedResult)\n }\n }\n\n return aggregated\n}\n\ntype IteratedResult<TInput, TOutput> = SingleTurnIteratedResult<TInput, TOutput> | MultiTurnIteratedResult<TInput, TOutput>\n\nfunction filterIteratedResults<TInput, TOutput>(\n results: EvalTestResult<TInput, TOutput>[]\n): IteratedResult<TInput, TOutput>[] {\n return results.filter(\n (r): r is IteratedResult<TInput, TOutput> =>\n r.kind === 'single-turn-iterated' || r.kind === 'multi-turn-iterated'\n )\n}\n\nfunction averageIterationStat<TInput, TOutput>(\n results: EvalTestResult<TInput, TOutput>[],\n selector: (stats: IterationStats) => number\n): number | undefined {\n const iteratedResults = filterIteratedResults(results)\n if (iteratedResults.length === 0) {\n return undefined\n }\n const total = iteratedResults.reduce((sum, r) => sum + selector(r.iterationStats), 0)\n return total / iteratedResults.length\n}\n\n/**\n * Calculate average standard deviation across multiple test results.\n * Used for report summary.\n *\n * @param results - Eval results (only iterated results have stats)\n * @returns Average stdDev across all iterated tests, or undefined if no iteration data\n */\nexport function calculateAvgStdDev<TInput, TOutput>(\n results: EvalTestResult<TInput, TOutput>[]\n): number | undefined {\n return averageIterationStat(results, (stats) => stats.stdDev)\n}\n\n/**\n * Calculate average pass rate across multiple test results.\n * Used for report summary.\n *\n * @param results - Eval results (only iterated results have stats)\n * @returns Average passRate across all iterated tests, or undefined if no iteration data\n */\nexport function calculateAvgPassRate<TInput, TOutput>(\n results: EvalTestResult<TInput, TOutput>[]\n): number | undefined {\n return averageIterationStat(results, (stats) => stats.passRate)\n}\n","import type {\n EvalAgent,\n EvalTestResult,\n TestCase,\n TestResultWithVerdict,\n} from './types'\nimport type { Judge } from '@/judge/types'\nimport type { Improver, AggregatedMetrics, Suggestion } from '@/improver/types'\nimport type { EvalReport, ReportSummary } from '@/reporter/types'\nimport { runWithConcurrency, type RunOptions } from './runner'\nimport {\n aggregateIterationResults,\n calculateAvgPassRate,\n calculateAvgStdDev,\n} from './iteration'\nimport { EvalError, EvalErrorCode } from './errors'\n\nexport type { RunOptions } from './runner'\n\n/**\n * Configuration for creating an EvalSuite.\n *\n * @example\n * ```typescript\n * const suite = createEvalSuite({\n * agent: myAgent,\n * judge: myJudge,\n * agentDescription: 'Recommends career paths based on student profiles',\n * })\n * ```\n */\nexport interface EvalSuiteConfig<TInput, TOutput> {\n /** The agent to evaluate */\n agent: EvalAgent<TInput, TOutput>\n\n /** Human-readable description of what the agent does (used by Judge) */\n agentDescription?: string\n\n /** Judge instance for evaluating agent outputs */\n judge: Judge\n\n /** Improver instance for generating prompt improvement suggestions (optional) */\n improver?: Improver\n}\n\n/**\n * Evaluation suite for running test cases against an agent.\n *\n * @example\n * ```typescript\n * const report = await suite.run(testCases, { concurrency: 3 })\n * console.log(reportToMarkdown(report))\n *\n * // Test with a different agent\n * const newReport = await suite.withAgent(improvedAgent).run(testCases)\n * ```\n */\nexport interface EvalSuite<TInput, TOutput> {\n /**\n * Run test cases and generate an evaluation report.\n *\n * @param testCases - Test cases to run\n * @param options - Run options (concurrency, stopOnFirstFailure, signal)\n * @returns Evaluation report with results, summary, and suggestions\n */\n run(\n testCases: TestCase<TInput>[],\n options?: RunOptions\n ): Promise<EvalReport<TInput, TOutput>>\n\n /**\n * Create a new suite with a different agent.\n * Useful for A/B testing or testing prompt improvements.\n *\n * @param agent - New agent to use\n * @returns New EvalSuite instance with the updated agent\n */\n withAgent(agent: EvalAgent<TInput, TOutput>): EvalSuite<TInput, TOutput>\n}\n\n/**\n * Calculate aggregated metrics from test results.\n * @internal\n *\n * Cost calculation is done via post-processing utilities (Phase 11).\n * Use calculateReportCosts() or addCostsToResults() from pricing module.\n */\nfunction calculateAggregatedMetrics<TInput, TOutput>(\n results: TestResultWithVerdict<TInput, TOutput>[]\n): AggregatedMetrics {\n if (results.length === 0) {\n return { avgLatencyMs: 0, totalTokens: 0 }\n }\n\n const totalLatencyMs = sumBy(results, (r) => r.metrics.latencyMs)\n const totalTokens = sumBy(results, (r) => r.metrics.tokenUsage.totalTokens)\n\n return {\n avgLatencyMs: totalLatencyMs / results.length,\n totalTokens,\n }\n}\n\nfunction sumBy<T>(items: T[], selector: (item: T) => number): number {\n return items.reduce((sum, item) => sum + selector(item), 0)\n}\n\n/** @internal */\nfunction calculateSummary<TInput, TOutput>(\n results: EvalTestResult<TInput, TOutput>[],\n iterations?: number\n): ReportSummary {\n const metrics = calculateAggregatedMetrics(results)\n const passedCount = results.filter((r) => r.passed).length\n const failedCount = results.length - passedCount\n const avgScore = results.length > 0\n ? sumBy(results, (r) => r.overallScore) / results.length\n : 0\n\n const summary: ReportSummary = {\n totalTests: results.length,\n passed: passedCount,\n failed: failedCount,\n avgScore,\n metrics,\n }\n\n const hasMultipleIterations = iterations && iterations > 1\n if (hasMultipleIterations) {\n summary.iterations = iterations\n summary.avgStdDev = calculateAvgStdDev(results)\n summary.avgPassRate = calculateAvgPassRate(results)\n }\n\n return summary\n}\n\n/**\n * Create an evaluation suite for testing an agent.\n *\n * The suite orchestrates test execution, evaluation, and optional\n * prompt improvement suggestions.\n *\n * @example\n * ```typescript\n * const suite = createEvalSuite({\n * agent: scenarioGenerator,\n * agentDescription: 'Recommends majors based on student profiles',\n * judge: createJudge({\n * llm: openaiClient,\n * prompt: defaultJudgePrompt,\n * criteria: [accuracy(), relevance()],\n * }),\n * })\n *\n * const report = await suite.run(testCases, { concurrency: 3 })\n * ```\n */\nexport function createEvalSuite<TInput, TOutput>(\n config: EvalSuiteConfig<TInput, TOutput>\n): EvalSuite<TInput, TOutput> {\n const { agent, agentDescription, judge, improver } = config\n const description = agentDescription ?? agent.config.description ?? agent.config.name\n\n const suite: EvalSuite<TInput, TOutput> = {\n async run(\n testCases: TestCase<TInput>[],\n options?: RunOptions\n ): Promise<EvalReport<TInput, TOutput>> {\n const iterations = options?.iterations ?? 1\n validateIterations(iterations)\n\n const executeContext = { agent, judge, agentDescription: description }\n const results = iterations <= 1\n ? await runWithConcurrency<TInput, TOutput>(testCases, executeContext, options)\n : await runMultipleIterations(testCases, executeContext, options, iterations)\n\n const summary = calculateSummary(results, iterations > 1 ? iterations : undefined)\n const suggestions = improver\n ? (await improver.improve(agent.prompt, results)).suggestions\n : []\n\n return {\n summary,\n results,\n suggestions,\n generatedAt: new Date(),\n promptVersion: agent.prompt.version,\n }\n },\n\n withAgent(newAgent: EvalAgent<TInput, TOutput>): EvalSuite<TInput, TOutput> {\n return createEvalSuite({\n ...config,\n agent: newAgent,\n agentDescription: undefined,\n })\n },\n }\n\n return suite\n}\n\nfunction validateIterations(iterations: number): void {\n if (iterations < 1 || !Number.isInteger(iterations)) {\n throw new EvalError(\n `Invalid iterations value: ${iterations}. Must be a positive integer.`,\n { code: EvalErrorCode.INVALID_CONFIG, context: { iterations } }\n )\n }\n}\n\nasync function runMultipleIterations<TInput, TOutput>(\n testCases: TestCase<TInput>[],\n executeContext: { agent: EvalAgent<TInput, TOutput>; judge: Judge; agentDescription: string },\n options: RunOptions | undefined,\n iterations: number\n): Promise<EvalTestResult<TInput, TOutput>[]> {\n const allIterationResults: EvalTestResult<TInput, TOutput>[][] = []\n\n for (let i = 0; i < iterations; i++) {\n const iterationResults = await runWithConcurrency<TInput, TOutput>(\n testCases,\n executeContext,\n { ...options, iterations: undefined }\n )\n allIterationResults.push(iterationResults)\n }\n\n return aggregateIterationResults(allIterationResults)\n}\n","/**\n * agent-eval - LLM-as-Judge based AI Agent testing library\n *\n * @example\n * ```typescript\n * import {\n * createEvalSuite,\n * createJudge,\n * createOpenAIClient,\n * accuracy,\n * relevance,\n * } from 'agent-eval'\n *\n * const openai = createOpenAIClient({\n * apiKey: process.env.OPENAI_API_KEY,\n * defaultModel: 'gpt-5-nano',\n * reasoningEffort: 'minimal',\n * })\n *\n * const judge = createJudge({\n * llm: openai,\n * criteria: [accuracy(), relevance()],\n * })\n *\n * const suite = createEvalSuite({\n * agent: myAgent,\n * judge,\n * agentDescription: 'Recommends careers based on student profiles',\n * })\n *\n * const report = await suite.run(testCases, { concurrency: 3 })\n * console.log(report.summary)\n * ```\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Suite - Main Entry Point\n// ============================================================================\n\nexport {\n createEvalSuite,\n type EvalSuiteConfig,\n type EvalSuite,\n type RunOptions,\n} from '@/core/suite';\n\n// ============================================================================\n// Runner - Low-level Execution\n// ============================================================================\n\nexport { executeTestCase, runWithConcurrency, type ExecuteContext } from '@/core/runner';\n\n// ============================================================================\n// Core Types\n// ============================================================================\n\nexport type {\n // Token usage\n EvalTokenUsage,\n // Agent types\n EvalAgent,\n EvalAgentConfig,\n AgentPrompt,\n AgentResult,\n AgentMetadata,\n // Component metadata types (Phase 10)\n ComponentMetadata,\n JudgeMetadata,\n ImproverMetadata,\n // Test types\n TestCase,\n TestResult,\n TestResultWithVerdict,\n MetricsResult,\n // Iteration types (Phase 6.2)\n IterationStats,\n IterationData,\n // Multi-turn iteration types (Phase 7.2)\n MultiTurnIterationStats,\n // Eval result types (Discriminated Union)\n EvalResultKind,\n EvalTestResult,\n SingleTurnResult,\n SingleTurnIteratedResult,\n MultiTurnResult,\n MultiTurnIteratedResult,\n ConversationEntry,\n TerminationInfo,\n MultiTurnData,\n // Evaluation types\n Verdict,\n Criterion,\n // Schema validation types (Phase 6.3)\n SchemaValidationResult,\n ValidatorFn,\n ValidatorCriterion,\n ZodIssue,\n // File context types (Phase 5.3)\n FileContent,\n FileContentMetadata,\n} from '@/core/types';\n\nexport {\n toEvalAgent,\n // Type guards for EvalTestResult\n isSingleTurnResult,\n isMultiTurnResult,\n isIteratedResult,\n} from '@/core/types';\n\n// ============================================================================\n// FileSource (Embedded Files in Input)\n// ============================================================================\n\nexport {\n // Resolver\n resolveFileSource,\n resolveFileSourcesInInput,\n // Scanner\n scanForFileSources,\n // Display info\n getFileSourceDisplayInfo,\n getFileSourcesDisplayInfo,\n // Utilities\n inferMediaType,\n // Type guards\n isFileSource,\n isFileSourcePath,\n isFileSourceData,\n isFileSourceBase64,\n isFileSourceUrl,\n // Types\n type FileSource,\n type FileSourcePath,\n type FileSourceData,\n type FileSourceBase64,\n type FileSourceUrl,\n type FoundFileSource,\n type FileSourceDisplayInfo,\n type ResolveOptions,\n} from '@agtlantis/core';\n\n// ============================================================================\n// Iteration Utilities (Phase 6.2, 7.2)\n// ============================================================================\n\nexport {\n calculateIterationStats,\n calculateMultiTurnIterationStats,\n selectRepresentativeResult,\n aggregateIterationResults,\n calculateAvgStdDev,\n calculateAvgPassRate,\n} from '@/core/iteration';\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nexport { EvalError, EvalErrorCode, type EvalErrorOptions } from '@/core/errors';\n\n// ============================================================================\n// Judge\n// ============================================================================\n\nexport {\n createJudge,\n // Criteria\n accuracy,\n consistency,\n relevance,\n schema,\n type CriterionOptions,\n type SchemaOptions,\n // Types\n type Judge,\n type JudgeConfig,\n type JudgeContext,\n type JudgePrompt,\n // Context-based API types (Phase 5.3)\n type EvalContext,\n type JudgeResult,\n} from '@/judge/index';\n\n// ============================================================================\n// Reporter\n// ============================================================================\n\nexport type {\n EvalReport,\n ReportSummary,\n ReportMarkdownOptions,\n ReportComparison,\n} from '@/reporter/types';\n\nexport { reportToMarkdown, saveReportMarkdown, compareReports } from '@/reporter/markdown';\n\n// Reporter classes\nexport {\n JsonReporter,\n MarkdownReporter,\n ConsoleReporter,\n CompositeReporter,\n type MarkdownReporterOptions,\n} from '@/reporter';\n\n// Reporter factory functions\nexport {\n createJsonReporter,\n createMarkdownReporter,\n createConsoleReporter,\n createCompositeReporter,\n createDefaultReporter,\n} from '@/reporter';\n\n// Report runner (convenience wrapper)\nexport { createReportRunner, type ReportRunnerOptions } from '@/reporter';\n\n// Reporter types\nexport type {\n Reporter,\n FileReporterOptions,\n ConsoleReporterOptions,\n LogVerbosity,\n} from '@/reporter';\n\n// ImprovementCycleResult helpers\nexport {\n saveCycleJson,\n logCycle,\n cycleToMarkdown,\n saveCycleMarkdown,\n type SaveCycleJsonOptions,\n type LogCycleOptions,\n type CycleMarkdownOptions,\n} from '@/reporter';\n\n// ============================================================================\n// Improver\n// ============================================================================\n\nexport {\n createImprover,\n // Utility functions\n suggestionDiff,\n suggestionPreview,\n suggestionSummary,\n applyPromptSuggestions,\n bumpVersion,\n // Types\n type Suggestion,\n type AggregatedMetrics,\n type Improver,\n type ImproverConfig,\n type ImproverPrompt,\n type ImproverContext,\n type ApplyPromptSuggestionsOptions,\n type ApplySuggestionsResult,\n // Phase 10 - ImproveResult with metadata\n type ImproveResult,\n} from '@/improver/index';\n\n// ============================================================================\n// Testing Utilities\n// ============================================================================\n\n// Re-export core testing mock utilities\nexport { mock, MockProvider } from '@agtlantis/core/testing';\nexport type { MockCall } from '@agtlantis/core/testing';\n\n// Agent/Judge/Improver mocks\nexport {\n createMockAgent,\n createMockJudge,\n createMockImprover,\n type MockAgentConfig,\n type MockJudgeConfig,\n type MockImproverConfig,\n} from '@/testing/mock-agent';\n\n// ============================================================================\n// Prompt (from @agtlantis/core)\n// ============================================================================\n\nexport {\n compileTemplate,\n createFilePromptRepository,\n type FilePromptRepositoryOptions,\n type FileSystem,\n type PromptTemplate,\n type PromptRepository,\n} from '@agtlantis/core';\n\n// ============================================================================\n// Multi-turn Testing\n// ============================================================================\n\n// Types\nexport type {\n ConversationContext,\n FieldsCondition,\n FieldSetCondition,\n FieldValueCondition,\n ContinueResult,\n CustomCondition,\n FollowUpInput,\n MaxTurnsCondition,\n MultiTurnTestCase,\n MultiTurnTestResult,\n NaturalLanguageConditionOptions,\n TerminatedResult,\n TerminationCheckResult,\n TerminationCondition,\n MultiTurnExecuteContext,\n MultiTurnExecuteOptions,\n} from '@/multi-turn/index';\n\n// Type guards\nexport {\n isCustomCondition,\n isFieldSetCondition,\n isFieldValueCondition,\n isMaxTurnsCondition,\n isMultiTurnTestCase,\n isTerminated,\n} from '@/multi-turn/index';\n\n// Termination utilities\nexport { checkCondition, checkTermination, getFieldValue } from '@/multi-turn/index';\n\n// Condition factory functions\nexport {\n afterTurns,\n and,\n fieldEquals,\n fieldIsSet,\n naturalLanguage,\n not,\n or,\n} from '@/multi-turn/index';\n\n// Runner\nexport { executeMultiTurnTestCase } from '@/multi-turn/index';\n\n// AI User\nexport { aiUser, type AIUserOptions } from '@/multi-turn/index';\n\n// ============================================================================\n// Cost Calculation (re-export from reporter/cost-helpers)\n// ============================================================================\n\nexport {\n calculateResultCost,\n calculateReportCosts,\n addCostsToResults,\n type CostBreakdown,\n type CostSummary,\n type MetricsWithCost,\n type TestResultWithCost,\n type EvalPricingConfig,\n} from '@/reporter/cost-helpers';\n\n// Re-export core pricing utilities for convenience\nexport {\n calculateCostFromUsage,\n OPENAI_PRICING,\n GOOGLE_PRICING,\n ANTHROPIC_PRICING,\n DEFAULT_PRICING_CONFIG,\n type PricingConfig,\n type ModelPricing,\n type CostResult,\n} from '@agtlantis/core';\n\n// ============================================================================\n// CLI Configuration\n// ============================================================================\n\nexport {\n defineConfig,\n type EvalConfig,\n type LLMConfig,\n type CLIJudgeConfig,\n type CLIImproverConfig,\n type OutputConfig,\n type RunConfig,\n type CLITestCase,\n type CLISingleTurnTestCase,\n type CLIMultiTurnTestCase,\n} from '@/cli/config/types';\n\nexport { discoverEvalFiles, type DiscoverOptions } from '@/cli/config/loader';\n\n// ============================================================================\n// Improvement Cycle (Automated Prompt Refinement)\n// ============================================================================\n\n// Types\nexport type {\n // Termination conditions\n TargetScoreCondition,\n MaxRoundsCondition,\n NoImprovementCondition,\n MaxCostCondition,\n CustomCycleCondition,\n CycleTerminationCondition,\n // Context and results\n CycleContext,\n CycleContinueResult,\n CycleTerminatedResult,\n CycleTerminationResult,\n // Round types\n RoundYield,\n RoundDecision,\n RoundCost,\n RoundResult,\n // Serialization\n SerializedPrompt,\n SerializedRoundResult,\n // History and config\n ImprovementHistory,\n HistoryConfig,\n ImprovementCycleConfig,\n ImprovementCycleOptions,\n ImprovementCycleResult,\n HistoryStorage,\n ImprovementSession,\n SessionConfig,\n} from '@/improvement-cycle';\n\n// Type guards\nexport {\n isTargetScoreCondition,\n isMaxRoundsCondition,\n isNoImprovementCondition,\n isMaxCostCondition,\n isCustomCycleCondition,\n isCycleTerminated,\n} from '@/improvement-cycle';\n\n// Condition utilities\nexport { checkCycleCondition, checkCycleTermination } from '@/improvement-cycle';\n\n// Condition factory functions\nexport {\n targetScore,\n maxRounds,\n noImprovement,\n maxCost,\n customCondition,\n // Composite conditions\n and as cycleAnd,\n or as cycleOr,\n not as cycleNot,\n} from '@/improvement-cycle';\n\n// Runner\nexport { runImprovementCycle, runImprovementCycleAuto } from '@/improvement-cycle';\n\n// History/Persistence\nexport {\n createSession,\n resumeSession,\n loadHistory,\n saveHistory,\n serializePrompt,\n deserializePrompt,\n defaultHistoryStorage,\n} from '@/improvement-cycle';\n\n// ============================================================================\n// Test Case Utilities\n// ============================================================================\n\nexport {\n TestCaseCollection,\n testCase,\n testCases,\n type RandomOptions,\n} from '@/core/test-case-collection';\n","import { type LanguageModelUsage, type ModelMessage, Output } from 'ai';\nimport { z } from 'zod';\n\nimport { SCORE } from '@/core/constants.js';\nimport { EvalError, EvalErrorCode } from '@/core/errors.js';\nimport type {\n Criterion,\n EvalTokenUsage,\n JudgeMetadata,\n ValidatorCriterion,\n Verdict,\n} from '@/core/types.js';\n\nimport { defaultJudgePrompt } from './prompts/default.js';\nimport type { EvalContext, Judge, JudgeConfig, JudgeContext, JudgeResult } from './types.js';\n\nfunction toEvalTokenUsage(usage: LanguageModelUsage): EvalTokenUsage {\n return {\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n totalTokens: usage.totalTokens ?? 0,\n };\n}\n\nfunction hasValidator(criterion: Criterion): criterion is ValidatorCriterion {\n return (\n 'validator' in criterion &&\n typeof (criterion as ValidatorCriterion).validator === 'function'\n );\n}\n\nconst JudgeResponseSchema = z.object({\n verdicts: z.array(\n z.object({\n criterionId: z.string(),\n score: z.number().min(SCORE.MIN).max(SCORE.MAX),\n reasoning: z.string(),\n passed: z.boolean().optional(),\n })\n ),\n});\n\ntype JudgeResponse = z.infer<typeof JudgeResponseSchema>;\n\nfunction validateAllCriteriaHaveVerdicts(\n verdicts: JudgeResponse['verdicts'],\n criteriaIds: string[]\n): void {\n const providedIds = new Set(verdicts.map((v) => v.criterionId));\n const missingIds = criteriaIds.filter((id) => !providedIds.has(id));\n\n if (missingIds.length > 0) {\n throw new EvalError('Judge response missing verdicts for some criteria', {\n code: EvalErrorCode.VERDICT_PARSE_ERROR,\n context: { missingCriteriaIds: missingIds, providedIds: [...providedIds] },\n });\n }\n}\n\nfunction calculateOverallScore(verdicts: Verdict[], criteriaWeights: Map<string, number>): number {\n let totalWeight = 0;\n let weightedSum = 0;\n\n for (const verdict of verdicts) {\n const weight = criteriaWeights.get(verdict.criterionId) ?? 1;\n weightedSum += verdict.score * weight;\n totalWeight += weight;\n }\n\n if (totalWeight === 0) {\n return 0;\n }\n\n return Math.round((weightedSum / totalWeight) * 100) / 100;\n}\n\nfunction runValidatorCriteria(validatorCriteria: ValidatorCriterion[], output: unknown): Verdict[] {\n return validatorCriteria.map((criterion) => {\n const result = criterion.validator!(output);\n\n if (result.valid) {\n return {\n criterionId: criterion.id,\n score: 100,\n reasoning: `${criterion.name} 통과`,\n passed: true,\n };\n }\n\n return {\n criterionId: criterion.id,\n score: 0,\n reasoning: `${criterion.name} 실패:\\n${result.errorSummary ?? '유효성 검증 오류'}`,\n passed: false,\n };\n });\n}\n\nasync function runLLMEvaluation(\n provider: JudgeConfig['provider'],\n prompt: NonNullable<JudgeConfig['prompt']>,\n context: JudgeContext,\n llmCriteriaIds: string[],\n passThreshold: number\n): Promise<{ verdicts: Verdict[]; usage?: LanguageModelUsage }> {\n const messages: ModelMessage[] = [\n { role: 'system', content: prompt.system },\n { role: 'user', content: prompt.renderUserPrompt(context) },\n ];\n\n let response: JudgeResponse;\n let usage: LanguageModelUsage | undefined;\n\n try {\n const execution = provider.simpleExecution(async (session) => {\n const result = await session.generateText({\n messages,\n output: Output.object({ schema: JudgeResponseSchema }),\n });\n return result.output!;\n });\n\n const executionResult = await execution.result();\n\n if (executionResult.status !== 'succeeded') {\n throw executionResult.status === 'failed'\n ? executionResult.error\n : new Error('Execution was canceled');\n }\n\n response = executionResult.value;\n usage = executionResult.summary.totalLLMUsage;\n } catch (cause) {\n throw EvalError.from(cause, EvalErrorCode.LLM_API_ERROR, {\n promptId: prompt.id,\n promptVersion: prompt.version,\n });\n }\n\n validateAllCriteriaHaveVerdicts(response.verdicts, llmCriteriaIds);\n\n const verdicts: Verdict[] = response.verdicts.map((v) => ({\n criterionId: v.criterionId,\n score: v.score,\n reasoning: v.reasoning,\n passed: v.passed ?? v.score >= passThreshold,\n }));\n\n return { verdicts, usage };\n}\n\n/**\n * Creates an LLM-as-Judge evaluator.\n *\n * @example\n * ```typescript\n * import { createJudge, defaultJudgePrompt, accuracy, consistency } from 'agent-eval'\n * import { createGoogleProvider } from '@agtlantis/core'\n *\n * const provider = createGoogleProvider({ apiKey }).withDefaultModel('gemini-2.5-flash')\n *\n * const judge = createJudge({\n * provider,\n * prompt: defaultJudgePrompt,\n * criteria: [accuracy(), consistency()],\n * passThreshold: 70,\n * })\n *\n * const result = await judge.evaluate({\n * input: { query: 'What is 2+2?' },\n * output: { answer: '4' },\n * agentDescription: 'A math tutor agent',\n * files: [{ path: 'reference.md', content: '...' }],\n * })\n *\n * console.log(result.overallScore) // e.g., 85\n * console.log(result.passed) // true\n * ```\n */\nexport function createJudge(config: JudgeConfig): Judge {\n const {\n provider,\n prompt = defaultJudgePrompt,\n criteria,\n passThreshold = SCORE.DEFAULT_PASS_THRESHOLD,\n model,\n } = config;\n\n const validatorCriteria: ValidatorCriterion[] = [];\n const llmCriteria: Criterion[] = [];\n const criteriaWeights = new Map<string, number>();\n const llmCriteriaIds: string[] = [];\n\n for (const c of criteria) {\n criteriaWeights.set(c.id, c.weight ?? 1);\n\n if (hasValidator(c)) {\n validatorCriteria.push(c);\n } else {\n llmCriteria.push(c);\n llmCriteriaIds.push(c.id);\n }\n }\n\n return {\n async evaluate(evalContext: EvalContext): Promise<JudgeResult> {\n const { input, output, agentDescription, files } = evalContext;\n\n const validatorVerdicts = runValidatorCriteria(validatorCriteria, output);\n\n let llmVerdicts: Verdict[] = [];\n let llmUsage: LanguageModelUsage | undefined;\n\n if (llmCriteria.length > 0) {\n const context: JudgeContext = {\n agentDescription,\n input,\n output,\n criteria: llmCriteria,\n files,\n };\n\n const llmResult = await runLLMEvaluation(\n provider,\n prompt,\n context,\n llmCriteriaIds,\n passThreshold\n );\n llmVerdicts = llmResult.verdicts;\n llmUsage = llmResult.usage;\n }\n\n const allVerdicts: Verdict[] = [...validatorVerdicts, ...llmVerdicts];\n const overallScore = calculateOverallScore(allVerdicts, criteriaWeights);\n const passed = overallScore >= passThreshold;\n\n const metadata: JudgeMetadata | undefined = llmUsage\n ? { tokenUsage: toEvalTokenUsage(llmUsage), model }\n : undefined;\n\n return {\n verdicts: allVerdicts,\n overallScore,\n passed,\n metadata,\n };\n },\n };\n}\n","import type { JudgeContext, JudgePrompt } from '../types';\n\nexport const defaultJudgePrompt: JudgePrompt = {\n id: 'default-judge',\n version: '2.0.0',\n\n system: `You are an expert evaluator specializing in assessing AI Agent outputs.\n\nYour role is to fairly and thoroughly evaluate the agent's output against the provided criteria.\n\n## Evaluation Principles\n\n1. **Scoring**: Assign a score between 0-100 for each criterion\n - 90-100: Exceptional - Exceeds expectations with no significant issues\n - 70-89: Good - Meets expectations with minor issues\n - 50-69: Acceptable - Partially meets expectations, notable issues present\n - 30-49: Poor - Falls short of expectations, significant issues\n - 0-29: Failing - Does not meet minimum requirements\n\n2. **Reasoning**: Always provide specific, evidence-based reasoning\n - Quote or reference specific parts of the output\n - Explain both strengths and weaknesses\n - Be constructive and actionable in feedback\n\n3. **Objectivity**: Evaluate based solely on the criteria provided\n - Avoid personal preferences or unstated requirements\n - Consider the agent's intended purpose and context\n - Weight severity of issues proportionally\n\n## Response Format\n\nYou MUST respond with valid JSON only. No additional text or explanation outside the JSON structure.\n\n{\n \"verdicts\": [\n {\n \"criterionId\": \"criterion-id\",\n \"score\": 0-100,\n \"reasoning\": \"Detailed explanation with specific evidence from the output\",\n \"passed\": true/false\n }\n ]\n}`,\n\n renderUserPrompt: (ctx: JudgeContext): string => {\n const fileSection = buildFileSection(ctx.files);\n\n return `\n## Agent Under Evaluation\n${ctx.agentDescription}\n\n## Input Provided to Agent\n\\`\\`\\`json\n${JSON.stringify(ctx.input, null, 2)}\n\\`\\`\\`\n${fileSection}\n## Agent Output\n\\`\\`\\`json\n${JSON.stringify(ctx.output, null, 2)}\n\\`\\`\\`\n\n## Evaluation Criteria\n${ctx.criteria.map((c) => `- **${c.name}** (id: ${c.id}, weight: ${c.weight ?? 1}): ${c.description}`).join('\\n')}\n\nPlease evaluate the agent's output against each criterion listed above.`.trim();\n },\n};\n\nfunction buildFileSection(files: JudgeContext['files']): string {\n if (!files || files.length === 0) {\n return '';\n }\n\n return `\n## Reference Files\n${files.map((f) => `### ${f.path}\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``).join('\\n\\n')}\n`;\n}\n","import { writeFileSync } from 'node:fs'\nimport type { Reporter, FileReporterOptions, EvalReport } from './types'\nimport { calculateReportCosts, type CostSummary, type EvalPricingConfig } from './cost-helpers'\nimport { buildOutputPath } from './format-utils'\n\ninterface SerializedReport<TInput, TOutput> {\n summary: EvalReport<TInput, TOutput>['summary']\n results: EvalReport<TInput, TOutput>['results']\n suggestions: EvalReport<TInput, TOutput>['suggestions']\n generatedAt: string\n promptVersion: string\n costs?: CostSummary\n}\n\n/**\n * Reporter that saves EvalReport as JSON.\n *\n * @example\n * ```typescript\n * const reporter = new JsonReporter({ outputDir: './reports' })\n * reporter.save(report, 'my-test') // -> ./reports/my-test-1736691234567.json\n *\n * // Without timestamp\n * const fixedReporter = new JsonReporter({\n * outputDir: './reports',\n * addTimestamp: false,\n * })\n * fixedReporter.save(report, 'round-1') // -> ./reports/round-1.json\n * ```\n */\nexport class JsonReporter<TInput = unknown, TOutput = unknown>\n implements Reporter<TInput, TOutput>\n{\n private readonly outputDir: string\n private readonly pricing?: EvalPricingConfig\n private readonly addTimestamp: boolean\n\n constructor(options: FileReporterOptions) {\n this.outputDir = options.outputDir\n this.pricing = options.pricing\n this.addTimestamp = options.addTimestamp ?? true\n }\n\n save(report: EvalReport<TInput, TOutput>, name: string): string {\n const filepath = buildOutputPath(this.outputDir, name, 'json', this.addTimestamp)\n\n const costs = this.pricing\n ? calculateReportCosts(report, this.pricing)\n : undefined\n\n const output: SerializedReport<TInput, TOutput> = {\n summary: report.summary,\n results: report.results,\n suggestions: report.suggestions,\n generatedAt: report.generatedAt.toISOString(),\n promptVersion: report.promptVersion,\n ...(costs && { costs }),\n }\n\n writeFileSync(filepath, JSON.stringify(output, null, 2))\n return filepath\n }\n}\n","import type { EvalTokenUsage } from '@/core/types'\nimport {\n calculateCostFromUsage,\n type ProviderType,\n type ProviderPricing,\n} from '@agtlantis/core'\nimport type { LanguageModelUsage } from 'ai'\n\nfunction toLanguageModelUsage(usage: EvalTokenUsage): LanguageModelUsage {\n return {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n } as LanguageModelUsage\n}\n\n/** Cost breakdown by component (Agent, Judge, Improver) */\nexport interface CostBreakdown {\n agent?: number\n judge?: number\n improver?: number\n total?: number\n}\n\n/** Cost summary aggregated across all test results */\nexport interface CostSummary {\n total: number\n byComponent: {\n agent: number\n judge: number\n improver?: number\n }\n}\n\nexport interface MetricsWithCost {\n latencyMs: number\n tokenUsage: EvalTokenUsage\n costBreakdown: CostBreakdown\n}\n\n/** Test result with cost breakdown, returned by addCostsToResults() */\nexport interface TestResultWithCost<TInput, TOutput> {\n testCase: {\n id?: string\n input: TInput\n tags?: string[]\n description?: string\n expectedOutput?: unknown\n }\n output: TOutput\n metrics: MetricsWithCost\n error?: Error\n verdicts: Array<{\n criterionId: string\n score: number\n reasoning: string\n passed: boolean\n }>\n overallScore: number\n passed: boolean\n}\n\n/** Pricing configuration for eval */\nexport interface EvalPricingConfig {\n /** Provider-specific pricing overrides. Key is provider name (e.g., 'google', 'openai'), value is model pricing. */\n providerPricing?: Partial<Record<ProviderType, ProviderPricing>>\n}\n\n/** Maps eval's provider names to core's provider names (eval uses 'gemini', core uses 'google') */\nconst PROVIDER_MAPPING: Record<string, ProviderType> = {\n gemini: 'google',\n openai: 'openai',\n anthropic: 'anthropic',\n google: 'google',\n}\n\nfunction detectProvider(model: string | undefined): ProviderType {\n if (!model) return 'google' // default\n\n if (model.startsWith('gpt-') || model.startsWith('o1') || model.startsWith('o3')) {\n return 'openai'\n }\n if (model.startsWith('gemini-')) {\n return 'google'\n }\n if (model.startsWith('claude-')) {\n return 'anthropic'\n }\n\n return 'google'\n}\n\nfunction normalizeProvider(provider: string | undefined): ProviderType {\n if (!provider) return 'google'\n return PROVIDER_MAPPING[provider] ?? provider\n}\n\n/** Minimal result interface compatible with TestResultWithVerdict and TestResultWithIteration */\ninterface ResultForCostCalculation<TInput, TOutput> {\n testCase: {\n id?: string\n input: TInput\n tags?: string[]\n description?: string\n expectedOutput?: unknown\n }\n output: TOutput\n metrics: {\n latencyMs: number\n tokenUsage: EvalTokenUsage\n }\n error?: Error\n verdicts: Array<{\n criterionId: string\n score: number\n reasoning: string\n passed: boolean\n }>\n overallScore: number\n passed: boolean\n agentMetadata?: {\n tokenUsage?: EvalTokenUsage\n model?: string\n provider?: string\n }\n judgeMetadata?: {\n tokenUsage?: EvalTokenUsage\n model?: string\n provider?: string\n }\n}\n\ninterface ReportForCostCalculation<TInput, TOutput> {\n results: ResultForCostCalculation<TInput, TOutput>[]\n}\n\nfunction calculateComponentCost(\n tokenUsage: EvalTokenUsage | undefined,\n model: string | undefined,\n provider: string | undefined,\n config?: EvalPricingConfig\n): number | undefined {\n if (!tokenUsage) return undefined\n\n const normalizedProvider = provider\n ? normalizeProvider(provider)\n : detectProvider(model)\n\n // Get the pricing for this specific provider from the config\n const providerPricing = config?.providerPricing?.[normalizedProvider]\n\n const result = calculateCostFromUsage(\n toLanguageModelUsage(tokenUsage),\n model ?? 'unknown',\n normalizedProvider,\n providerPricing\n )\n\n return result.total\n}\n\nfunction buildCostBreakdown(costs: {\n agent?: number\n judge?: number\n improver?: number\n}): CostBreakdown {\n const total =\n (costs.agent ?? 0) + (costs.judge ?? 0) + (costs.improver ?? 0)\n\n return {\n ...costs,\n total: total > 0 ? total : undefined,\n }\n}\n\nexport function calculateResultCost<TInput, TOutput>(\n result: ResultForCostCalculation<TInput, TOutput>,\n config?: EvalPricingConfig\n): CostBreakdown {\n const agentCost = calculateComponentCost(\n result.metrics.tokenUsage,\n result.agentMetadata?.model,\n result.agentMetadata?.provider,\n config\n )\n\n const judgeCost = result.judgeMetadata?.tokenUsage\n ? calculateComponentCost(\n result.judgeMetadata.tokenUsage,\n result.judgeMetadata.model,\n result.judgeMetadata.provider,\n config\n )\n : undefined\n\n return buildCostBreakdown({\n agent: agentCost,\n judge: judgeCost,\n })\n}\n\nexport function calculateReportCosts<TInput, TOutput>(\n report: ReportForCostCalculation<TInput, TOutput>,\n config?: EvalPricingConfig\n): CostSummary {\n let totalAgent = 0\n let totalJudge = 0\n\n for (const result of report.results) {\n const breakdown = calculateResultCost(result, config)\n totalAgent += breakdown.agent ?? 0\n totalJudge += breakdown.judge ?? 0\n }\n\n return {\n total: totalAgent + totalJudge,\n byComponent: {\n agent: totalAgent,\n judge: totalJudge,\n },\n }\n}\n\n/** Add cost breakdown to each result. Returns new array (does not mutate original). */\nexport function addCostsToResults<TInput, TOutput>(\n results: ResultForCostCalculation<TInput, TOutput>[],\n config?: EvalPricingConfig\n): TestResultWithCost<TInput, TOutput>[] {\n return results.map((result) => {\n const costBreakdown = calculateResultCost(result, config)\n\n const metricsWithCost: MetricsWithCost = {\n latencyMs: result.metrics.latencyMs,\n tokenUsage: result.metrics.tokenUsage,\n costBreakdown,\n }\n\n return {\n testCase: result.testCase,\n output: result.output,\n metrics: metricsWithCost,\n error: result.error,\n verdicts: result.verdicts,\n overallScore: result.overallScore,\n passed: result.passed,\n }\n })\n}\n","import { mkdirSync } from 'node:fs'\nimport path from 'node:path'\n\n/**\n * Formats a score delta for display with consistent sign prefix.\n *\n * @example\n * formatScoreDelta(5.2) // \"+5.2\"\n * formatScoreDelta(-3.1) // \"-3.1\"\n * formatScoreDelta(0) // \"+0.0\"\n * formatScoreDelta(null) // \"-\"\n */\nexport function formatScoreDelta(delta: number | null): string {\n if (delta === null) {\n return '-'\n }\n const sign = delta >= 0 ? '+' : ''\n return `${sign}${delta.toFixed(1)}`\n}\n\n/**\n * Builds the output file path, creating the output directory if it doesn't exist.\n * Used by file-based reporters for consistent path handling.\n */\nexport function buildOutputPath(\n outputDir: string,\n name: string,\n extension: string,\n addTimestamp: boolean\n): string {\n mkdirSync(outputDir, { recursive: true })\n const filename = addTimestamp\n ? `${name}-${Date.now()}.${extension}`\n : `${name}.${extension}`\n return path.join(outputDir, filename)\n}\n\n/** Converts a Date to ISO string, handling both Date objects and already-serialized strings */\nexport function toISOStringIfDate(value: Date | string): string {\n return value instanceof Date ? value.toISOString() : value\n}\n","import { writeFileSync } from 'node:fs'\nimport type { Reporter, FileReporterOptions, EvalReport, ReportMarkdownOptions } from './types'\nimport { reportToMarkdown } from './markdown'\nimport { buildOutputPath } from './format-utils'\n\nexport interface MarkdownReporterOptions extends FileReporterOptions {\n /** Markdown generation options */\n markdown?: ReportMarkdownOptions\n}\n\n/**\n * Reporter that saves EvalReport as Markdown.\n *\n * @example\n * ```typescript\n * const reporter = new MarkdownReporter({ outputDir: './reports' })\n * reporter.save(report, 'my-test') // -> ./reports/my-test-1736691234567.md\n *\n * // With expanded passed tests\n * const detailedReporter = new MarkdownReporter({\n * outputDir: './reports',\n * markdown: { expandPassedTests: true },\n * })\n * ```\n */\nexport class MarkdownReporter<TInput = unknown, TOutput = unknown>\n implements Reporter<TInput, TOutput>\n{\n private readonly outputDir: string\n private readonly addTimestamp: boolean\n private readonly markdownOptions: ReportMarkdownOptions\n\n constructor(options: MarkdownReporterOptions) {\n this.outputDir = options.outputDir\n this.addTimestamp = options.addTimestamp ?? true\n this.markdownOptions = options.markdown ?? {}\n }\n\n save(report: EvalReport<TInput, TOutput>, name: string): string {\n const filepath = buildOutputPath(this.outputDir, name, 'md', this.addTimestamp)\n const markdown = reportToMarkdown(report, this.markdownOptions)\n writeFileSync(filepath, markdown)\n return filepath\n }\n}\n","import { writeFileSync, mkdirSync } from 'node:fs'\nimport path from 'node:path'\nimport type { ImprovementCycleResult } from '@/improvement-cycle/types'\nimport { toISOStringIfDate } from './format-utils'\n\n/**\n * Options for saving an ImprovementCycleResult as JSON.\n *\n * Supports two modes:\n * - **Auto mode**: Provide `outputDir` and `name` to create a timestamped subdirectory\n * - **Explicit mode**: Provide `directory` to use an existing directory directly\n */\nexport interface SaveCycleJsonOptions {\n /** Base output directory (creates {name}-{timestamp}/ subdirectory) */\n outputDir?: string\n /** Cycle name (used for folder name with timestamp) */\n name?: string\n /** Use this exact directory path (no timestamp suffix added) */\n directory?: string\n /** Whether to save individual round reports (default: true) */\n saveRounds?: boolean\n}\n\n/**\n * Saves an ImprovementCycleResult to JSON files.\n *\n * Creates a directory containing:\n * - `cycle-summary.json`: Structured cycle summary\n * - `round-{n}-report.json`: Individual round reports (if saveRounds=true)\n *\n * @example Auto mode (creates timestamped directory)\n * ```typescript\n * const dir = saveCycleJson(result, {\n * outputDir: './reports',\n * name: 'my-agent',\n * })\n * // -> ./reports/my-agent-1736691234567/\n * ```\n *\n * @example Explicit mode (uses existing directory)\n * ```typescript\n * const dir = saveCycleJson(result, {\n * directory: './reports/my-existing-dir',\n * })\n * // -> ./reports/my-existing-dir/\n * ```\n */\nexport function saveCycleJson<TInput, TOutput>(\n result: ImprovementCycleResult<TInput, TOutput>,\n options: SaveCycleJsonOptions,\n): string {\n const { outputDir, name, directory, saveRounds = true } = options\n\n const cycleDir = resolveCycleDirectory(outputDir, name, directory)\n mkdirSync(cycleDir, { recursive: true })\n\n saveCycleSummary(cycleDir, result)\n\n if (saveRounds) {\n saveRoundReports(cycleDir, result.rounds)\n }\n\n return cycleDir\n}\n\nfunction resolveCycleDirectory(\n outputDir: string | undefined,\n name: string | undefined,\n directory: string | undefined\n): string {\n if (directory) {\n return directory\n }\n if (outputDir && name) {\n return path.join(outputDir, `${name}-${Date.now()}`)\n }\n throw new Error('saveCycleJson requires either \"directory\" or both \"outputDir\" and \"name\"')\n}\n\nfunction saveCycleSummary<TInput, TOutput>(\n cycleDir: string,\n result: ImprovementCycleResult<TInput, TOutput>\n): void {\n const summaryPath = path.join(cycleDir, 'cycle-summary.json')\n const summary = {\n rounds: result.rounds.map((round) => ({\n round: round.round,\n completedAt: toISOStringIfDate(round.completedAt),\n score: round.report.summary.avgScore,\n scoreDelta: round.scoreDelta,\n cost: round.cost,\n suggestionsGenerated: round.suggestionsGenerated.length,\n suggestionsApproved: round.suggestionsApproved.length,\n promptVersionAfter: round.promptVersionAfter,\n })),\n terminationReason: result.terminationReason,\n totalCost: result.totalCost,\n roundCount: result.rounds.length,\n initialScore: result.rounds[0]?.report.summary.avgScore ?? null,\n finalScore: result.rounds[result.rounds.length - 1]?.report.summary.avgScore ?? null,\n }\n writeFileSync(summaryPath, JSON.stringify(summary, null, 2))\n}\n\nfunction saveRoundReports<TInput, TOutput>(\n cycleDir: string,\n rounds: ImprovementCycleResult<TInput, TOutput>['rounds']\n): void {\n for (const round of rounds) {\n const roundPath = path.join(cycleDir, `round-${round.round}-report.json`)\n const roundData = {\n round: round.round,\n completedAt: toISOStringIfDate(round.completedAt),\n report: {\n ...round.report,\n generatedAt: toISOStringIfDate(round.report.generatedAt),\n },\n suggestionsGenerated: round.suggestionsGenerated,\n suggestionsApproved: round.suggestionsApproved,\n promptSnapshot: round.promptSnapshot,\n cost: round.cost,\n scoreDelta: round.scoreDelta,\n }\n writeFileSync(roundPath, JSON.stringify(roundData, null, 2))\n }\n}\n","import { writeFileSync } from 'node:fs';\n\nimport type { ImprovementCycleResult } from '@/improvement-cycle/types';\n\nimport { formatScoreDelta } from './format-utils';\nimport { reportToMarkdown } from './markdown';\n\n/**\n * Options for generating cycle markdown.\n */\nexport interface CycleMarkdownOptions {\n /** Include full per-round details (default: true) */\n includeRoundDetails?: boolean;\n /** Show prompt evolution - initial vs final (default: false) */\n showPromptEvolution?: boolean;\n}\n\n/**\n * Converts an ImprovementCycleResult to markdown.\n *\n * Generates a comprehensive report including:\n * - Summary table (rounds, termination, cost, scores)\n * - Score progression table\n * - Per-round details (optional)\n * - Prompt evolution (optional)\n *\n * @param result - The improvement cycle result\n * @param options - Markdown generation options\n * @returns Markdown string\n *\n * @example\n * ```typescript\n * import { cycleToMarkdown } from '@agtlantis/eval'\n *\n * const result = await runImprovementCycleAuto(config)\n * const markdown = cycleToMarkdown(result, {\n * includeRoundDetails: true,\n * showPromptEvolution: true,\n * })\n * ```\n */\nexport function cycleToMarkdown<TInput, TOutput>(\n result: ImprovementCycleResult<TInput, TOutput>,\n options: CycleMarkdownOptions = {}\n): string {\n const { includeRoundDetails = true, showPromptEvolution = false } = options;\n const lines: string[] = [];\n\n // Header\n lines.push('# Improvement Cycle Report');\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Rounds | ${result.rounds.length} |`);\n lines.push(`| Termination | ${result.terminationReason} |`);\n lines.push(`| Total Cost | $${result.totalCost.toFixed(4)} |`);\n\n if (result.rounds.length > 0) {\n const first = result.rounds[0].report.summary.avgScore;\n const last = result.rounds[result.rounds.length - 1].report.summary.avgScore;\n lines.push(`| Initial Score | ${first.toFixed(1)} |`);\n lines.push(`| Final Score | ${last.toFixed(1)} |`);\n lines.push(`| Improvement | ${formatScoreDelta(last - first)} |`);\n }\n lines.push('');\n\n // Score progression table\n lines.push('## Score Progression');\n lines.push('');\n lines.push('| Round | Score | Delta | Cost |');\n lines.push('|-------|-------|-------|------|');\n for (const round of result.rounds) {\n const delta = formatScoreDelta(round.scoreDelta);\n lines.push(\n `| ${round.round} | ${round.report.summary.avgScore.toFixed(1)} | ${delta} | $${round.cost.total.toFixed(4)} |`\n );\n }\n lines.push('');\n\n // Per-round details\n if (includeRoundDetails) {\n lines.push('## Round Details');\n lines.push('');\n for (const round of result.rounds) {\n lines.push(`### Round ${round.round}`);\n lines.push('');\n lines.push(reportToMarkdown(round.report));\n lines.push('');\n }\n }\n\n // Prompt evolution\n if (showPromptEvolution && result.rounds.length > 0) {\n lines.push('## Prompt Evolution');\n lines.push('');\n lines.push('### Initial Prompt');\n lines.push('');\n lines.push('```');\n lines.push(result.rounds[0].promptSnapshot.userTemplate);\n lines.push('```');\n lines.push('');\n lines.push('### Final Prompt');\n lines.push('');\n lines.push('```');\n // Use the final prompt's userTemplate if available, otherwise try to call renderUserPrompt\n const finalPrompt = result.finalPrompt;\n if ('userTemplate' in finalPrompt && typeof finalPrompt.userTemplate === 'string') {\n lines.push(finalPrompt.userTemplate);\n } else {\n lines.push('[Compiled prompt - template not available]');\n }\n lines.push('```');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Saves an ImprovementCycleResult as markdown.\n *\n * @param result - The improvement cycle result\n * @param filePath - Path to save the markdown file\n * @param options - Markdown generation options\n *\n * @example\n * ```typescript\n * import { saveCycleMarkdown } from '@agtlantis/eval'\n *\n * const result = await runImprovementCycleAuto(config)\n * saveCycleMarkdown(result, './reports/cycle-report.md', {\n * includeRoundDetails: true,\n * })\n * ```\n */\nexport function saveCycleMarkdown<TInput, TOutput>(\n result: ImprovementCycleResult<TInput, TOutput>,\n filePath: string,\n options?: CycleMarkdownOptions\n): void {\n const markdown = cycleToMarkdown(result, options);\n writeFileSync(filePath, markdown);\n}\n","import { compileTemplate } from '@agtlantis/core';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors';\nimport type { AgentPrompt } from '@/core/types';\nimport { truncate } from '@/utils/json';\n\nimport type { Suggestion } from './types';\n\n/**\n * Generates a unified diff string for a suggestion.\n *\n * @example\n * ```typescript\n * const diff = suggestionDiff(suggestion)\n * console.log(diff)\n * // - Old value here\n * // + New value here\n * ```\n */\nexport function suggestionDiff(suggestion: Suggestion): string {\n const oldLines = suggestion.currentValue.split('\\n');\n const newLines = suggestion.suggestedValue.split('\\n');\n\n const lines: string[] = [];\n lines.push(`--- ${suggestion.type} (current)`);\n lines.push(`+++ ${suggestion.type} (suggested)`);\n lines.push('');\n\n for (const line of oldLines) {\n lines.push(`- ${line}`);\n }\n for (const line of newLines) {\n lines.push(`+ ${line}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generates a preview of what the suggestion would look like when applied.\n *\n * @example\n * ```typescript\n * const preview = suggestionPreview(suggestion)\n * console.log(preview)\n * ```\n */\nexport function suggestionPreview(suggestion: Suggestion): string {\n const lines: string[] = [];\n\n lines.push(`=== Suggestion Preview ===`);\n lines.push(`Type: ${suggestion.type}`);\n lines.push(`Priority: ${suggestion.priority}`);\n lines.push(``);\n lines.push(`Reasoning: ${suggestion.reasoning}`);\n lines.push(``);\n lines.push(`Expected Improvement: ${suggestion.expectedImprovement}`);\n lines.push(``);\n lines.push(`--- Current Value ---`);\n lines.push(suggestion.currentValue);\n lines.push(``);\n lines.push(`--- Suggested Value ---`);\n lines.push(suggestion.suggestedValue);\n\n return lines.join('\\n');\n}\n\n/**\n * Formats a suggestion as a compact summary string.\n *\n * @example\n * ```typescript\n * console.log(suggestionSummary(suggestion))\n * // [HIGH] system_prompt: Improve clarity in instructions\n * ```\n */\nexport function suggestionSummary(suggestion: Suggestion): string {\n const priorityTag = `[${suggestion.priority.toUpperCase()}]`;\n return `${priorityTag} ${suggestion.type}: ${truncate(suggestion.reasoning, 60)}`;\n}\n\n/**\n * Safely replaces the first occurrence of a search string with a replacement string.\n * Uses a function replacement to avoid special pattern interpretation ($&, $1, etc.)\n * that JavaScript's String.replace() performs.\n *\n * @internal\n */\nfunction safeReplace(str: string, search: string, replacement: string): string {\n return str.replace(search, () => replacement);\n}\n\n/**\n * Options for applying suggestions to a prompt.\n */\nexport interface ApplyPromptSuggestionsOptions {\n /**\n * Version bump type for semver.\n * - 'major': 1.0.0 → 2.0.0 (breaking changes)\n * - 'minor': 1.0.0 → 1.1.0 (new features)\n * - 'patch': 1.0.0 → 1.0.1 (bug fixes)\n */\n bumpVersion?: 'major' | 'minor' | 'patch';\n}\n\n/**\n * Result of applying suggestions to a prompt.\n */\nexport interface ApplySuggestionsResult<TInput, TOutput = unknown> {\n /** The updated prompt with suggestions applied */\n prompt: AgentPrompt<TInput>;\n /** Number of suggestions that were successfully applied */\n appliedCount: number;\n /** Suggestions that could not be applied (currentValue not found) */\n skipped: Array<{ suggestion: Suggestion; reason: string }>;\n}\n\n/**\n * Bumps a semver version string.\n *\n * @example\n * ```typescript\n * bumpVersion('1.0.0', 'major') // '2.0.0'\n * bumpVersion('1.0.0', 'minor') // '1.1.0'\n * bumpVersion('1.0.0', 'patch') // '1.0.1'\n * bumpVersion('1.2.3', 'minor') // '1.3.0'\n * ```\n */\nexport function bumpVersion(version: string, bump: 'major' | 'minor' | 'patch'): string {\n const parts = version.split('.').map((n) => parseInt(n, 10));\n\n // Handle invalid version formats\n if (parts.length !== 3 || parts.some(isNaN)) {\n throw new EvalError(\n `Invalid version format: \"${version}\". Expected semver format (x.y.z)`,\n {\n code: EvalErrorCode.SUGGESTION_APPLY_ERROR,\n context: { version, expectedFormat: 'x.y.z' },\n }\n );\n }\n\n const [major, minor, patch] = parts;\n\n switch (bump) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n }\n}\n\n/**\n * Applies approved suggestions to an AgentPrompt and returns a new prompt.\n *\n * This function:\n * - Only applies suggestions where `approved === true`\n * - For `system_prompt`: replaces `currentValue` in `prompt.system`\n * - For `user_prompt`: requires `prompt.userTemplate` field, updates it and regenerates `renderUserPrompt`\n * - For `parameters`: applies to custom fields in the prompt\n * - Optionally bumps the version (major/minor/patch)\n *\n * **Important behaviors:**\n * - Only the **first occurrence** of `currentValue` is replaced (not all occurrences)\n * - Special characters like `$&`, `$1` in `suggestedValue` are preserved as-is (no regex interpretation)\n *\n * @example\n * ```typescript\n * // Apply approved suggestions with minor version bump\n * const result = applyPromptSuggestions(\n * currentPrompt,\n * suggestions.filter(s => s.approved),\n * { bumpVersion: 'minor' }\n * )\n *\n * console.log(result.prompt.version) // '1.1.0'\n * console.log(`Applied ${result.appliedCount} suggestions`)\n *\n * if (result.skipped.length > 0) {\n * console.warn('Skipped suggestions:', result.skipped)\n * }\n * ```\n *\n * @throws {EvalError} with code SUGGESTION_APPLY_ERROR if:\n * - A `user_prompt` suggestion is applied but prompt lacks `userTemplate` field\n * - Version format is invalid when bumpVersion is specified\n */\nexport function applyPromptSuggestions<TInput, TOutput = unknown>(\n currentPrompt: AgentPrompt<TInput>,\n suggestions: Suggestion[],\n options?: ApplyPromptSuggestionsOptions\n): ApplySuggestionsResult<TInput, TOutput> {\n const approvedSuggestions = suggestions.filter((s) => s.approved);\n\n if (approvedSuggestions.length === 0) {\n return {\n prompt: currentPrompt,\n appliedCount: 0,\n skipped: [],\n };\n }\n\n let newPrompt: AgentPrompt<TInput> = { ...currentPrompt };\n let appliedCount = 0;\n const skipped: Array<{ suggestion: Suggestion; reason: string }> = [];\n\n for (const suggestion of approvedSuggestions) {\n const applyResult = applySingleSuggestion(newPrompt, suggestion);\n\n if (applyResult.success) {\n newPrompt = applyResult.prompt;\n appliedCount++;\n } else {\n skipped.push({ suggestion, reason: applyResult.reason });\n }\n }\n\n if (options?.bumpVersion && appliedCount > 0) {\n newPrompt = {\n ...newPrompt,\n version: bumpVersion(currentPrompt.version, options.bumpVersion),\n };\n }\n\n return {\n prompt: newPrompt,\n appliedCount,\n skipped,\n };\n}\n\n/** Fields that are part of the core AgentPrompt interface and should not be modified by 'parameters' suggestions */\nconst AGENT_PROMPT_CORE_FIELDS = [\n 'id',\n 'version',\n 'system',\n 'renderUserPrompt',\n 'userTemplate',\n] as const;\n\nfunction applySingleSuggestion<TInput, TOutput>(\n prompt: AgentPrompt<TInput>,\n suggestion: Suggestion\n): { success: true; prompt: AgentPrompt<TInput> } | { success: false; reason: string } {\n switch (suggestion.type) {\n case 'system_prompt': {\n if (!prompt.system.includes(suggestion.currentValue)) {\n return {\n success: false,\n reason: `currentValue not found in system prompt: \"${truncate(suggestion.currentValue, 50)}\"`,\n };\n }\n return {\n success: true,\n prompt: {\n ...prompt,\n system: safeReplace(\n prompt.system,\n suggestion.currentValue,\n suggestion.suggestedValue\n ),\n },\n };\n }\n\n case 'user_prompt': {\n const userTemplate = prompt.userTemplate as string | undefined;\n\n if (typeof userTemplate !== 'string') {\n throw new EvalError(\n `Cannot apply user_prompt suggestion: prompt does not have a userTemplate field. ` +\n `The renderUserPrompt is a function and cannot be modified directly.`,\n {\n code: EvalErrorCode.SUGGESTION_APPLY_ERROR,\n context: {\n suggestionType: suggestion.type,\n hasUserTemplate: 'userTemplate' in prompt,\n },\n }\n );\n }\n\n if (!userTemplate.includes(suggestion.currentValue)) {\n return {\n success: false,\n reason: `currentValue not found in userTemplate: \"${truncate(suggestion.currentValue, 50)}\"`,\n };\n }\n\n const newTemplate = safeReplace(\n userTemplate,\n suggestion.currentValue,\n suggestion.suggestedValue\n );\n\n return {\n success: true,\n prompt: {\n ...prompt,\n userTemplate: newTemplate,\n renderUserPrompt: compileTemplate<TInput>(newTemplate, prompt.id),\n },\n };\n }\n\n case 'parameters': {\n const updatedPrompt = { ...prompt };\n let found = false;\n\n for (const [key, value] of Object.entries(updatedPrompt)) {\n if (\n AGENT_PROMPT_CORE_FIELDS.includes(\n key as (typeof AGENT_PROMPT_CORE_FIELDS)[number]\n )\n ) {\n continue;\n }\n\n if (typeof value === 'string' && value.includes(suggestion.currentValue)) {\n (updatedPrompt as Record<string, unknown>)[key] = safeReplace(\n value,\n suggestion.currentValue,\n suggestion.suggestedValue\n );\n found = true;\n break;\n }\n }\n\n if (!found) {\n return {\n success: false,\n reason: `currentValue not found in any parameter field: \"${truncate(suggestion.currentValue, 50)}\"`,\n };\n }\n\n return {\n success: true,\n prompt: updatedPrompt,\n };\n }\n\n default: {\n const _exhaustive: never = suggestion.type;\n return {\n success: false,\n reason: `Unknown suggestion type: ${suggestion.type}`,\n };\n }\n }\n}\n","import { type LanguageModelUsage, type ModelMessage, Output } from 'ai';\nimport { z } from 'zod';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors';\nimport type { AgentPrompt, EvalTestResult, EvalTokenUsage, ImproverMetadata } from '@/core/types';\n\nimport { defaultImproverPrompt } from './prompts/default';\nimport type {\n AggregatedMetrics,\n ImproveResult,\n Improver,\n ImproverConfig,\n ImproverContext,\n Suggestion,\n} from './types';\n\nfunction toEvalTokenUsage(usage: LanguageModelUsage): EvalTokenUsage {\n return {\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n totalTokens: usage.totalTokens ?? 0,\n };\n}\n\nconst ImproverResponseSchema = z.object({\n suggestions: z.array(\n z.object({\n type: z.enum(['system_prompt', 'user_prompt', 'parameters']),\n priority: z.enum(['high', 'medium', 'low']),\n currentValue: z.string(),\n suggestedValue: z.string(),\n reasoning: z.string(),\n expectedImprovement: z.string(),\n })\n ),\n});\n\ntype ImproverResponse = z.infer<typeof ImproverResponseSchema>;\n\nfunction aggregateMetrics(results: EvalTestResult<unknown, unknown>[]): AggregatedMetrics {\n if (results.length === 0) {\n return {\n avgLatencyMs: 0,\n totalTokens: 0,\n };\n }\n\n let totalLatency = 0;\n let totalTokens = 0;\n\n for (const result of results) {\n totalLatency += result.metrics.latencyMs;\n totalTokens += result.metrics.tokenUsage.totalTokens;\n }\n\n return {\n avgLatencyMs: Math.round(totalLatency / results.length),\n totalTokens,\n };\n}\n\n/**\n * Creates an LLM-based prompt improver.\n *\n * Analyzes test results and suggests improvements to the agent's prompt,\n * focusing on low-scoring criteria with actionable suggestions.\n *\n * @example\n * ```typescript\n * import { createImprover, defaultImproverPrompt } from '@agtlantis/eval'\n * import { createGoogleProvider } from '@agtlantis/core'\n *\n * const provider = createGoogleProvider({ apiKey }).withDefaultModel('gemini-2.5-flash')\n *\n * const improver = createImprover({\n * provider,\n * prompt: defaultImproverPrompt,\n * })\n *\n * const { suggestions } = await improver.improve(agent.prompt, evaluatedResults)\n *\n * for (const suggestion of suggestions) {\n * console.log(suggestionDiff(suggestion))\n * suggestion.approved = true\n * }\n *\n * const newPrompt = applyPromptSuggestions(agent.prompt, suggestions)\n * ```\n */\nexport function createImprover(config: ImproverConfig): Improver {\n const { provider, prompt = defaultImproverPrompt, model } = config;\n\n return {\n async improve(\n agentPrompt: AgentPrompt<any>,\n results: EvalTestResult<any, any>[]\n ): Promise<ImproveResult> {\n const context: ImproverContext = {\n agentPrompt,\n evaluatedResults: results,\n aggregatedMetrics: aggregateMetrics(results),\n };\n\n const messages: ModelMessage[] = [\n { role: 'system', content: prompt.system },\n { role: 'user', content: prompt.renderUserPrompt(context) },\n ];\n\n let response: ImproverResponse;\n let llmUsage: LanguageModelUsage | undefined;\n\n try {\n const execution = provider.simpleExecution(async (session) => {\n const result = await session.generateText({\n messages,\n output: Output.object({ schema: ImproverResponseSchema }),\n });\n return result.output!;\n });\n\n const executionResult = await execution.result();\n\n if (executionResult.status !== 'succeeded') {\n throw executionResult.status === 'failed'\n ? executionResult.error\n : new Error('Execution was canceled');\n }\n\n response = executionResult.value;\n llmUsage = executionResult.summary.totalLLMUsage;\n } catch (cause) {\n throw EvalError.from(cause, EvalErrorCode.LLM_API_ERROR, {\n promptId: prompt.id,\n promptVersion: prompt.version,\n });\n }\n\n const suggestions: Suggestion[] = response.suggestions.map((s) => ({\n ...s,\n approved: undefined,\n modified: undefined,\n }));\n\n const metadata: ImproverMetadata | undefined = llmUsage\n ? { tokenUsage: toEvalTokenUsage(llmUsage), model }\n : undefined;\n\n return { suggestions, metadata };\n },\n };\n}\n","import { truncate } from '@/utils/json';\n\nimport type { ImproverContext, ImproverPrompt } from '../types';\n\nexport const defaultImproverPrompt: ImproverPrompt = {\n id: 'default-improver',\n version: '2.0.0',\n\n system: `You are an expert prompt engineer specializing in optimizing AI Agent prompts.\n\nYour role is to analyze test results and evaluation feedback to propose targeted improvements.\n\n## Improvement Principles\n\n1. **Focus on Impact**: Prioritize changes that address the lowest-scoring criteria\n - Target specific failure patterns, not general improvements\n - One well-crafted change is better than many superficial ones\n\n2. **Be Specific and Actionable**: Provide concrete changes, not vague suggestions\n - Show exact text to add, modify, or remove\n - Explain the mechanism by which the change will help\n\n3. **Consider Trade-offs**: Evaluate side effects of each change\n - Will this fix break other test cases?\n - Does it increase prompt length/cost significantly?\n - Could it introduce new failure modes?\n\n4. **Maintain Prompt Quality**: Preserve clarity and structure\n - Keep prompts readable and maintainable\n - Avoid over-engineering or excessive constraints\n - Ensure changes align with the agent's core purpose\n\n## Suggestion Priority Levels\n- **high**: Critical issues causing test failures, should be addressed immediately\n- **medium**: Issues affecting quality scores, recommended for next iteration\n- **low**: Minor optimizations, nice-to-have improvements\n\n## Response Format\n\nYou MUST respond with valid JSON only. No additional text outside the JSON structure.\n\n{\n \"suggestions\": [\n {\n \"type\": \"system_prompt\" | \"user_prompt\" | \"parameters\",\n \"priority\": \"high\" | \"medium\" | \"low\",\n \"currentValue\": \"The specific text or value being changed\",\n \"suggestedValue\": \"The proposed replacement text or value\",\n \"reasoning\": \"Why this change addresses the identified issue\",\n \"expectedImprovement\": \"Predicted impact on scores and behavior\"\n }\n ]\n}`,\n\n renderUserPrompt: (ctx: ImproverContext): string => {\n const failedDetails = buildFailedCaseDetails(ctx.evaluatedResults);\n\n return `\n## Current Agent Prompt\n\n### System Prompt\n\\`\\`\\`\n${ctx.agentPrompt.system}\n\\`\\`\\`\n\n## Test Results Summary\n- Total tests: ${ctx.evaluatedResults.length}\n- Passed: ${ctx.evaluatedResults.filter((r) => r.passed).length}\n- Failed: ${ctx.evaluatedResults.filter((r) => !r.passed).length}\n\n## Performance Metrics\n- Average latency: ${ctx.aggregatedMetrics.avgLatencyMs}ms\n- Total tokens used: ${ctx.aggregatedMetrics.totalTokens}\n\n## Failed/Low-Score Cases Details\n${failedDetails}\n\nBased on the above results, please propose specific prompt improvements.`.trim();\n },\n};\n\nfunction buildFailedCaseDetails(results: ImproverContext['evaluatedResults']): string {\n const failedOrLowScore = results.filter((r) => !r.passed || r.overallScore < 70);\n\n if (failedOrLowScore.length === 0) {\n return '(None - all tests passed with acceptable scores)';\n }\n\n return failedOrLowScore\n .map(\n (r) => `\n### ${r.testCase.id ?? 'unnamed'} (Score: ${r.overallScore})\n**Input:** ${truncate(JSON.stringify(r.testCase.input), 200)}\n**Output:** ${truncate(JSON.stringify(r.output), 200)}\n**Evaluation:**\n${r.verdicts.map((v) => `- ${v.criterionId}: ${v.score}/100 - ${v.reasoning}`).join('\\n')}`\n )\n .join('\\n');\n}\n","import type { AgentPrompt, EvalAgent, TestCase } from '@/core/types';\nimport type { Improver, Suggestion } from '@/improver/types';\nimport type { Judge } from '@/judge/types';\nimport type { EvalPricingConfig } from '@/reporter/cost-helpers';\nimport type { EvalReport } from '@/reporter/types';\n\nimport type { ImprovementSession } from './history';\n\n/** Terminate when average score reaches threshold */\nexport interface TargetScoreCondition {\n type: 'targetScore';\n /** Score threshold (0-100) */\n threshold: number;\n}\n\n/** Terminate after N rounds */\nexport interface MaxRoundsCondition {\n type: 'maxRounds';\n /** Maximum number of improvement rounds */\n count: number;\n}\n\n/** Terminate when score doesn't improve for N consecutive rounds */\nexport interface NoImprovementCondition {\n type: 'noImprovement';\n /** Number of consecutive rounds without improvement */\n consecutiveRounds: number;\n /** Minimum score delta to count as improvement (default: 0) */\n minDelta?: number;\n}\n\n/** Terminate when total cost exceeds budget */\nexport interface MaxCostCondition {\n type: 'maxCost';\n /** Maximum cost in USD */\n maxUSD: number;\n}\n\n/** Custom condition with user-defined check function */\nexport interface CustomCycleCondition {\n type: 'custom';\n /** Function to check if termination condition is met */\n check: (ctx: CycleContext) => boolean | Promise<boolean>;\n /** Human-readable description (for debugging/logging) */\n description?: string;\n}\n\n/** Discriminated union of termination conditions. Uses OR semantics - first match triggers. */\nexport type CycleTerminationCondition =\n | TargetScoreCondition\n | MaxRoundsCondition\n | NoImprovementCondition\n | MaxCostCondition\n | CustomCycleCondition;\n\n/** Context available to termination condition checks */\nexport interface CycleContext {\n /** Current round number (1-indexed) */\n currentRound: number;\n /** Average score from the latest round */\n latestScore: number;\n /** Score history from all previous rounds */\n previousScores: number[];\n /** Total accumulated cost in USD */\n totalCost: number;\n /** Full history of completed rounds */\n history: RoundResult[];\n}\n\n/** Result when cycle should continue (no termination) */\nexport interface CycleContinueResult {\n terminated: false;\n reason: string;\n /** Not present when not terminated (for type safety with discriminated union) */\n matchedCondition?: never;\n}\n\n/** Result when cycle should terminate */\nexport interface CycleTerminatedResult {\n terminated: true;\n matchedCondition: CycleTerminationCondition;\n reason: string;\n}\n\nexport type CycleTerminationResult = CycleContinueResult | CycleTerminatedResult;\n\n/**\n * Data yielded after each improvement round for Human-in-the-Loop (HITL) control.\n * The AsyncGenerator yields this after each round, allowing inspection and decision.\n */\nexport interface RoundYield {\n /** Result of the completed round */\n roundResult: RoundResult;\n /** Current cycle context */\n context: CycleContext;\n /** Suggestions awaiting approval */\n pendingSuggestions: Suggestion[];\n /** Termination check result (use isCycleTerminated() to check if terminated) */\n terminationCheck: CycleTerminationResult;\n}\n\n/** Decision from the caller after reviewing a round */\nexport interface RoundDecision {\n /** Action to take */\n action: 'continue' | 'stop' | 'rollback';\n /** Target round for rollback (required if action is 'rollback') */\n rollbackToRound?: number;\n /** Suggestions approved by user (optional override) */\n approvedSuggestions?: Suggestion[];\n}\n\n/** Cost breakdown for a single round */\nexport interface RoundCost {\n /** Agent LLM cost in USD */\n agent: number;\n /** Judge LLM cost in USD */\n judge: number;\n /** Improver LLM cost in USD */\n improver: number;\n /** Total cost in USD */\n total: number;\n}\n\n/** Result of a single improvement round */\nexport interface RoundResult {\n /** Round number (1-indexed) */\n round: number;\n /** When this round completed */\n completedAt: Date;\n /** Full evaluation report */\n report: EvalReport<unknown, unknown>;\n /** All suggestions generated by improver */\n suggestionsGenerated: Suggestion[];\n /** Suggestions that were approved/applied */\n suggestionsApproved: Suggestion[];\n /** Prompt snapshot at start of this round (for rollback) */\n promptSnapshot: SerializedPrompt;\n /** Prompt version after applying suggestions */\n promptVersionAfter: string;\n /** Cost breakdown for this round */\n cost: RoundCost;\n /** Score change from previous round (null for first round) */\n scoreDelta: number | null;\n}\n\n/**\n * Serialized prompt for JSON storage.\n * Note: renderUserPrompt cannot be serialized; use compileTemplate(userTemplate) to reconstruct.\n */\nexport interface SerializedPrompt {\n /** Prompt unique ID */\n id: string;\n /** Version string (e.g., \"1.0.0\") */\n version: string;\n /** System prompt */\n system: string;\n /** User prompt template (Mustache format) */\n userTemplate: string;\n /** Additional custom fields from AgentPrompt */\n customFields?: Record<string, unknown>;\n}\n\n/** Serialized round result for JSON storage */\nexport interface SerializedRoundResult {\n /** Round number (1-indexed) */\n round: number;\n /** Completion timestamp (ISO 8601) */\n completedAt: string;\n /** Average score from this round */\n avgScore: number;\n /** Number of passed tests */\n passed: number;\n /** Number of failed tests */\n failed: number;\n /** Total number of tests */\n totalTests: number;\n /** All suggestions generated */\n suggestionsGenerated: Suggestion[];\n /** Suggestions that were approved/applied */\n suggestionsApproved: Suggestion[];\n /** Prompt snapshot at start of this round */\n promptSnapshot: SerializedPrompt;\n /** Prompt version after applying suggestions */\n promptVersionAfter: string;\n /** Cost breakdown */\n cost: RoundCost;\n /** Score change from previous round */\n scoreDelta: number | null;\n}\n\n/**\n * Improvement cycle history (JSON file schema v1.1.0).\n * Includes promptSnapshot per round for rollback support.\n */\nexport interface ImprovementHistory {\n /** Schema version for migration compatibility */\n schemaVersion: '1.1.0';\n /** Unique session identifier */\n sessionId: string;\n /** Session start timestamp (ISO 8601) */\n startedAt: string;\n /** Session completion timestamp (ISO 8601, if completed) */\n completedAt?: string;\n /** Initial prompt before any improvements */\n initialPrompt: SerializedPrompt;\n /** Current/latest prompt */\n currentPrompt: SerializedPrompt;\n /** All completed rounds */\n rounds: SerializedRoundResult[];\n /** Reason for termination (if completed) */\n terminationReason?: string;\n /** Total accumulated cost in USD */\n totalCost: number;\n}\n\n/** History persistence configuration */\nexport interface HistoryConfig {\n /** Path to save history JSON */\n path: string;\n /** Auto-save after each round (default: true) */\n autoSave?: boolean;\n}\n\n/** Configuration for running an improvement cycle */\nexport interface ImprovementCycleConfig<TInput, TOutput> {\n /** Factory function to create agent with given prompt */\n createAgent: (prompt: AgentPrompt<TInput>) => EvalAgent<TInput, TOutput>;\n /** Starting prompt for improvements */\n initialPrompt: AgentPrompt<TInput>;\n /** Test cases to evaluate against */\n testCases: TestCase<TInput>[];\n /** Judge for evaluation */\n judge: Judge;\n /** Improver for generating suggestions */\n improver: Improver;\n /** Termination conditions (OR semantics) */\n terminateWhen: CycleTerminationCondition[];\n /** Optional configuration */\n options?: ImprovementCycleOptions;\n}\n\n/** Optional configuration for improvement cycle */\nexport interface ImprovementCycleOptions {\n /** Options passed to eval suite run */\n runOptions?: { concurrency?: number; iterations?: number };\n /** How to bump version on each improvement */\n versionBump?: 'major' | 'minor' | 'patch';\n /** Pricing configuration for cost calculation */\n pricingConfig?: EvalPricingConfig;\n /** History persistence settings */\n history?: HistoryConfig;\n /** Description for agent (passed to judge) */\n agentDescription?: string;\n /** Existing session to resume (preserves session ID and accumulated state) */\n session?: ImprovementSession;\n}\n\n/** Final result of an improvement cycle */\nexport interface ImprovementCycleResult<TInput, TOutput> {\n /** Final improved prompt */\n finalPrompt: AgentPrompt<TInput>;\n /** All completed rounds */\n rounds: RoundResult[];\n /** Reason for termination */\n terminationReason: string;\n /** Total cost in USD */\n totalCost: number;\n /** Saved history (if persistence was enabled) */\n history?: ImprovementHistory;\n}\n\nexport function isTargetScoreCondition(\n condition: CycleTerminationCondition\n): condition is TargetScoreCondition {\n return condition.type === 'targetScore';\n}\n\nexport function isMaxRoundsCondition(\n condition: CycleTerminationCondition\n): condition is MaxRoundsCondition {\n return condition.type === 'maxRounds';\n}\n\nexport function isNoImprovementCondition(\n condition: CycleTerminationCondition\n): condition is NoImprovementCondition {\n return condition.type === 'noImprovement';\n}\n\nexport function isMaxCostCondition(\n condition: CycleTerminationCondition\n): condition is MaxCostCondition {\n return condition.type === 'maxCost';\n}\n\nexport function isCustomCycleCondition(\n condition: CycleTerminationCondition\n): condition is CustomCycleCondition {\n return condition.type === 'custom';\n}\n\nexport function isCycleTerminated(result: CycleTerminationResult): result is CycleTerminatedResult {\n return result.terminated === true;\n}\n","import type {\n CycleContext,\n CycleTerminationCondition,\n CycleTerminationResult,\n TargetScoreCondition,\n MaxRoundsCondition,\n NoImprovementCondition,\n MaxCostCondition,\n CustomCycleCondition,\n} from './types'\nimport {\n isTargetScoreCondition,\n isMaxRoundsCondition,\n isNoImprovementCondition,\n isMaxCostCondition,\n isCustomCycleCondition,\n} from './types'\nimport { EvalError, EvalErrorCode } from '@/core/errors'\nimport {\n createAndCheck,\n createOrCheck,\n createNotCheck,\n formatCompositeDescription,\n} from '../utils/condition-composites'\n\n/** Terminates when the average score reaches or exceeds threshold. */\nexport function targetScore(threshold: number): TargetScoreCondition {\n if (!Number.isFinite(threshold)) {\n throw new EvalError('threshold must be a finite number', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { threshold },\n })\n }\n if (threshold < 0 || threshold > 100) {\n throw new EvalError('threshold must be between 0 and 100', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { threshold },\n })\n }\n return { type: 'targetScore', threshold }\n}\n\n/** Terminates after completing the specified number of rounds. */\nexport function maxRounds(count: number): MaxRoundsCondition {\n if (!Number.isInteger(count) || count < 1) {\n throw new EvalError('count must be a positive integer', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { count },\n })\n }\n return { type: 'maxRounds', count }\n}\n\n/** Terminates when score hasn't improved for N consecutive rounds. */\nexport function noImprovement(\n consecutiveRounds: number,\n minDelta?: number\n): NoImprovementCondition {\n if (!Number.isInteger(consecutiveRounds) || consecutiveRounds < 1) {\n throw new EvalError('consecutiveRounds must be a positive integer', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { consecutiveRounds },\n })\n }\n if (minDelta !== undefined && (!Number.isFinite(minDelta) || minDelta < 0)) {\n throw new EvalError('minDelta must be a non-negative finite number', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { minDelta },\n })\n }\n return {\n type: 'noImprovement',\n consecutiveRounds,\n ...(minDelta !== undefined && { minDelta }),\n }\n}\n\n/** Terminates when total accumulated cost reaches or exceeds the budget. */\nexport function maxCost(maxUSD: number): MaxCostCondition {\n if (!Number.isFinite(maxUSD) || maxUSD <= 0) {\n throw new EvalError('maxUSD must be a positive finite number', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { maxUSD },\n })\n }\n return { type: 'maxCost', maxUSD }\n}\n\n/** Custom termination condition with arbitrary logic. Supports async checks. */\nexport function customCondition(\n check: (ctx: CycleContext) => boolean | Promise<boolean>,\n description?: string\n): CustomCycleCondition {\n return {\n type: 'custom',\n check,\n ...(description !== undefined && { description }),\n }\n}\n\n/** All conditions must be met for termination. Short-circuits on first false. */\nexport function and(\n ...conditions: CycleTerminationCondition[]\n): CustomCycleCondition {\n if (conditions.length === 0) {\n return {\n type: 'custom',\n check: () => false,\n description: formatCompositeDescription('and', []),\n }\n }\n\n return {\n type: 'custom',\n check: createAndCheck(conditions, checkCycleCondition),\n description: formatCompositeDescription('and', conditions),\n }\n}\n\n/** Any condition being met causes termination. Short-circuits on first true. */\nexport function or(\n ...conditions: CycleTerminationCondition[]\n): CustomCycleCondition {\n if (conditions.length === 0) {\n return {\n type: 'custom',\n check: () => false,\n description: formatCompositeDescription('or', []),\n }\n }\n\n return {\n type: 'custom',\n check: createOrCheck(conditions, checkCycleCondition),\n description: formatCompositeDescription('or', conditions),\n }\n}\n\n/** Invert a condition's result. Terminates when inner condition does NOT terminate. */\nexport function not(\n condition: CycleTerminationCondition\n): CustomCycleCondition {\n return {\n type: 'custom',\n check: createNotCheck(condition, checkCycleCondition),\n description: `not(${condition.type})`,\n }\n}\n\nfunction checkTargetScore(\n condition: TargetScoreCondition,\n ctx: CycleContext\n): CycleTerminationResult {\n if (ctx.latestScore >= condition.threshold) {\n return {\n terminated: true,\n matchedCondition: condition,\n reason: `Target score ${condition.threshold} reached (current: ${ctx.latestScore})`,\n }\n }\n return {\n terminated: false,\n reason: `Score ${ctx.latestScore} below target ${condition.threshold}`,\n }\n}\n\nfunction checkMaxRounds(\n condition: MaxRoundsCondition,\n ctx: CycleContext\n): CycleTerminationResult {\n if (ctx.currentRound >= condition.count) {\n return {\n terminated: true,\n matchedCondition: condition,\n reason: `Maximum rounds reached (${condition.count})`,\n }\n }\n return {\n terminated: false,\n reason: `Round ${ctx.currentRound} of ${condition.count}`,\n }\n}\n\n/**\n * Counts consecutive rounds without improvement from most recent to oldest.\n * Breaks on null delta (first round) or on improvement (scoreDelta > minDelta).\n */\nfunction checkNoImprovement(\n condition: NoImprovementCondition,\n ctx: CycleContext\n): CycleTerminationResult {\n const { consecutiveRounds, minDelta = 0 } = condition\n const { history } = ctx\n\n let noImprovementCount = 0\n\n for (let i = history.length - 1; i >= 0; i--) {\n const round = history[i]\n\n if (round.scoreDelta === null) break\n if (round.scoreDelta <= minDelta) {\n noImprovementCount++\n } else {\n break\n }\n }\n\n if (noImprovementCount >= consecutiveRounds) {\n return {\n terminated: true,\n matchedCondition: condition,\n reason: `No improvement for ${noImprovementCount} consecutive round${noImprovementCount === 1 ? '' : 's'}`,\n }\n }\n\n const roundWord = noImprovementCount === 1 ? 'round' : 'rounds'\n return {\n terminated: false,\n reason: `${noImprovementCount} ${roundWord} without improvement (need ${consecutiveRounds})`,\n }\n}\n\nfunction checkMaxCost(\n condition: MaxCostCondition,\n ctx: CycleContext\n): CycleTerminationResult {\n if (ctx.totalCost >= condition.maxUSD) {\n return {\n terminated: true,\n matchedCondition: condition,\n reason: `Cost limit exceeded ($${ctx.totalCost.toFixed(2)} >= $${condition.maxUSD.toFixed(2)})`,\n }\n }\n return {\n terminated: false,\n reason: `Cost $${ctx.totalCost.toFixed(2)} under limit $${condition.maxUSD.toFixed(2)}`,\n }\n}\n\nasync function checkCustomCondition(\n condition: CustomCycleCondition,\n ctx: CycleContext\n): Promise<CycleTerminationResult> {\n const description = condition.description ?? 'Custom condition'\n\n try {\n const shouldTerminate = await condition.check(ctx)\n\n if (shouldTerminate) {\n return {\n terminated: true,\n matchedCondition: condition,\n reason: `${description} met`,\n }\n }\n return {\n terminated: false,\n reason: `${description} not met`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n terminated: false,\n reason: `${description} check failed: ${message}`,\n }\n }\n}\n\n/** Dispatches to the appropriate check function based on condition type. */\nexport async function checkCycleCondition(\n condition: CycleTerminationCondition,\n context: CycleContext\n): Promise<CycleTerminationResult> {\n if (isTargetScoreCondition(condition)) {\n return checkTargetScore(condition, context)\n }\n if (isMaxRoundsCondition(condition)) {\n return checkMaxRounds(condition, context)\n }\n if (isNoImprovementCondition(condition)) {\n return checkNoImprovement(condition, context)\n }\n if (isMaxCostCondition(condition)) {\n return checkMaxCost(condition, context)\n }\n if (isCustomCycleCondition(condition)) {\n return checkCustomCondition(condition, context)\n }\n\n // Exhaustive check - TypeScript will error if we miss a case\n const _exhaustive: never = condition\n throw new EvalError(`Unknown condition type: ${JSON.stringify(_exhaustive)}`, {\n code: EvalErrorCode.UNKNOWN_ERROR,\n context: { condition: _exhaustive },\n })\n}\n\n/** Check all conditions with OR semantics - first match wins. */\nexport async function checkCycleTermination(\n conditions: CycleTerminationCondition[],\n context: CycleContext\n): Promise<CycleTerminationResult> {\n if (conditions.length === 0) {\n return {\n terminated: false,\n reason: 'No termination conditions specified',\n }\n }\n\n for (const condition of conditions) {\n const result = await checkCycleCondition(condition, context)\n if (result.terminated) {\n return result // First match wins (OR semantics)\n }\n }\n\n return {\n terminated: false,\n reason: 'No termination conditions met',\n }\n}\n","import type { LanguageModelUsage } from 'ai'\nimport { calculateCostFromUsage } from '@agtlantis/core'\nimport { createEvalSuite } from '@/core/suite'\nimport { applyPromptSuggestions } from '@/improver/utils'\nimport { calculateReportCosts, type EvalPricingConfig } from '@/reporter/cost-helpers'\nimport type { EvalAgent, AgentPrompt, EvalTokenUsage } from '@/core/types'\nimport type { EvalReport } from '@/reporter/types'\nimport type { Suggestion, ImproveResult } from '@/improver/types'\n\nimport { createSession, serializePrompt, deserializePrompt } from './history'\nimport type { ImprovementSession, SessionConfig } from './history'\nimport { checkCycleTermination } from './conditions'\nimport type {\n ImprovementCycleConfig,\n ImprovementCycleResult,\n RoundYield,\n RoundDecision,\n RoundResult,\n RoundCost,\n CycleContext,\n SerializedPrompt,\n} from './types'\n\ninterface CycleState<TInput, TOutput> {\n currentPrompt: AgentPrompt<TInput>\n currentRound: number\n previousScores: number[]\n totalCost: number\n completedRounds: RoundResult[]\n}\n\n/** Initialize cycle state, resuming from existing session if provided. */\nfunction initializeCycleState<TInput, TOutput>(\n initialPrompt: AgentPrompt<TInput>,\n existingSession: ImprovementSession | undefined\n): CycleState<TInput, TOutput> {\n const resumeFromRound = existingSession ? existingSession.history.rounds.length : 0\n return {\n currentPrompt: initialPrompt,\n currentRound: resumeFromRound,\n previousScores: existingSession\n ? existingSession.history.rounds.map((r) => r.avgScore)\n : [],\n totalCost: existingSession ? existingSession.history.totalCost : 0,\n completedRounds: [],\n }\n}\n\n/** Returns null for the first round (no previous score to compare). */\nfunction calculateScoreDelta(currentScore: number, previousScores: number[]): number | null {\n if (previousScores.length === 0) {\n return null\n }\n const previousScore = previousScores[previousScores.length - 1]\n return currentScore - previousScore\n}\n\nfunction buildCycleContext<TInput, TOutput>(\n state: CycleState<TInput, TOutput>,\n currentScore: number\n): CycleContext {\n return {\n currentRound: state.currentRound,\n latestScore: currentScore,\n previousScores: [...state.previousScores],\n totalCost: state.totalCost,\n history: state.completedRounds,\n }\n}\n\nfunction createRoundResult<TInput, TOutput>(\n state: CycleState<TInput, TOutput>,\n report: EvalReport<TInput, TOutput>,\n improveResult: ImproveResult,\n cost: RoundCost,\n scoreDelta: number | null,\n promptSnapshot: SerializedPrompt\n): RoundResult {\n return {\n round: state.currentRound,\n report: report as EvalReport<unknown, unknown>,\n completedAt: new Date(),\n suggestionsGenerated: improveResult.suggestions,\n suggestionsApproved: [], // Will be updated after decision\n promptSnapshot,\n promptVersionAfter: state.currentPrompt.version,\n cost,\n scoreDelta,\n }\n}\n\nasync function handleStopDecision<TInput, TOutput>(\n state: CycleState<TInput, TOutput>,\n session: ImprovementSession,\n roundResult: RoundResult,\n promptSnapshot: SerializedPrompt,\n terminatedByCondition: boolean,\n conditionReason: string | undefined\n): Promise<ImprovementCycleResult<TInput, TOutput>> {\n const reason = terminatedByCondition ? conditionReason! : 'User requested stop'\n\n session.addRound(roundResult, promptSnapshot)\n session.complete(reason)\n await session.flush()\n state.completedRounds.push(roundResult)\n\n return {\n rounds: state.completedRounds,\n finalPrompt: deserializePrompt(session.history.currentPrompt),\n terminationReason: reason,\n totalCost: state.totalCost,\n history: session.history,\n }\n}\n\n/** Throws if target round is invalid. */\nfunction handleRollbackDecision<TInput, TOutput>(\n state: CycleState<TInput, TOutput>,\n rollbackToRound: number\n): void {\n const targetRoundIndex = rollbackToRound - 1\n if (targetRoundIndex < 0 || targetRoundIndex >= state.completedRounds.length) {\n throw new Error(`Cannot rollback to round ${rollbackToRound}: round not found`)\n }\n\n const targetRound = state.completedRounds[targetRoundIndex]\n state.currentPrompt = deserializePrompt(targetRound.promptSnapshot)\n state.previousScores = state.previousScores.slice(0, rollbackToRound - 1)\n}\n\nfunction handleContinueDecision<TInput, TOutput>(\n state: CycleState<TInput, TOutput>,\n session: ImprovementSession,\n roundResult: RoundResult,\n approvedSuggestions: Suggestion[],\n versionBump: 'major' | 'minor' | 'patch'\n): RoundResult {\n const updatedRoundResult: RoundResult = {\n ...roundResult,\n suggestionsApproved: approvedSuggestions,\n }\n\n if (approvedSuggestions.length > 0) {\n const applyResult = applyPromptSuggestions(state.currentPrompt, approvedSuggestions, {\n bumpVersion: versionBump,\n })\n state.currentPrompt = applyResult.prompt\n updatedRoundResult.promptVersionAfter = state.currentPrompt.version\n }\n\n const updatedPromptSnapshot = serializePrompt(state.currentPrompt)\n session.addRound(updatedRoundResult, updatedPromptSnapshot)\n state.completedRounds.push(updatedRoundResult)\n\n return updatedRoundResult\n}\n\ninterface RoundExecutionResult<TInput, TOutput> {\n report: EvalReport<TInput, TOutput>\n improveResult: ImproveResult\n cost: RoundCost\n}\n\nasync function executeRound<TInput, TOutput>(\n config: ImprovementCycleConfig<TInput, TOutput>,\n state: CycleState<TInput, TOutput>,\n pricingConfig: EvalPricingConfig | undefined\n): Promise<RoundExecutionResult<TInput, TOutput>> {\n const { createAgent, judge, improver, testCases, options = {} } = config\n const agent = createAgent(state.currentPrompt)\n\n // Improver is called separately (not via suite) to capture full ImproveResult\n // with metadata, enabling accurate cost calculation via tokenUsage\n const suite = createEvalSuite({\n agent,\n judge,\n agentDescription: options.agentDescription,\n })\n const report = await suite.run(testCases, options.runOptions)\n\n const improveResult: ImproveResult = improver\n ? await improver.improve(state.currentPrompt, report.results)\n : { suggestions: [] }\n\n const cost = calculateRoundCost(report, improveResult, pricingConfig)\n\n return { report, improveResult, cost }\n}\n\nfunction detectProviderForImprover(model: string | undefined): string {\n if (!model) return 'anthropic' // improver typically uses Claude\n\n if (model.startsWith('claude-')) return 'anthropic'\n if (model.startsWith('gpt-') || model.startsWith('o1') || model.startsWith('o3')) return 'openai'\n if (model.startsWith('gemini-')) return 'google'\n\n return 'anthropic'\n}\n\nfunction toLanguageModelUsage(usage: EvalTokenUsage): LanguageModelUsage {\n return {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n } as LanguageModelUsage\n}\n\nfunction calculateImproverCost(\n improveResult: ImproveResult,\n pricingConfig?: EvalPricingConfig\n): number {\n const usage = improveResult.metadata?.tokenUsage as EvalTokenUsage | undefined\n if (!usage) return 0\n\n const model = improveResult.metadata?.model ?? 'unknown'\n const provider = detectProviderForImprover(model)\n\n // Get the pricing for this specific provider\n const providerPricing = pricingConfig?.providerPricing?.[provider]\n\n const result = calculateCostFromUsage(\n toLanguageModelUsage(usage),\n model,\n provider,\n providerPricing\n )\n\n return result.total\n}\n\nfunction calculateRoundCost(\n report: EvalReport<unknown, unknown>,\n improveResult: ImproveResult,\n pricingConfig?: EvalPricingConfig\n): RoundCost {\n const reportCosts = pricingConfig\n ? calculateReportCosts(report, pricingConfig)\n : { total: 0, byComponent: { agent: 0, judge: 0 } }\n\n const improverCost = calculateImproverCost(improveResult, pricingConfig)\n\n return {\n agent: reportCosts.byComponent.agent ?? 0,\n judge: reportCosts.byComponent.judge ?? 0,\n improver: improverCost,\n total: reportCosts.total + improverCost,\n }\n}\n\n/**\n * Run an improvement cycle as an AsyncGenerator for Human-in-the-Loop control.\n * Yields after each round for decision-making (continue, stop, or rollback).\n */\nexport async function* runImprovementCycle<TInput, TOutput>(\n config: ImprovementCycleConfig<TInput, TOutput>\n): AsyncGenerator<RoundYield, ImprovementCycleResult<TInput, TOutput>, RoundDecision | undefined> {\n const { initialPrompt, terminateWhen = [], options = {} } = config\n const { pricingConfig, versionBump = 'patch', history: historyConfig, session: existingSession } = options\n\n const session: ImprovementSession = existingSession ?? createSession(\n initialPrompt,\n historyConfig ? { path: historyConfig.path, autoSave: historyConfig.autoSave } : undefined\n )\n const state = initializeCycleState(initialPrompt, existingSession)\n\n try {\n while (true) {\n state.currentRound++\n\n const { report, improveResult, cost } = await executeRound(config, state, pricingConfig)\n state.totalCost += cost.total\n\n const currentScore = report.summary.avgScore\n const scoreDelta = calculateScoreDelta(currentScore, state.previousScores)\n const promptSnapshot = serializePrompt(state.currentPrompt)\n const roundResult = createRoundResult(state, report, improveResult, cost, scoreDelta, promptSnapshot)\n const context = buildCycleContext(state, currentScore)\n\n state.previousScores.push(currentScore)\n\n const terminationCheck = await checkCycleTermination(terminateWhen, context)\n const pendingSuggestions: Suggestion[] = improveResult.suggestions.map((s) => ({\n ...s,\n approved: false,\n }))\n\n const roundYield: RoundYield = {\n roundResult,\n pendingSuggestions,\n terminationCheck,\n context,\n }\n\n const decision: RoundDecision | undefined = yield roundYield\n\n if (!decision || decision.action === 'stop') {\n return await handleStopDecision(\n state,\n session,\n roundResult,\n promptSnapshot,\n terminationCheck.terminated,\n terminationCheck.reason\n )\n }\n\n if (decision.action === 'rollback' && decision.rollbackToRound !== undefined) {\n handleRollbackDecision(state, decision.rollbackToRound)\n continue\n }\n\n handleContinueDecision(\n state,\n session,\n roundResult,\n decision.approvedSuggestions ?? [],\n versionBump\n )\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n session.complete(`Error: ${errorMessage}`)\n throw error\n }\n}\n\n/**\n * Run improvement cycle with automatic approval of all suggestions.\n * Continues until a termination condition is met.\n */\nexport async function runImprovementCycleAuto<TInput, TOutput>(\n config: ImprovementCycleConfig<TInput, TOutput>\n): Promise<ImprovementCycleResult<TInput, TOutput>> {\n const cycle = runImprovementCycle(config)\n\n let iteratorResult = await cycle.next()\n\n while (!iteratorResult.done) {\n const roundYield = iteratorResult.value\n let decision: RoundDecision\n\n if (roundYield.terminationCheck.terminated) {\n decision = { action: 'stop' }\n } else {\n const approvedSuggestions = roundYield.pendingSuggestions.map((s) => ({\n ...s,\n approved: true,\n }))\n decision = { action: 'continue', approvedSuggestions }\n }\n\n iteratorResult = await cycle.next(decision)\n }\n\n return iteratorResult.value\n}\n","import crypto from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport { compileTemplate } from '@agtlantis/core';\n\nimport { EvalError, EvalErrorCode } from '@/core/errors';\nimport type { AgentPrompt } from '@/core/types';\n\nimport type {\n ImprovementHistory,\n RoundResult,\n SerializedPrompt,\n SerializedRoundResult,\n} from './types';\n\n/** Storage abstraction for testability - allows injecting mock storage */\nexport interface HistoryStorage {\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n exists: (path: string) => boolean;\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<string | undefined | void>;\n}\n\nexport const defaultHistoryStorage: HistoryStorage = {\n readFile: (path) => readFile(path, 'utf-8'),\n writeFile: (path, content) => writeFile(path, content, 'utf-8'),\n exists: existsSync,\n mkdir: (path, options) => mkdir(path, options),\n};\n\nexport interface ImprovementSession {\n readonly sessionId: string;\n readonly history: Readonly<ImprovementHistory>;\n readonly canSave: boolean;\n addRound(roundResult: RoundResult, updatedPrompt: SerializedPrompt): void;\n complete(terminationReason: string): void;\n save(): Promise<void>;\n flush(): Promise<void>;\n}\n\nexport interface SessionConfig {\n path?: string;\n autoSave?: boolean;\n storage?: HistoryStorage;\n onAutoSaveError?: (error: Error) => void;\n}\n\nexport function hasUserTemplate(\n prompt: AgentPrompt<unknown>\n): prompt is AgentPrompt<unknown> & { userTemplate: string } {\n return typeof (prompt as { userTemplate?: unknown }).userTemplate === 'string';\n}\n\n/** @throws EvalError with PROMPT_INVALID_FORMAT if userTemplate is missing */\nexport function serializePrompt<TInput>(prompt: AgentPrompt<TInput>): SerializedPrompt {\n const p = prompt as AgentPrompt<unknown>;\n if (!hasUserTemplate(p)) {\n throw new EvalError('Cannot serialize prompt: userTemplate field is required', {\n code: EvalErrorCode.PROMPT_INVALID_FORMAT,\n context: { promptId: p.id },\n });\n }\n\n const { id, version, system, userTemplate, renderUserPrompt, ...rest } =\n p as AgentPrompt<unknown> & {\n userTemplate: string;\n };\n const customFields =\n Object.keys(rest).length > 0 ? (rest as Record<string, unknown>) : undefined;\n\n return {\n id,\n version,\n system,\n userTemplate,\n ...(customFields && { customFields }),\n };\n}\n\nfunction validateDeserializedPrompt(\n obj: Record<string, unknown>,\n promptId: string\n): asserts obj is Record<string, unknown> & {\n id: string;\n version: string;\n system: string;\n userTemplate: string;\n renderUserPrompt: (input: unknown) => string;\n} {\n const requiredStrings = ['id', 'version', 'system', 'userTemplate'] as const;\n for (const field of requiredStrings) {\n if (typeof obj[field] !== 'string') {\n throw new EvalError(`Invalid deserialized prompt: ${field} must be a string`, {\n code: EvalErrorCode.PROMPT_INVALID_FORMAT,\n context: { promptId, field, actual: typeof obj[field] },\n });\n }\n }\n\n if (typeof obj.renderUserPrompt !== 'function') {\n throw new EvalError('Invalid deserialized prompt: renderUserPrompt must be a function', {\n code: EvalErrorCode.PROMPT_INVALID_FORMAT,\n context: { promptId, actual: typeof obj.renderUserPrompt },\n });\n }\n}\n\n/** Reconstructs renderUserPrompt using compileTemplate. */\nexport function deserializePrompt<TInput>(serialized: SerializedPrompt): AgentPrompt<TInput> {\n const { id, version, system, userTemplate, customFields } = serialized;\n\n let renderUserPrompt: (input: TInput) => string;\n try {\n renderUserPrompt = compileTemplate<TInput>(userTemplate, id);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new EvalError(`Failed to compile userTemplate: ${message}`, {\n code: EvalErrorCode.TEMPLATE_COMPILE_ERROR,\n context: { promptId: id, userTemplate },\n });\n }\n\n // Spread customFields first, then core fields to prevent override attacks\n const result = {\n ...customFields,\n id,\n version,\n system,\n userTemplate,\n renderUserPrompt,\n };\n\n validateDeserializedPrompt(result, id);\n return result as AgentPrompt<TInput>;\n}\n\nfunction serializeRoundResult(result: RoundResult): SerializedRoundResult {\n const { summary } = result.report;\n\n return {\n round: result.round,\n completedAt: result.completedAt.toISOString(),\n avgScore: summary.avgScore,\n passed: summary.passed,\n failed: summary.failed,\n totalTests: summary.totalTests,\n suggestionsGenerated: result.suggestionsGenerated,\n suggestionsApproved: result.suggestionsApproved,\n promptSnapshot: result.promptSnapshot,\n promptVersionAfter: result.promptVersionAfter,\n cost: result.cost,\n scoreDelta: result.scoreDelta,\n };\n}\n\nfunction validateHistorySchema(data: unknown): asserts data is ImprovementHistory {\n if (typeof data !== 'object' || data === null) {\n throw new EvalError('Invalid history: not an object', {\n code: EvalErrorCode.SCHEMA_VALIDATION_ERROR,\n });\n }\n\n const h = data as Record<string, unknown>;\n\n if (h.schemaVersion !== '1.1.0') {\n throw new EvalError(`Unsupported schema version: ${String(h.schemaVersion)}`, {\n code: EvalErrorCode.SCHEMA_VALIDATION_ERROR,\n context: { schemaVersion: h.schemaVersion },\n });\n }\n\n const requiredFields = [\n 'sessionId',\n 'startedAt',\n 'initialPrompt',\n 'currentPrompt',\n 'rounds',\n 'totalCost',\n ];\n for (const field of requiredFields) {\n if (!(field in h)) {\n throw new EvalError(`Invalid history: missing field \"${field}\"`, {\n code: EvalErrorCode.SCHEMA_VALIDATION_ERROR,\n context: { missingField: field },\n });\n }\n }\n}\n\nclass ImprovementSessionImpl implements ImprovementSession {\n private _history: ImprovementHistory;\n private _isUpdating = false;\n private _savePromise: Promise<void> = Promise.resolve();\n private readonly config: Required<Pick<SessionConfig, 'autoSave'>> & SessionConfig;\n\n constructor(history: ImprovementHistory, config: SessionConfig = {}) {\n this._history = history;\n this.config = {\n autoSave: config.autoSave ?? false,\n ...config,\n };\n }\n\n get sessionId(): string {\n return this._history.sessionId;\n }\n\n get history(): Readonly<ImprovementHistory> {\n return this._history;\n }\n\n get canSave(): boolean {\n return this.config.path !== undefined;\n }\n\n addRound(roundResult: RoundResult, updatedPrompt: SerializedPrompt): void {\n if (this._isUpdating) {\n throw new EvalError('Session is being updated', {\n code: EvalErrorCode.CONCURRENT_MODIFICATION,\n context: { sessionId: this.sessionId },\n });\n }\n\n if (this._history.completedAt) {\n throw new EvalError('Cannot add round to completed session', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { sessionId: this.sessionId },\n });\n }\n\n this._isUpdating = true;\n try {\n const serializedRound = serializeRoundResult(roundResult);\n\n this._history = {\n ...this._history,\n currentPrompt: updatedPrompt,\n rounds: [...this._history.rounds, serializedRound],\n totalCost: this._history.totalCost + roundResult.cost.total,\n };\n\n if (this.config.autoSave && this.canSave) {\n this.save().catch((err) => this.handleAutoSaveError(err));\n }\n } finally {\n this._isUpdating = false;\n }\n }\n\n complete(terminationReason: string): void {\n this._history = {\n ...this._history,\n completedAt: new Date().toISOString(),\n terminationReason,\n };\n\n if (this.config.autoSave && this.canSave) {\n this.save().catch((err) => this.handleAutoSaveError(err));\n }\n }\n\n private handleAutoSaveError(error: unknown): void {\n const err = error instanceof Error ? error : new Error(String(error));\n if (this.config.onAutoSaveError) {\n this.config.onAutoSaveError(err);\n } else {\n console.error('Auto-save failed:', err);\n }\n }\n\n async save(): Promise<void> {\n if (!this.config.path) {\n throw new EvalError('Cannot save: no path configured', {\n code: EvalErrorCode.INVALID_CONFIG,\n context: { sessionId: this.sessionId },\n });\n }\n\n // Serialize saves to prevent race conditions from back-to-back autoSave triggers\n this._savePromise = this._savePromise.then(async () => {\n await saveHistory(this._history, this.config.path!, this.config.storage);\n });\n return this._savePromise;\n }\n\n async flush(): Promise<void> {\n return this._savePromise;\n }\n}\n\n/** @throws EvalError with PROMPT_INVALID_FORMAT if prompt lacks userTemplate */\nexport function createSession<TInput>(\n initialPrompt: AgentPrompt<TInput>,\n config?: SessionConfig\n): ImprovementSession {\n const serializedPrompt = serializePrompt(initialPrompt);\n\n const history: ImprovementHistory = {\n schemaVersion: '1.1.0',\n sessionId: crypto.randomUUID(),\n startedAt: new Date().toISOString(),\n initialPrompt: serializedPrompt,\n currentPrompt: serializedPrompt,\n rounds: [],\n totalCost: 0,\n };\n\n return new ImprovementSessionImpl(history, config);\n}\n\n/** Resume from a history file. Clears completion status to allow adding new rounds. */\nexport async function resumeSession(\n path: string,\n config?: Omit<SessionConfig, 'path'>\n): Promise<ImprovementSession> {\n const history = await loadHistory(path, config?.storage);\n\n const reopenedHistory: ImprovementHistory = {\n ...history,\n completedAt: undefined,\n terminationReason: undefined,\n };\n\n return new ImprovementSessionImpl(reopenedHistory, { ...config, path });\n}\n\n/** Save history to JSON file. Creates parent directories if needed. */\nexport async function saveHistory(\n history: ImprovementHistory,\n path: string,\n storage: HistoryStorage = defaultHistoryStorage\n): Promise<void> {\n try {\n const dir = dirname(path);\n if (dir && dir !== '.' && dir !== '/' && !storage.exists(dir)) {\n await storage.mkdir(dir, { recursive: true });\n }\n await storage.writeFile(path, JSON.stringify(history, null, 2));\n } catch (error) {\n if (error instanceof EvalError) throw error;\n throw EvalError.from(error, EvalErrorCode.FILE_WRITE_ERROR, { path });\n }\n}\n\nexport async function loadHistory(\n path: string,\n storage: HistoryStorage = defaultHistoryStorage\n): Promise<ImprovementHistory> {\n try {\n if (!storage.exists(path)) {\n throw new EvalError(`History file not found: ${path}`, {\n code: EvalErrorCode.FILE_READ_ERROR,\n context: { path },\n });\n }\n\n const content = await storage.readFile(path);\n const history = JSON.parse(content) as unknown;\n validateHistorySchema(history);\n\n return history;\n } catch (error) {\n if (error instanceof EvalError) throw error;\n throw EvalError.from(error, EvalErrorCode.FILE_READ_ERROR, { path });\n }\n}\n","import { loadConfigWithDefaults, ConfigError, discoverEvalFiles } from '../config/index.js'\nimport {\n loadYamlEvalFiles,\n convertToTestCases,\n type YamlConversionContext,\n type DiscoveredEvalFile,\n} from '../yaml/index.js'\nimport { loadEnvFile } from '../utils/env.js'\nimport { initializeProviders, type Providers } from '../utils/provider-factory.js'\nimport { printSummary, printError, printProgress, printBanner } from '../output/console.js'\nimport { generateReport } from '../output/report.js'\nimport type { RunCommandOptions } from '../index.js'\nimport type {\n EvalConfig,\n CLITestCase,\n CLISingleTurnTestCase,\n CLIMultiTurnTestCase,\n} from '../config/types.js'\nimport type { EvalReport } from '@/reporter/types'\nimport {\n createEvalSuite,\n createJudge,\n createImprover,\n executeMultiTurnTestCase,\n type EvalTestResult,\n type MultiTurnTestCase,\n type Suggestion,\n} from '../../index.js'\nimport type { Provider } from '@agtlantis/core'\nimport { isMultiTurnConfig } from '../config/types.js'\n\nexport async function runCommand(\n configPath: string | undefined,\n options: RunCommandOptions\n): Promise<void> {\n const startTime = Date.now()\n\n try {\n printBanner()\n\n printProgress('Loading environment...')\n await loadEnvFile(options.envFile)\n\n printProgress('Loading configuration...')\n const config = await loadConfigWithDefaults(configPath)\n\n printProgress('Initializing providers...')\n const { mainProvider, judgeProvider, improverProvider } = initializeProviders(config, options)\n\n const judge = createJudge({\n provider: judgeProvider,\n prompt: config.judge.prompt,\n criteria: config.judge.criteria,\n passThreshold: config.judge.passThreshold,\n })\n\n const improver = config.improver\n ? createImprover({\n provider: improverProvider,\n prompt: config.improver.prompt,\n })\n : undefined\n\n const concurrency = options.concurrency\n ? parseInt(options.concurrency, 10)\n : config.run?.concurrency ?? 1\n const iterations = options.iterations\n ? parseInt(options.iterations, 10)\n : config.run?.iterations ?? 1\n const verbose = options.verbose ?? config.output?.verbose ?? false\n\n const allReports: EvalReport<unknown, unknown>[] = []\n\n const includePatterns = options.include ?? config.include\n\n if (includePatterns && includePatterns.length > 0) {\n const yamlReports = await runYamlTests({\n config,\n options,\n includePatterns,\n mainProvider,\n judge,\n improver,\n concurrency,\n iterations,\n })\n allReports.push(...yamlReports)\n }\n\n if (config.testCases && config.testCases.length > 0) {\n const inlineReports = await runInlineTests({\n config,\n options,\n judge,\n improver,\n concurrency,\n iterations,\n })\n allReports.push(...inlineReports)\n }\n\n const report = mergeReports(allReports, resolvePromptVersion(config))\n\n if (report.summary.totalTests === 0) {\n printError(\n new Error(\n 'No test cases to run after filtering.\\n' +\n (options.tags ? ` Tags filter: ${options.tags.join(', ')}\\n` : '') +\n (options.agent ? ` Agent filter: ${options.agent}\\n` : '')\n )\n )\n process.exit(1)\n }\n\n const duration = Date.now() - startTime\n printSummary(report, { verbose, duration })\n\n if (options.report !== false) {\n const outputPath = await generateReport(report, {\n dir: config.output?.dir,\n filename: options.output ?? config.output?.filename,\n })\n console.log(`\\nReport saved to: ${outputPath}`)\n }\n\n const hasFailures = report.summary.failed > 0\n process.exit(hasFailures ? 1 : 0)\n } catch (error) {\n printError(error instanceof Error ? error : new Error(String(error)))\n process.exit(1)\n }\n}\n\ninterface YamlTestsParams {\n config: EvalConfig\n options: RunCommandOptions\n includePatterns: string[]\n mainProvider: Provider\n judge: ReturnType<typeof createJudge>\n improver: ReturnType<typeof createImprover> | undefined\n concurrency: number\n iterations: number\n}\n\nasync function runYamlTests(params: YamlTestsParams): Promise<EvalReport<unknown, unknown>[]> {\n const { config, options, includePatterns, mainProvider, judge, improver, concurrency, iterations } =\n params\n const reports: EvalReport<unknown, unknown>[] = []\n\n printProgress('Discovering YAML eval files...')\n const filePaths = await discoverEvalFiles(config, { include: includePatterns })\n\n if (filePaths.length === 0) {\n printProgress('No YAML files found matching patterns')\n return reports\n }\n\n printProgress(`Discovered ${filePaths.length} YAML file(s)`)\n const yamlFiles = await loadYamlEvalFiles(filePaths)\n\n const filteredFiles = options.agent\n ? yamlFiles.filter((f) => f.content.agent === options.agent)\n : yamlFiles\n\n if (options.agent && filteredFiles.length === 0) {\n const availableAgents = [...new Set(yamlFiles.map((f) => f.content.agent))]\n throw new ConfigError(\n `No YAML files found for agent \"${options.agent}\".\\n` +\n `Available agents: ${availableAgents.join(', ')}`,\n 'CONFIG_VALIDATION_ERROR'\n )\n }\n\n const yamlByAgent = groupYamlByAgent(filteredFiles)\n\n for (const [agentName, agentFiles] of yamlByAgent) {\n printProgress(`Running tests for agent: ${agentName}`)\n\n const agent = lookupAgent(config, agentName)\n\n // buildInput uses default { message: response } format\n // Future: Could be customized per-agent in config.agents registry\n const yamlContext: YamlConversionContext<unknown, unknown> = {\n provider: mainProvider,\n buildInput: (response, _ctx) => ({ message: response }),\n }\n\n const yamlTestCases: CLITestCase<unknown, unknown>[] = []\n for (const file of agentFiles) {\n const cases = convertToTestCases(file.content, yamlContext)\n yamlTestCases.push(...(cases as CLITestCase<unknown, unknown>[]))\n }\n\n const filteredCases = filterByTags(yamlTestCases, options.tags)\n\n if (filteredCases.length === 0) {\n printProgress(` No matching tests after tag filter for ${agentName}`)\n continue\n }\n\n const { singleTurnCases, multiTurnCases } = splitTestCases(filteredCases)\n\n const suite = createEvalSuite({\n agent,\n judge,\n improver,\n agentDescription: resolveAgentDescription(config, agent),\n })\n\n if (singleTurnCases.length > 0) {\n printProgress(` Running ${singleTurnCases.length} single-turn test(s)...`)\n const report = await suite.run(singleTurnCases, {\n concurrency,\n iterations,\n stopOnFirstFailure: config.run?.stopOnFirstFailure,\n })\n reports.push(report)\n }\n\n if (multiTurnCases.length > 0) {\n printProgress(` Running ${multiTurnCases.length} multi-turn test(s)...`)\n const multiTurnResults = await runMultiTurnCases(multiTurnCases, {\n agent,\n judge,\n agentDescription: resolveAgentDescription(config, agent),\n })\n\n const multiTurnReport = createMultiTurnReport(multiTurnResults, { ...config, agent })\n reports.push(multiTurnReport)\n }\n }\n\n return reports\n}\n\ninterface InlineTestsParams {\n config: EvalConfig\n options: RunCommandOptions\n judge: ReturnType<typeof createJudge>\n improver: ReturnType<typeof createImprover> | undefined\n concurrency: number\n iterations: number\n}\n\nasync function runInlineTests(params: InlineTestsParams): Promise<EvalReport<unknown, unknown>[]> {\n const { config, options, judge, improver, concurrency, iterations } = params\n const reports: EvalReport<unknown, unknown>[] = []\n\n const filteredInline = filterByTags(config.testCases!, options.tags)\n\n if (filteredInline.length === 0) {\n return reports\n }\n\n const { singleTurnCases, multiTurnCases } = splitTestCases(filteredInline)\n\n if (singleTurnCases.length > 0) {\n printProgress(`Running ${singleTurnCases.length} inline single-turn test(s)...`)\n\n const suite = createEvalSuite({\n agent: config.agent,\n judge,\n improver,\n agentDescription: resolveAgentDescription(config, config.agent),\n })\n\n const report = await suite.run(singleTurnCases, {\n concurrency,\n iterations,\n stopOnFirstFailure: config.run?.stopOnFirstFailure,\n })\n reports.push(report)\n }\n\n if (multiTurnCases.length > 0) {\n printProgress(`Running ${multiTurnCases.length} inline multi-turn test(s)...`)\n\n const multiTurnResults = await runMultiTurnCases(multiTurnCases, {\n agent: config.agent,\n judge,\n agentDescription: resolveAgentDescription(config, config.agent),\n })\n\n const multiTurnReport = createMultiTurnReport(multiTurnResults, config)\n reports.push(multiTurnReport)\n }\n\n return reports\n}\n\ninterface MultiTurnExecutionContext {\n agent: import('../../index.js').EvalAgent<unknown, unknown>\n judge: ReturnType<typeof createJudge>\n agentDescription: string\n}\n\nasync function runMultiTurnCases(\n testCases: CLIMultiTurnTestCase<unknown, unknown>[],\n context: MultiTurnExecutionContext\n): Promise<EvalTestResult<unknown, unknown>[]> {\n const results: EvalTestResult<unknown, unknown>[] = []\n\n for (const testCase of testCases) {\n const result = await executeMultiTurnTestCase(\n testCase as MultiTurnTestCase<unknown, unknown>,\n context\n )\n results.push(result as EvalTestResult<unknown, unknown>)\n }\n\n return results\n}\n\nfunction createMultiTurnReport(\n results: EvalTestResult<unknown, unknown>[],\n config: EvalConfig\n): EvalReport<unknown, unknown> {\n const totalTests = results.length\n const passed = results.filter((r) => r.passed).length\n const failed = totalTests - passed\n const avgScore =\n totalTests > 0 ? results.reduce((sum, r) => sum + r.overallScore, 0) / totalTests : 0\n const totalLatency = results.reduce((sum, r) => sum + r.metrics.latencyMs, 0)\n const totalTokens = results.reduce((sum, r) => sum + r.metrics.tokenUsage.totalTokens, 0)\n\n return {\n summary: {\n totalTests,\n passed,\n failed,\n avgScore,\n metrics: {\n avgLatencyMs: totalTests > 0 ? totalLatency / totalTests : 0,\n totalTokens,\n totalEstimatedCost: 0,\n },\n },\n results,\n suggestions: [],\n generatedAt: new Date(),\n promptVersion: resolvePromptVersion(config),\n }\n}\n\nfunction groupYamlByAgent(\n files: DiscoveredEvalFile[]\n): Map<string, DiscoveredEvalFile[]> {\n const groups = new Map<string, DiscoveredEvalFile[]>()\n\n for (const file of files) {\n const agentName = file.content.agent\n if (!groups.has(agentName)) {\n groups.set(agentName, [])\n }\n groups.get(agentName)!.push(file)\n }\n\n return groups\n}\n\nfunction lookupAgent(\n config: EvalConfig,\n agentName: string\n): import('../../index.js').EvalAgent<unknown, unknown> {\n if (!config.agents || !(agentName in config.agents)) {\n const available = config.agents ? Object.keys(config.agents) : []\n throw new ConfigError(\n `Agent \"${agentName}\" not found in config.agents registry.\\n` +\n `Available agents: ${available.length > 0 ? available.join(', ') : '(none)'}`,\n 'CONFIG_VALIDATION_ERROR'\n )\n }\n return config.agents[agentName]\n}\n\n/** Filters test cases by tags using OR logic. Returns all if no tags specified. */\nfunction filterByTags<T extends { tags?: string[] }>(\n testCases: T[],\n tags: string[] | undefined\n): T[] {\n if (!tags || tags.length === 0) {\n return testCases\n }\n\n return testCases.filter((tc) => {\n if (!tc.tags || tc.tags.length === 0) {\n return false\n }\n return tc.tags.some((tag) => tags.includes(tag))\n })\n}\n\nfunction splitTestCases(\n testCases: CLITestCase<unknown, unknown>[]\n): {\n singleTurnCases: CLISingleTurnTestCase<unknown>[]\n multiTurnCases: CLIMultiTurnTestCase<unknown, unknown>[]\n} {\n const singleTurnCases: CLISingleTurnTestCase<unknown>[] = []\n const multiTurnCases: CLIMultiTurnTestCase<unknown, unknown>[] = []\n\n for (const testCase of testCases) {\n if (isMultiTurnConfig(testCase)) {\n multiTurnCases.push(testCase)\n } else {\n singleTurnCases.push(testCase as CLISingleTurnTestCase<unknown>)\n }\n }\n\n return { singleTurnCases, multiTurnCases }\n}\n\nfunction resolveAgentDescription(\n config: EvalConfig,\n agent: import('../../index.js').EvalAgent<unknown, unknown>\n): string {\n return config.agentDescription ?? agent.config.description ?? ''\n}\n\n/** Priority: config.agent > first agent in registry > 'unknown' */\nfunction resolvePromptVersion(config: EvalConfig): string {\n if (config.agent?.prompt?.version) {\n return config.agent.prompt.version\n }\n\n if (config.agents) {\n const firstAgent = Object.values(config.agents)[0]\n if (firstAgent?.prompt?.version) {\n return firstAgent.prompt.version\n }\n }\n\n return 'unknown'\n}\n\nfunction mergeReports(\n reports: EvalReport<unknown, unknown>[],\n promptVersion: string\n): EvalReport<unknown, unknown> {\n if (reports.length === 0) {\n return createEmptyReport(promptVersion)\n }\n\n if (reports.length === 1) {\n return reports[0]\n }\n\n const allResults: EvalTestResult<unknown, unknown>[] = []\n const suggestionMap = new Map<string, Suggestion>()\n let totalTests = 0\n let passed = 0\n let failed = 0\n let totalScore = 0\n let totalLatency = 0\n let totalTokens = 0\n let totalCost = 0\n\n for (const report of reports) {\n allResults.push(...report.results)\n deduplicateSuggestions(report.suggestions, suggestionMap)\n totalTests += report.summary.totalTests\n passed += report.summary.passed\n failed += report.summary.failed\n totalScore += report.summary.avgScore * report.summary.totalTests\n totalLatency += report.summary.metrics.avgLatencyMs * report.summary.totalTests\n totalTokens += report.summary.metrics.totalTokens\n totalCost += report.summary.metrics.totalEstimatedCost ?? 0\n }\n\n return {\n summary: {\n totalTests,\n passed,\n failed,\n avgScore: totalTests > 0 ? totalScore / totalTests : 0,\n metrics: {\n avgLatencyMs: totalTests > 0 ? totalLatency / totalTests : 0,\n totalTokens,\n totalEstimatedCost: totalCost,\n },\n },\n results: allResults,\n suggestions: [...suggestionMap.values()],\n generatedAt: new Date(),\n promptVersion,\n }\n}\n\nfunction createEmptyReport(promptVersion: string): EvalReport<unknown, unknown> {\n return {\n summary: {\n totalTests: 0,\n passed: 0,\n failed: 0,\n avgScore: 0,\n metrics: {\n avgLatencyMs: 0,\n totalTokens: 0,\n totalEstimatedCost: 0,\n },\n },\n results: [],\n suggestions: [],\n generatedAt: new Date(),\n promptVersion,\n }\n}\n\nfunction deduplicateSuggestions(\n suggestions: Suggestion[],\n map: Map<string, Suggestion>\n): void {\n for (const suggestion of suggestions) {\n const key = `${suggestion.type}:${suggestion.suggestedValue}`\n if (!map.has(key)) {\n map.set(key, suggestion)\n }\n }\n}\n","import type { ImprovementCycleResult, RoundResult } from '@/improvement-cycle/types'\nimport { CLI_DEFAULTS } from '../constants.js'\nimport { c } from './colors.js'\n\nexport interface PrintImprovementSummaryOptions {\n verbose?: boolean\n duration?: number\n}\n\nexport function printImprovementSummary(\n result: ImprovementCycleResult<unknown, unknown>,\n options: PrintImprovementSummaryOptions = {}\n): void {\n const { rounds, terminationReason, totalCost, finalPrompt } = result\n const { verbose, duration } = options\n\n const divider = '═'.repeat(CLI_DEFAULTS.DIVIDER_WIDTH)\n\n console.log()\n console.log(c('cyan', divider))\n console.log(c('bold', ' Improvement Cycle Results'))\n console.log(c('cyan', divider))\n console.log()\n\n const finalScore = getFinalScore(rounds)\n const scoreChange = getScoreChange(rounds)\n\n console.log(` ${c('bold', 'Total Rounds:')} ${rounds.length}`)\n console.log(` ${c('bold', 'Final Score:')} ${finalScore.toFixed(1)}/100`)\n console.log(` ${c('bold', 'Score Change:')} ${scoreChange}`)\n console.log(` ${c('bold', 'Total Cost:')} $${totalCost.toFixed(2)}`)\n console.log(` ${c('bold', 'Final Version:')} ${finalPrompt.version}`)\n\n console.log()\n console.log(` ${c('bold', 'Termination:')} ${terminationReason}`)\n\n if (duration !== undefined) {\n console.log()\n console.log(` ${c('bold', 'Duration:')} ${formatDuration(duration)}`)\n }\n\n console.log()\n console.log(c('cyan', divider))\n\n if (verbose && rounds.length > 0) {\n printRoundsDetail(rounds)\n }\n}\n\nfunction getFinalScore(rounds: RoundResult[]): number {\n if (rounds.length === 0) return 0\n return rounds[rounds.length - 1].report.summary.avgScore\n}\n\nfunction getScoreChange(rounds: RoundResult[]): string {\n if (rounds.length < 1) return 'N/A'\n\n const firstScore = rounds[0].report.summary.avgScore\n const lastScore = rounds[rounds.length - 1].report.summary.avgScore\n const delta = lastScore - firstScore\n\n if (rounds.length === 1) {\n return c('dim', 'N/A (first round)')\n }\n\n if (delta > 0) {\n return c('green', `+${delta.toFixed(1)}`)\n } else if (delta < 0) {\n return c('red', `${delta.toFixed(1)}`)\n }\n return '0.0'\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`\n return `${(ms / 60000).toFixed(1)}m`\n}\n\nfunction printRoundsDetail(rounds: RoundResult[]): void {\n console.log()\n console.log(c('bold', ' Round History:'))\n console.log()\n\n for (const round of rounds) {\n const scoreStr = round.report.summary.avgScore.toFixed(1)\n const deltaStr =\n round.scoreDelta !== null\n ? ` (${round.scoreDelta >= 0 ? '+' : ''}${round.scoreDelta.toFixed(1)})`\n : ''\n const costStr = `$${round.cost.total.toFixed(2)}`\n\n console.log(\n ` Round ${round.round}: Score ${scoreStr}${deltaStr} | Cost ${costStr}`\n )\n console.log(\n ` Suggestions: ${round.suggestionsGenerated.length} generated, ${round.suggestionsApproved.length} applied`\n )\n }\n}\n\nexport function printRoundProgress(round: RoundResult): void {\n const scoreStr = round.report.summary.avgScore.toFixed(1)\n const passRate = (\n (round.report.summary.passed / round.report.summary.totalTests) *\n 100\n ).toFixed(0)\n\n console.log()\n console.log(` ${c('cyan', `Round ${round.round} completed`)}`)\n console.log(` Score: ${scoreStr}/100 | Pass rate: ${passRate}%`)\n console.log(\n ` Tests: ${round.report.summary.totalTests} | Suggestions: ${round.suggestionsGenerated.length}`\n )\n}\n","import { loadConfigWithDefaults, ConfigError } from '../config/index.js'\nimport { loadEnvFile } from '../utils/env.js'\nimport { initializeProviders } from '../utils/provider-factory.js'\nimport { printBanner, printProgress, printError } from '../output/console.js'\nimport { printImprovementSummary, printRoundProgress } from '../output/improve-report.js'\nimport type { EvalConfig } from '../config/types.js'\nimport {\n createJudge,\n createImprover,\n type AgentPrompt,\n type EvalAgent,\n} from '../../index.js'\nimport type { Provider } from '@agtlantis/core'\nimport {\n runImprovementCycleAuto,\n resumeSession,\n deserializePrompt,\n targetScore,\n maxRounds,\n maxCost,\n noImprovement,\n type CycleTerminationCondition,\n type ImprovementCycleConfig,\n} from '../../improvement-cycle/index.js'\n\nexport interface ImproveCommandOptions {\n envFile: string\n history?: string\n targetScore?: string\n maxRounds?: string\n maxCost?: string\n staleRounds?: string\n resume?: string\n concurrency?: string\n iterations?: string\n verbose?: boolean\n mock?: boolean\n}\n\nexport async function improveCommand(\n configPath: string | undefined,\n options: ImproveCommandOptions\n): Promise<void> {\n const startTime = Date.now()\n\n try {\n printBanner()\n\n validateImproveOptions(options)\n\n printProgress('Loading environment...')\n await loadEnvFile(options.envFile)\n\n printProgress('Loading configuration...')\n const config = await loadConfigWithDefaults(configPath)\n\n printProgress('Initializing providers...')\n const { mainProvider, judgeProvider, improverProvider } = initializeProviders(config, options)\n\n const conditions = buildTerminationConditions(options)\n\n if (conditions.length === 0) {\n throw new Error(\n 'At least one termination condition is required.\\n' +\n 'Use --target-score, --max-rounds, --max-cost, or --stale-rounds'\n )\n }\n\n const judge = createJudge({\n provider: judgeProvider,\n prompt: config.judge.prompt,\n criteria: config.judge.criteria,\n passThreshold: config.judge.passThreshold,\n })\n\n if (!config.improver) {\n throw new Error(\n 'Improver configuration is required for improvement cycles.\\n' +\n 'Add an `improver` section to your config file.'\n )\n }\n\n const improver = createImprover({\n provider: improverProvider,\n prompt: config.improver.prompt,\n })\n\n if (options.resume) {\n await runResumeMode(\n options,\n config,\n conditions,\n judge,\n improver,\n mainProvider,\n startTime\n )\n } else {\n await runFreshMode(\n options,\n config,\n conditions,\n judge,\n improver,\n mainProvider,\n startTime\n )\n }\n } catch (error) {\n printError(error instanceof Error ? error : new Error(String(error)))\n process.exit(1)\n }\n}\n\nfunction validateImproveOptions(options: ImproveCommandOptions): void {\n if (!options.history && !options.resume) {\n throw new Error(\n '--history <path> is required to save improvement history.\\n' +\n 'Or use --resume <path> to continue from existing history.'\n )\n }\n}\n\nfunction buildTerminationConditions(\n options: ImproveCommandOptions\n): CycleTerminationCondition[] {\n const conditions: CycleTerminationCondition[] = []\n\n if (options.targetScore) {\n const score = parseInt(options.targetScore, 10)\n if (isNaN(score) || score < 0 || score > 100) {\n throw new Error(`Invalid target score: ${options.targetScore}. Must be 0-100.`)\n }\n conditions.push(targetScore(score))\n }\n\n if (options.maxRounds) {\n const rounds = parseInt(options.maxRounds, 10)\n if (isNaN(rounds) || rounds < 1) {\n throw new Error(`Invalid max rounds: ${options.maxRounds}. Must be >= 1.`)\n }\n conditions.push(maxRounds(rounds))\n }\n\n if (options.maxCost) {\n const cost = parseFloat(options.maxCost)\n if (isNaN(cost) || cost <= 0) {\n throw new Error(`Invalid max cost: ${options.maxCost}. Must be > 0.`)\n }\n conditions.push(maxCost(cost))\n }\n\n if (options.staleRounds) {\n const rounds = parseInt(options.staleRounds, 10)\n if (isNaN(rounds) || rounds < 1) {\n throw new Error(`Invalid stale-rounds: ${options.staleRounds}. Must be >= 1.`)\n }\n conditions.push(noImprovement(rounds))\n }\n\n return conditions\n}\n\nfunction createAgentFactory<TInput, TOutput>(\n baseAgent: EvalAgent<TInput, TOutput>\n): (prompt: AgentPrompt<TInput>) => EvalAgent<TInput, TOutput> {\n return (prompt: AgentPrompt<TInput>) => ({\n ...baseAgent,\n prompt,\n })\n}\n\nasync function runFreshMode(\n options: ImproveCommandOptions,\n config: EvalConfig,\n conditions: CycleTerminationCondition[],\n judge: ReturnType<typeof createJudge>,\n improver: ReturnType<typeof createImprover>,\n _mainProvider: Provider,\n startTime: number\n): Promise<void> {\n printProgress('Starting improvement cycle...')\n\n const testCases = config.testCases ?? []\n\n if (testCases.length === 0) {\n throw new Error(\n 'No test cases found. Add testCases to your config or use include patterns.'\n )\n }\n\n const cycleConfig: ImprovementCycleConfig<unknown, unknown> = {\n createAgent: createAgentFactory(config.agent),\n initialPrompt: config.agent.prompt,\n testCases,\n judge,\n improver,\n terminateWhen: conditions,\n options: {\n pricingConfig: config.pricing,\n agentDescription: config.agentDescription,\n history: options.history\n ? {\n path: options.history,\n autoSave: true,\n }\n : undefined,\n runOptions: {\n concurrency: options.concurrency\n ? parseInt(options.concurrency, 10)\n : config.run?.concurrency,\n iterations: options.iterations\n ? parseInt(options.iterations, 10)\n : config.run?.iterations,\n },\n },\n }\n\n printProgress(`Running with ${testCases.length} test case(s)...`)\n printProgress(`Termination: ${formatConditions(conditions)}`)\n console.log()\n\n const result = await runImprovementCycleAuto(cycleConfig)\n\n const duration = Date.now() - startTime\n printImprovementSummary(result, { verbose: options.verbose, duration })\n\n if (options.history) {\n console.log(`\\nHistory saved to: ${options.history}`)\n }\n\n process.exit(0)\n}\n\nasync function runResumeMode(\n options: ImproveCommandOptions,\n config: EvalConfig,\n conditions: CycleTerminationCondition[],\n judge: ReturnType<typeof createJudge>,\n improver: ReturnType<typeof createImprover>,\n _mainProvider: Provider,\n startTime: number\n): Promise<void> {\n printProgress(`Resuming from ${options.resume}...`)\n\n const session = await resumeSession(options.resume!, { autoSave: true })\n const currentPrompt = deserializePrompt(session.history.currentPrompt)\n\n printProgress(`Resumed session ${session.sessionId}`)\n printProgress(`Continuing from round ${session.history.rounds.length + 1}`)\n\n const testCases = config.testCases ?? []\n\n if (testCases.length === 0) {\n throw new Error(\n 'No test cases found. Add testCases to your config or use include patterns.'\n )\n }\n\n const cycleConfig: ImprovementCycleConfig<unknown, unknown> = {\n createAgent: createAgentFactory(config.agent),\n initialPrompt: currentPrompt,\n testCases,\n judge,\n improver,\n terminateWhen: conditions,\n options: {\n pricingConfig: config.pricing,\n agentDescription: config.agentDescription,\n history: {\n path: options.resume!,\n autoSave: true,\n },\n session, // Pass the resumed session to preserve session ID and accumulated state\n runOptions: {\n concurrency: options.concurrency\n ? parseInt(options.concurrency, 10)\n : config.run?.concurrency,\n iterations: options.iterations\n ? parseInt(options.iterations, 10)\n : config.run?.iterations,\n },\n },\n }\n\n printProgress(`Running with ${testCases.length} test case(s)...`)\n printProgress(`Termination: ${formatConditions(conditions)}`)\n console.log()\n\n const result = await runImprovementCycleAuto(cycleConfig)\n\n const duration = Date.now() - startTime\n printImprovementSummary(result, { verbose: options.verbose, duration })\n\n console.log(`\\nHistory saved to: ${options.resume}`)\n\n process.exit(0)\n}\n\nfunction formatConditions(conditions: CycleTerminationCondition[]): string {\n return conditions\n .map((c) => {\n switch (c.type) {\n case 'targetScore':\n return `score >= ${c.threshold}`\n case 'maxRounds':\n return `max ${c.count} rounds`\n case 'maxCost':\n return `max $${c.maxUSD}`\n case 'noImprovement':\n return `no improvement for ${c.consecutiveRounds} rounds`\n case 'custom':\n return c.description ?? 'custom condition'\n }\n })\n .join(' OR ')\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport {\n type ImprovementHistory,\n type SerializedPrompt,\n loadHistory,\n} from '../../improvement-cycle/index.js';\nimport { printBanner, printError, printProgress } from '../output/console.js';\n\nexport interface RollbackCommandOptions {\n round?: string;\n initial?: boolean;\n output: string;\n format?: 'json' | 'ts';\n}\n\nexport async function rollbackCommand(\n historyPath: string,\n options: RollbackCommandOptions\n): Promise<void> {\n try {\n printBanner();\n\n validateRollbackOptions(historyPath, options);\n\n printProgress(`Loading history from ${historyPath}...`);\n const history = await loadHistory(historyPath);\n\n const { prompt: serializedPrompt, sourceLabel } = extractPromptSnapshot(history, options);\n\n printProgress(`Extracting ${sourceLabel}...`);\n\n const format = options.format ?? 'json';\n const output = formatPromptOutput(serializedPrompt, format);\n\n await writeOutputFile(options.output, output);\n\n console.log();\n console.log(` Prompt extracted to: ${options.output}`);\n console.log(` Prompt ID: ${serializedPrompt.id}`);\n console.log(` Version: ${serializedPrompt.version}`);\n console.log();\n } catch (error) {\n printError(error instanceof Error ? error : new Error(String(error)));\n process.exit(1);\n }\n}\n\ninterface PromptSnapshot {\n prompt: SerializedPrompt;\n sourceLabel: string;\n}\n\nfunction extractPromptSnapshot(\n history: ImprovementHistory,\n options: RollbackCommandOptions\n): PromptSnapshot {\n if (options.initial) {\n return {\n prompt: history.initialPrompt,\n sourceLabel: 'initial prompt',\n };\n }\n\n const roundNumber = parseInt(options.round!, 10);\n return {\n prompt: extractPromptFromRound(history, roundNumber),\n sourceLabel: `round ${roundNumber}`,\n };\n}\n\nfunction validateRollbackOptions(historyPath: string, options: RollbackCommandOptions): void {\n if (!historyPath) {\n throw new Error('History file path is required');\n }\n\n const hasRound = options.round !== undefined;\n const hasInitial = options.initial === true;\n\n if (!hasRound && !hasInitial) {\n throw new Error('Either --round <n> or --initial is required');\n }\n\n if (hasRound && hasInitial) {\n throw new Error('Cannot use both --round and --initial');\n }\n\n if (!options.output) {\n throw new Error('--output <path> is required');\n }\n\n if (hasRound) {\n const roundNum = parseInt(options.round!, 10);\n if (!Number.isInteger(roundNum) || roundNum < 1) {\n throw new Error(`Invalid round number: ${options.round}. Must be 1 or greater.`);\n }\n }\n\n if (options.format && !['json', 'ts'].includes(options.format)) {\n throw new Error(`Invalid format: ${options.format}. Use 'json' or 'ts'`);\n }\n}\n\nfunction extractPromptFromRound(\n history: ImprovementHistory,\n roundNumber: number\n): SerializedPrompt {\n const roundIndex = roundNumber - 1;\n if (roundIndex < 0 || roundIndex >= history.rounds.length) {\n const availableRounds = history.rounds.length > 0 ? `1-${history.rounds.length}` : 'none';\n throw new Error(\n `Round ${roundNumber} not found. Available rounds: ${availableRounds}. Use --initial for the original prompt.`\n );\n }\n\n return history.rounds[roundIndex].promptSnapshot;\n}\n\nfunction formatPromptOutput(prompt: SerializedPrompt, format: 'json' | 'ts'): string {\n if (format === 'json') {\n return JSON.stringify(prompt, null, 2);\n }\n\n return generateTypeScriptPrompt(prompt);\n}\n\nfunction generateTypeScriptPrompt(prompt: SerializedPrompt): string {\n const escapedSystem = escapeTemplateString(prompt.system);\n const escapedUserTemplate = escapeTemplateString(prompt.userTemplate);\n\n const customFieldsComment = prompt.customFields\n ? `\\n * Custom fields: ${Object.keys(prompt.customFields).join(', ')}`\n : '';\n\n return `import { compileTemplate } from 'agent-eval'\nimport type { AgentPrompt } from 'agent-eval'\n\n/**\n * Extracted from improvement cycle\n * Original ID: ${prompt.id}\n * Version: ${prompt.version}${customFieldsComment}\n */\nexport const prompt: AgentPrompt<YourInputType> = {\n id: '${prompt.id}',\n version: '${prompt.version}',\n system: \\`${escapedSystem}\\`,\n userTemplate: \\`${escapedUserTemplate}\\`,\n renderUserPrompt: compileTemplate(\\`${escapedUserTemplate}\\`),\n}\n`;\n}\n\nfunction escapeTemplateString(str: string): string {\n return str.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\${/g, '\\\\${');\n}\n\nasync function writeOutputFile(path: string, content: string): Promise<void> {\n const dir = dirname(path);\n if (dir && dir !== '.' && dir !== '/' && !existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n await writeFile(path, content, 'utf-8');\n}\n","import cac from 'cac'\nimport { runCommand } from './commands/run.js'\nimport { improveCommand, type ImproveCommandOptions } from './commands/improve.js'\nimport { rollbackCommand, type RollbackCommandOptions } from './commands/rollback.js'\n\nconst VERSION = '0.1.0'\nconst cli = cac('agent-eval')\n\ncli\n .command('run [config]', 'Run evaluation suite')\n .option('-o, --output <path>', 'Output path for markdown report')\n .option('-e, --env-file <path>', 'Path to env file', { default: '.env' })\n .option('-v, --verbose', 'Enable verbose output')\n .option('-c, --concurrency <n>', 'Concurrency level')\n .option('-i, --iterations <n>', 'Number of iterations per test')\n .option('--no-report', 'Skip saving markdown report')\n .option('--mock', 'Use mock LLM for testing (no API calls)')\n .option('--include <pattern>', 'Glob patterns for YAML files (can be repeated)')\n .option('--tags <tag>', 'Filter test cases by tags, OR logic (can be repeated)')\n .option('--agent <name>', 'Filter to specific agent name')\n .action(async (configPath: string | undefined, options: RunCommandOptions) => {\n try {\n await runCommand(configPath, options)\n } catch {\n process.exit(1)\n }\n })\n\n// improve command - Run improvement cycle\ncli\n .command('improve [config]', 'Run improvement cycle on prompts')\n .option('-e, --env-file <path>', 'Path to env file', { default: '.env' })\n .option('--history <path>', 'Path to save history JSON')\n .option('--target-score <n>', 'Target score to reach (0-100)')\n .option('--max-rounds <n>', 'Maximum improvement rounds')\n .option('--max-cost <usd>', 'Maximum cost in USD')\n .option('--stale-rounds <n>', 'Stop after N rounds without improvement')\n .option('--resume <path>', 'Resume from existing history file')\n .option('-c, --concurrency <n>', 'Concurrency level')\n .option('-i, --iterations <n>', 'Iterations per test')\n .option('-v, --verbose', 'Enable verbose output')\n .option('--mock', 'Use mock LLM for testing (no API calls)')\n .action(async (configPath: string | undefined, options: ImproveCommandOptions) => {\n try {\n await improveCommand(configPath, options)\n } catch {\n process.exit(1)\n }\n })\n\n// rollback command - Extract prompt from history\ncli\n .command('rollback <history>', 'Extract prompt from improvement history')\n .option('-r, --round <n>', 'Round number to extract (1, 2, ...)')\n .option('--initial', 'Extract the initial prompt (before any improvements)')\n .option('-o, --output <path>', 'Output file path')\n .option('-f, --format <type>', 'Output format: json or ts', { default: 'json' })\n .action(async (historyPath: string, options: RollbackCommandOptions) => {\n try {\n await rollbackCommand(historyPath, options)\n } catch {\n process.exit(1)\n }\n })\n\ncli.help()\ncli.version(VERSION)\ncli.parse()\n\nexport interface RunCommandOptions {\n output?: string\n envFile: string\n verbose?: boolean\n concurrency?: string\n iterations?: string\n report?: boolean // --no-report sets this to false\n mock?: boolean // Use mock LLM for testing\n // YAML discovery options\n include?: string[] // Multiple --include flags collected by CAC\n tags?: string[] // Multiple --tags flags collected by CAC\n agent?: string // Single agent name filter\n}\n"],"mappings":"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","names":["cli","testCase","path","z","z","path","existsSync","resolve","testCase","fieldIsSet","c","testCase","path","resolve","existsSync","testCase","existsSync","readFile","resolve","writeFile","existsSync","existsSync","writeFile","resolveFileSourcesInInput","resolve","testCase","resolveFileSourcesInInput","error","testCases","testCases","resolveFileSourcesInInput","getFileSourcesDisplayInfo","z","c","z","c","writeFileSync","writeFileSync","mkdirSync","path","writeFileSync","Output","z","toEvalTokenUsage","z","Output","mock","compileTemplate","calculateCostFromUsage","calculateCostFromUsage","existsSync","mkdir","readFile","writeFile","compileTemplate","path","readFile","writeFile","existsSync","mkdir","compileTemplate","testCases","toLanguageModelUsage","calculateCostFromUsage","testCases","testCase","testCases","c","existsSync","mkdir","writeFile","dirname","path","dirname","existsSync","mkdir","writeFile"]}