@m4trix/evals 0.30.0 → 0.31.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.
- package/README.md +1 -1
- package/dist/cli-simple.cjs +1 -0
- package/dist/cli-simple.cjs.map +1 -1
- package/dist/cli-simple.js +1 -0
- package/dist/cli-simple.js.map +1 -1
- package/dist/cli.cjs +1 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-simple.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner/api.ts","../src/evals/entity-name.ts","../src/evals/evaluator.ts","../src/runner/artifact-loader.ts","../src/runner/config.ts","../src/runner/config-loader.ts","../src/runner/discovery.ts","../src/runner/execution.ts","../src/evals/diff.ts","../src/evals/test-case.ts","../src/evals/dataset.ts","../src/evals/metric.ts","../src/evals/aggregators.ts","../src/evals/metrics/standard.ts","../src/evals/score.ts","../src/evals/scores/standard.ts","../src/runner/score-utils.ts","../src/runner/name-pattern.ts","../src/runner/persistence.ts","../src/runner/search.ts","../src/cli-simple/args.ts","../src/cli-simple/banner.ts","../src/cli-simple/generate.ts","../src/cli-simple/views/GenerateView.tsx","../src/cli-simple/views/Banner.tsx","../src/cli-simple/run.ts","../src/cli-simple/views/RunView.tsx","../src/cli/components/TextBar.tsx","../src/cli-simple/views/Spinner.tsx","../src/cli-simple/index.ts"],"names":["randomUUID","Effect","Queue","Ref","resolve","createJiti","readdir","jitiModule","loaded","join","parts","registry","Box","Text","jsx","jsxs","writeFile","parse","readOutput","render","React","useEffect","useState","Fragment","sampleStdDev","ansi","createBar"],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { Effect, Fiber, PubSub, Queue, Ref } from 'effect';\nimport { getEvaluatorDisplayLabel } from '../evals/evaluator';\nimport { validateRunConfigName } from '../evals/run-config';\nimport { loadRunSnapshotsFromArtifacts as loadSnapshotsFromArtifacts } from './artifact-loader';\nimport type { RunnerConfig, RunnerConfigOverrides } from './config';\nimport { withRunnerConfig } from './config';\nimport { loadRunnerConfigFile } from './config-loader';\nimport {\n collectDatasetsFromFiles,\n collectEvaluatorsFromFiles,\n collectRunConfigsFromFiles,\n collectTestCasesFromFiles,\n} from './discovery';\nimport type {\n CollectedDataset,\n CollectedEvaluator,\n CollectedRunConfig,\n CollectedTestCase,\n RunDatasetJob,\n RunDatasetRequest,\n RunnerEvent,\n RunSnapshot,\n SearchTestCasesQuery,\n} from './events';\nimport { createArtifactPath, executeRunTask, type RunTask } from './execution';\nimport { createNameMatcher } from './name-pattern';\nimport { createPersistenceWorker } from './persistence';\nimport { searchCollectedTestCases } from './search';\n\ninterface SubscribeOptions {\n runId?: string;\n}\n\nfunction normalizeRunRepetitions(value: number | undefined): number {\n const n = value ?? 1;\n if (!Number.isInteger(n) || n < 1) {\n throw new Error(`repetitions must be a positive integer, got ${String(value)}`);\n }\n return n;\n}\n\nexport interface RunDatasetJobsWithSharedConcurrencyRequest {\n jobs: ReadonlyArray<RunDatasetJob>;\n globalConcurrency: number;\n triggerId?: string;\n /**\n * When the batch was triggered (`Date.now()` ms); defaults to now. CLI sets this once at command start.\n */\n triggerTimestamp?: number;\n /** Applied to every job in this batch (e.g. CLI `--experiment`). */\n experimentName?: string;\n}\n\nexport interface RunnerApi {\n collectDatasets(): Promise<ReadonlyArray<CollectedDataset>>;\n collectEvaluators(): Promise<ReadonlyArray<CollectedEvaluator>>;\n collectRunConfigs(): Promise<ReadonlyArray<CollectedRunConfig>>;\n /** Resolves a dataset by canonical **`Dataset` `name`** (id), case-insensitive. */\n resolveDatasetByName(name: string): Promise<CollectedDataset | undefined>;\n resolveEvaluatorsByNamePattern(pattern: string): Promise<ReadonlyArray<CollectedEvaluator>>;\n /**\n * Resolves a RunConfig by display name (case-insensitive).\n * @throws If more than one discovered RunConfig uses the same name (list file paths in the error).\n */\n resolveRunConfigByName(name: string): Promise<CollectedRunConfig | undefined>;\n expandRunConfigToJobs(collected: CollectedRunConfig): Promise<ReadonlyArray<RunDatasetJob>>;\n /** Resolves each name in order and concatenates expanded jobs (the same name may appear more than once). */\n expandRunConfigNamesToJobs(names: ReadonlyArray<string>): Promise<ReadonlyArray<RunDatasetJob>>;\n runDatasetJobsWithSharedConcurrency(\n request: RunDatasetJobsWithSharedConcurrencyRequest,\n ): Promise<ReadonlyArray<RunSnapshot>>;\n searchTestCases(query?: SearchTestCasesQuery): Promise<ReadonlyArray<CollectedTestCase>>;\n collectDatasetTestCases(datasetId: string): Promise<ReadonlyArray<CollectedTestCase>>;\n runDatasetWith(request: RunDatasetRequest): Promise<RunSnapshot>;\n subscribeRunEvents(\n listener: (event: RunnerEvent) => void,\n options?: SubscribeOptions,\n ): () => void;\n getRunSnapshot(runId: string): RunSnapshot | undefined;\n getAllRunSnapshots(): ReadonlyArray<RunSnapshot>;\n loadRunSnapshotsFromArtifacts(): Promise<ReadonlyArray<RunSnapshot>>;\n shutdown(): Promise<void>;\n}\n\nfunction mergeRunnerOverrides(\n base?: RunnerConfigOverrides,\n next?: RunnerConfigOverrides,\n): RunnerConfigOverrides | undefined {\n if (!base) {\n return next;\n }\n if (!next) {\n return base;\n }\n const discovery =\n base.discovery || next.discovery\n ? {\n ...(base.discovery ?? {}),\n ...(next.discovery ?? {}),\n }\n : undefined;\n return {\n ...base,\n ...next,\n discovery,\n };\n}\n\nexport function createRunner(overrides?: RunnerConfigOverrides): RunnerApi {\n const fileOverrides = loadRunnerConfigFile();\n const merged = mergeRunnerOverrides(fileOverrides, overrides);\n return new EffectRunner(withRunnerConfig(merged));\n}\n\nclass EffectRunner implements RunnerApi {\n private readonly config: RunnerConfig;\n\n private readonly eventBus = Effect.runSync(PubSub.unbounded<RunnerEvent>());\n\n private readonly runQueue = Effect.runSync(Queue.unbounded<RunTask>());\n\n private readonly persistenceQueue = Effect.runSync(\n Queue.unbounded<{\n runId: string;\n artifactPath: string;\n payload: unknown;\n }>(),\n );\n\n private readonly snapshotsRef = Effect.runSync(Ref.make(new Map<string, RunSnapshot>()));\n private readonly listeners = new Set<{\n runId?: string;\n listener: (event: RunnerEvent) => void;\n }>();\n\n private readonly datasetsById = new Map<string, CollectedDataset>();\n\n private readonly evaluatorsById = new Map<string, CollectedEvaluator>();\n\n private readonly runConfigsById = new Map<string, CollectedRunConfig>();\n\n private readonly schedulerFiber = Effect.runFork(this.createSchedulerEffect());\n\n private readonly persistenceFiber = Effect.runFork(\n createPersistenceWorker(this.persistenceQueue),\n );\n\n constructor(config: RunnerConfig) {\n this.config = config;\n }\n\n async collectDatasets(): Promise<ReadonlyArray<CollectedDataset>> {\n const datasets = await collectDatasetsFromFiles(this.config.discovery);\n this.datasetsById.clear();\n for (const dataset of datasets) {\n this.datasetsById.set(dataset.id, dataset);\n }\n return datasets;\n }\n\n async collectEvaluators(): Promise<ReadonlyArray<CollectedEvaluator>> {\n const evaluators = await collectEvaluatorsFromFiles(this.config.discovery);\n this.evaluatorsById.clear();\n for (const evaluator of evaluators) {\n this.evaluatorsById.set(evaluator.id, evaluator);\n }\n return evaluators;\n }\n\n async resolveDatasetByName(name: string): Promise<CollectedDataset | undefined> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n const normalized = name.trim().toLowerCase();\n return Array.from(this.datasetsById.values()).find(\n (item) => item.dataset.getName().toLowerCase() === normalized,\n );\n }\n\n async resolveEvaluatorsByNamePattern(\n pattern: string,\n ): Promise<ReadonlyArray<CollectedEvaluator>> {\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n const matcher = createNameMatcher(pattern);\n return Array.from(this.evaluatorsById.values()).filter((item) =>\n matcher(item.evaluator.getName() ?? ''),\n );\n }\n\n async collectRunConfigs(): Promise<ReadonlyArray<CollectedRunConfig>> {\n const runConfigs = await collectRunConfigsFromFiles(this.config.discovery);\n this.runConfigsById.clear();\n const byNameLower = new Map<string, CollectedRunConfig>();\n for (const item of runConfigs) {\n const id = item.runConfig.getName();\n const lower = id.toLowerCase();\n const prev = byNameLower.get(lower);\n if (prev !== undefined && prev.filePath !== item.filePath) {\n throw new Error(\n `Duplicate RunConfig name \"${id}\" (matches \"${prev.runConfig.getName()}\" case-insensitively): ${prev.filePath} and ${item.filePath}`,\n );\n }\n byNameLower.set(lower, item);\n this.runConfigsById.set(id, item);\n }\n return runConfigs;\n }\n\n async resolveRunConfigByName(name: string): Promise<CollectedRunConfig | undefined> {\n if (this.runConfigsById.size === 0) {\n await this.collectRunConfigs();\n }\n const key = validateRunConfigName(name, `RunConfig \"${name.trim()}\"`);\n const keyLower = key.toLowerCase();\n const matches = Array.from(this.runConfigsById.values()).filter(\n (item) => item.runConfig.getName().toLowerCase() === keyLower,\n );\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw new Error(\n `Multiple RunConfigs named \"${name}\": ${matches.map((m) => m.filePath).join(', ')}`,\n );\n }\n return matches[0];\n }\n\n async expandRunConfigToJobs(\n collected: CollectedRunConfig,\n ): Promise<ReadonlyArray<RunDatasetJob>> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n\n const rcName = collected.runConfig.getName();\n const jobs: RunDatasetJob[] = [];\n const runs = collected.runConfig.getRuns();\n\n for (const [i, row] of runs.entries()) {\n const dsCollected = Array.from(this.datasetsById.values()).find(\n (d) => d.dataset === row.dataset,\n );\n if (!dsCollected) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: dataset \"${row.dataset.getDisplayLabel()}\" was not found among discovered dataset exports (import the same module instances the scanner loads).`,\n );\n }\n\n let evaluatorIds: string[];\n if ('evaluatorPattern' in row && typeof row.evaluatorPattern === 'string') {\n const matcher = createNameMatcher(row.evaluatorPattern);\n const matched = Array.from(this.evaluatorsById.values()).filter((item) =>\n matcher(item.evaluator.getName() ?? ''),\n );\n if (matched.length === 0) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: no evaluator matched pattern \"${row.evaluatorPattern}\"`,\n );\n }\n evaluatorIds = matched.map((item) => item.id);\n } else {\n const evaluators = row.evaluators;\n evaluatorIds = [];\n for (const ev of evaluators) {\n const found = Array.from(this.evaluatorsById.values()).find(\n (item) => item.evaluator === ev,\n );\n if (!found) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: evaluator \"${getEvaluatorDisplayLabel(ev) ?? 'unknown'}\" was not found among discovered evaluator exports`,\n );\n }\n evaluatorIds.push(found.id);\n }\n }\n\n const repetitions =\n 'repetitions' in row && row.repetitions !== undefined ? row.repetitions : 1;\n\n jobs.push({\n datasetId: dsCollected.id,\n evaluatorIds,\n runConfigName: rcName,\n runConfigDisplayLabel: collected.runConfig.getDisplayLabel(),\n runConfigTags: collected.runConfig.getTags(),\n repetitions,\n });\n }\n\n return jobs;\n }\n\n async expandRunConfigNamesToJobs(\n names: ReadonlyArray<string>,\n ): Promise<ReadonlyArray<RunDatasetJob>> {\n const jobs: RunDatasetJob[] = [];\n for (const name of names) {\n const collected = await this.resolveRunConfigByName(name);\n if (!collected) {\n const known = await this.collectRunConfigs();\n const available = known.map((r) => r.runConfig.getName()).sort();\n throw new Error(\n available.length > 0\n ? `RunConfig \"${name}\" not found. Available RunConfigs: ${available.join(', ')}`\n : `RunConfig \"${name}\" not found and no RunConfigs were discovered.`,\n );\n }\n jobs.push(...(await this.expandRunConfigToJobs(collected)));\n }\n return jobs;\n }\n\n async runDatasetJobsWithSharedConcurrency(\n request: RunDatasetJobsWithSharedConcurrencyRequest,\n ): Promise<ReadonlyArray<RunSnapshot>> {\n const globalConcurrency = Math.max(1, request.globalConcurrency);\n const sem = Effect.unsafeMakeSemaphore(globalConcurrency);\n const triggerId = request.triggerId ?? `trg-${randomUUID()}`;\n const triggerTimestamp = request.triggerTimestamp ?? Date.now();\n const snapshots: RunSnapshot[] = [];\n for (const job of request.jobs) {\n snapshots.push(\n await this.startDatasetRun({\n datasetId: job.datasetId,\n evaluatorIds: job.evaluatorIds,\n triggerId,\n triggerTimestamp,\n maxConcurrency: this.config.maxConcurrency ?? 1,\n globalEvaluationSemaphore: sem,\n runConfigName: job.runConfigName,\n runConfigTags: job.runConfigTags,\n repetitions: job.repetitions,\n experimentName: request.experimentName,\n }),\n );\n }\n return snapshots;\n }\n\n async searchTestCases(query?: SearchTestCasesQuery): Promise<ReadonlyArray<CollectedTestCase>> {\n const testCases = await collectTestCasesFromFiles(this.config.discovery);\n return searchCollectedTestCases(testCases, query);\n }\n\n async collectDatasetTestCases(datasetId: string): Promise<ReadonlyArray<CollectedTestCase>> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n const dataset = this.datasetsById.get(datasetId);\n if (!dataset) {\n throw new Error(`Unknown dataset: ${datasetId}`);\n }\n const allTestCases = await collectTestCasesFromFiles(this.config.discovery);\n return allTestCases.filter((testCase) =>\n dataset.dataset.matchesTestCase(testCase.testCase, testCase.filePath),\n );\n }\n\n async runDatasetWith(request: RunDatasetRequest): Promise<RunSnapshot> {\n const runConfigName = validateRunConfigName(\n request.runConfigName,\n 'runDatasetWith.runConfigName',\n );\n return this.startDatasetRun({\n datasetId: request.datasetId,\n evaluatorIds: request.evaluatorIds,\n triggerId: request.triggerId,\n triggerTimestamp: request.triggerTimestamp ?? Date.now(),\n maxConcurrency: request.concurrency ?? this.config.maxConcurrency ?? 1,\n repetitions: request.repetitions,\n runConfigName,\n runConfigTags: request.runConfigTags,\n experimentName: request.experimentName,\n });\n }\n\n private async startDatasetRun(params: {\n datasetId: string;\n evaluatorIds: ReadonlyArray<string>;\n triggerId?: string;\n triggerTimestamp?: number;\n maxConcurrency: number;\n globalEvaluationSemaphore?: ReturnType<typeof Effect.unsafeMakeSemaphore>;\n runConfigName: string;\n runConfigTags?: ReadonlyArray<string>;\n repetitions?: number;\n experimentName?: string;\n }): Promise<RunSnapshot> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n\n const dataset = this.datasetsById.get(params.datasetId);\n if (!dataset) {\n throw new Error(`Unknown dataset: ${params.datasetId}`);\n }\n\n const selectedEvaluators = params.evaluatorIds\n .map((id) => this.evaluatorsById.get(id))\n .filter((value): value is CollectedEvaluator => Boolean(value))\n .map((value) => ({ id: value.id, evaluator: value.evaluator }));\n\n if (selectedEvaluators.length === 0) {\n throw new Error('No evaluators selected for run');\n }\n\n const selectedTestCases = await this.collectDatasetTestCases(params.datasetId);\n\n const repetitions = normalizeRunRepetitions(params.repetitions);\n const totalEvaluations = selectedTestCases.length * repetitions;\n const runConfigTags = [...(params.runConfigTags ?? [])];\n\n const triggerId = params.triggerId ?? `trg-${randomUUID()}`;\n const triggerTimestamp = params.triggerTimestamp ?? Date.now();\n const runId = `run-${randomUUID()}`;\n const artifactPath = createArtifactPath(this.config.artifactDirectory, params.datasetId, runId);\n const snapshot: RunSnapshot = {\n runId,\n datasetId: params.datasetId,\n datasetName: dataset.dataset.getDisplayLabel(),\n evaluatorIds: selectedEvaluators.map((item) => item.id),\n queuedAt: Date.now(),\n totalTestCases: totalEvaluations,\n completedTestCases: 0,\n passedTestCases: 0,\n failedTestCases: 0,\n status: 'queued',\n artifactPath,\n };\n\n await Effect.runPromise(\n Ref.update(this.snapshotsRef, (map) => {\n const next = new Map(map);\n next.set(runId, snapshot);\n return next;\n }),\n );\n const queuedEvent: RunnerEvent = {\n type: 'RunQueued',\n runId,\n datasetId: params.datasetId,\n datasetName: dataset.dataset.getDisplayLabel(),\n evaluatorIds: selectedEvaluators.map((item) => item.id),\n totalTestCases: totalEvaluations,\n artifactPath,\n };\n await Effect.runPromise(this.publishEvent(queuedEvent));\n await Effect.runPromise(\n Queue.offer(this.persistenceQueue, {\n runId,\n artifactPath,\n payload: queuedEvent,\n }),\n );\n\n await Effect.runPromise(\n Queue.offer(this.runQueue, {\n runId,\n triggerId,\n triggerTimestamp,\n datasetId: params.datasetId,\n dataset: dataset.dataset,\n evaluators: selectedEvaluators,\n testCases: selectedTestCases,\n snapshot,\n maxConcurrency: params.maxConcurrency,\n globalEvaluationSemaphore: params.globalEvaluationSemaphore,\n runConfigName: params.runConfigName,\n runConfigTags,\n repetitions,\n experimentName: params.experimentName,\n }),\n );\n\n return snapshot;\n }\n\n subscribeRunEvents(\n listener: (event: RunnerEvent) => void,\n options?: SubscribeOptions,\n ): () => void {\n const entry = { runId: options?.runId, listener };\n this.listeners.add(entry);\n return () => {\n this.listeners.delete(entry);\n };\n }\n\n getRunSnapshot(runId: string): RunSnapshot | undefined {\n return Effect.runSync(Ref.get(this.snapshotsRef)).get(runId);\n }\n\n getAllRunSnapshots(): ReadonlyArray<RunSnapshot> {\n return Array.from(Effect.runSync(Ref.get(this.snapshotsRef)).values()).sort(\n (a, b) => b.queuedAt - a.queuedAt,\n );\n }\n\n async loadRunSnapshotsFromArtifacts(): Promise<ReadonlyArray<RunSnapshot>> {\n return loadSnapshotsFromArtifacts(this.config);\n }\n\n async shutdown(): Promise<void> {\n await Effect.runPromise(Fiber.interrupt(this.schedulerFiber));\n await Effect.runPromise(Fiber.interrupt(this.persistenceFiber));\n await Effect.runPromise(Queue.shutdown(this.runQueue));\n await Effect.runPromise(Queue.shutdown(this.persistenceQueue));\n await Effect.runPromise(PubSub.shutdown(this.eventBus));\n }\n\n private createSchedulerEffect() {\n const self = this;\n return Effect.forever(\n Effect.gen(function* () {\n const task = yield* Queue.take(self.runQueue);\n yield* Effect.fork(\n executeRunTask(\n task,\n self.publishEvent.bind(self),\n self.persistenceQueue,\n self.updateSnapshot.bind(self),\n ),\n );\n }),\n );\n }\n\n private updateSnapshot(\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ): Effect.Effect<void, never, never> {\n return Ref.modify(this.snapshotsRef, (map) => {\n const existing = map.get(runId);\n if (!existing) {\n return [undefined, map] as const;\n }\n const next = new Map(map);\n next.set(runId, updater(existing));\n return [undefined, next] as const;\n }).pipe(Effect.asVoid);\n }\n\n private publishEvent(event: RunnerEvent): Effect.Effect<void, never, never> {\n return Effect.sync(() => {\n for (const entry of this.listeners) {\n if (entry.runId && entry.runId !== event.runId) {\n continue;\n }\n entry.listener(event);\n }\n }).pipe(\n Effect.flatMap(() => PubSub.publish(this.eventBus, event)),\n Effect.asVoid,\n );\n }\n}\n","import { Either, ParseResult, Schema } from 'effect';\n\nconst ENTITY_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\nfunction makeEntityIdSchema<const B extends string>(brand: B, label: string) {\n return Schema.String.pipe(\n Schema.trimmed(),\n Schema.minLength(1, {\n message: () => `${label} must be non-empty.`,\n }),\n Schema.pattern(ENTITY_ID_PATTERN, {\n message: () =>\n `${label} may only contain letters, digits, underscores, and hyphens (no spaces). Examples: \"my-nightly\", \"my_nightly\", \"myNightly\".`,\n }),\n Schema.brand(brand),\n );\n}\n\n/** Branded id for `RunConfig` `name` (decode with {@link RunConfigNameSchema}). */\nexport const RunConfigNameSchema = makeEntityIdSchema('RunConfigName', 'RunConfig name');\n\n/** Branded id for `Evaluator.define({ name })` (decode with {@link EvaluatorNameSchema}). */\nexport const EvaluatorNameSchema = makeEntityIdSchema('EvaluatorName', 'Evaluator name');\n\n/** Branded id for `TestCase.describe({ name })` (decode with {@link TestCaseNameSchema}). */\nexport const TestCaseNameSchema = makeEntityIdSchema('TestCaseName', 'Test case name');\n\n/** Branded id for `Dataset.define({ name })` (decode with {@link DatasetNameSchema}). */\nexport const DatasetNameSchema = makeEntityIdSchema('DatasetName', 'Dataset name');\n\nexport type RunConfigName = Schema.Schema.Type<typeof RunConfigNameSchema>;\nexport type EvaluatorName = Schema.Schema.Type<typeof EvaluatorNameSchema>;\nexport type TestCaseName = Schema.Schema.Type<typeof TestCaseNameSchema>;\nexport type DatasetName = Schema.Schema.Type<typeof DatasetNameSchema>;\n\nfunction validateWithSchema(schema: Schema.Schema.Any, raw: string, context: string): unknown {\n const trimmed = raw.trim();\n // Branded string schemas use `Context = unknown`; `decodeUnknownEither` is typed for context `never`.\n const decode = Schema.decodeUnknownEither(\n schema as unknown as Schema.Schema<string, string, never>,\n );\n const result = decode(trimmed);\n if (Either.isLeft(result)) {\n throw new Error(`${context}: ${ParseResult.TreeFormatter.formatErrorSync(result.left)}`);\n }\n return result.right;\n}\n\nexport function validateRunConfigName(raw: string, context: string): RunConfigName {\n return validateWithSchema(RunConfigNameSchema, raw, context) as RunConfigName;\n}\n\nexport function validateEvaluatorName(raw: string, context: string): EvaluatorName {\n return validateWithSchema(EvaluatorNameSchema, raw, context) as EvaluatorName;\n}\n\nexport function validateTestCaseName(raw: string, context: string): TestCaseName {\n return validateWithSchema(TestCaseNameSchema, raw, context) as TestCaseName;\n}\n\nexport function validateDatasetName(raw: string, context: string): DatasetName {\n return validateWithSchema(DatasetNameSchema, raw, context) as DatasetName;\n}\n\n/** Optional UI label: trim; empty after trim becomes undefined. */\nexport function normalizeOptionalDisplayName(raw: string | undefined): string | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const t = raw.trim();\n return t.length === 0 ? undefined : t;\n}\n","import type { Schema as S } from 'effect';\nimport type { CreateDiffLogEntryOptions } from './diff';\nimport {\n type EvaluatorName,\n normalizeOptionalDisplayName,\n validateEvaluatorName,\n} from './entity-name';\n\nexport interface EvalMiddleware<TCtx> {\n name: string;\n resolve: () => TCtx | Promise<TCtx>;\n}\n\nexport interface EvaluateMeta {\n /** Identifier of the trigger that started the run (for example, a CLI invocation). */\n triggerId: string;\n /**\n * Milliseconds since Unix epoch when the run was triggered (e.g. `Date.now()` at CLI start, or when\n * `runDatasetWith` / `runDatasetJobsWithSharedConcurrency` was invoked). Shared across all jobs in a batch.\n */\n triggerTimestamp: number;\n /**\n * Identifier of the current test-case execution shared across all evaluators\n * for this specific test-case run.\n */\n runId: string;\n /** Display label for the dataset (`Dataset.getDisplayLabel()`, i.e. `displayName ?? name`). */\n datasetName: string;\n /** Discovery id for the current test case (same as runner events’ `testCaseId`). */\n testCaseId: string;\n /** Display label for the test case (`TestCase.getDisplayLabel()`, i.e. `displayName ?? name`). */\n testCaseName: string;\n /** Canonical `RunConfig` name (or `programmatic` for API/TUI-only runs). */\n runConfigName: string;\n /**\n * Optional label for this invocation (e.g. CLI `--experiment`); omitted when not set.\n */\n experimentName?: string;\n /**\n * Stable id shared by every execution of the same logical test case when `repetitionCount > 1`\n * (and present with count 1 for consistency).\n */\n repetitionId: string;\n /** 1-based index of this execution within the repetition group. */\n repetitionIndex: number;\n /** Total scheduled executions for this logical test case in the current run. */\n repetitionCount: number;\n /** Declared tags on the current test case (`TestCase.describe({ tags })`); empty when none. */\n testCaseTags: string[];\n /**\n * Declared tags on the current run config or programmatic request (`RunConfig.define({ tags })`,\n * `RunDatasetRequest.runConfigTags`); empty when none.\n */\n runConfigTags: string[];\n /** Declared tags on this evaluator (`Evaluator.define({ tags })`); empty when none. */\n evaluatorTags: string[];\n}\n\nexport interface EvaluateArgs<TInput, TOutput = unknown, TCtx = Record<string, never>> {\n input: TInput;\n ctx: TCtx;\n output?: TOutput;\n /** Metadata about the current evaluator invocation. */\n meta: EvaluateMeta;\n /** Records a diff for this test case; stored in run artifact and shown by CLI */\n logDiff: (expected: unknown, actual: unknown, options?: CreateDiffLogEntryOptions) => void;\n /** Logs a message or object for this test case; stored in run artifact and shown by CLI */\n log: (message: unknown, options?: { label?: string }) => void;\n /**\n * Creates an Error from string/object payloads for `return createError(...)` (or `throw createError(...)`).\n * The payload is also logged and shown by the CLI when the evaluator fails.\n */\n createError: (message: unknown, options?: { label?: string }) => Error;\n}\n\ntype EvaluateFn<TInput, TOutput, TScore, TCtx> = (\n args: EvaluateArgs<TInput, TOutput, TCtx>,\n) => TScore | Error | Promise<TScore | Error>;\n\ninterface EvaluatorConfig<TInput, TOutput, TScore, TCtx> {\n name?: EvaluatorName;\n displayName?: string;\n tags: readonly string[];\n inputSchema?: S.Schema.Any;\n outputSchema?: S.Schema.Any;\n scoreSchema?: S.Schema.Any;\n middlewares: ReadonlyArray<EvalMiddleware<unknown>>;\n evaluateFn?: EvaluateFn<TInput, TOutput, TScore, TCtx>;\n passThreshold?: number;\n passCriterion?: (score: unknown) => boolean;\n /** Phantom field for TOutput type parameter */\n _outputType?: TOutput;\n}\n\ninterface EvaluatorDefineConfig<\n TI extends S.Schema.Any,\n TO extends S.Schema.Any,\n TS extends S.Schema.Any,\n> {\n /**\n * Stable id (letters, digits, `_`, `-`); used for discovery, name patterns, and `meta`.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI (any characters). */\n displayName?: string;\n inputSchema: TI;\n outputSchema: TO;\n scoreSchema: TS;\n passThreshold?: number;\n passCriterion?: (score: unknown) => boolean;\n /**\n * Declared tags for this evaluator (not dataset filter rules); echoed on every `evaluate` call as\n * `meta.evaluatorTags`.\n */\n tags?: ReadonlyArray<string>;\n}\n\nexport class Evaluator<\n TInput = unknown,\n TOutput = unknown,\n TScore = unknown,\n TCtx = Record<string, never>,\n> {\n private readonly _config: EvaluatorConfig<TInput, TOutput, TScore, TCtx>;\n\n private constructor(config: EvaluatorConfig<TInput, TOutput, TScore, TCtx>) {\n this._config = config;\n }\n\n private getState(): EvaluatorConfig<TInput, TOutput, TScore, TCtx> {\n return {\n name: this._config.name,\n displayName: this._config.displayName,\n tags: this._config.tags,\n inputSchema: this._config.inputSchema,\n outputSchema: this._config.outputSchema,\n scoreSchema: this._config.scoreSchema,\n middlewares: this._config.middlewares,\n evaluateFn: this._config.evaluateFn,\n passThreshold: this._config.passThreshold,\n passCriterion: this._config.passCriterion,\n };\n }\n\n static use<TCtx>(middleware: EvalMiddleware<TCtx>): Evaluator<unknown, unknown, unknown, TCtx> {\n return new Evaluator<unknown, unknown, unknown, TCtx>({\n middlewares: [middleware as EvalMiddleware<unknown>],\n tags: [],\n });\n }\n\n use<TNew>(middleware: EvalMiddleware<TNew>): Evaluator<TInput, TOutput, TScore, TCtx & TNew> {\n const state = this.getState();\n return new Evaluator<TInput, TOutput, TScore, TCtx & TNew>({\n ...(state as unknown as EvaluatorConfig<TInput, TOutput, TScore, TCtx & TNew>),\n middlewares: [...state.middlewares, middleware as EvalMiddleware<unknown>],\n });\n }\n\n define<TI extends S.Schema.Any, TO extends S.Schema.Any, TS extends S.Schema.Any>(\n config: EvaluatorDefineConfig<TI, TO, TS>,\n ): Evaluator<S.Schema.Type<TI>, S.Schema.Type<TO>, S.Schema.Type<TS>, TCtx> {\n const { middlewares } = this.getState();\n const name = validateEvaluatorName(config.name, 'Evaluator.define');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n const tags = config.tags !== undefined ? [...config.tags] : [];\n return new Evaluator<S.Schema.Type<TI>, S.Schema.Type<TO>, S.Schema.Type<TS>, TCtx>({\n name,\n displayName,\n tags,\n inputSchema: config.inputSchema,\n outputSchema: config.outputSchema,\n scoreSchema: config.scoreSchema,\n middlewares,\n passThreshold: config.passThreshold,\n passCriterion: config.passCriterion,\n });\n }\n\n evaluate(\n fn: EvaluateFn<TInput, TOutput, TScore, TCtx>,\n ): Evaluator<TInput, TOutput, TScore, TCtx> {\n return new Evaluator<TInput, TOutput, TScore, TCtx>({\n ...this.getState(),\n evaluateFn: fn,\n });\n }\n\n /** Canonical evaluator id when defined; otherwise undefined (middleware-only chain). */\n getName(): string | undefined {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n /** Label for CLI/TUI: {@link getDisplayName} if set, otherwise {@link getName}. Undefined if not yet defined. */\n getDisplayLabel(): string | undefined {\n const id = this._config.name;\n if (id === undefined) {\n return undefined;\n }\n return this._config.displayName ?? id;\n }\n\n /** Tags from `Evaluator.define({ tags })`; empty until defined. */\n getTags(): string[] {\n return [...this._config.tags];\n }\n\n getInputSchema(): S.Schema.Any | undefined {\n return this._config.inputSchema;\n }\n\n getOutputSchema(): S.Schema.Any | undefined {\n return this._config.outputSchema;\n }\n\n getScoreSchema(): S.Schema.Any | undefined {\n return this._config.scoreSchema;\n }\n\n getMiddlewares(): ReadonlyArray<EvalMiddleware<unknown>> {\n return this._config.middlewares;\n }\n\n getEvaluateFn(): EvaluateFn<TInput, TOutput, TScore, TCtx> | undefined {\n return this._config.evaluateFn;\n }\n\n getPassThreshold(): number | undefined {\n return this._config.passThreshold;\n }\n\n getPassCriterion(): ((score: unknown) => boolean) | undefined {\n return this._config.passCriterion;\n }\n\n async resolveContext(): Promise<TCtx> {\n const parts = await Promise.all(this._config.middlewares.map((mw) => mw.resolve()));\n return Object.assign({}, ...parts) as TCtx;\n }\n}\n\n/** CLI-friendly label: {@link Evaluator.getDisplayLabel} when present, else {@link Evaluator.getName} (supports plain evaluator-shaped objects from discovery). */\nexport function getEvaluatorDisplayLabel(evaluator: {\n getDisplayLabel?: () => string | undefined;\n getName?: () => string | undefined;\n}): string | undefined {\n if (typeof evaluator.getDisplayLabel === 'function') {\n const label = evaluator.getDisplayLabel();\n if (label !== undefined) {\n return label;\n }\n }\n return typeof evaluator.getName === 'function' ? evaluator.getName() : undefined;\n}\n\n/** Tags for evaluator `meta.evaluatorTags` (plain evaluator-shaped objects without `getTags` yield `[]`). */\nexport function getEvaluatorTagList(evaluator: {\n getTags?: () => ReadonlyArray<string>;\n}): string[] {\n return typeof evaluator.getTags === 'function' ? [...evaluator.getTags()] : [];\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nimport type { RunnerConfig } from './config';\nimport type { RunSnapshot } from './events';\n\nexport interface ParsedTestCaseProgress {\n testCaseId: string;\n testCaseName: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionId?: string;\n repetitionIndex?: number;\n repetitionCount?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<{\n id: string;\n data: unknown;\n passed?: boolean;\n name?: string;\n }>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<\n | { type: 'diff'; label?: string; expected: unknown; actual: unknown; diff: string }\n | { type: 'log'; label?: string; message: string }\n >;\n }>;\n}\n\nexport async function loadRunSnapshotsFromArtifacts(config: RunnerConfig): Promise<RunSnapshot[]> {\n const baseDir = resolve(config.artifactDirectory);\n let entries: string[];\n try {\n entries = await readdir(baseDir);\n } catch {\n return [];\n }\n\n const jsonlFiles = entries.filter((name) => name.endsWith('.jsonl'));\n const snapshots: RunSnapshot[] = [];\n\n for (const fileName of jsonlFiles) {\n const filePath = join(baseDir, fileName);\n try {\n const snapshot = await parseArtifactToSnapshot(filePath, config);\n if (snapshot) {\n snapshots.push(snapshot);\n }\n } catch {\n // Skip malformed or unreadable files\n }\n }\n\n return snapshots.sort((a, b) => b.queuedAt - a.queuedAt);\n}\n\nasync function parseArtifactToSnapshot(\n filePath: string,\n _config: RunnerConfig,\n): Promise<RunSnapshot | null> {\n const content = await readFile(filePath, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim().length > 0);\n if (lines.length === 0) {\n return null;\n }\n\n let runQueued: {\n runId: string;\n datasetId: string;\n datasetName: string;\n evaluatorIds: ReadonlyArray<string>;\n totalTestCases: number;\n artifactPath: string;\n ts?: number;\n } | null = null;\n\n let runCompleted: {\n passedTestCases: number;\n failedTestCases: number;\n totalTestCases: number;\n finishedAt: number;\n } | null = null;\n\n let runFailed: { finishedAt: number; errorMessage: string } | null = null;\n let runStarted: { startedAt: number } | null = null;\n\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n const type = event.type as string;\n\n if (type === 'RunQueued') {\n runQueued = {\n runId: event.runId as string,\n datasetId: event.datasetId as string,\n datasetName: event.datasetName as string,\n evaluatorIds: event.evaluatorIds as ReadonlyArray<string>,\n totalTestCases: (event.totalTestCases as number) ?? 0,\n artifactPath: (event.artifactPath as string) ?? filePath,\n ts: event.ts as number | undefined,\n };\n }\n if (type === 'RunStarted') {\n runStarted = { startedAt: event.startedAt as number };\n }\n if (type === 'RunCompleted') {\n runCompleted = {\n passedTestCases: event.passedTestCases as number,\n failedTestCases: event.failedTestCases as number,\n totalTestCases: event.totalTestCases as number,\n finishedAt: event.finishedAt as number,\n };\n }\n if (type === 'RunFailed') {\n runFailed = {\n finishedAt: event.finishedAt as number,\n errorMessage: event.errorMessage as string,\n };\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n if (!runQueued) {\n return null;\n }\n\n const artifactPath = filePath;\n\n const status = runFailed\n ? 'failed'\n : runCompleted\n ? 'completed'\n : runStarted\n ? 'running'\n : 'queued';\n\n const progress = aggregateTestCaseProgress(lines);\n const completedTestCases = runCompleted ? runQueued.totalTestCases : progress.completedTestCases;\n const passedTestCases = runCompleted?.passedTestCases ?? progress.passedTestCases;\n const failedTestCases = runCompleted?.failedTestCases ?? progress.failedTestCases;\n\n return {\n runId: runQueued.runId,\n datasetId: runQueued.datasetId,\n datasetName: runQueued.datasetName,\n evaluatorIds: runQueued.evaluatorIds,\n queuedAt: runQueued.ts ?? 0,\n startedAt: runStarted?.startedAt,\n finishedAt: runCompleted?.finishedAt ?? runFailed?.finishedAt,\n totalTestCases: runQueued.totalTestCases,\n completedTestCases,\n passedTestCases,\n failedTestCases,\n status,\n artifactPath,\n errorMessage: runFailed?.errorMessage,\n };\n}\n\nfunction aggregateTestCaseProgress(lines: string[]): {\n completedTestCases: number;\n passedTestCases: number;\n failedTestCases: number;\n} {\n let completedTestCases = 0;\n const testCasePassedBy = new Map<string, boolean>();\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n if (event.type === 'TestCaseProgress') {\n const ev = event as {\n testCaseId: string;\n completedTestCases: number;\n passed: boolean;\n };\n completedTestCases = ev.completedTestCases ?? completedTestCases;\n const id = ev.testCaseId;\n const current = testCasePassedBy.get(id);\n testCasePassedBy.set(id, current === undefined ? ev.passed : current && ev.passed);\n }\n } catch {\n // skip\n }\n }\n let passedTestCases = 0;\n let failedTestCases = 0;\n for (const passed of testCasePassedBy.values()) {\n if (passed) {\n passedTestCases += 1;\n } else {\n failedTestCases += 1;\n }\n }\n return { completedTestCases, passedTestCases, failedTestCases };\n}\n\nexport async function parseArtifactFile(artifactPath: string): Promise<ParsedTestCaseProgress[]> {\n try {\n const content = await readFile(artifactPath, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim().length > 0);\n const results: ParsedTestCaseProgress[] = [];\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n if (event.type === 'TestCaseProgress') {\n const ev = event as {\n testCaseId: string;\n testCaseName: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionId?: string;\n repetitionIndex?: number;\n repetitionCount?: number;\n rerunIndex?: number;\n rerunTotal?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<{\n id: string;\n data: unknown;\n passed?: boolean;\n name?: string;\n }>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<\n | { type: 'diff'; label?: string; expected: unknown; actual: unknown; diff: string }\n | { type: 'log'; label?: string; message: string }\n >;\n }>;\n };\n const repetitionIndex = ev.repetitionIndex ?? ev.rerunIndex;\n const repetitionCount = ev.repetitionCount ?? ev.rerunTotal;\n results.push({\n testCaseId: ev.testCaseId,\n testCaseName: ev.testCaseName,\n completedTestCases: ev.completedTestCases,\n totalTestCases: ev.totalTestCases,\n repetitionId: ev.repetitionId,\n repetitionIndex,\n repetitionCount,\n passed: ev.passed,\n durationMs: ev.durationMs,\n evaluatorScores: ev.evaluatorScores ?? [],\n });\n }\n } catch {\n // skip malformed lines\n }\n }\n return results;\n } catch {\n return [];\n }\n}\n","export interface RunnerDiscoveryConfig {\n rootDir: string;\n datasetSuffixes: ReadonlyArray<string>;\n evaluatorSuffixes: ReadonlyArray<string>;\n runConfigSuffixes: ReadonlyArray<string>;\n testCaseSuffixes: ReadonlyArray<string>;\n excludeDirectories: ReadonlyArray<string>;\n}\n\nexport interface RunnerConfig {\n discovery: RunnerDiscoveryConfig;\n artifactDirectory: string;\n /** Max concurrent test cases per run. Default: 1 (sequential). */\n maxConcurrency: number;\n}\n\nexport type RunnerConfigOverrides = Omit<Partial<RunnerConfig>, 'discovery'> & {\n discovery?: Partial<RunnerDiscoveryConfig>;\n};\n\nexport interface M4trixEvalConfigDiscovery {\n rootDir?: string;\n datasetFilePatterns?: ReadonlyArray<string>;\n evaluatorFilePatterns?: ReadonlyArray<string>;\n runConfigFilePatterns?: ReadonlyArray<string>;\n testCaseFilePatterns?: ReadonlyArray<string>;\n datasetSuffixes?: ReadonlyArray<string>;\n evaluatorSuffixes?: ReadonlyArray<string>;\n runConfigSuffixes?: ReadonlyArray<string>;\n testCaseSuffixes?: ReadonlyArray<string>;\n excludeDirectories?: ReadonlyArray<string>;\n}\n\nexport interface M4trixEvalConfig {\n discovery?: M4trixEvalConfigDiscovery;\n artifactDirectory?: string;\n /** Max concurrent test cases per run. Default: 1 (sequential). */\n maxConcurrency?: number;\n}\n\nexport type ConfigType = M4trixEvalConfig;\n\nexport type M4trixEvalConfigFactory<TConfig extends ConfigType = ConfigType> = () => TConfig;\n\nexport function defineConfig<TConfig extends ConfigType>(\n factory: M4trixEvalConfigFactory<TConfig>,\n): M4trixEvalConfigFactory<TConfig> {\n return factory;\n}\n\nexport const defaultRunnerConfig: RunnerConfig = {\n discovery: {\n rootDir: process.cwd(),\n datasetSuffixes: ['.dataset.ts', '.dataset.tsx', '.dataset.js', '.dataset.mjs'],\n evaluatorSuffixes: ['.evaluator.ts', '.evaluator.tsx', '.evaluator.js', '.evaluator.mjs'],\n runConfigSuffixes: ['.run-config.ts', '.run-config.tsx', '.run-config.js', '.run-config.mjs'],\n testCaseSuffixes: ['.test-case.ts', '.test-case.tsx', '.test-case.js', '.test-case.mjs'],\n excludeDirectories: ['node_modules', 'dist', '.next', '.git', '.pnpm-store'],\n },\n artifactDirectory: '.eval-results',\n maxConcurrency: 1,\n};\n\nexport function toRunnerConfigOverrides(config?: ConfigType): RunnerConfigOverrides | undefined {\n if (!config) {\n return undefined;\n }\n\n const rawDiscovery = config.discovery;\n const discovery: Partial<RunnerDiscoveryConfig> = {};\n if (rawDiscovery?.rootDir !== undefined) {\n discovery.rootDir = rawDiscovery.rootDir;\n }\n if (rawDiscovery?.datasetFilePatterns !== undefined) {\n discovery.datasetSuffixes = rawDiscovery.datasetFilePatterns;\n } else if (rawDiscovery?.datasetSuffixes !== undefined) {\n discovery.datasetSuffixes = rawDiscovery.datasetSuffixes;\n }\n if (rawDiscovery?.evaluatorFilePatterns !== undefined) {\n discovery.evaluatorSuffixes = rawDiscovery.evaluatorFilePatterns;\n } else if (rawDiscovery?.evaluatorSuffixes !== undefined) {\n discovery.evaluatorSuffixes = rawDiscovery.evaluatorSuffixes;\n }\n if (rawDiscovery?.runConfigFilePatterns !== undefined) {\n discovery.runConfigSuffixes = rawDiscovery.runConfigFilePatterns;\n } else if (rawDiscovery?.runConfigSuffixes !== undefined) {\n discovery.runConfigSuffixes = rawDiscovery.runConfigSuffixes;\n }\n if (rawDiscovery?.testCaseFilePatterns !== undefined) {\n discovery.testCaseSuffixes = rawDiscovery.testCaseFilePatterns;\n } else if (rawDiscovery?.testCaseSuffixes !== undefined) {\n discovery.testCaseSuffixes = rawDiscovery.testCaseSuffixes;\n }\n if (rawDiscovery?.excludeDirectories !== undefined) {\n discovery.excludeDirectories = rawDiscovery.excludeDirectories;\n }\n\n const overrides: RunnerConfigOverrides = {};\n if (config.artifactDirectory !== undefined) {\n overrides.artifactDirectory = config.artifactDirectory;\n }\n if (config.maxConcurrency !== undefined) {\n overrides.maxConcurrency = config.maxConcurrency;\n }\n if (Object.keys(discovery).length > 0) {\n overrides.discovery = discovery;\n }\n return overrides;\n}\n\nexport function withRunnerConfig(overrides?: RunnerConfigOverrides): RunnerConfig {\n if (!overrides) {\n return defaultRunnerConfig;\n }\n const discovery = overrides.discovery\n ? {\n ...defaultRunnerConfig.discovery,\n ...overrides.discovery,\n }\n : defaultRunnerConfig.discovery;\n\n return {\n ...defaultRunnerConfig,\n ...overrides,\n discovery,\n };\n}\n","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport * as jitiModule from 'jiti';\n\nimport type { RunnerConfigOverrides } from './config';\nimport { type ConfigType, type M4trixEvalConfigFactory, toRunnerConfigOverrides } from './config';\n\nconst CONFIG_FILE_NAME = 'm4trix-eval.config.ts';\n\ntype JitiLoader = {\n (id: string): unknown;\n import?: (id: string) => Promise<unknown> | unknown;\n};\n\nlet cachedLoader: JitiLoader | undefined;\n\nfunction getJitiLoader(): JitiLoader {\n if (cachedLoader) {\n return cachedLoader;\n }\n const createJiti =\n (jitiModule as { createJiti?: unknown; default?: unknown }).createJiti ??\n (jitiModule as { default?: unknown }).default;\n if (typeof createJiti !== 'function') {\n throw new Error('Failed to initialize jiti for m4trix eval config loading.');\n }\n cachedLoader = (createJiti as (id: string, options?: Record<string, unknown>) => JitiLoader)(\n import.meta.url,\n {\n interopDefault: true,\n moduleCache: true,\n },\n );\n return cachedLoader;\n}\n\nfunction resolveConfigModuleExport(loadedModule: unknown): unknown {\n if (loadedModule && typeof loadedModule === 'object' && 'default' in loadedModule) {\n return (loadedModule as { default: unknown }).default;\n }\n return loadedModule;\n}\n\nfunction resolveConfigValue(value: unknown): ConfigType | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n if (typeof value === 'function') {\n return (value as M4trixEvalConfigFactory<ConfigType>)();\n }\n if (typeof value !== 'object') {\n throw new Error(\n 'Invalid m4trix eval config export. Expected an object or defineConfig(() => config).',\n );\n }\n return value as ConfigType;\n}\n\nexport function loadRunnerConfigFile(cwd = process.cwd()): RunnerConfigOverrides | undefined {\n const configPath = resolve(cwd, CONFIG_FILE_NAME);\n if (!existsSync(configPath)) {\n return undefined;\n }\n const loader = getJitiLoader();\n const loaded = loader(configPath);\n const exportedValue = resolveConfigModuleExport(loaded);\n const config = resolveConfigValue(exportedValue);\n return toRunnerConfigOverrides(config);\n}\n","import type { Dirent } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { Dataset } from '../evals/dataset';\nimport type { Evaluator } from '../evals/evaluator';\nimport type { RunConfig } from '../evals/run-config';\nimport type { TestCase } from '../evals/test-case';\nimport type { RunnerDiscoveryConfig } from './config';\nimport type {\n CollectedDataset,\n CollectedEvaluator,\n CollectedRunConfig,\n CollectedTestCase,\n} from './events';\n\ntype JitiModuleLoader = {\n (id: string): unknown;\n import?: (id: string) => Promise<unknown> | unknown;\n};\n\nlet jitiLoader: JitiModuleLoader | undefined;\n\nfunction toId(prefix: string, filePath: string, name?: string): string {\n const stable = name && name.trim().length > 0 ? name : filePath;\n return `${prefix}:${stable}`\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction hasMethod(value: unknown, methodName: string): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n methodName in value &&\n typeof (value as Record<string, unknown>)[methodName] === 'function'\n );\n}\n\nfunction isDatasetLike(value: unknown): value is Dataset {\n return hasMethod(value, 'getName') && hasMethod(value, 'matchesTestCase');\n}\n\nfunction isEvaluatorLike(value: unknown): value is Evaluator<unknown, unknown, unknown, unknown> {\n return (\n hasMethod(value, 'getName') &&\n hasMethod(value, 'resolveContext') &&\n hasMethod(value, 'getEvaluateFn')\n );\n}\n\nfunction isRunConfigLike(value: unknown): value is RunConfig {\n return (\n hasMethod(value, 'getName') &&\n hasMethod(value, 'getRuns') &&\n typeof (value as RunConfig).getRuns === 'function'\n );\n}\n\nfunction isTestCaseLike(value: unknown): value is TestCase<unknown> {\n return hasMethod(value, 'getName') && hasMethod(value, 'getTags') && hasMethod(value, 'getInput');\n}\n\nasync function walkDirectory(\n rootDir: string,\n excludeDirectories: ReadonlyArray<string>,\n): Promise<string[]> {\n const out: string[] = [];\n\n async function walk(currentDir: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n await Promise.all(\n entries.map(async (entry) => {\n const absolute = resolve(currentDir, entry.name);\n if (entry.isDirectory()) {\n if (excludeDirectories.includes(entry.name)) {\n return;\n }\n await walk(absolute);\n return;\n }\n\n if (entry.isFile()) {\n out.push(absolute);\n }\n }),\n );\n }\n\n await walk(rootDir);\n return out;\n}\n\nfunction hasOneSuffix(filePath: string, suffixes: ReadonlyArray<string>): boolean {\n return suffixes.some((suffix) => filePath.endsWith(suffix));\n}\n\nasync function loadModuleExports(filePath: string): Promise<unknown[]> {\n if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {\n if (!jitiLoader) {\n const jitiModule = (await import('jiti')) as unknown as {\n createJiti?: (filename: string, opts?: Record<string, unknown>) => JitiModuleLoader;\n default?: (filename: string, opts?: Record<string, unknown>) => JitiModuleLoader;\n };\n const createJiti = jitiModule.createJiti ?? jitiModule.default;\n if (!createJiti) {\n throw new Error('Failed to initialize jiti TypeScript loader');\n }\n jitiLoader = createJiti(import.meta.url, {\n interopDefault: true,\n moduleCache: true,\n }) as JitiModuleLoader;\n }\n const loaded = jitiLoader.import\n ? await jitiLoader.import(filePath)\n : await Promise.resolve(jitiLoader(filePath));\n return Object.values(loaded as Record<string, unknown>);\n }\n\n const moduleUrl = pathToFileURL(filePath).href;\n const loaded = (await import(moduleUrl)) as Record<string, unknown>;\n return Object.values(loaded);\n}\n\nexport async function collectDatasetsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedDataset>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.datasetSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const datasets = exports.filter(isDatasetLike);\n const relPath = relative(config.rootDir, absolutePath);\n return datasets.map((dataset) => ({\n id: toId('dataset', relPath, dataset.getName()),\n filePath: relPath,\n dataset,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectEvaluatorsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedEvaluator>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.evaluatorSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const evaluators = exports.filter(isEvaluatorLike);\n const relPath = relative(config.rootDir, absolutePath);\n return evaluators.map((evaluator) => ({\n id: toId('evaluator', relPath, evaluator.getName()),\n filePath: relPath,\n evaluator,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectRunConfigsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedRunConfig>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.runConfigSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const runConfigs = exports.filter(isRunConfigLike);\n const relPath = relative(config.rootDir, absolutePath);\n return runConfigs.map((runConfig) => ({\n id: runConfig.getName(),\n filePath: relPath,\n runConfig,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectTestCasesFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedTestCase>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.testCaseSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const testCases = exports.filter(isTestCaseLike);\n const relPath = relative(config.rootDir, absolutePath);\n return testCases.map((testCase) => ({\n id: toId('test-case', relPath, testCase.getName()),\n filePath: relPath,\n testCase,\n }));\n }),\n );\n\n return found.flat();\n}\n","import { randomUUID } from 'node:crypto';\nimport { join } from 'node:path';\n\nimport { Effect, Queue, Ref } from 'effect';\nimport type { Dataset } from '../evals/dataset';\nimport type { CreateDiffLogEntryOptions, EvaluatorLogEntry } from '../evals/diff';\nimport { createDiffLogEntry, createLogEntry } from '../evals/diff';\nimport type { Evaluator } from '../evals/evaluator';\nimport { getEvaluatorTagList } from '../evals/evaluator';\nimport type { MetricItem } from '../evals/metric';\nimport type { ScoreItem } from '../evals/score';\nimport { getTestCaseDisplayLabel, getTestCaseTagList } from '../evals/test-case';\nimport type { CollectedTestCase, RunnerEvent, RunSnapshot } from './events';\nimport type { PersistenceMessage } from './persistence';\nimport { toNumericScoreFromScores } from './score-utils';\n\nconst evaluatorErrorLogEntryKey = '__m4trixEvaluatorLogEntry';\n\ntype EvaluatorCreatedError = Error & {\n [evaluatorErrorLogEntryKey]?: EvaluatorLogEntry;\n};\n\nfunction computeEvaluatorPassed(\n evaluator: Evaluator<unknown, unknown, unknown, unknown>,\n result: unknown,\n scores: ReadonlyArray<ScoreItem>,\n): boolean {\n const scoresWithPassed = scores.filter((s) => 'passed' in s && s.passed !== undefined);\n if (scoresWithPassed.length > 0) {\n return scoresWithPassed.every((s) => s.passed === true);\n }\n const passCriterion = evaluator.getPassCriterion();\n if (passCriterion) {\n return passCriterion(result);\n }\n const passThreshold = evaluator.getPassThreshold();\n if (passThreshold !== undefined) {\n const numeric = toNumericScoreFromScores(scores);\n return numeric !== undefined && numeric >= passThreshold;\n }\n return true;\n}\n\nfunction normalizeResult(result: unknown): {\n scores: ReadonlyArray<ScoreItem>;\n metrics?: ReadonlyArray<MetricItem>;\n} {\n if (typeof result !== 'object' || result === null) {\n return { scores: [] };\n }\n const obj = result as Record<string, unknown>;\n const scores = Array.isArray(obj.scores) ? (obj.scores as ReadonlyArray<ScoreItem>) : [];\n const metrics = Array.isArray(obj.metrics)\n ? (obj.metrics as ReadonlyArray<MetricItem>)\n : undefined;\n return { scores, metrics };\n}\n\nfunction readOutput(testCase: CollectedTestCase['testCase']): unknown {\n const candidate = testCase as unknown as { getOutput?: () => unknown };\n if (typeof candidate.getOutput !== 'function') {\n return undefined;\n }\n return candidate.getOutput();\n}\n\nexport interface RunTask {\n runId: string;\n triggerId: string;\n /** Same value as `meta.triggerTimestamp` for this run. */\n triggerTimestamp: number;\n datasetId: string;\n dataset: Dataset;\n evaluators: ReadonlyArray<{\n id: string;\n evaluator: Evaluator<unknown, unknown, unknown, unknown>;\n }>;\n testCases: ReadonlyArray<CollectedTestCase>;\n snapshot: RunSnapshot;\n maxConcurrency: number;\n /** When set, limits concurrent evaluation units across all runs sharing this semaphore. */\n globalEvaluationSemaphore?: ReturnType<typeof Effect.unsafeMakeSemaphore>;\n runConfigName: string;\n /** When set, forwarded as `experimentName` on evaluator `meta`. */\n experimentName?: string;\n /** Per job: tags from the run config or programmatic request; forwarded to evaluator callbacks. */\n runConfigTags: string[];\n /** Per scheduled job: how many times each dataset test case is executed. */\n repetitions: number;\n}\n\ninterface EvaluationUnit {\n testCaseItem: CollectedTestCase;\n repetitionId: string;\n repetitionIndex: number;\n repetitionCount: number;\n}\n\nfunction buildEvaluationUnits(\n testCases: ReadonlyArray<CollectedTestCase>,\n repetitionCount: number,\n): EvaluationUnit[] {\n const count = Math.max(1, repetitionCount);\n const units: EvaluationUnit[] = [];\n for (const testCaseItem of testCases) {\n const repetitionId = `rep-${randomUUID()}`;\n for (let r = 0; r < count; r++) {\n units.push({\n testCaseItem,\n repetitionId,\n repetitionIndex: r + 1,\n repetitionCount: count,\n });\n }\n }\n return units;\n}\n\nfunction nowIsoForFile(): string {\n return new Date().toISOString().replace(/[:.]/g, '-');\n}\n\nexport function createArtifactPath(\n artifactDirectory: string,\n datasetId: string,\n runId: string,\n): string {\n return join(artifactDirectory, `${datasetId}_${runId}_${nowIsoForFile()}.jsonl`);\n}\n\nfunction processOneEvaluation(\n task: RunTask,\n unit: EvaluationUnit,\n totalEvaluations: number,\n publishEvent: (event: RunnerEvent) => Effect.Effect<void, never, never>,\n persistenceQueue: Queue.Queue<PersistenceMessage>,\n updateSnapshot: (\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ) => Effect.Effect<void, never, never>,\n startedRef: Ref.Ref<number>,\n completedRef: Ref.Ref<number>,\n passedRef: Ref.Ref<number>,\n failedRef: Ref.Ref<number>,\n testCaseResultsRef: Ref.Ref<Map<string, { completedCount: number; results: boolean[] }>>,\n): Effect.Effect<void, never, never> {\n const { testCaseItem, repetitionId, repetitionIndex, repetitionCount } = unit;\n return Effect.gen(function* () {\n const evaluatorRunId = `run-${randomUUID()}`;\n const started = Date.now();\n const startedEvaluations = yield* Ref.modify(startedRef, (n) => [n + 1, n + 1]);\n yield* publishEvent({\n type: 'TestCaseStarted',\n runId: task.runId,\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n startedTestCases: startedEvaluations,\n totalTestCases: totalEvaluations,\n repetitionId,\n repetitionIndex,\n repetitionCount,\n });\n const evaluatorScores: Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<MetricItem>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n }> = [];\n let testCaseError: string | undefined;\n const output = readOutput(testCaseItem.testCase);\n\n for (const { id: evaluatorId, evaluator } of task.evaluators) {\n const evaluateFn = evaluator.getEvaluateFn();\n if (!evaluateFn) {\n continue;\n }\n\n const logs: EvaluatorLogEntry[] = [];\n const logDiff = (expected: unknown, actual: unknown, options?: CreateDiffLogEntryOptions) => {\n logs.push(createDiffLogEntry(expected, actual, options));\n };\n const log = (message: unknown, options?: { label?: string }) => {\n logs.push(createLogEntry(message, options));\n };\n const createError = (message: unknown, options?: { label?: string }): Error => {\n const entry = createLogEntry(message, options);\n const error = message instanceof Error ? message : new Error(entry.message);\n (error as EvaluatorCreatedError)[evaluatorErrorLogEntryKey] = entry;\n return error;\n };\n\n try {\n const ctx = yield* Effect.promise(() => Promise.resolve(evaluator.resolveContext()));\n const result = yield* Effect.promise(() =>\n Promise.resolve().then(() =>\n evaluateFn({\n input: testCaseItem.testCase.getInput(),\n ctx,\n output,\n meta: {\n triggerId: task.triggerId,\n triggerTimestamp: task.triggerTimestamp,\n runId: evaluatorRunId,\n datasetName: task.dataset.getDisplayLabel(),\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n repetitionId,\n repetitionIndex,\n repetitionCount,\n runConfigName: task.runConfigName,\n ...(task.experimentName !== undefined && task.experimentName !== ''\n ? { experimentName: task.experimentName }\n : {}),\n testCaseTags: getTestCaseTagList(testCaseItem.testCase),\n runConfigTags: task.runConfigTags,\n evaluatorTags: getEvaluatorTagList(evaluator),\n },\n logDiff,\n log,\n createError,\n }),\n ),\n );\n if (result instanceof Error) {\n const evaluatorError = result as EvaluatorCreatedError;\n const taggedEntry = evaluatorError[evaluatorErrorLogEntryKey];\n logs.push(taggedEntry ?? createLogEntry(result));\n testCaseError = result.message;\n evaluatorScores.push({\n evaluatorId,\n scores: [],\n passed: false,\n logs: logs.length > 0 ? logs : undefined,\n });\n continue;\n }\n const { scores, metrics } = normalizeResult(result);\n const passed = computeEvaluatorPassed(evaluator, result, scores);\n evaluatorScores.push({\n evaluatorId,\n scores,\n passed,\n metrics,\n logs: logs.length > 0 ? logs : undefined,\n });\n } catch (error) {\n if (error instanceof Error) {\n const taggedEntry = (error as EvaluatorCreatedError)[evaluatorErrorLogEntryKey];\n logs.push(taggedEntry ?? createLogEntry(error));\n }\n testCaseError = error instanceof Error ? error.message : 'Evaluator execution failed';\n evaluatorScores.push({\n evaluatorId,\n scores: [],\n passed: false,\n logs: logs.length > 0 ? logs : undefined,\n });\n }\n }\n\n const repetitionPassedThis = evaluatorScores.every((s) => s.passed);\n const completedEvaluations = yield* Ref.modify(completedRef, (n) => [n + 1, n + 1]);\n\n const progressEvent: RunnerEvent = {\n type: 'TestCaseProgress',\n runId: task.runId,\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n completedTestCases: completedEvaluations,\n totalTestCases: totalEvaluations,\n repetitionId,\n repetitionIndex,\n repetitionCount,\n passed: repetitionPassedThis,\n durationMs: Date.now() - started,\n evaluatorScores,\n output,\n errorMessage: testCaseError,\n };\n\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n completedTestCases: completedEvaluations,\n }));\n\n yield* publishEvent(progressEvent);\n yield* Queue.offer(persistenceQueue, {\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n payload: progressEvent,\n });\n\n const testCaseCompleted = yield* Ref.modify(\n testCaseResultsRef,\n (map): [boolean | null, Map<string, { completedCount: number; results: boolean[] }>] => {\n const key = testCaseItem.id;\n const existing = map.get(key) ?? { completedCount: 0, results: [] };\n const newResults = [...existing.results, repetitionPassedThis];\n const newCompletedCount = existing.completedCount + 1;\n const isLast = newCompletedCount === repetitionCount;\n const newMap = new Map(map);\n newMap.set(key, {\n completedCount: newCompletedCount,\n results: newResults,\n });\n const outcome: boolean | null = isLast ? newResults.every(Boolean) : null;\n return [outcome, newMap];\n },\n );\n\n if (testCaseCompleted !== null) {\n if (testCaseCompleted) {\n yield* Ref.update(passedRef, (n) => n + 1);\n } else {\n yield* Ref.update(failedRef, (n) => n + 1);\n }\n const [passed, failed] = yield* Effect.all([Ref.get(passedRef), Ref.get(failedRef)]);\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n passedTestCases: passed,\n failedTestCases: failed,\n }));\n }\n });\n}\n\nexport const executeRunTask = (\n task: RunTask,\n publishEvent: (event: RunnerEvent) => Effect.Effect<void, never, never>,\n persistenceQueue: Queue.Queue<PersistenceMessage>,\n updateSnapshot: (\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ) => Effect.Effect<void, never, never>,\n): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const startedAt = Date.now();\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n status: 'running',\n startedAt,\n }));\n yield* publishEvent({\n type: 'RunStarted',\n runId: task.runId,\n startedAt,\n });\n\n const totalEvaluations = task.testCases.length * Math.max(1, task.repetitions);\n const maxConcurrency = Math.max(1, task.maxConcurrency ?? 1);\n\n const completedRef = yield* Ref.make(0);\n const startedRef = yield* Ref.make(0);\n const passedRef = yield* Ref.make(0);\n const failedRef = yield* Ref.make(0);\n const testCaseResultsRef = yield* Ref.make(\n new Map<string, { completedCount: number; results: boolean[] }>(),\n );\n\n const evaluationUnits = buildEvaluationUnits(task.testCases, task.repetitions);\n\n const processEvaluation = (unit: EvaluationUnit) =>\n processOneEvaluation(\n task,\n unit,\n totalEvaluations,\n publishEvent,\n persistenceQueue,\n updateSnapshot,\n startedRef,\n completedRef,\n passedRef,\n failedRef,\n testCaseResultsRef,\n );\n\n const globalSem = task.globalEvaluationSemaphore;\n if (globalSem !== undefined) {\n yield* Effect.forEach(\n evaluationUnits,\n (unit) => globalSem.withPermits(1)(processEvaluation(unit)),\n { concurrency: 'unbounded', discard: true },\n );\n } else {\n yield* Effect.forEach(\n evaluationUnits,\n processEvaluation,\n maxConcurrency > 1 ? { concurrency: maxConcurrency } : undefined,\n );\n }\n\n const [completedEvaluations, passedUniqueTestCases, failedUniqueTestCases] = yield* Effect.all([\n Ref.get(completedRef),\n Ref.get(passedRef),\n Ref.get(failedRef),\n ]);\n\n const finishedAt = Date.now();\n const completedEvent: RunnerEvent = {\n type: 'RunCompleted',\n runId: task.runId,\n finishedAt,\n passedTestCases: passedUniqueTestCases,\n failedTestCases: failedUniqueTestCases,\n totalTestCases: task.testCases.length,\n artifactPath: task.snapshot.artifactPath,\n };\n\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n status: 'completed',\n completedTestCases: completedEvaluations,\n passedTestCases: passedUniqueTestCases,\n failedTestCases: failedUniqueTestCases,\n finishedAt,\n }));\n\n yield* publishEvent(completedEvent);\n yield* Queue.offer(persistenceQueue, {\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n payload: completedEvent,\n });\n yield* publishEvent({\n type: 'ArtifactFlushed',\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n });\n });\n","import { diffLines } from 'diff';\nimport stringify from 'fast-json-stable-stringify';\n\n/**\n * Options for customizing JSON diff output. Passed to logDiff, createDiffLogEntry, and printJsonDiff.\n */\nexport interface JsonDiffOptions {\n /** Include equal sections of the document, not just deltas (always true with current implementation) */\n full?: boolean;\n /** Sort primitive values in arrays before comparing */\n sort?: boolean;\n /** Compare only keys, ignore value differences */\n keysOnly?: boolean;\n /** Always output these keys when their parent object has any diff (comma-separated or array) */\n outputKeys?: string | string[];\n /** Output only new/updated values (no - lines) */\n outputNewOnly?: boolean;\n /** Exclude these keys from comparison (comma-separated or array) */\n excludeKeys?: string | string[];\n /** Include unchanged values in output */\n keepUnchangedValues?: boolean;\n /** Round floats to this many decimals before comparing */\n precision?: number;\n /** Max ... elisions in a row before collapsing */\n maxElisions?: number;\n}\n\nfunction preprocessForDiff(value: unknown, options?: JsonDiffOptions): unknown {\n if (options?.sort && Array.isArray(value)) {\n return [...value]\n .sort((a, b) => {\n const aStr = stringify(preprocessForDiff(a, options));\n const bStr = stringify(preprocessForDiff(b, options));\n return aStr.localeCompare(bStr);\n })\n .map((item) => preprocessForDiff(item, options));\n }\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n options?.excludeKeys\n ) {\n const keys = Array.isArray(options.excludeKeys)\n ? options.excludeKeys\n : options.excludeKeys.split(',').map((k) => k.trim());\n const filtered: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (!keys.includes(k)) {\n filtered[k] = preprocessForDiff(v, options);\n }\n }\n return filtered;\n }\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = preprocessForDiff(v, options);\n }\n return result;\n }\n if (typeof value === 'number' && options?.precision !== undefined) {\n return Number(value.toFixed(options.precision));\n }\n return value;\n}\n\nfunction toPrettyJson(value: unknown): string {\n const str = stringify(value);\n try {\n const parsed = JSON.parse(str) as unknown;\n return JSON.stringify(parsed, null, 2);\n } catch {\n return str;\n }\n}\n\nfunction formatDiffParts(\n parts: Array<{ added?: boolean; removed?: boolean; value: string }>,\n): string {\n const lines: string[] = [];\n for (const part of parts) {\n const prefix = part.added ? '+ ' : part.removed ? '- ' : '';\n const partLines = part.value.split('\\n');\n for (let i = 0; i < partLines.length; i++) {\n const line = partLines[i]!;\n if (i === partLines.length - 1 && line === '') continue;\n lines.push(prefix + line);\n }\n }\n return lines.join('\\n');\n}\n\nfunction createDiffString(\n expected: unknown,\n actual: unknown,\n diffOptions?: JsonDiffOptions,\n): string {\n const expectedProcessed = preprocessForDiff(expected, diffOptions);\n const actualProcessed = preprocessForDiff(actual, diffOptions);\n\n if (diffOptions?.keysOnly) {\n const expectedKeys = JSON.stringify(extractKeys(expectedProcessed), null, 2);\n const actualKeys = JSON.stringify(extractKeys(actualProcessed), null, 2);\n const parts = diffLines(expectedKeys, actualKeys);\n return formatDiffParts(parts);\n }\n\n const expectedStr = toPrettyJson(expectedProcessed);\n const actualStr = toPrettyJson(actualProcessed);\n\n if (expectedStr === actualStr) {\n return '';\n }\n\n const parts = diffLines(expectedStr, actualStr);\n\n if (diffOptions?.outputNewOnly) {\n const filtered = parts.filter((p: { added?: boolean }) => p.added === true);\n return formatDiffParts(filtered);\n }\n\n return formatDiffParts(parts);\n}\n\nfunction extractKeys(value: unknown): unknown {\n if (value === null || typeof value !== 'object') {\n return '·';\n }\n if (Array.isArray(value)) {\n return value.map(extractKeys);\n }\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = extractKeys(v);\n }\n return result;\n}\n\nexport interface DiffLogEntry {\n type: 'diff';\n label?: string;\n expected: unknown;\n actual: unknown;\n diff: string;\n}\n\nexport interface LogEntry {\n type: 'log';\n label?: string;\n message: string;\n}\n\nexport type EvaluatorLogEntry = DiffLogEntry | LogEntry;\n\nfunction formatLogMessage(msg: unknown): string {\n if (typeof msg === 'string') return msg;\n if (msg instanceof Error) return msg.stack ?? msg.message;\n try {\n if (msg !== null && typeof msg === 'object') {\n return JSON.stringify(msg, null, 2);\n }\n return String(msg);\n } catch {\n return String(msg);\n }\n}\n\n/**\n * Creates a LogEntry for storage in run artifacts. Use for logging objects or text.\n */\nexport function createLogEntry(message: unknown, options?: { label?: string }): LogEntry {\n return {\n type: 'log',\n label: options?.label,\n message: formatLogMessage(message),\n };\n}\n\n/**\n * Returns lines from a log entry for display.\n */\nexport function getLogLines(entry: LogEntry): string[] {\n return entry.message.split('\\n');\n}\n\nexport interface CreateDiffLogEntryOptions extends JsonDiffOptions {\n label?: string;\n}\n\nexport interface PrintJsonDiffOptions extends JsonDiffOptions {\n /** Enable ANSI colors (default: true) */\n color?: boolean;\n}\n\n/**\n * Creates a DiffLogEntry for storage in run artifacts (plain text, no ANSI).\n */\nexport function createDiffLogEntry(\n expected: unknown,\n actual: unknown,\n options?: CreateDiffLogEntryOptions,\n): DiffLogEntry {\n const { label, ...diffOpts } = options ?? {};\n const diff = createDiffString(expected, actual, diffOpts);\n return {\n type: 'diff',\n label,\n expected,\n actual,\n diff: diff || '(no differences)',\n };\n}\n\n/**\n * Returns the plain diff string. Use for storage or when applying colors separately.\n */\nexport function getDiffString(entry: DiffLogEntry): string {\n return entry.diff || '(no differences)';\n}\n\n/**\n * Returns lines from the diff, each with a type for color application.\n */\nexport function getDiffLines(\n entry: DiffLogEntry,\n): Array<{ type: 'add' | 'remove' | 'context'; line: string }> {\n const raw = entry.diff || '(no differences)';\n return raw.split('\\n').map((line) => {\n const trimmed = line.trimStart();\n if (trimmed.startsWith('-') && !trimmed.startsWith('---')) {\n return { type: 'remove' as const, line };\n }\n if (trimmed.startsWith('+') && !trimmed.startsWith('+++')) {\n return { type: 'add' as const, line };\n }\n return { type: 'context' as const, line };\n });\n}\n\n/**\n * Prints a colorized JSON diff between two values to stdout.\n * Useful in evaluators to show expected vs actual output differences.\n * @param expected - The expected/reference value (shown as removed with -)\n * @param actual - The actual value (shown as added with +)\n * @returns The diff string (also printed to console)\n */\nexport function printJsonDiff(\n expected: unknown,\n actual: unknown,\n options: PrintJsonDiffOptions = {},\n): string {\n const { color = true, ...diffOpts } = options;\n const diff = createDiffString(expected, actual, diffOpts);\n if (color) {\n const lines = diff.split('\\n').map((line) => {\n const trimmed = line.trimStart();\n if (trimmed.startsWith('-') && !trimmed.startsWith('---')) {\n return `\\x1b[31m${line}\\x1b[0m`;\n }\n if (trimmed.startsWith('+') && !trimmed.startsWith('+++')) {\n return `\\x1b[32m${line}\\x1b[0m`;\n }\n return line;\n });\n const colored = lines.join('\\n');\n console.log(colored || '(no differences)');\n return colored;\n }\n console.log(diff || '(no differences)');\n return diff;\n}\n","import type { Schema as S } from 'effect';\nimport {\n normalizeOptionalDisplayName,\n type TestCaseName,\n validateTestCaseName,\n} from './entity-name';\n\ntype InputOrBuilder<T> = T | (() => T);\n\ninterface TestCaseConfig<TInput, TOutput> {\n name: TestCaseName;\n displayName?: string;\n tags: string[];\n inputSchema: S.Schema.Any;\n input: InputOrBuilder<TInput>;\n outputSchema?: S.Schema.Any;\n output?: InputOrBuilder<TOutput>;\n}\n\ninterface TestCaseDescribeConfig<\n TI extends S.Schema.Any,\n TO extends S.Schema.Any = S.Schema<unknown>,\n> {\n /**\n * Stable id (letters, digits, `_`, `-`); used in discovery and matching.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI and evaluator args (any characters). */\n displayName?: string;\n /**\n * Declared tags on this test case (not `Dataset` filter options). Use `Dataset` `includedTags` /\n * `excludedTags` to select which cases belong to a dataset; evaluators read the resolved tags as\n * `meta.testCaseTags`.\n */\n tags?: ReadonlyArray<string>;\n inputSchema: TI;\n input: InputOrBuilder<S.Schema.Type<TI>>;\n outputSchema?: TO;\n output?: InputOrBuilder<S.Schema.Type<TO>>;\n}\n\nfunction resolve<T>(value: InputOrBuilder<T>): T {\n return typeof value === 'function' ? (value as () => T)() : value;\n}\n\nexport class TestCase<TInput = unknown, TOutput = unknown> {\n private readonly _config: TestCaseConfig<TInput, TOutput>;\n\n private constructor(config: TestCaseConfig<TInput, TOutput>) {\n this._config = config;\n }\n\n static describe<TI extends S.Schema.Any, TO extends S.Schema.Any = S.Schema<unknown>>(\n config: TestCaseDescribeConfig<TI, TO>,\n ): TestCase<S.Schema.Type<TI>, S.Schema.Type<TO>> {\n const name = validateTestCaseName(config.name, 'TestCase.describe');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n const tags = config.tags !== undefined ? [...config.tags] : [];\n return new TestCase<S.Schema.Type<TI>, S.Schema.Type<TO>>({\n name,\n displayName,\n tags,\n inputSchema: config.inputSchema,\n input: config.input,\n outputSchema: config.outputSchema,\n output: config.output,\n });\n }\n\n getName(): string {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n getDisplayLabel(): string {\n return this._config.displayName ?? this._config.name;\n }\n\n getTags(): string[] {\n return [...this._config.tags];\n }\n\n getInputSchema(): S.Schema.Any {\n return this._config.inputSchema;\n }\n\n getInput(): TInput {\n return resolve(this._config.input);\n }\n\n getOutputSchema(): S.Schema.Any | undefined {\n return this._config.outputSchema;\n }\n\n getOutput(): TOutput | undefined {\n if (this._config.output === undefined) {\n return undefined;\n }\n return resolve(this._config.output);\n }\n}\n\n/** CLI-friendly label: {@link TestCase.getDisplayLabel} when present, else {@link TestCase.getName} (supports plain test-case-shaped objects). */\nexport function getTestCaseDisplayLabel(testCase: {\n getDisplayLabel?: () => string;\n getName?: () => string;\n}): string {\n if (typeof testCase.getDisplayLabel === 'function') {\n return testCase.getDisplayLabel();\n }\n return typeof testCase.getName === 'function' ? testCase.getName() : '';\n}\n\n/** Tags for evaluator `meta.testCaseTags` (supports plain test-case-shaped objects without `getTags`). */\nexport function getTestCaseTagList(testCase: { getTags?: () => ReadonlyArray<string> }): string[] {\n return typeof testCase.getTags === 'function' ? [...testCase.getTags()] : [];\n}\n","import { type DatasetName, normalizeOptionalDisplayName, validateDatasetName } from './entity-name';\nimport type { TestCase } from './test-case';\nimport type { PathMatcher, TagMatcher } from './types';\n\ninterface DatasetConfig {\n name: DatasetName;\n displayName?: string;\n includedTags: ReadonlyArray<TagMatcher>;\n excludedTags: ReadonlyArray<TagMatcher>;\n includedPaths: ReadonlyArray<PathMatcher>;\n excludedPaths: ReadonlyArray<PathMatcher>;\n}\n\nexport interface DatasetDefineConfig {\n /**\n * Stable id (letters, digits, `_`, `-`); used for discovery ids and `resolveDatasetByName`.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI (any characters). */\n displayName?: string;\n includedTags?: TagMatcher[];\n excludedTags?: TagMatcher[];\n includedPaths?: PathMatcher[];\n excludedPaths?: PathMatcher[];\n}\n\nfunction matchesAny(value: string, matchers: ReadonlyArray<string | RegExp>): boolean {\n return matchers.some((matcher) =>\n typeof matcher === 'string' ? value === matcher : matcher.test(value),\n );\n}\n\nfunction matchesAnyPath(filePath: string, matchers: ReadonlyArray<string | RegExp>): boolean {\n return matchers.some((matcher) => {\n if (typeof matcher === 'string') {\n return simpleGlobMatch(matcher, filePath);\n }\n return matcher.test(filePath);\n });\n}\n\nfunction simpleGlobMatch(pattern: string, value: string): boolean {\n const escaped = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\?/g, '[^/]')\n .replace(/\\*\\*\\//g, '(?:.*/)?')\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*');\n return new RegExp(`^${escaped}$`).test(value);\n}\n\nexport class Dataset {\n private readonly _config: DatasetConfig;\n\n private constructor(config: DatasetConfig) {\n this._config = config;\n }\n\n static define(config: DatasetDefineConfig): Dataset {\n const name = validateDatasetName(config.name, 'Dataset.define');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n return new Dataset({\n name,\n displayName,\n includedTags: config.includedTags ?? [],\n excludedTags: config.excludedTags ?? [],\n includedPaths: config.includedPaths ?? [],\n excludedPaths: config.excludedPaths ?? [],\n });\n }\n\n /** Canonical dataset id (same rules as `RunConfig` / `TestCase` `name`). */\n getName(): string {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n /** Label for CLI/TUI and evaluator `meta.datasetName`: {@link getDisplayName} if set, otherwise {@link getName}. */\n getDisplayLabel(): string {\n return this._config.displayName ?? this._config.name;\n }\n\n getIncludedTags(): ReadonlyArray<TagMatcher> {\n return this._config.includedTags;\n }\n\n getExcludedTags(): ReadonlyArray<TagMatcher> {\n return this._config.excludedTags;\n }\n\n getIncludedPaths(): ReadonlyArray<PathMatcher> {\n return this._config.includedPaths;\n }\n\n getExcludedPaths(): ReadonlyArray<PathMatcher> {\n return this._config.excludedPaths;\n }\n\n matchesTestCase(testCase: TestCase<unknown>, filePath: string): boolean {\n const tags = testCase.getTags();\n\n if (this._config.excludedTags.length > 0) {\n if (tags.some((tag) => matchesAny(tag, this._config.excludedTags))) {\n return false;\n }\n }\n\n if (this._config.excludedPaths.length > 0) {\n if (matchesAnyPath(filePath, this._config.excludedPaths)) {\n return false;\n }\n }\n\n const tagMatch =\n this._config.includedTags.length === 0 ||\n tags.some((tag) => matchesAny(tag, this._config.includedTags));\n\n const pathMatch =\n this._config.includedPaths.length === 0 ||\n matchesAnyPath(filePath, this._config.includedPaths);\n\n return tagMatch && pathMatch;\n }\n}\n\n/** CLI / runner: display label for a dataset-shaped object (supports discovery duck-types). */\nexport function getDatasetDisplayLabel(dataset: {\n getDisplayLabel?: () => string;\n getName?: () => string;\n}): string {\n if (typeof dataset.getDisplayLabel === 'function') {\n return dataset.getDisplayLabel();\n }\n return typeof dataset.getName === 'function' ? dataset.getName() : '';\n}\n","const registry = new Map<string, MetricDef<unknown>>();\n\nexport interface MetricItem<TData = unknown> {\n readonly id: string;\n readonly data: TData;\n /** Per-item display name override (wins over def.name in rendering) */\n readonly name?: string;\n}\n\nexport interface FormatMetricOptions {\n isAggregated?: boolean;\n}\n\nexport interface MetricDef<TData = unknown> {\n readonly id: string;\n readonly name?: string;\n readonly aggregate?: (values: ReadonlyArray<TData>) => TData;\n format(data: TData, options?: FormatMetricOptions): string;\n make(data: TData, options?: { name?: string }): MetricItem<TData>;\n}\n\nexport const Metric = {\n of<TData>(config: {\n id: string;\n name?: string;\n format: (data: TData, options?: FormatMetricOptions) => string;\n aggregate?: (values: ReadonlyArray<TData>) => TData;\n }): MetricDef<TData> {\n const def: MetricDef<TData> = {\n id: config.id,\n name: config.name,\n aggregate: config.aggregate,\n format: config.format,\n make: (data: TData, options?: { name?: string }) => ({\n id: config.id,\n data,\n ...(options?.name !== undefined && { name: options.name }),\n }),\n };\n registry.set(config.id, def as MetricDef<unknown>);\n return def;\n },\n};\n\nexport function getMetricById(id: string): MetricDef<unknown> | undefined {\n return registry.get(id);\n}\n","/** Average of numeric `value` fields (e.g. for percentScore) */\nexport function aggregateAverage(values: ReadonlyArray<{ value: number }>): {\n value: number;\n} {\n if (values.length === 0) {\n return { value: 0 };\n }\n const sum = values.reduce((s, v) => s + v.value, 0);\n return { value: sum / values.length };\n}\n\n/** Average with sample std dev (for percentScore when aggregated) */\nexport function aggregateAverageWithVariance(values: ReadonlyArray<{ value: number }>): {\n value: number;\n stdDev?: number;\n count: number;\n} {\n if (values.length === 0) {\n return { value: 0, count: 0 };\n }\n const sum = values.reduce((s, v) => s + v.value, 0);\n const sumSq = values.reduce((s, v) => s + v.value * v.value, 0);\n const mean = sum / values.length;\n let stdDev: number | undefined;\n if (values.length >= 2) {\n const variance = (sumSq - values.length * mean * mean) / (values.length - 1);\n stdDev = variance > 0 ? Math.sqrt(variance) : 0;\n }\n return { value: mean, stdDev, count: values.length };\n}\n\n/** All runs must pass (for binaryScore). Returns passed and count for spread display. */\nexport function aggregateAll(values: ReadonlyArray<{ passed: boolean }>): {\n passed: boolean;\n passedCount?: number;\n totalCount?: number;\n} {\n const total = values.length;\n const passedCount = values.filter((v) => v.passed).length;\n return {\n passed: total > 0 && values.every((v) => v.passed),\n passedCount,\n totalCount: total,\n };\n}\n\ntype TokenCountSum = {\n input: number;\n output: number;\n inputCached: number;\n outputCached: number;\n};\n\n/** Sum token counts across repetitions of the same test case */\nexport function aggregateTokenCountSum(\n values: ReadonlyArray<{\n input?: number;\n output?: number;\n inputCached?: number;\n outputCached?: number;\n }>,\n): TokenCountSum {\n const initial: TokenCountSum = {\n input: 0,\n output: 0,\n inputCached: 0,\n outputCached: 0,\n };\n return values.reduce<TokenCountSum>(\n (acc, v) => ({\n input: acc.input + (v.input ?? 0),\n output: acc.output + (v.output ?? 0),\n inputCached: acc.inputCached + (v.inputCached ?? 0),\n outputCached: acc.outputCached + (v.outputCached ?? 0),\n }),\n initial,\n );\n}\n\n/** Average latency across repetitions of the same test case */\nexport function aggregateLatencyAverage(values: ReadonlyArray<{ ms: number }>): { ms: number } {\n if (values.length === 0) {\n return { ms: 0 };\n }\n const sum = values.reduce((s, v) => s + v.ms, 0);\n return { ms: sum / values.length };\n}\n","import { aggregateLatencyAverage, aggregateTokenCountSum } from '../aggregators';\nimport { Metric } from '../metric';\n\nexport interface TokenCountData {\n input?: number;\n output?: number;\n inputCached?: number;\n outputCached?: number;\n}\n\nexport const tokenCountMetric = Metric.of<TokenCountData>({\n id: 'token-count',\n name: 'Tokens',\n aggregate: aggregateTokenCountSum,\n format: (data, options) => {\n const input = data.input ?? 0;\n const output = data.output ?? 0;\n const inputCached = data.inputCached ?? 0;\n const outputCached = data.outputCached ?? 0;\n const cached = inputCached + outputCached;\n const base = `in:${input} out:${output} cached:${cached}`;\n return options?.isAggregated ? `Total: ${base}` : base;\n },\n});\n\nexport interface LatencyData {\n ms: number;\n}\n\nexport const latencyMetric = Metric.of<LatencyData>({\n id: 'latency',\n name: 'Latency',\n aggregate: aggregateLatencyAverage,\n format: (data, options) => (options?.isAggregated ? `Avg: ${data.ms}ms` : `${data.ms}ms`),\n});\n","const registry = new Map<string, ScoreDef<unknown>>();\n\nexport type ScoreDisplayStrategy = 'bar' | 'number' | 'passFail';\n\nexport interface ScoreItem<TData = unknown> {\n readonly id: string;\n readonly data: TData;\n readonly passed?: boolean;\n /** Per-item display name override (wins over def.name in rendering) */\n readonly name?: string;\n /** Attached def for formatting/aggregation without registry lookup (avoids n/a across module boundaries) */\n readonly def?: ScoreDef<TData>;\n}\n\nexport interface FormatScoreOptions {\n isAggregated?: boolean;\n}\n\nexport interface ScoreDef<TData = unknown> {\n readonly id: string;\n readonly name?: string;\n readonly displayStrategy: ScoreDisplayStrategy;\n readonly formatValue: (data: TData) => string;\n readonly formatAggregate: (data: TData) => string;\n readonly aggregateValues: (values: ReadonlyArray<TData>) => TData;\n make(\n data: TData,\n options?: { definePassed?: (data: TData) => boolean; name?: string },\n ): ScoreItem<TData>;\n}\n\n/** Helper to format using the right method based on isAggregated (for consumers that need a single entry point) */\nexport function formatScoreData<TData>(\n def: ScoreDef<TData>,\n data: TData,\n options?: FormatScoreOptions,\n): string {\n return options?.isAggregated ? def.formatAggregate(data) : def.formatValue(data);\n}\n\n/** Aggregate helpers for common patterns. Use with aggregateValues in Score.of(). */\nexport const ScoreAggregate = {\n /** Average numeric fields. Use for scores like { value, delta }. */\n averageFields<K extends string>(\n fields: readonly K[],\n ): (values: ReadonlyArray<Record<K, number>>) => Record<K, number> {\n return (values) => {\n const count = values.length || 1;\n const result = {} as Record<string, number>;\n for (const field of fields) {\n result[field] =\n values.reduce((s, v) => s + ((v as Record<string, number>)[field] ?? 0), 0) / count;\n }\n return result as unknown as Record<K, number>;\n };\n },\n\n /** Average selected numeric fields, with sample std dev tracked for `value`. */\n averageWithVariance<K extends string>(\n fields: readonly K[],\n ): (\n values: ReadonlyArray<Record<K, number>>,\n ) => Record<K, number> & { stdDev?: number; count: number } {\n return (values) => {\n const count = values.length;\n const result = {} as Record<string, number>;\n\n for (const field of fields) {\n result[field] =\n count === 0\n ? 0\n : values.reduce(\n (sum, item) => sum + ((item as Record<string, number>)[field] ?? 0),\n 0,\n ) / count;\n }\n\n const valueField = 'value' as K;\n const hasValueField = fields.includes(valueField);\n\n if (count === 0) {\n if (hasValueField) {\n result[valueField] = 0;\n }\n return {\n ...(result as Record<K, number>),\n stdDev: undefined,\n count: 0,\n };\n }\n\n let stdDev: number | undefined;\n if (hasValueField && count >= 2) {\n const sum = values.reduce(\n (s, v) => s + ((v as Record<string, number>)[valueField] ?? 0),\n 0,\n );\n const sumSq = values.reduce((s, v) => {\n const value = (v as Record<string, number>)[valueField] ?? 0;\n return s + value * value;\n }, 0);\n const mean = sum / count;\n const variance = (sumSq - count * mean * mean) / (count - 1);\n stdDev = variance > 0 ? Math.sqrt(variance) : 0;\n }\n\n return {\n ...values[0],\n ...(result as Record<K, number>),\n stdDev,\n count,\n };\n };\n },\n\n /** All runs must pass. Use for binary scores. */\n all<T extends { passed: boolean }>(\n values: ReadonlyArray<T>,\n ): T & { passedCount?: number; totalCount?: number } {\n const total = values.length;\n const passedCount = values.filter((v) => v.passed).length;\n return {\n ...values[0],\n passed: total > 0 && values.every((v) => v.passed),\n passedCount,\n totalCount: total,\n } as T & { passedCount?: number; totalCount?: number };\n },\n\n /** Take last value (no aggregation). Use when aggregation is not meaningful. */\n last<T>(values: ReadonlyArray<T>): T {\n return values[values.length - 1] ?? ({} as T);\n },\n};\n\nexport const Score = {\n aggregate: ScoreAggregate,\n\n of<TData>(config: {\n id: string;\n name?: string;\n displayStrategy: ScoreDisplayStrategy;\n formatValue: (data: TData) => string;\n formatAggregate: (data: TData) => string;\n aggregateValues: (values: ReadonlyArray<TData>) => TData;\n }): ScoreDef<TData> {\n const def: ScoreDef<TData> = {\n id: config.id,\n name: config.name,\n displayStrategy: config.displayStrategy,\n formatValue: config.formatValue,\n formatAggregate: config.formatAggregate,\n aggregateValues: config.aggregateValues,\n make: (data: TData, options?: { definePassed?: (data: TData) => boolean; name?: string }) => {\n const passed = options?.definePassed !== undefined ? options.definePassed(data) : undefined;\n return {\n id: config.id,\n data,\n ...(passed !== undefined && { passed }),\n ...(options?.name !== undefined && { name: options.name }),\n def, // Attach def so rendering/aggregation works without registry lookup\n };\n },\n };\n registry.set(config.id, def as ScoreDef<unknown>);\n return def;\n },\n};\n\nexport function getScoreById(id: string): ScoreDef<unknown> | undefined {\n return registry.get(id);\n}\n","import { Score } from '../score';\n\nexport interface PercentScoreData {\n value: number;\n stdDev?: number;\n count?: number;\n}\n\nexport const percentScore = Score.of<PercentScoreData>({\n id: 'percent',\n name: 'Score',\n displayStrategy: 'bar',\n formatValue: (data) => data.value.toFixed(2),\n formatAggregate: (data) =>\n data.stdDev != null\n ? `Avg: ${data.value.toFixed(2)} ± ${data.stdDev.toFixed(2)}`\n : `Avg: ${data.value.toFixed(2)}`,\n aggregateValues: Score.aggregate.averageWithVariance(['value']),\n});\n\nexport interface DeltaScoreData {\n value: number;\n delta: number;\n}\n\nexport const deltaScore = Score.of<DeltaScoreData>({\n id: 'delta',\n name: 'Delta',\n displayStrategy: 'number',\n formatValue: (data) =>\n `${data.value.toFixed(2)} (${data.delta >= 0 ? '+' : ''}${data.delta.toFixed(2)} vs baseline)`,\n formatAggregate: (data) =>\n `Avg: ${data.value.toFixed(2)} (Delta: ${data.delta >= 0 ? '+' : ''}${data.delta.toFixed(2)})`,\n aggregateValues: Score.aggregate.averageFields(['value', 'delta']),\n});\n\nexport interface BinaryScoreData {\n passed: boolean;\n passedCount?: number;\n totalCount?: number;\n}\n\nexport const binaryScore = Score.of<BinaryScoreData>({\n id: 'binary',\n name: 'Result',\n displayStrategy: 'passFail',\n formatValue: (data) => (data.passed ? 'PASSED' : 'NOT PASSED'),\n formatAggregate: (data) => {\n const base = data.passed ? 'All: PASSED' : 'Some: FAILED';\n if (data.passedCount != null && data.totalCount != null && data.totalCount > 1) {\n return `${base} (${data.passedCount}/${data.totalCount})`;\n }\n return base;\n },\n aggregateValues: Score.aggregate.all,\n});\n","import type { MetricItem } from '../evals/metric';\nimport type { ScoreDef, ScoreItem } from '../evals/score';\nimport { getMetricById, getScoreById } from '../evals';\n\nfunction getScoreDef(item: ScoreItem): ScoreDef<unknown> | undefined {\n return item.def ?? getScoreById(item.id);\n}\n\nfunction lastNonEmptyName(items: ReadonlyArray<{ name?: string }>): string | undefined {\n for (let i = items.length - 1; i >= 0; i--) {\n const n = items[i].name;\n if (n != null && n.trim().length > 0) return n;\n }\n return undefined;\n}\n\nexport function aggregateScoreItems(items: ReadonlyArray<ScoreItem>): ScoreItem | undefined {\n if (items.length === 0) return undefined;\n const def = getScoreDef(items[0]);\n if (!def?.aggregateValues) return items[items.length - 1];\n const aggregated = def.aggregateValues(items.map((i) => i.data as never));\n const nameOverride = lastNonEmptyName(items);\n return {\n ...items[0],\n data: aggregated,\n def,\n ...(nameOverride !== undefined && { name: nameOverride }),\n };\n}\n\nexport function aggregateMetricItems(items: ReadonlyArray<MetricItem>): MetricItem | undefined {\n if (items.length === 0) return undefined;\n const def = getMetricById(items[0].id);\n if (!def?.aggregate) return items[items.length - 1];\n const aggregated = def.aggregate(items.map((i) => i.data as never));\n const nameOverride = lastNonEmptyName(items);\n return {\n ...items[0],\n data: aggregated,\n ...(nameOverride !== undefined && { name: nameOverride }),\n };\n}\n\nexport function toNumericScoreFromScores(scores: ReadonlyArray<ScoreItem>): number | undefined {\n for (const item of scores) {\n const def = getScoreDef(item);\n if (\n def &&\n def.displayStrategy === 'bar' &&\n typeof item.data === 'object' &&\n item.data !== null &&\n 'value' in item.data\n ) {\n const value = (item.data as { value: unknown }).value;\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n }\n const numeric = toNumericScore(item.data);\n if (numeric !== undefined) {\n return numeric;\n }\n }\n return undefined;\n}\n\nexport function toNumericScore(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value !== 'object' || value === null) {\n return undefined;\n }\n const obj = value as Record<string, unknown>;\n if ('score' in obj && typeof obj.score === 'number' && Number.isFinite(obj.score)) {\n return obj.score;\n }\n const numberValues = Object.values(value).filter(\n (entry): entry is number => typeof entry === 'number' && Number.isFinite(entry),\n );\n if (numberValues.length === 0) {\n return undefined;\n }\n return numberValues.reduce((sum, entry) => sum + entry, 0) / numberValues.length;\n}\n","export function parseRegexLiteral(pattern: string): { source: string; flags: string } | undefined {\n if (!pattern.startsWith('/')) {\n return undefined;\n }\n const lastSlash = pattern.lastIndexOf('/');\n if (lastSlash <= 0) {\n return undefined;\n }\n return {\n source: pattern.slice(1, lastSlash),\n flags: pattern.slice(lastSlash + 1),\n };\n}\n\n/** Same matching rules as `RunnerApi.resolveEvaluatorsByNamePattern` (RunConfig `evaluatorPattern`, etc.). */\nexport function createNameMatcher(pattern: string): (value: string) => boolean {\n const normalizedPattern = pattern.trim();\n const regexLiteral = parseRegexLiteral(normalizedPattern);\n if (regexLiteral) {\n const regex = new RegExp(regexLiteral.source, regexLiteral.flags);\n return (value: string) => regex.test(value);\n }\n\n if (normalizedPattern.includes('*')) {\n const escaped = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n const regex = new RegExp(`^${escaped}$`, 'i');\n return (value: string) => regex.test(value);\n }\n\n return (value: string) => value.toLowerCase() === normalizedPattern.toLowerCase();\n}\n","import { appendFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport { Effect, Queue } from 'effect';\n\nexport interface PersistenceMessage {\n runId: string;\n artifactPath: string;\n payload: unknown;\n}\n\nasync function appendJsonLine(artifactPath: string, payload: unknown): Promise<void> {\n await mkdir(dirname(artifactPath), { recursive: true });\n await appendFile(artifactPath, `${JSON.stringify(payload)}\\n`, 'utf8');\n}\n\nexport const createPersistenceWorker = (\n queue: Queue.Queue<PersistenceMessage>,\n): Effect.Effect<never, never, never> =>\n Effect.forever(\n Effect.gen(function* () {\n const message = yield* Queue.take(queue);\n yield* Effect.promise(() =>\n appendJsonLine(message.artifactPath, {\n runId: message.runId,\n ts: Date.now(),\n ...(typeof message.payload === 'object' &&\n message.payload !== null &&\n !Array.isArray(message.payload)\n ? message.payload\n : {}),\n }),\n );\n }),\n );\n","import type { CollectedTestCase, SearchTestCasesQuery } from './events';\n\nfunction matchesAny(value: string, matchers: ReadonlyArray<string | RegExp> | undefined): boolean {\n if (!matchers || matchers.length === 0) {\n return true;\n }\n return matchers.some((matcher) =>\n typeof matcher === 'string' ? matcher === value : matcher.test(value),\n );\n}\n\nfunction matchesPath(value: string, matchers: ReadonlyArray<string | RegExp> | undefined): boolean {\n if (!matchers || matchers.length === 0) {\n return true;\n }\n return matchers.some((matcher) => {\n if (typeof matcher === 'string') {\n return value.includes(matcher);\n }\n return matcher.test(value);\n });\n}\n\nexport function searchCollectedTestCases(\n all: ReadonlyArray<CollectedTestCase>,\n query?: SearchTestCasesQuery,\n): ReadonlyArray<CollectedTestCase> {\n if (!query) {\n return all;\n }\n\n return all.filter((item) => {\n const tags = item.testCase.getTags();\n\n if (query.excludedTags && tags.some((tag) => matchesAny(tag, query.excludedTags))) {\n return false;\n }\n if (query.excludedPaths && matchesPath(item.filePath, query.excludedPaths)) {\n return false;\n }\n\n const includedTagsMatch =\n !query.includedTags ||\n query.includedTags.length === 0 ||\n tags.some((tag) => matchesAny(tag, query.includedTags));\n\n const includedPathsMatch =\n !query.includedPaths ||\n query.includedPaths.length === 0 ||\n matchesPath(item.filePath, query.includedPaths);\n\n return includedTagsMatch && includedPathsMatch;\n });\n}\n","export type SimpleCliCommand = 'run' | 'generate';\n\nexport interface SimpleCliArgs {\n command?: SimpleCliCommand;\n /** For `generate` only. */\n datasetName?: string;\n /** Repeatable: each `--run-config` adds a RunConfig to execute (expanded jobs run with shared concurrency). */\n runConfigNames: string[];\n /** Max concurrent evaluations. Default: 4. Use 1 for sequential. */\n concurrency?: number;\n /** Optional label passed to evaluator `meta.experimentName` for this CLI run. */\n experimentName?: string;\n /**\n * When set (typically for `run`), exit with code 1 if any test case fails.\n * Ignored for `generate`.\n */\n ci: boolean;\n help: boolean;\n unknownArgs: string[];\n}\n\n/** Default concurrency for I/O-bound evals (e.g. LLM API calls). Node is single-threaded, so CPU count is not meaningful. */\nexport function getDefaultConcurrency(): number {\n return 4;\n}\n\nexport function parseSimpleCliArgs(argv: string[]): SimpleCliArgs {\n const args: SimpleCliArgs = {\n help: false,\n ci: false,\n runConfigNames: [],\n unknownArgs: [],\n };\n let index = 0;\n if (argv[0] === 'run' || argv[0] === 'generate') {\n args.command = argv[0];\n index = 1;\n }\n\n for (; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === '--help' || token === '-h') {\n args.help = true;\n continue;\n }\n if (token === '--ci') {\n args.ci = true;\n continue;\n }\n if ((token === '--dataset' || token === '--datasetName') && argv[index + 1]) {\n args.datasetName = argv[index + 1];\n index += 1;\n continue;\n }\n if ((token === '--run-config' || token === '--runConfig') && argv[index + 1]) {\n const next = argv[index + 1];\n if (typeof next === 'string') {\n args.runConfigNames.push(next);\n }\n index += 1;\n continue;\n }\n if ((token === '--concurrency' || token === '-c') && argv[index + 1]) {\n const nextConc = argv[index + 1];\n const n = typeof nextConc === 'string' ? parseInt(nextConc, 10) : Number.NaN;\n if (!Number.isNaN(n) && n >= 1) {\n args.concurrency = n;\n }\n index += 1;\n continue;\n }\n if (token === '--experiment' && argv[index + 1]) {\n const raw = argv[index + 1];\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n if (trimmed.length > 0) {\n args.experimentName = trimmed;\n }\n }\n index += 1;\n continue;\n }\n args.unknownArgs.push(token);\n }\n\n return args;\n}\n\nexport function getSimpleCliUsage(): string {\n return [\n 'Usage:',\n ' eval-agents-simple run --run-config <name> [--run-config <name> ...] [--concurrency N] [--experiment <name>] [--ci]',\n ' eval-agents-simple generate --dataset <datasetId>',\n '',\n 'Options:',\n ' --ci With run: exit with code 1 if any test case fails.',\n ' --concurrency, -c N Max concurrent evaluations (default: 4). Use 1 for sequential.',\n ' --experiment <name> With run: set evaluator meta.experimentName for this invocation.',\n ].join('\\n');\n}\n","const ansi = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n cyan: '\\x1b[36m',\n} as const;\n\nexport function printBanner(): void {\n const c = (s: string) => `${ansi.cyan}${s}${ansi.reset}`;\n const d = (s: string) => `${ansi.dim}${s}${ansi.reset}`;\n\n const lines = [\n '',\n ` ${c('╭─────────────────────────────────────────────╮')}`,\n ` ${c('│')} ${d('@m4trix/evals')} ${c('·')} ${d('eval-agents-simple')} ${c('│')}`,\n ` ${c('╰─────────────────────────────────────────────╯')}`,\n '',\n ];\n\n console.log(lines.join('\\n'));\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport { writeFile } from 'node:fs/promises';\nimport { join, parse, resolve } from 'node:path';\n\nimport { getDatasetDisplayLabel } from '../evals/dataset';\nimport { getTestCaseDisplayLabel } from '../evals/test-case';\nimport type { RunnerApi } from '../runner';\nimport { GenerateView } from './views/GenerateView';\n\ninterface GeneratedDatasetCase {\n name: string;\n input: unknown;\n output?: unknown;\n}\n\nfunction readOutput(testCase: { getOutput?: () => unknown }): unknown {\n if (typeof testCase.getOutput !== 'function') {\n return undefined;\n }\n return testCase.getOutput();\n}\n\nfunction createOutputPath(datasetFilePath: string): string {\n const parsed = parse(datasetFilePath);\n return join(parsed.dir, `${parsed.name}.cases.json`);\n}\n\nexport async function generateDatasetJsonCommandPlain(\n runner: RunnerApi,\n datasetName: string,\n): Promise<void> {\n const dataset = await runner.resolveDatasetByName(datasetName);\n if (!dataset) {\n throw new Error(`Dataset \"${datasetName}\" not found.`);\n }\n\n const testCases = await runner.collectDatasetTestCases(dataset.id);\n const payload: GeneratedDatasetCase[] = testCases.map((item) => ({\n name: getTestCaseDisplayLabel(item.testCase),\n input: item.testCase.getInput(),\n output: readOutput(item.testCase),\n }));\n\n const absoluteDatasetPath = resolve(process.cwd(), dataset.filePath);\n const outputPath = createOutputPath(absoluteDatasetPath);\n\n await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n\n console.log(`Generated ${payload.length} test cases for dataset \"${getDatasetDisplayLabel(dataset.dataset)}\".`);\n console.log(`Wrote ${outputPath}`);\n}\n\nexport async function generateDatasetJsonCommandInk(\n runner: RunnerApi,\n datasetName: string,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const app = render(\n React.createElement(GenerateView, {\n runner,\n datasetName,\n onComplete: (err) => {\n app.unmount();\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n },\n }),\n );\n });\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\n\nimport { getDatasetDisplayLabel } from '../../evals/dataset';\nimport { getTestCaseDisplayLabel } from '../../evals/test-case';\nimport type { RunnerApi } from '../../runner';\nimport { Banner } from './Banner';\n\ninterface GenerateViewProps {\n runner: RunnerApi;\n datasetName: string;\n onComplete: (error?: Error) => void;\n}\n\nexport function GenerateView({\n runner,\n datasetName,\n onComplete,\n}: GenerateViewProps): React.ReactNode {\n const [result, setResult] = useState<{\n count: number;\n datasetName: string;\n outputPath: string;\n } | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n async function run() {\n const dataset = await runner.resolveDatasetByName(datasetName);\n if (!dataset) {\n setError(new Error(`Dataset \"${datasetName}\" not found.`));\n onComplete(new Error(`Dataset \"${datasetName}\" not found.`));\n return;\n }\n\n const { writeFile } = await import('node:fs/promises');\n const { join, parse, resolve } = await import('node:path');\n\n const testCases = await runner.collectDatasetTestCases(dataset.id);\n const payload = testCases.map((item) => {\n const tc = item.testCase as { getOutput?: () => unknown };\n return {\n name: getTestCaseDisplayLabel(item.testCase),\n input: item.testCase.getInput(),\n output: typeof tc.getOutput === 'function' ? tc.getOutput() : undefined,\n };\n });\n\n const absoluteDatasetPath = resolve(process.cwd(), dataset.filePath);\n const parsed = parse(absoluteDatasetPath);\n const outputPath = join(parsed.dir, `${parsed.name}.cases.json`);\n\n await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n\n if (!cancelled) {\n setResult({\n count: payload.length,\n datasetName: getDatasetDisplayLabel(dataset.dataset),\n outputPath,\n });\n setTimeout(() => onComplete(), 200);\n }\n }\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [runner, datasetName, onComplete]);\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Banner />\n <Text color=\"red\">{error.message}</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Banner />\n </Box>\n {result && (\n <Box flexDirection=\"column\">\n <Text color=\"green\">\n Generated {result.count} test cases for dataset \"{result.datasetName}\".\n </Text>\n <Text color=\"gray\">Wrote {result.outputPath}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { Box, Text } from 'ink';\n\nexport function Banner(): React.ReactNode {\n return (\n <Box borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} paddingY={0}>\n <Text color=\"gray\">@m4trix/evals</Text>\n <Text color=\"cyan\"> · </Text>\n <Text color=\"gray\">eval-agents-simple</Text>\n </Box>\n );\n}\n","import { render } from 'ink';\nimport * as React from 'react';\nimport {\n type EvaluatorLogEntry,\n formatScoreData,\n getDiffLines,\n getEvaluatorDisplayLabel,\n getLogLines,\n getMetricById,\n getScoreById,\n type LogEntry,\n} from '../evals';\nimport type { ScoreItem } from '../evals/score';\nimport type { RunnerApi, RunnerEvent } from '../runner';\nimport {\n aggregateMetricItems,\n aggregateScoreItems,\n toNumericScore,\n toNumericScoreFromScores,\n} from '../runner/score-utils';\nimport { RunView } from './views/RunView';\n\ninterface EvaluatorAggregate {\n total: number;\n sumSq: number;\n count: number;\n passed: number;\n failed: number;\n}\n\nfunction sampleStdDev(sum: number, sumSq: number, n: number): number | undefined {\n if (n < 2) return undefined;\n const mean = sum / n;\n const variance = (sumSq - n * mean * mean) / (n - 1);\n return variance > 0 ? Math.sqrt(variance) : 0;\n}\n\ninterface TestCaseScoreSummary {\n name: string;\n averageScore?: number;\n stdDev?: number;\n aggregatedScoreItem?: ScoreItem;\n isAggregated: boolean;\n durationMs: number;\n passed: boolean;\n}\n\ninterface TestCaseEventAcc {\n name: string;\n events: Array<{\n averageScore?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n }>;\n }>;\n}\n\nfunction buildTestCaseSummaries(byId: Map<string, TestCaseEventAcc>): TestCaseScoreSummary[] {\n const summaries: TestCaseScoreSummary[] = [];\n for (const { name, events } of byId.values()) {\n const passed = events.every((e) => e.passed);\n const durationMs = events.reduce((sum, e) => sum + e.durationMs, 0);\n const isAggregated = events.length > 1;\n const allScores = events.flatMap((ev) =>\n ev.evaluatorScores\n .map((es) => toNumericScoreFromScores(es.scores))\n .filter((n): n is number => n !== undefined),\n );\n const averageScore =\n allScores.length > 0 ? allScores.reduce((a, b) => a + b, 0) / allScores.length : undefined;\n const sumSq = allScores.length > 0 ? allScores.reduce((s, v) => s + v * v, 0) : 0;\n const total = allScores.reduce((a, b) => a + b, 0);\n const stdDev = sampleStdDev(total, sumSq, allScores.length);\n let firstAggregatedScore: ScoreItem | undefined;\n for (const evaluatorScores of events[0]?.evaluatorScores ?? []) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorScores.evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n }\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg && firstAggregatedScore === undefined) {\n firstAggregatedScore = agg;\n break;\n }\n }\n if (firstAggregatedScore !== undefined) break;\n }\n summaries.push({\n name,\n averageScore,\n stdDev: stdDev ?? undefined,\n aggregatedScoreItem: firstAggregatedScore,\n isAggregated,\n durationMs,\n passed,\n });\n }\n return summaries;\n}\n\nconst ansi = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n cyan: '\\x1b[36m',\n magenta: '\\x1b[35m',\n} as const;\n\nfunction colorize(text: string, color: string): string {\n return `${color}${text}${ansi.reset}`;\n}\n\nfunction scoreToColor(score: number): string {\n if (score >= 80) {\n return ansi.green;\n }\n if (score >= 50) {\n return ansi.yellow;\n }\n return ansi.red;\n}\n\nfunction getEvaluatorSummaryLines(\n evaluatorId: string,\n evaluatorName: string,\n aggregate: EvaluatorAggregate | undefined,\n scoreItemsByKey: Map<string, ScoreItem[]>,\n): string[] {\n const lines: string[] = [];\n const scoreKeys = [...scoreItemsByKey.keys()].filter((k) => k.startsWith(`${evaluatorId}:`));\n if (scoreKeys.length === 0) {\n lines.push(`- ${evaluatorName.padEnd(28)} no scores`);\n return lines;\n }\n const passedFailed =\n aggregate != null ? ` passed=${aggregate.passed} failed=${aggregate.failed}` : '';\n const scoreLines: string[] = [];\n for (const key of scoreKeys) {\n const items = scoreItemsByKey.get(key) ?? [];\n const agg = aggregateScoreItems(items);\n if (!agg) continue;\n const def = agg.def ?? getScoreById(agg.id);\n const label = agg.name ?? def?.name ?? def?.id ?? agg.id;\n const formatted = def ? def.formatAggregate(agg.data) : 'n/a';\n const numeric = toNumericScore(agg.data);\n const colored = numeric !== undefined ? colorize(formatted, scoreToColor(numeric)) : formatted;\n scoreLines.push(` ${label}: ${colored}`);\n }\n if (scoreLines.length > 0) {\n lines.push(`- ${evaluatorName.padEnd(28)}${passedFailed}`);\n lines.push(...scoreLines);\n } else {\n lines.push(`- ${evaluatorName.padEnd(28)} no numeric scores${passedFailed}`);\n }\n return lines;\n}\n\nfunction createBar(value: number, max = 100, width = 20): string {\n const safe = Math.max(0, Math.min(max, value));\n const filled = Math.round((safe / max) * width);\n return `${'█'.repeat(filled)}${'░'.repeat(width - filled)}`;\n}\n\nfunction aggregateEvaluatorScoresFromEvents(\n events: TestCaseEventAcc['events'],\n _evaluatorNameById: Map<string, string>,\n): Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n}> {\n if (events.length === 0) return [];\n const evaluatorIds = new Set(events.flatMap((e) => e.evaluatorScores.map((x) => x.evaluatorId)));\n const result: Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n }> = [];\n for (const evaluatorId of evaluatorIds) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n const metricIdToItems = new Map<string, Array<{ id: string; data: unknown }>>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n for (const m of es?.metrics ?? []) {\n const list = metricIdToItems.get(m.id) ?? [];\n list.push(m);\n metricIdToItems.set(m.id, list);\n }\n }\n const aggregatedScores: ScoreItem[] = [];\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg) aggregatedScores.push(agg);\n }\n const aggregatedMetrics = Array.from(metricIdToItems.entries())\n .map(([, items]) => aggregateMetricItems(items as never))\n .filter((m): m is { id: string; data: unknown } => m !== undefined);\n const passed = events.every((ev) => {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n return es?.passed ?? false;\n });\n result.push({\n evaluatorId,\n scores: aggregatedScores,\n passed,\n metrics: aggregatedMetrics.length > 0 ? aggregatedMetrics : undefined,\n });\n }\n return result;\n}\n\nfunction formatEvaluatorScoreLine(\n name: string,\n scores: ReadonlyArray<ScoreItem>,\n passed: boolean,\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>,\n options?: { isAggregated?: boolean },\n): string[] {\n const passLabel = passed\n ? colorize('PASS', `${ansi.bold}${ansi.green}`)\n : colorize('FAIL', `${ansi.bold}${ansi.red}`);\n const metricParts: string[] = [];\n if (metrics && metrics.length > 0) {\n for (const m of metrics) {\n const def = getMetricById(m.id);\n if (def) {\n const formatted = def.format(m.data, options);\n const label = m.name ?? def.name;\n metricParts.push(label ? `[${label}: ${formatted}]` : `[${formatted}]`);\n }\n }\n }\n const scoreLines: string[] = [];\n for (const item of scores) {\n const def = item.def ?? getScoreById(item.id);\n const scoreLabel = item.name ?? def?.name ?? def?.id ?? item.id;\n let formatted: string;\n if (!def) {\n const numeric = toNumericScore(item.data);\n formatted =\n numeric !== undefined ? colorize(numeric.toFixed(2), scoreToColor(numeric)) : 'n/a';\n } else {\n const raw = formatScoreData(def, item.data, options);\n switch (def.displayStrategy) {\n case 'bar': {\n const numeric =\n typeof item.data === 'object' && item.data !== null && 'value' in item.data\n ? (item.data as { value: unknown }).value\n : toNumericScore(item.data);\n if (typeof numeric === 'number' && Number.isFinite(numeric)) {\n formatted = `${colorize(raw, scoreToColor(numeric))} ${colorize(createBar(numeric), ansi.dim)}`;\n } else {\n formatted = raw;\n }\n break;\n }\n case 'number':\n formatted = raw;\n break;\n case 'passFail':\n formatted = colorize(\n raw,\n item.passed === true\n ? `${ansi.bold}${ansi.green}`\n : item.passed === false\n ? `${ansi.bold}${ansi.red}`\n : ansi.dim,\n );\n break;\n }\n }\n scoreLines.push(` ${scoreLabel}: ${formatted}`);\n }\n const lines: string[] = [];\n const metricStr = metricParts.length > 0 ? ` ${metricParts.join(' ')}` : '';\n lines.push(` ${name}: ${passLabel}${metricStr}`);\n if (scoreLines.length > 0) {\n lines.push(...scoreLines);\n } else {\n lines.push(` n/a`);\n }\n return lines;\n}\n\n/** @returns `0` if every completed run had zero failed test cases; `1` otherwise. */\nexport async function runSimpleEvalRunConfigsPlain(\n runner: RunnerApi,\n runConfigNames: ReadonlyArray<string>,\n concurrency: number,\n experimentName?: string,\n triggerTimestamp?: number,\n): Promise<0 | 1> {\n const jobs = await runner.expandRunConfigNamesToJobs(runConfigNames);\n if (jobs.length === 0) {\n throw new Error('No jobs expanded from RunConfigs.');\n }\n\n const evaluators = await runner.collectEvaluators();\n const evaluatorNameById = new Map(\n evaluators.map((item) => [item.id, getEvaluatorDisplayLabel(item.evaluator) ?? item.id]),\n );\n\n const aggregates = new Map<string, EvaluatorAggregate>();\n const scoreItemsByEvaluatorScore = new Map<string, ScoreItem[]>();\n const testCaseByTestId = new Map<string, TestCaseEventAcc>();\n let overallScoreTotal = 0;\n let overallScoreSumSq = 0;\n let overallScoreCount = 0;\n let globalStartedUnits = 0;\n let globalCompletedUnits = 0;\n let totalCount = 0;\n let runFinished = false;\n const inFlightRepetitions = new Set<string>();\n const spinnerFrames = ['⠋', '⠙', '⠸', '⠴', '⠦', '⠇'];\n let spinnerIndex = 0;\n\n function clearLine(): void {\n if (!process.stdout.isTTY) {\n return;\n }\n process.stdout.write('\\r\\x1b[2K');\n }\n\n function cursorUp(n: number): void {\n if (!process.stdout.isTTY || n <= 0) return;\n process.stdout.write(`\\x1b[${n}A`);\n }\n\n function drawSpinner(): void {\n if (!process.stdout.isTTY || runFinished) {\n return;\n }\n const frame = spinnerFrames[spinnerIndex % spinnerFrames.length];\n spinnerIndex += 1;\n process.stdout.write(\n `\\r${colorize(frame, ansi.cyan)} Running evaluations ${colorize(\n `${globalCompletedUnits}/${totalCount}`,\n ansi.bold,\n )} completed ${colorize(`${globalStartedUnits}/${totalCount}`, ansi.bold)} started ${colorize(`(${inFlightRepetitions.size} running)`, ansi.dim)}`,\n );\n }\n\n let lastPrintedTestCaseId: string | null = null;\n let lastPrintedLineCount = 0;\n\n let spinnerTimer: NodeJS.Timeout | undefined;\n\n const batchPendingRunIds = new Set<string>();\n const runIdToLabel = new Map<string, string>();\n let batchReady = false;\n\n const completedRuns = new Map<string, Extract<RunnerEvent, { type: 'RunCompleted' }>>();\n\n const done = new Promise<void>((resolve, reject) => {\n const unsubscribe = runner.subscribeRunEvents((event) => {\n if (\n batchReady &&\n 'runId' in event &&\n typeof event.runId === 'string' &&\n !batchPendingRunIds.has(event.runId)\n ) {\n return;\n }\n\n const rowPrefix = typeof event.runId === 'string' ? runIdToLabel.get(event.runId) : undefined;\n const pfx = rowPrefix !== undefined ? `${colorize(`[${rowPrefix}]`, ansi.dim)} ` : '';\n\n if (event.type === 'TestCaseStarted') {\n globalStartedUnits += 1;\n inFlightRepetitions.add(\n `${event.runId}:${event.testCaseId}:${event.repetitionId}:${event.repetitionIndex}`,\n );\n clearLine();\n process.stdout.write(\n `${pfx}${colorize(`[started ${event.startedTestCases}/${event.totalTestCases}]`, ansi.cyan)} ${event.testCaseName} ${colorize(`(${event.repetitionIndex}/${event.repetitionCount})`, ansi.cyan)} ${colorize('(running)', ansi.dim)}\\n`,\n );\n drawSpinner();\n }\n if (event.type === 'TestCaseProgress') {\n globalCompletedUnits += 1;\n inFlightRepetitions.delete(\n `${event.runId}:${event.testCaseId}:${event.repetitionId}:${event.repetitionIndex}`,\n );\n const numericScores = event.evaluatorScores\n .map((item) => toNumericScoreFromScores(item.scores))\n .filter((item): item is number => item !== undefined);\n const averageScore =\n numericScores.length > 0\n ? numericScores.reduce((sum, value) => sum + value, 0) / numericScores.length\n : undefined;\n\n const compositeId = `${event.runId}:${event.testCaseId}`;\n const existing = testCaseByTestId.get(compositeId) ?? {\n name: event.testCaseName,\n events: [],\n };\n existing.events.push({\n averageScore,\n passed: event.passed,\n durationMs: event.durationMs,\n evaluatorScores: event.evaluatorScores,\n });\n testCaseByTestId.set(compositeId, existing);\n\n for (const item of event.evaluatorScores) {\n const numeric = toNumericScoreFromScores(item.scores);\n if (numeric !== undefined) {\n const current = aggregates.get(item.evaluatorId) ?? {\n total: 0,\n sumSq: 0,\n count: 0,\n passed: 0,\n failed: 0,\n };\n aggregates.set(item.evaluatorId, {\n total: current.total + numeric,\n sumSq: current.sumSq + numeric * numeric,\n count: current.count + 1,\n passed: current.passed + (item.passed ? 1 : 0),\n failed: current.failed + (item.passed ? 0 : 1),\n });\n overallScoreTotal += numeric;\n overallScoreSumSq += numeric * numeric;\n overallScoreCount += 1;\n }\n for (const s of item.scores) {\n const key = `${item.evaluatorId}:${s.id}`;\n const list = scoreItemsByEvaluatorScore.get(key) ?? [];\n list.push(s);\n scoreItemsByEvaluatorScore.set(key, list);\n }\n }\n\n const isSameTestCase = lastPrintedTestCaseId === compositeId;\n const isLastRepetition = event.repetitionIndex >= event.repetitionCount;\n const isNonTty = !process.stdout.isTTY;\n const skipPrintNonTty = isNonTty && event.repetitionCount > 1 && !isLastRepetition;\n\n if (isSameTestCase && lastPrintedLineCount > 0 && !skipPrintNonTty) {\n cursorUp(lastPrintedLineCount);\n }\n\n const aggregatedScores = aggregateEvaluatorScoresFromEvents(\n existing.events,\n evaluatorNameById,\n );\n const isAggregated = existing.events.length > 1;\n const durationMs = existing.events.reduce((s, e) => s + e.durationMs, 0);\n\n const lines: string[] = [];\n const statusSuffix = event.errorMessage\n ? ` ${colorize('ERROR', `${ansi.bold}${ansi.red}`)}`\n : '';\n lines.push(\n `${pfx}${colorize(`[${event.completedTestCases}/${event.totalTestCases}]`, ansi.cyan)} ${event.testCaseName} ${colorize(`(${event.repetitionIndex}/${event.repetitionCount})`, ansi.cyan)} ${colorize(`(${durationMs}ms)`, ansi.dim)}${statusSuffix}`,\n );\n if (event.errorMessage) {\n lines.push(colorize(event.errorMessage, ansi.red));\n }\n for (const item of aggregatedScores) {\n const name = evaluatorNameById.get(item.evaluatorId) ?? item.evaluatorId;\n lines.push(\n ...formatEvaluatorScoreLine(name, item.scores, item.passed, item.metrics, {\n isAggregated,\n }),\n );\n const lastEvent = existing.events[existing.events.length - 1];\n const lastEs = lastEvent?.evaluatorScores.find((x) => x.evaluatorId === item.evaluatorId);\n if (!item.passed && lastEs?.logs && lastEs.logs.length > 0) {\n for (const log of lastEs.logs) {\n if (log.type === 'diff') {\n const useColor = process.stdout.isTTY;\n for (const { type, line } of getDiffLines(log)) {\n const colored =\n useColor && type === 'remove'\n ? colorize(` ${line}`, ansi.red)\n : useColor && type === 'add'\n ? colorize(` ${line}`, ansi.green)\n : ` ${line}`;\n lines.push(colored);\n }\n } else if (log.type === 'log') {\n for (const line of getLogLines(log as LogEntry)) {\n lines.push(` ${line}`);\n }\n }\n }\n }\n }\n\n if (!skipPrintNonTty) {\n for (let i = 0; i < lines.length; i += 1) {\n process.stdout.write(`\\r\\x1b[2K${lines[i]}\\n`);\n }\n lastPrintedTestCaseId = compositeId;\n lastPrintedLineCount = lines.length;\n }\n\n drawSpinner();\n }\n if (event.type === 'RunFailed') {\n if (batchReady && !batchPendingRunIds.has(event.runId)) {\n return;\n }\n runFinished = true;\n clearLine();\n unsubscribe();\n reject(new Error(`Run failed: ${event.errorMessage}`));\n return;\n }\n if (event.type === 'RunCompleted') {\n if (!batchPendingRunIds.has(event.runId)) {\n return;\n }\n completedRuns.set(event.runId, event);\n batchPendingRunIds.delete(event.runId);\n if (batchPendingRunIds.size === 0) {\n runFinished = true;\n clearLine();\n unsubscribe();\n resolve();\n }\n }\n });\n });\n\n console.log(colorize('=== Eval Run Started (RunConfigs) ===', `${ansi.bold}${ansi.cyan}`));\n for (const name of runConfigNames) {\n const collected = await runner.resolveRunConfigByName(name);\n const label = collected?.runConfig.getDisplayLabel() ?? name;\n console.log(`RunConfig: ${colorize(label, ansi.bold)}`);\n }\n console.log(`Jobs: ${colorize(String(jobs.length), ansi.bold)}`);\n console.log(`Shared concurrency: ${colorize(String(concurrency), ansi.bold)}`);\n console.log('');\n\n const snapshots = await runner.runDatasetJobsWithSharedConcurrency({\n jobs,\n globalConcurrency: concurrency,\n experimentName,\n triggerTimestamp,\n });\n for (let i = 0; i < snapshots.length; i += 1) {\n const snap = snapshots[i];\n const job = jobs[i];\n if (snap && job) {\n runIdToLabel.set(\n snap.runId,\n `${job.runConfigDisplayLabel ?? job.runConfigName} · ${snap.datasetName}`,\n );\n batchPendingRunIds.add(snap.runId);\n }\n }\n totalCount = snapshots.reduce((sum, s) => sum + s.totalTestCases, 0);\n console.log(`Total evaluation units: ${colorize(String(totalCount), ansi.bold)}`);\n console.log('');\n batchReady = true;\n\n drawSpinner();\n spinnerTimer = setInterval(drawSpinner, 100);\n\n await done;\n if (spinnerTimer) {\n clearInterval(spinnerTimer);\n }\n\n console.log('');\n console.log(colorize('=== Run Summary (all jobs) ===', `${ansi.bold}${ansi.cyan}`));\n for (const snap of snapshots) {\n const completed = completedRuns.get(snap.runId);\n if (!completed) {\n continue;\n }\n const label = runIdToLabel.get(snap.runId) ?? snap.runId;\n console.log('');\n console.log(colorize(`— ${label}`, ansi.magenta));\n console.log(\n `- passed: ${colorize(`${completed.passedTestCases}/${completed.totalTestCases}`, ansi.green)}`,\n );\n console.log(\n `- failed: ${colorize(\n `${completed.failedTestCases}/${completed.totalTestCases}`,\n completed.failedTestCases > 0 ? ansi.red : ansi.dim,\n )}`,\n );\n console.log(`- artifact: ${colorize(completed.artifactPath, ansi.dim)}`);\n }\n\n if (overallScoreCount > 0) {\n const overallAverage = overallScoreTotal / overallScoreCount;\n const overallSd = sampleStdDev(overallScoreTotal, overallScoreSumSq, overallScoreCount);\n const avgStr =\n overallSd !== undefined\n ? `${overallAverage.toFixed(2)} ± ${overallSd.toFixed(2)}`\n : overallAverage.toFixed(2);\n console.log('');\n console.log(\n `- overall avg score (all jobs): ${colorize(\n avgStr,\n scoreToColor(overallAverage),\n )} ${colorize(createBar(overallAverage), ansi.dim)}`,\n );\n }\n console.log(colorize('- evaluator averages:', ansi.magenta));\n for (const [evaluatorId, evaluatorName] of evaluatorNameById.entries()) {\n const evaluatorLines = getEvaluatorSummaryLines(\n evaluatorId,\n evaluatorName,\n aggregates.get(evaluatorId),\n scoreItemsByEvaluatorScore,\n );\n for (const line of evaluatorLines) {\n console.log(line);\n }\n }\n const testCaseSummaries = buildTestCaseSummaries(testCaseByTestId);\n if (testCaseSummaries.length > 0) {\n console.log(colorize('- test case scores:', ansi.magenta));\n for (const summary of testCaseSummaries) {\n const status = summary.passed ? colorize('PASS', ansi.green) : colorize('FAIL', ansi.red);\n if (summary.averageScore === undefined) {\n console.log(\n ` ${status} ${summary.name.padEnd(24)} score=n/a ${colorize(`(${summary.durationMs}ms)`, ansi.dim)}`,\n );\n continue;\n }\n const scoreLabel =\n summary.isAggregated && summary.aggregatedScoreItem\n ? (() => {\n const def =\n summary.aggregatedScoreItem.def ?? getScoreById(summary.aggregatedScoreItem.id);\n return def\n ? def.formatAggregate(summary.aggregatedScoreItem.data)\n : summary.averageScore!.toFixed(2);\n })()\n : summary.stdDev !== undefined && summary.isAggregated\n ? `${summary.averageScore.toFixed(2)} ± ${summary.stdDev.toFixed(2)}`\n : summary.averageScore.toFixed(2);\n console.log(\n ` ${status} ${summary.name.padEnd(24)} score=${colorize(\n scoreLabel,\n scoreToColor(summary.averageScore),\n )} ${colorize(createBar(summary.averageScore, 100, 14), ansi.dim)} ${colorize(`(${summary.durationMs}ms)`, ansi.dim)}`,\n );\n }\n }\n\n let failedTestCasesTotal = 0;\n for (const snap of snapshots) {\n const completed = completedRuns.get(snap.runId);\n if (completed) {\n failedTestCasesTotal += completed.failedTestCases;\n }\n }\n return failedTestCasesTotal > 0 ? 1 : 0;\n}\n\nexport async function runSimpleEvalRunConfigsInk(\n runner: RunnerApi,\n runConfigNames: ReadonlyArray<string>,\n concurrency: number,\n experimentName?: string,\n triggerTimestamp?: number,\n): Promise<0 | 1> {\n return new Promise<0 | 1>((resolve, reject) => {\n const app = render(\n React.createElement(RunView, {\n runner,\n runConfigNames,\n concurrency,\n experimentName,\n triggerTimestamp,\n onComplete: (err?: Error, exitCode?: 0 | 1) => {\n app.unmount();\n if (err) {\n reject(err);\n } else {\n resolve(exitCode ?? 0);\n }\n },\n }),\n );\n });\n}\n","/** @jsxImportSource react */\n\nimport { Box, Text } from 'ink';\nimport { type ReactNode, useCallback, useEffect, useState } from 'react';\nimport { TextBar } from '../../cli/components/TextBar';\nimport {\n formatScoreData,\n getDiffLines,\n getEvaluatorDisplayLabel,\n getLogLines,\n getMetricById,\n getScoreById,\n} from '../../evals';\nimport type { EvaluatorLogEntry } from '../../evals/diff';\nimport type { ScoreItem } from '../../evals/score';\nimport type { RunDatasetJob, RunnerApi, RunnerEvent } from '../../runner';\nimport {\n aggregateMetricItems,\n aggregateScoreItems,\n toNumericScore,\n toNumericScoreFromScores,\n} from '../../runner/score-utils';\nimport { Banner } from './Banner';\nimport { Spinner } from './Spinner';\n\ninterface EvaluatorScoreRow {\n evaluatorId: string;\n evaluatorName: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n}\n\n/** One displayed block per unique test case, updated in place as repetitions complete */\ninterface TestCaseDisplay {\n name: string;\n testCaseId: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionIndex: number;\n repetitionCount: number;\n durationMs: number;\n passed: boolean;\n errorMessage?: string;\n events: Array<{\n evaluatorScores: EvaluatorScoreRow[];\n passed: boolean;\n durationMs: number;\n }>;\n aggregatedEvaluatorScores: EvaluatorScoreRow[];\n isAggregated: boolean;\n}\n\ninterface RunningEvaluationDisplay {\n runId?: string;\n testCaseId: string;\n name: string;\n repetitionId: string;\n repetitionIndex: number;\n repetitionCount: number;\n startedTestCases: number;\n totalTestCases: number;\n}\n\ninterface EvaluatorAggregate {\n total: number;\n sumSq: number;\n count: number;\n passed: number;\n failed: number;\n}\n\nfunction sampleStdDev(sum: number, sumSq: number, n: number): number | undefined {\n if (n < 2) return undefined;\n const mean = sum / n;\n const variance = (sumSq - n * mean * mean) / (n - 1);\n return variance > 0 ? Math.sqrt(variance) : 0;\n}\n\nfunction scoreColor(score: number): 'green' | 'yellow' | 'red' {\n if (score >= 80) return 'green';\n if (score >= 50) return 'yellow';\n return 'red';\n}\n\nfunction createBar(value: number, max = 100, width = 20): string {\n const safe = Math.max(0, Math.min(max, value));\n const filled = Math.round((safe / max) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction aggregateEvaluatorScores(\n events: Array<{ evaluatorScores: EvaluatorScoreRow[] }>,\n nameById: Map<string, string>,\n): EvaluatorScoreRow[] {\n if (events.length === 0) return [];\n const evaluatorIds = new Set(events.flatMap((e) => e.evaluatorScores.map((x) => x.evaluatorId)));\n const result: EvaluatorScoreRow[] = [];\n for (const evaluatorId of evaluatorIds) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n const metricIdToItems = new Map<string, Array<{ id: string; data: unknown }>>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n for (const m of es?.metrics ?? []) {\n const list = metricIdToItems.get(m.id) ?? [];\n list.push(m);\n metricIdToItems.set(m.id, list);\n }\n }\n const aggregatedScores: ScoreItem[] = [];\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg) aggregatedScores.push(agg);\n }\n const aggregatedMetrics = Array.from(metricIdToItems.entries())\n .map(([, items]) => aggregateMetricItems(items))\n .filter((m): m is { id: string; data: unknown } => m !== undefined);\n const passed = events.every((ev) => {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n return es?.passed ?? false;\n });\n const lastEvent = events[events.length - 1];\n const lastEs = lastEvent?.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n result.push({\n evaluatorId,\n evaluatorName: nameById.get(evaluatorId) ?? evaluatorId,\n scores: aggregatedScores,\n passed,\n metrics: aggregatedMetrics.length > 0 ? aggregatedMetrics : undefined,\n logs: lastEs?.logs,\n });\n }\n return result;\n}\n\nfunction formatScorePart(\n item: ScoreItem,\n _scoreToColor: (n: number) => 'green' | 'yellow' | 'red',\n options?: { isAggregated?: boolean },\n): string {\n const def = item.def ?? getScoreById(item.id);\n if (!def) {\n const numeric = toNumericScore(item.data);\n return numeric !== undefined ? `${numeric.toFixed(2)}` : 'n/a';\n }\n const formatted = formatScoreData(def, item.data, options);\n if (def.displayStrategy === 'bar') {\n const numeric =\n typeof item.data === 'object' && item.data !== null && 'value' in item.data\n ? (item.data as { value: unknown }).value\n : toNumericScore(item.data);\n if (typeof numeric === 'number' && Number.isFinite(numeric)) {\n return `${formatted} ${createBar(numeric)}`;\n }\n }\n return formatted;\n}\n\ninterface RunViewProps {\n runner: RunnerApi;\n runConfigNames: ReadonlyArray<string>;\n concurrency: number;\n /** Forwarded to evaluator `meta.experimentName` for this run. */\n experimentName?: string;\n /** `Date.now()` when the CLI run command started; forwarded as `meta.triggerTimestamp`. */\n triggerTimestamp?: number;\n /**\n * Error ends the run unsuccessfully; on success `exitCode` is 0 when all test cases passed\n * across completed runs, or 1 when any had failures (`RunCompleted.failedTestCases`).\n */\n onComplete: (error?: Error, exitCode?: 0 | 1) => void;\n}\n\ninterface RunInfoState {\n names: string[];\n jobs: number;\n totalTestCases: number;\n}\n\nexport function RunView({\n runner,\n runConfigNames,\n concurrency,\n experimentName,\n triggerTimestamp,\n onComplete,\n}: RunViewProps): ReactNode {\n const [phase, setPhase] = useState<'loading' | 'running' | 'completed'>('loading');\n const [runInfo, setRunInfo] = useState<RunInfoState | null>(null);\n const [testCases, setTestCases] = useState<TestCaseDisplay[]>([]);\n const [startedEvaluations, setStartedEvaluations] = useState(0);\n const [completedEvaluations, setCompletedEvaluations] = useState(0);\n const [runningEvaluations, setRunningEvaluations] = useState<RunningEvaluationDisplay[]>([]);\n const [summary, setSummary] = useState<{\n passedTestCases: number;\n failedTestCases: number;\n totalTestCases: number;\n overallScoreTotal: number;\n overallScoreSumSq: number;\n overallScoreCount: number;\n aggregates: Map<string, EvaluatorAggregate>;\n scoreItemsByEvaluatorScore: Map<string, ScoreItem[]>;\n artifactPath: string;\n } | null>(null);\n const [evaluatorNameById, setEvaluatorNameById] = useState<Map<string, string>>(new Map());\n\n const runEval = useCallback(async () => {\n const rcList = runConfigNames.filter((n) => n.trim().length > 0);\n if (rcList.length === 0) {\n onComplete(new Error('At least one RunConfig name is required.'));\n return;\n }\n\n setStartedEvaluations(0);\n setCompletedEvaluations(0);\n setTestCases([]);\n setRunningEvaluations([]);\n setSummary(null);\n\n let jobs: ReadonlyArray<RunDatasetJob>;\n try {\n jobs = await runner.expandRunConfigNamesToJobs(rcList);\n } catch (err) {\n onComplete(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n if (jobs.length === 0) {\n onComplete(new Error('No jobs expanded from RunConfigs.'));\n return;\n }\n\n const allEvaluators = await runner.collectEvaluators();\n const nameById = new Map(\n allEvaluators.map((item) => [item.id, getEvaluatorDisplayLabel(item.evaluator) ?? item.id]),\n );\n setEvaluatorNameById(nameById);\n\n const aggregates = new Map<string, EvaluatorAggregate>();\n const scoreItemsByEvaluatorScore = new Map<string, ScoreItem[]>();\n let overallScoreTotal = 0;\n let overallScoreSumSq = 0;\n let overallScoreCount = 0;\n\n const batchPendingRunIds = new Set<string>();\n const runIdToLabel = new Map<string, string>();\n let batchReady = false;\n const completedRuns = new Map<string, Extract<RunnerEvent, { type: 'RunCompleted' }>>();\n\n const done = new Promise<void>((resolve, reject) => {\n const unsubscribe = runner.subscribeRunEvents((event) => {\n if (\n batchReady &&\n 'runId' in event &&\n typeof event.runId === 'string' &&\n !batchPendingRunIds.has(event.runId)\n ) {\n return;\n }\n\n if (event.type === 'TestCaseStarted') {\n setStartedEvaluations((c) => c + 1);\n setRunningEvaluations((prev) => {\n const withoutDuplicate = prev.filter(\n (item) =>\n !(\n item.testCaseId === event.testCaseId &&\n item.repetitionIndex === event.repetitionIndex &&\n item.runId === event.runId\n ),\n );\n return [\n ...withoutDuplicate,\n {\n runId: event.runId,\n testCaseId: event.testCaseId,\n name: event.testCaseName,\n repetitionId: event.repetitionId,\n repetitionIndex: event.repetitionIndex,\n repetitionCount: event.repetitionCount,\n startedTestCases: event.startedTestCases,\n totalTestCases: event.totalTestCases,\n },\n ];\n });\n }\n\n if (event.type === 'TestCaseProgress') {\n for (const item of event.evaluatorScores) {\n const numeric = toNumericScoreFromScores(item.scores);\n if (numeric !== undefined) {\n const current = aggregates.get(item.evaluatorId) ?? {\n total: 0,\n sumSq: 0,\n count: 0,\n passed: 0,\n failed: 0,\n };\n aggregates.set(item.evaluatorId, {\n total: current.total + numeric,\n sumSq: current.sumSq + numeric * numeric,\n count: current.count + 1,\n passed: current.passed + (item.passed ? 1 : 0),\n failed: current.failed + (item.passed ? 0 : 1),\n });\n overallScoreTotal += numeric;\n overallScoreSumSq += numeric * numeric;\n overallScoreCount += 1;\n }\n for (const s of item.scores) {\n const key = `${item.evaluatorId}:${s.id}`;\n const list = scoreItemsByEvaluatorScore.get(key) ?? [];\n list.push(s);\n scoreItemsByEvaluatorScore.set(key, list);\n }\n }\n\n const label = runIdToLabel.get(event.runId);\n const compositeId = `${event.runId}:${event.testCaseId}`;\n const displayName =\n label !== undefined ? `${label} › ${event.testCaseName}` : event.testCaseName;\n\n setTestCases((prev) => {\n const byId = new Map(prev.map((tc) => [tc.testCaseId, tc]));\n const existing = byId.get(compositeId);\n const newEvent = {\n evaluatorScores: event.evaluatorScores.map((item) => ({\n evaluatorId: item.evaluatorId,\n evaluatorName: nameById.get(item.evaluatorId) ?? item.evaluatorId,\n scores: item.scores,\n passed: item.passed,\n metrics: item.metrics,\n logs: item.logs,\n })),\n passed: event.passed,\n durationMs: event.durationMs,\n };\n const events = existing ? [...existing.events, newEvent] : [newEvent];\n const isAggregated = events.length > 1;\n const aggregatedEvaluatorScores = aggregateEvaluatorScores(events, nameById);\n const merged: TestCaseDisplay = {\n name: displayName,\n testCaseId: compositeId,\n completedTestCases: event.completedTestCases,\n totalTestCases: event.totalTestCases,\n repetitionIndex: event.repetitionIndex,\n repetitionCount: event.repetitionCount,\n durationMs: events.reduce((s, e) => s + e.durationMs, 0),\n passed: events.every((e) => e.passed),\n errorMessage: event.errorMessage,\n events,\n aggregatedEvaluatorScores,\n isAggregated,\n };\n byId.set(compositeId, merged);\n return Array.from(byId.values());\n });\n setCompletedEvaluations((c) => c + 1);\n setRunningEvaluations((running) =>\n running.filter(\n (item) =>\n !(\n item.testCaseId === event.testCaseId &&\n item.repetitionIndex === event.repetitionIndex &&\n item.runId === event.runId\n ),\n ),\n );\n }\n\n if (event.type === 'RunFailed') {\n if (batchReady && !batchPendingRunIds.has(event.runId)) {\n return;\n }\n unsubscribe();\n reject(new Error(`Run failed: ${event.errorMessage}`));\n return;\n }\n\n if (event.type === 'RunCompleted') {\n if (!batchPendingRunIds.has(event.runId)) {\n return;\n }\n completedRuns.set(event.runId, event);\n batchPendingRunIds.delete(event.runId);\n if (batchPendingRunIds.size === 0) {\n unsubscribe();\n resolve();\n }\n }\n });\n });\n\n const snapshots = await runner.runDatasetJobsWithSharedConcurrency({\n jobs,\n globalConcurrency: concurrency,\n experimentName,\n triggerTimestamp,\n });\n for (let i = 0; i < snapshots.length; i += 1) {\n const snap = snapshots[i];\n const job = jobs[i];\n if (snap && job) {\n runIdToLabel.set(\n snap.runId,\n `${job.runConfigDisplayLabel ?? job.runConfigName} · ${snap.datasetName}`,\n );\n batchPendingRunIds.add(snap.runId);\n }\n }\n const totalUnits = snapshots.reduce((sum, s) => sum + s.totalTestCases, 0);\n batchReady = true;\n\n const runConfigLabels = await Promise.all(\n rcList.map(async (n) => {\n const collected = await runner.resolveRunConfigByName(n);\n return collected?.runConfig.getDisplayLabel() ?? n;\n }),\n );\n\n setRunInfo({\n names: runConfigLabels,\n jobs: jobs.length,\n totalTestCases: totalUnits,\n });\n setPhase('running');\n\n try {\n await done;\n } catch (err) {\n onComplete(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n let passedTestCases = 0;\n let failedTestCases = 0;\n let totalTestCases = 0;\n const artifacts: string[] = [];\n for (const ev of completedRuns.values()) {\n passedTestCases += ev.passedTestCases;\n failedTestCases += ev.failedTestCases;\n totalTestCases += ev.totalTestCases;\n artifacts.push(ev.artifactPath);\n }\n\n setSummary({\n passedTestCases,\n failedTestCases,\n totalTestCases,\n overallScoreTotal,\n overallScoreSumSq,\n overallScoreCount,\n aggregates: new Map(aggregates),\n scoreItemsByEvaluatorScore: new Map(scoreItemsByEvaluatorScore),\n artifactPath: artifacts.join('\\n'),\n });\n setPhase('completed');\n const exitCode: 0 | 1 = failedTestCases > 0 ? 1 : 0;\n setTimeout(() => onComplete(undefined, exitCode), 200);\n }, [runner, runConfigNames, concurrency, experimentName, triggerTimestamp, onComplete]);\n\n useEffect(() => {\n void runEval();\n }, [runEval]);\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Banner />\n </Box>\n\n {runInfo && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"cyan\" bold>\n RunConfigs{' '}\n </Text>\n <Text color=\"gray\">{runInfo.names.join(', ')}</Text>\n <Text>\n <Text color=\"cyan\" bold>\n Jobs{' '}\n </Text>\n {runInfo.jobs}\n </Text>\n <Text>\n <Text color=\"cyan\" bold>\n Evaluation units{' '}\n </Text>\n {runInfo.totalTestCases}\n </Text>\n </Box>\n )}\n\n {phase === 'running' && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Spinner\n label={`Evaluations ${completedEvaluations}/${runInfo?.totalTestCases ?? 0} completed • ${startedEvaluations}/${runInfo?.totalTestCases ?? 0} started`}\n />\n {runningEvaluations.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n {runningEvaluations.map((item) => (\n <Text\n key={`${item.runId ?? ''}:${item.testCaseId}:${item.repetitionId}:${item.repetitionIndex}`}\n color=\"yellow\"\n >\n [running {item.startedTestCases}/{item.totalTestCases}] {item.name}{' '}\n <Text color=\"gray\">\n ({item.repetitionIndex}/{item.repetitionCount})\n </Text>\n </Text>\n ))}\n </Box>\n )}\n </Box>\n )}\n\n {testCases.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {testCases.map((tc) => (\n <Box key={tc.testCaseId} flexDirection=\"column\" marginBottom={0}>\n <Text>\n <Text color=\"cyan\">\n [{tc.completedTestCases}/{tc.totalTestCases}]\n </Text>{' '}\n {tc.name}{' '}\n <Text color=\"cyan\">\n ({tc.repetitionIndex}/{tc.repetitionCount})\n </Text>\n <Text color=\"gray\"> ({tc.durationMs}ms)</Text>\n {tc.errorMessage ? (\n <Text color=\"red\" bold>\n {' '}\n ERROR\n </Text>\n ) : null}\n </Text>\n {tc.errorMessage ? <Text color=\"red\">{tc.errorMessage}</Text> : null}\n {tc.aggregatedEvaluatorScores.map((item) => (\n <Box key={item.evaluatorId} flexDirection=\"column\" marginLeft={2}>\n <Text>\n {item.evaluatorName}:{' '}\n <Text color={item.passed ? 'green' : 'red'} bold>\n {item.passed ? 'PASS' : 'FAIL'}\n </Text>\n {item.metrics && item.metrics.length > 0 ? (\n <>\n {' '}\n {item.metrics.map((m) => {\n const def = getMetricById(m.id);\n if (!def) return null;\n const formatted = def.format(m.data, {\n isAggregated: tc.isAggregated,\n });\n const label = m.name ?? def.name;\n return (\n <Text key={m.id} color=\"gray\">\n [{label ? `${label}: ` : ''}\n {formatted}]{' '}\n </Text>\n );\n })}\n </>\n ) : null}\n </Text>\n {item.scores.length > 0 ? (\n item.scores.map((s) => {\n const def = s.def ?? getScoreById(s.id);\n const scoreLabel = s.name ?? def?.name ?? def?.id ?? s.id;\n return (\n <Text\n key={`${item.evaluatorId}-${s.id}-${scoreLabel}`}\n color={scoreColor(toNumericScore(s.data) ?? 0)}\n >\n {' '}\n {scoreLabel}:{' '}\n {formatScorePart(s, scoreColor, {\n isAggregated: tc.isAggregated,\n })}\n </Text>\n );\n })\n ) : (\n <Text color=\"gray\"> n/a</Text>\n )}\n {!item.passed && item.logs && item.logs.length > 0 && (\n <Box marginLeft={2} flexDirection=\"column\">\n {item.logs.map((log) =>\n log.type === 'diff' ? (\n <Box\n key={`diff:${getDiffLines(log)\n .map((x) => x.line)\n .join('|')}`}\n flexDirection=\"column\"\n >\n {getDiffLines(log).map(({ type, line }) => (\n <Text\n key={`${type}:${line}`}\n color={\n type === 'remove' ? 'red' : type === 'add' ? 'green' : 'gray'\n }\n >\n {line}\n </Text>\n ))}\n </Box>\n ) : log.type === 'log' ? (\n <Box key={`log:${getLogLines(log).join('\\n')}`} flexDirection=\"column\">\n {getLogLines(log).map((line) => (\n <Text key={line} color=\"gray\">\n {line}\n </Text>\n ))}\n </Box>\n ) : null,\n )}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n ))}\n </Box>\n )}\n\n {phase === 'completed' && summary && (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Run Summary\n </Text>\n <Box marginTop={1}>\n <Text color=\"green\">passed</Text>\n <Text>\n {' '}\n {summary.passedTestCases}/{summary.totalTestCases}\n </Text>\n </Box>\n <Box>\n <Text color={summary.failedTestCases > 0 ? 'red' : 'gray'}>failed</Text>\n <Text>\n {' '}\n {summary.failedTestCases}/{summary.totalTestCases}\n </Text>\n </Box>\n {summary.overallScoreCount > 0 && (\n <Box marginTop={1}>\n <TextBar\n label=\"overall avg\"\n value={summary.overallScoreTotal / summary.overallScoreCount}\n barWidth={20}\n format={(v) => {\n const sd = sampleStdDev(\n summary.overallScoreTotal,\n summary.overallScoreSumSq,\n summary.overallScoreCount,\n );\n return sd !== undefined ? `${v.toFixed(2)} ± ${sd.toFixed(2)}` : v.toFixed(2);\n }}\n />\n </Box>\n )}\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"magenta\">evaluator averages</Text>\n {Array.from(evaluatorNameById.entries()).map(([id, name]) => {\n const agg = summary.aggregates.get(id);\n const scoreKeys = [...(summary.scoreItemsByEvaluatorScore?.keys() ?? [])].filter(\n (k) => k.startsWith(`${id}:`),\n );\n if (scoreKeys.length === 0) {\n return (\n <Text key={id} color=\"gray\">\n - {name.padEnd(28)} no scores\n </Text>\n );\n }\n const passedFailed =\n agg != null ? (\n <Text>\n {' '}\n passed={agg.passed} failed={agg.failed}\n </Text>\n ) : null;\n return (\n <Box key={id} flexDirection=\"column\">\n <Text>\n - {name.padEnd(28)}\n {passedFailed}\n </Text>\n {scoreKeys.map((key) => {\n const items = summary.scoreItemsByEvaluatorScore?.get(key) ?? [];\n const aggregated = aggregateScoreItems(items);\n if (!aggregated) return null;\n const def = aggregated.def ?? getScoreById(aggregated.id);\n const label = aggregated.name ?? def?.name ?? def?.id ?? aggregated.id;\n const formatted = def ? def.formatAggregate(aggregated.data) : 'n/a';\n const numeric = toNumericScore(aggregated.data);\n return (\n <Text key={key} color={numeric !== undefined ? scoreColor(numeric) : 'gray'}>\n {' '}\n {label}: {formatted}\n </Text>\n );\n })}\n </Box>\n );\n })}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"magenta\">test case scores</Text>\n {testCases.map((tc) => {\n const allScores = tc.events.flatMap((ev) =>\n ev.evaluatorScores\n .map((es) => toNumericScoreFromScores(es.scores))\n .filter((n): n is number => n !== undefined),\n );\n const averageScore =\n allScores.length > 0\n ? allScores.reduce((a, b) => a + b, 0) / allScores.length\n : undefined;\n const sumSq = allScores.length > 0 ? allScores.reduce((s, v) => s + v * v, 0) : 0;\n const total = allScores.reduce((a, b) => a + b, 0);\n const tcStdDev = sampleStdDev(total, sumSq, allScores.length);\n const firstScore = tc.aggregatedEvaluatorScores[0]?.scores[0];\n const scoreLabel =\n firstScore && tc.isAggregated\n ? formatScorePart(firstScore, scoreColor, {\n isAggregated: true,\n })\n : averageScore !== undefined\n ? tcStdDev !== undefined && tc.isAggregated\n ? `${averageScore.toFixed(2)} ± ${tcStdDev.toFixed(2)}`\n : averageScore.toFixed(2)\n : 'n/a';\n return (\n <Box key={tc.testCaseId}>\n <Text color={tc.passed ? 'green' : 'red'}>{tc.passed ? 'PASS' : 'FAIL'}</Text>\n <Text> {tc.name.padEnd(24)}</Text>\n {averageScore !== undefined ? (\n <>\n <Text color={scoreColor(averageScore)}>score={scoreLabel}</Text>\n <Text color=\"gray\"> {createBar(averageScore, 100, 14)}</Text>\n </>\n ) : (\n <Text color=\"gray\">score=n/a</Text>\n )}\n <Text color=\"gray\"> ({tc.durationMs}ms)</Text>\n </Box>\n );\n })}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\">artifact(s):</Text>\n {summary.artifactPath.split('\\n').map((line) => (\n <Text key={line} color=\"gray\">\n {line}\n </Text>\n ))}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { Text } from 'ink';\n\ninterface TextBarProps {\n label: string;\n value: number;\n max?: number;\n /** Label width (default 14 to match inspiration) */\n labelWidth?: number;\n /** Bar width in chars (default 20) */\n barWidth?: number;\n /** Format value for display (e.g. v => `${v}%`) */\n format?: (v: number) => string;\n /** Color bar by value: green > 70, yellow 40-70, red < 40 */\n colorByValue?: boolean;\n}\n\nfunction barColor(pct: number): 'green' | 'yellow' | 'red' | undefined {\n if (pct >= 70) return 'green';\n if (pct >= 40) return 'yellow';\n return 'red';\n}\n\nexport function TextBar({\n label,\n value,\n max = 100,\n labelWidth = 14,\n barWidth = 20,\n format = (v) => String(v),\n colorByValue = true,\n}: TextBarProps): React.ReactNode {\n const clamped = Math.max(0, Math.min(max, value));\n const pct = max > 0 ? (clamped / max) * 100 : 0;\n const filled = Math.round((clamped / max) * barWidth);\n const filledBar = '█'.repeat(filled);\n const emptyBar = '░'.repeat(Math.max(0, barWidth - filled));\n const color = colorByValue ? barColor(pct) : undefined;\n\n return (\n <Text>\n <Text color=\"gray\">{label.padEnd(labelWidth)}</Text>\n {' ['}\n {color ? (\n <>\n <Text color={color}>{filledBar}</Text>\n <Text color=\"gray\">{emptyBar}</Text>\n </>\n ) : (\n filledBar + emptyBar\n )}\n {'] '}\n <Text color={color ?? 'white'} bold>\n {format(value)}\n </Text>\n </Text>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Text } from 'ink';\n\nconst FRAMES = ['⠋', '⠙', '⠸', '⠴', '⠦', '⠇'];\n\ninterface SpinnerProps {\n label?: string;\n}\n\nexport function Spinner({ label = 'Running' }: SpinnerProps): React.ReactNode {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame((f) => (f + 1) % FRAMES.length);\n }, 100);\n return () => clearInterval(timer);\n }, []);\n\n return (\n <Text color=\"cyan\">\n {FRAMES[frame]} {label}\n </Text>\n );\n}\n","#!/usr/bin/env node\n\nimport { createRunner } from '../runner';\nimport { getDefaultConcurrency, getSimpleCliUsage, parseSimpleCliArgs } from './args';\nimport { printBanner } from './banner';\nimport { generateDatasetJsonCommandInk, generateDatasetJsonCommandPlain } from './generate';\nimport { runSimpleEvalRunConfigsInk, runSimpleEvalRunConfigsPlain } from './run';\n\nfunction printUsageAndExit(exitCode: number): never {\n const printer = exitCode === 0 ? console.log : console.error;\n printer(getSimpleCliUsage());\n process.exit(exitCode);\n}\n\nasync function main(): Promise<void> {\n const args = parseSimpleCliArgs(process.argv.slice(2));\n\n if (args.help) {\n printUsageAndExit(0);\n }\n if (args.unknownArgs.length > 0) {\n console.error(`Unknown arguments: ${args.unknownArgs.join(', ')}`);\n printUsageAndExit(1);\n }\n if (!args.command) {\n printUsageAndExit(1);\n }\n\n if (args.command === 'run') {\n if (args.runConfigNames.length === 0) {\n console.error(\n 'Missing required --run-config <name> (repeat the flag to queue multiple RunConfigs).',\n );\n printUsageAndExit(1);\n }\n if (args.datasetName !== undefined) {\n console.error(\n 'The run command no longer accepts --dataset; use --run-config <RunConfig name>.',\n );\n printUsageAndExit(1);\n }\n }\n\n if (args.command === 'generate' && args.runConfigNames.length > 0) {\n console.error('generate does not accept --run-config.');\n printUsageAndExit(1);\n }\n\n const useInk = process.stdout.isTTY === true;\n if (!useInk) {\n printBanner();\n }\n\n const runner = createRunner();\n try {\n if (args.command === 'run') {\n const concurrency = args.concurrency ?? getDefaultConcurrency();\n const triggerTimestamp = Date.now();\n const exitCode = await (useInk ? runSimpleEvalRunConfigsInk : runSimpleEvalRunConfigsPlain)(\n runner,\n args.runConfigNames,\n concurrency,\n args.experimentName,\n triggerTimestamp,\n );\n if (args.ci && exitCode !== 0) {\n process.exit(1);\n }\n return;\n }\n\n const genDataset = args.datasetName;\n if (!genDataset) {\n console.error('Missing required --dataset <datasetId> argument.');\n printUsageAndExit(1);\n }\n await (useInk ? generateDatasetJsonCommandInk : generateDatasetJsonCommandPlain)(\n runner,\n genDataset,\n );\n } finally {\n await runner.shutdown();\n }\n}\n\nvoid main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : 'Command failed');\n process.exit(1);\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/runner/api.ts","../src/evals/entity-name.ts","../src/evals/evaluator.ts","../src/runner/artifact-loader.ts","../src/runner/config.ts","../src/runner/config-loader.ts","../src/runner/discovery.ts","../src/runner/execution.ts","../src/evals/diff.ts","../src/evals/test-case.ts","../src/evals/dataset.ts","../src/evals/metric.ts","../src/evals/aggregators.ts","../src/evals/metrics/standard.ts","../src/evals/score.ts","../src/evals/scores/standard.ts","../src/runner/score-utils.ts","../src/runner/name-pattern.ts","../src/runner/persistence.ts","../src/runner/search.ts","../src/cli-simple/args.ts","../src/cli-simple/banner.ts","../src/cli-simple/generate.ts","../src/cli-simple/views/GenerateView.tsx","../src/cli-simple/views/Banner.tsx","../src/cli-simple/run.ts","../src/cli-simple/views/RunView.tsx","../src/cli/components/TextBar.tsx","../src/cli-simple/views/Spinner.tsx","../src/cli-simple/index.ts"],"names":["randomUUID","Effect","Queue","Ref","resolve","createJiti","readdir","jitiModule","loaded","join","parts","registry","Box","Text","jsx","jsxs","writeFile","parse","readOutput","render","React","useEffect","useState","Fragment","sampleStdDev","ansi","createBar"],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { Effect, Fiber, PubSub, Queue, Ref } from 'effect';\nimport { getEvaluatorDisplayLabel } from '../evals/evaluator';\nimport { validateRunConfigName } from '../evals/run-config';\nimport { loadRunSnapshotsFromArtifacts as loadSnapshotsFromArtifacts } from './artifact-loader';\nimport type { RunnerConfig, RunnerConfigOverrides } from './config';\nimport { withRunnerConfig } from './config';\nimport { loadRunnerConfigFile } from './config-loader';\nimport {\n collectDatasetsFromFiles,\n collectEvaluatorsFromFiles,\n collectRunConfigsFromFiles,\n collectTestCasesFromFiles,\n} from './discovery';\nimport type {\n CollectedDataset,\n CollectedEvaluator,\n CollectedRunConfig,\n CollectedTestCase,\n RunDatasetJob,\n RunDatasetRequest,\n RunnerEvent,\n RunSnapshot,\n SearchTestCasesQuery,\n} from './events';\nimport { createArtifactPath, executeRunTask, type RunTask } from './execution';\nimport { createNameMatcher } from './name-pattern';\nimport { createPersistenceWorker } from './persistence';\nimport { searchCollectedTestCases } from './search';\n\ninterface SubscribeOptions {\n runId?: string;\n}\n\nfunction normalizeRunRepetitions(value: number | undefined): number {\n const n = value ?? 1;\n if (!Number.isInteger(n) || n < 1) {\n throw new Error(`repetitions must be a positive integer, got ${String(value)}`);\n }\n return n;\n}\n\nexport interface RunDatasetJobsWithSharedConcurrencyRequest {\n jobs: ReadonlyArray<RunDatasetJob>;\n globalConcurrency: number;\n triggerId?: string;\n /**\n * When the batch was triggered (`Date.now()` ms); defaults to now. CLI sets this once at command start.\n */\n triggerTimestamp?: number;\n /** Applied to every job in this batch (e.g. CLI `--experiment`). */\n experimentName?: string;\n}\n\nexport interface RunnerApi {\n collectDatasets(): Promise<ReadonlyArray<CollectedDataset>>;\n collectEvaluators(): Promise<ReadonlyArray<CollectedEvaluator>>;\n collectRunConfigs(): Promise<ReadonlyArray<CollectedRunConfig>>;\n /** Resolves a dataset by canonical **`Dataset` `name`** (id), case-insensitive. */\n resolveDatasetByName(name: string): Promise<CollectedDataset | undefined>;\n resolveEvaluatorsByNamePattern(pattern: string): Promise<ReadonlyArray<CollectedEvaluator>>;\n /**\n * Resolves a RunConfig by display name (case-insensitive).\n * @throws If more than one discovered RunConfig uses the same name (list file paths in the error).\n */\n resolveRunConfigByName(name: string): Promise<CollectedRunConfig | undefined>;\n expandRunConfigToJobs(collected: CollectedRunConfig): Promise<ReadonlyArray<RunDatasetJob>>;\n /** Resolves each name in order and concatenates expanded jobs (the same name may appear more than once). */\n expandRunConfigNamesToJobs(names: ReadonlyArray<string>): Promise<ReadonlyArray<RunDatasetJob>>;\n runDatasetJobsWithSharedConcurrency(\n request: RunDatasetJobsWithSharedConcurrencyRequest,\n ): Promise<ReadonlyArray<RunSnapshot>>;\n searchTestCases(query?: SearchTestCasesQuery): Promise<ReadonlyArray<CollectedTestCase>>;\n collectDatasetTestCases(datasetId: string): Promise<ReadonlyArray<CollectedTestCase>>;\n runDatasetWith(request: RunDatasetRequest): Promise<RunSnapshot>;\n subscribeRunEvents(\n listener: (event: RunnerEvent) => void,\n options?: SubscribeOptions,\n ): () => void;\n getRunSnapshot(runId: string): RunSnapshot | undefined;\n getAllRunSnapshots(): ReadonlyArray<RunSnapshot>;\n loadRunSnapshotsFromArtifacts(): Promise<ReadonlyArray<RunSnapshot>>;\n shutdown(): Promise<void>;\n}\n\nfunction mergeRunnerOverrides(\n base?: RunnerConfigOverrides,\n next?: RunnerConfigOverrides,\n): RunnerConfigOverrides | undefined {\n if (!base) {\n return next;\n }\n if (!next) {\n return base;\n }\n const discovery =\n base.discovery || next.discovery\n ? {\n ...(base.discovery ?? {}),\n ...(next.discovery ?? {}),\n }\n : undefined;\n return {\n ...base,\n ...next,\n discovery,\n };\n}\n\nexport function createRunner(overrides?: RunnerConfigOverrides): RunnerApi {\n const fileOverrides = loadRunnerConfigFile();\n const merged = mergeRunnerOverrides(fileOverrides, overrides);\n return new EffectRunner(withRunnerConfig(merged));\n}\n\nclass EffectRunner implements RunnerApi {\n private readonly config: RunnerConfig;\n\n private readonly eventBus = Effect.runSync(PubSub.unbounded<RunnerEvent>());\n\n private readonly runQueue = Effect.runSync(Queue.unbounded<RunTask>());\n\n private readonly persistenceQueue = Effect.runSync(\n Queue.unbounded<{\n runId: string;\n artifactPath: string;\n payload: unknown;\n }>(),\n );\n\n private readonly snapshotsRef = Effect.runSync(Ref.make(new Map<string, RunSnapshot>()));\n private readonly listeners = new Set<{\n runId?: string;\n listener: (event: RunnerEvent) => void;\n }>();\n\n private readonly datasetsById = new Map<string, CollectedDataset>();\n\n private readonly evaluatorsById = new Map<string, CollectedEvaluator>();\n\n private readonly runConfigsById = new Map<string, CollectedRunConfig>();\n\n private readonly schedulerFiber = Effect.runFork(this.createSchedulerEffect());\n\n private readonly persistenceFiber = Effect.runFork(\n createPersistenceWorker(this.persistenceQueue),\n );\n\n constructor(config: RunnerConfig) {\n this.config = config;\n }\n\n async collectDatasets(): Promise<ReadonlyArray<CollectedDataset>> {\n const datasets = await collectDatasetsFromFiles(this.config.discovery);\n this.datasetsById.clear();\n for (const dataset of datasets) {\n this.datasetsById.set(dataset.id, dataset);\n }\n return datasets;\n }\n\n async collectEvaluators(): Promise<ReadonlyArray<CollectedEvaluator>> {\n const evaluators = await collectEvaluatorsFromFiles(this.config.discovery);\n this.evaluatorsById.clear();\n for (const evaluator of evaluators) {\n this.evaluatorsById.set(evaluator.id, evaluator);\n }\n return evaluators;\n }\n\n async resolveDatasetByName(name: string): Promise<CollectedDataset | undefined> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n const normalized = name.trim().toLowerCase();\n return Array.from(this.datasetsById.values()).find(\n (item) => item.dataset.getName().toLowerCase() === normalized,\n );\n }\n\n async resolveEvaluatorsByNamePattern(\n pattern: string,\n ): Promise<ReadonlyArray<CollectedEvaluator>> {\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n const matcher = createNameMatcher(pattern);\n return Array.from(this.evaluatorsById.values()).filter((item) =>\n matcher(item.evaluator.getName() ?? ''),\n );\n }\n\n async collectRunConfigs(): Promise<ReadonlyArray<CollectedRunConfig>> {\n const runConfigs = await collectRunConfigsFromFiles(this.config.discovery);\n this.runConfigsById.clear();\n const byNameLower = new Map<string, CollectedRunConfig>();\n for (const item of runConfigs) {\n const id = item.runConfig.getName();\n const lower = id.toLowerCase();\n const prev = byNameLower.get(lower);\n if (prev !== undefined && prev.filePath !== item.filePath) {\n throw new Error(\n `Duplicate RunConfig name \"${id}\" (matches \"${prev.runConfig.getName()}\" case-insensitively): ${prev.filePath} and ${item.filePath}`,\n );\n }\n byNameLower.set(lower, item);\n this.runConfigsById.set(id, item);\n }\n return runConfigs;\n }\n\n async resolveRunConfigByName(name: string): Promise<CollectedRunConfig | undefined> {\n if (this.runConfigsById.size === 0) {\n await this.collectRunConfigs();\n }\n const key = validateRunConfigName(name, `RunConfig \"${name.trim()}\"`);\n const keyLower = key.toLowerCase();\n const matches = Array.from(this.runConfigsById.values()).filter(\n (item) => item.runConfig.getName().toLowerCase() === keyLower,\n );\n if (matches.length === 0) {\n return undefined;\n }\n if (matches.length > 1) {\n throw new Error(\n `Multiple RunConfigs named \"${name}\": ${matches.map((m) => m.filePath).join(', ')}`,\n );\n }\n return matches[0];\n }\n\n async expandRunConfigToJobs(\n collected: CollectedRunConfig,\n ): Promise<ReadonlyArray<RunDatasetJob>> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n\n const rcName = collected.runConfig.getName();\n const jobs: RunDatasetJob[] = [];\n const runs = collected.runConfig.getRuns();\n\n for (const [i, row] of runs.entries()) {\n const dsCollected = Array.from(this.datasetsById.values()).find(\n (d) => d.dataset === row.dataset,\n );\n if (!dsCollected) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: dataset \"${row.dataset.getDisplayLabel()}\" was not found among discovered dataset exports (import the same module instances the scanner loads).`,\n );\n }\n\n let evaluatorIds: string[];\n if ('evaluatorPattern' in row && typeof row.evaluatorPattern === 'string') {\n const matcher = createNameMatcher(row.evaluatorPattern);\n const matched = Array.from(this.evaluatorsById.values()).filter((item) =>\n matcher(item.evaluator.getName() ?? ''),\n );\n if (matched.length === 0) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: no evaluator matched pattern \"${row.evaluatorPattern}\"`,\n );\n }\n evaluatorIds = matched.map((item) => item.id);\n } else {\n const evaluators = row.evaluators;\n evaluatorIds = [];\n for (const ev of evaluators) {\n const found = Array.from(this.evaluatorsById.values()).find(\n (item) => item.evaluator === ev,\n );\n if (!found) {\n throw new Error(\n `RunConfig \"${rcName}\" run[${i}]: evaluator \"${getEvaluatorDisplayLabel(ev) ?? 'unknown'}\" was not found among discovered evaluator exports`,\n );\n }\n evaluatorIds.push(found.id);\n }\n }\n\n const repetitions =\n 'repetitions' in row && row.repetitions !== undefined ? row.repetitions : 1;\n\n jobs.push({\n datasetId: dsCollected.id,\n evaluatorIds,\n runConfigName: rcName,\n runConfigDisplayLabel: collected.runConfig.getDisplayLabel(),\n runConfigTags: collected.runConfig.getTags(),\n repetitions,\n });\n }\n\n return jobs;\n }\n\n async expandRunConfigNamesToJobs(\n names: ReadonlyArray<string>,\n ): Promise<ReadonlyArray<RunDatasetJob>> {\n const jobs: RunDatasetJob[] = [];\n for (const name of names) {\n const collected = await this.resolveRunConfigByName(name);\n if (!collected) {\n const known = await this.collectRunConfigs();\n const available = known.map((r) => r.runConfig.getName()).sort();\n throw new Error(\n available.length > 0\n ? `RunConfig \"${name}\" not found. Available RunConfigs: ${available.join(', ')}`\n : `RunConfig \"${name}\" not found and no RunConfigs were discovered.`,\n );\n }\n jobs.push(...(await this.expandRunConfigToJobs(collected)));\n }\n return jobs;\n }\n\n async runDatasetJobsWithSharedConcurrency(\n request: RunDatasetJobsWithSharedConcurrencyRequest,\n ): Promise<ReadonlyArray<RunSnapshot>> {\n const globalConcurrency = Math.max(1, request.globalConcurrency);\n const sem = Effect.unsafeMakeSemaphore(globalConcurrency);\n const triggerId = request.triggerId ?? `trg-${randomUUID()}`;\n const triggerTimestamp = request.triggerTimestamp ?? Date.now();\n const snapshots: RunSnapshot[] = [];\n for (const job of request.jobs) {\n snapshots.push(\n await this.startDatasetRun({\n datasetId: job.datasetId,\n evaluatorIds: job.evaluatorIds,\n triggerId,\n triggerTimestamp,\n maxConcurrency: this.config.maxConcurrency ?? 1,\n globalEvaluationSemaphore: sem,\n runConfigName: job.runConfigName,\n runConfigTags: job.runConfigTags,\n repetitions: job.repetitions,\n experimentName: request.experimentName,\n }),\n );\n }\n return snapshots;\n }\n\n async searchTestCases(query?: SearchTestCasesQuery): Promise<ReadonlyArray<CollectedTestCase>> {\n const testCases = await collectTestCasesFromFiles(this.config.discovery);\n return searchCollectedTestCases(testCases, query);\n }\n\n async collectDatasetTestCases(datasetId: string): Promise<ReadonlyArray<CollectedTestCase>> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n const dataset = this.datasetsById.get(datasetId);\n if (!dataset) {\n throw new Error(`Unknown dataset: ${datasetId}`);\n }\n const allTestCases = await collectTestCasesFromFiles(this.config.discovery);\n return allTestCases.filter((testCase) =>\n dataset.dataset.matchesTestCase(testCase.testCase, testCase.filePath),\n );\n }\n\n async runDatasetWith(request: RunDatasetRequest): Promise<RunSnapshot> {\n const runConfigName = validateRunConfigName(\n request.runConfigName,\n 'runDatasetWith.runConfigName',\n );\n return this.startDatasetRun({\n datasetId: request.datasetId,\n evaluatorIds: request.evaluatorIds,\n triggerId: request.triggerId,\n triggerTimestamp: request.triggerTimestamp ?? Date.now(),\n maxConcurrency: request.concurrency ?? this.config.maxConcurrency ?? 1,\n repetitions: request.repetitions,\n runConfigName,\n runConfigTags: request.runConfigTags,\n experimentName: request.experimentName,\n });\n }\n\n private async startDatasetRun(params: {\n datasetId: string;\n evaluatorIds: ReadonlyArray<string>;\n triggerId?: string;\n triggerTimestamp?: number;\n maxConcurrency: number;\n globalEvaluationSemaphore?: ReturnType<typeof Effect.unsafeMakeSemaphore>;\n runConfigName: string;\n runConfigTags?: ReadonlyArray<string>;\n repetitions?: number;\n experimentName?: string;\n }): Promise<RunSnapshot> {\n if (this.datasetsById.size === 0) {\n await this.collectDatasets();\n }\n if (this.evaluatorsById.size === 0) {\n await this.collectEvaluators();\n }\n\n const dataset = this.datasetsById.get(params.datasetId);\n if (!dataset) {\n throw new Error(`Unknown dataset: ${params.datasetId}`);\n }\n\n const selectedEvaluators = params.evaluatorIds\n .map((id) => this.evaluatorsById.get(id))\n .filter((value): value is CollectedEvaluator => Boolean(value))\n .map((value) => ({ id: value.id, evaluator: value.evaluator }));\n\n if (selectedEvaluators.length === 0) {\n throw new Error('No evaluators selected for run');\n }\n\n const selectedTestCases = await this.collectDatasetTestCases(params.datasetId);\n\n const repetitions = normalizeRunRepetitions(params.repetitions);\n const totalEvaluations = selectedTestCases.length * repetitions;\n const runConfigTags = [...(params.runConfigTags ?? [])];\n\n const triggerId = params.triggerId ?? `trg-${randomUUID()}`;\n const triggerTimestamp = params.triggerTimestamp ?? Date.now();\n const runId = `run-${randomUUID()}`;\n const artifactPath = createArtifactPath(this.config.artifactDirectory, params.datasetId, runId);\n const snapshot: RunSnapshot = {\n runId,\n datasetId: params.datasetId,\n datasetName: dataset.dataset.getDisplayLabel(),\n evaluatorIds: selectedEvaluators.map((item) => item.id),\n queuedAt: Date.now(),\n totalTestCases: totalEvaluations,\n completedTestCases: 0,\n passedTestCases: 0,\n failedTestCases: 0,\n status: 'queued',\n artifactPath,\n };\n\n await Effect.runPromise(\n Ref.update(this.snapshotsRef, (map) => {\n const next = new Map(map);\n next.set(runId, snapshot);\n return next;\n }),\n );\n const queuedEvent: RunnerEvent = {\n type: 'RunQueued',\n runId,\n datasetId: params.datasetId,\n datasetName: dataset.dataset.getDisplayLabel(),\n evaluatorIds: selectedEvaluators.map((item) => item.id),\n totalTestCases: totalEvaluations,\n artifactPath,\n };\n await Effect.runPromise(this.publishEvent(queuedEvent));\n await Effect.runPromise(\n Queue.offer(this.persistenceQueue, {\n runId,\n artifactPath,\n payload: queuedEvent,\n }),\n );\n\n await Effect.runPromise(\n Queue.offer(this.runQueue, {\n runId,\n triggerId,\n triggerTimestamp,\n datasetId: params.datasetId,\n dataset: dataset.dataset,\n evaluators: selectedEvaluators,\n testCases: selectedTestCases,\n snapshot,\n maxConcurrency: params.maxConcurrency,\n globalEvaluationSemaphore: params.globalEvaluationSemaphore,\n runConfigName: params.runConfigName,\n runConfigTags,\n repetitions,\n experimentName: params.experimentName,\n }),\n );\n\n return snapshot;\n }\n\n subscribeRunEvents(\n listener: (event: RunnerEvent) => void,\n options?: SubscribeOptions,\n ): () => void {\n const entry = { runId: options?.runId, listener };\n this.listeners.add(entry);\n return () => {\n this.listeners.delete(entry);\n };\n }\n\n getRunSnapshot(runId: string): RunSnapshot | undefined {\n return Effect.runSync(Ref.get(this.snapshotsRef)).get(runId);\n }\n\n getAllRunSnapshots(): ReadonlyArray<RunSnapshot> {\n return Array.from(Effect.runSync(Ref.get(this.snapshotsRef)).values()).sort(\n (a, b) => b.queuedAt - a.queuedAt,\n );\n }\n\n async loadRunSnapshotsFromArtifacts(): Promise<ReadonlyArray<RunSnapshot>> {\n return loadSnapshotsFromArtifacts(this.config);\n }\n\n async shutdown(): Promise<void> {\n await Effect.runPromise(Fiber.interrupt(this.schedulerFiber));\n await Effect.runPromise(Fiber.interrupt(this.persistenceFiber));\n await Effect.runPromise(Queue.shutdown(this.runQueue));\n await Effect.runPromise(Queue.shutdown(this.persistenceQueue));\n await Effect.runPromise(PubSub.shutdown(this.eventBus));\n }\n\n private createSchedulerEffect() {\n const self = this;\n return Effect.forever(\n Effect.gen(function* () {\n const task = yield* Queue.take(self.runQueue);\n yield* Effect.fork(\n executeRunTask(\n task,\n self.publishEvent.bind(self),\n self.persistenceQueue,\n self.updateSnapshot.bind(self),\n ),\n );\n }),\n );\n }\n\n private updateSnapshot(\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ): Effect.Effect<void, never, never> {\n return Ref.modify(this.snapshotsRef, (map) => {\n const existing = map.get(runId);\n if (!existing) {\n return [undefined, map] as const;\n }\n const next = new Map(map);\n next.set(runId, updater(existing));\n return [undefined, next] as const;\n }).pipe(Effect.asVoid);\n }\n\n private publishEvent(event: RunnerEvent): Effect.Effect<void, never, never> {\n return Effect.sync(() => {\n for (const entry of this.listeners) {\n if (entry.runId && entry.runId !== event.runId) {\n continue;\n }\n entry.listener(event);\n }\n }).pipe(\n Effect.flatMap(() => PubSub.publish(this.eventBus, event)),\n Effect.asVoid,\n );\n }\n}\n","import { Either, ParseResult, Schema } from 'effect';\n\nconst ENTITY_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\nfunction makeEntityIdSchema<const B extends string>(brand: B, label: string) {\n return Schema.String.pipe(\n Schema.trimmed(),\n Schema.minLength(1, {\n message: () => `${label} must be non-empty.`,\n }),\n Schema.pattern(ENTITY_ID_PATTERN, {\n message: () =>\n `${label} may only contain letters, digits, underscores, and hyphens (no spaces). Examples: \"my-nightly\", \"my_nightly\", \"myNightly\".`,\n }),\n Schema.brand(brand),\n );\n}\n\n/** Branded id for `RunConfig` `name` (decode with {@link RunConfigNameSchema}). */\nexport const RunConfigNameSchema = makeEntityIdSchema('RunConfigName', 'RunConfig name');\n\n/** Branded id for `Evaluator.define({ name })` (decode with {@link EvaluatorNameSchema}). */\nexport const EvaluatorNameSchema = makeEntityIdSchema('EvaluatorName', 'Evaluator name');\n\n/** Branded id for `TestCase.describe({ name })` (decode with {@link TestCaseNameSchema}). */\nexport const TestCaseNameSchema = makeEntityIdSchema('TestCaseName', 'Test case name');\n\n/** Branded id for `Dataset.define({ name })` (decode with {@link DatasetNameSchema}). */\nexport const DatasetNameSchema = makeEntityIdSchema('DatasetName', 'Dataset name');\n\nexport type RunConfigName = Schema.Schema.Type<typeof RunConfigNameSchema>;\nexport type EvaluatorName = Schema.Schema.Type<typeof EvaluatorNameSchema>;\nexport type TestCaseName = Schema.Schema.Type<typeof TestCaseNameSchema>;\nexport type DatasetName = Schema.Schema.Type<typeof DatasetNameSchema>;\n\nfunction validateWithSchema(schema: Schema.Schema.Any, raw: string, context: string): unknown {\n const trimmed = raw.trim();\n // Branded string schemas use `Context = unknown`; `decodeUnknownEither` is typed for context `never`.\n const decode = Schema.decodeUnknownEither(\n schema as unknown as Schema.Schema<string, string, never>,\n );\n const result = decode(trimmed);\n if (Either.isLeft(result)) {\n throw new Error(`${context}: ${ParseResult.TreeFormatter.formatErrorSync(result.left)}`);\n }\n return result.right;\n}\n\nexport function validateRunConfigName(raw: string, context: string): RunConfigName {\n return validateWithSchema(RunConfigNameSchema, raw, context) as RunConfigName;\n}\n\nexport function validateEvaluatorName(raw: string, context: string): EvaluatorName {\n return validateWithSchema(EvaluatorNameSchema, raw, context) as EvaluatorName;\n}\n\nexport function validateTestCaseName(raw: string, context: string): TestCaseName {\n return validateWithSchema(TestCaseNameSchema, raw, context) as TestCaseName;\n}\n\nexport function validateDatasetName(raw: string, context: string): DatasetName {\n return validateWithSchema(DatasetNameSchema, raw, context) as DatasetName;\n}\n\n/** Optional UI label: trim; empty after trim becomes undefined. */\nexport function normalizeOptionalDisplayName(raw: string | undefined): string | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const t = raw.trim();\n return t.length === 0 ? undefined : t;\n}\n","import type { Schema as S } from 'effect';\nimport type { CreateDiffLogEntryOptions } from './diff';\nimport {\n type EvaluatorName,\n normalizeOptionalDisplayName,\n validateEvaluatorName,\n} from './entity-name';\n\nexport interface EvalMiddleware<TCtx> {\n name: string;\n resolve: () => TCtx | Promise<TCtx>;\n}\n\nexport interface EvaluateMeta {\n /** Identifier of the trigger that started the run (for example, a CLI invocation). */\n triggerId: string;\n /**\n * Milliseconds since Unix epoch when the run was triggered (e.g. `Date.now()` at CLI start, or when\n * `runDatasetWith` / `runDatasetJobsWithSharedConcurrency` was invoked). Shared across all jobs in a batch.\n */\n triggerTimestamp: number;\n /** Same instant as {@link triggerTimestamp}, as an ISO 8601 string (`toISOString()`). */\n triggeredAt: string;\n /**\n * Identifier of the current test-case execution shared across all evaluators\n * for this specific test-case run.\n */\n runId: string;\n /** Display label for the dataset (`Dataset.getDisplayLabel()`, i.e. `displayName ?? name`). */\n datasetName: string;\n /** Discovery id for the current test case (same as runner events’ `testCaseId`). */\n testCaseId: string;\n /** Display label for the test case (`TestCase.getDisplayLabel()`, i.e. `displayName ?? name`). */\n testCaseName: string;\n /** Canonical `RunConfig` name (or `programmatic` for API/TUI-only runs). */\n runConfigName: string;\n /**\n * Optional label for this invocation (e.g. CLI `--experiment`); omitted when not set.\n */\n experimentName?: string;\n /**\n * Stable id shared by every execution of the same logical test case when `repetitionCount > 1`\n * (and present with count 1 for consistency).\n */\n repetitionId: string;\n /** 1-based index of this execution within the repetition group. */\n repetitionIndex: number;\n /** Total scheduled executions for this logical test case in the current run. */\n repetitionCount: number;\n /** Declared tags on the current test case (`TestCase.describe({ tags })`); empty when none. */\n testCaseTags: string[];\n /**\n * Declared tags on the current run config or programmatic request (`RunConfig.define({ tags })`,\n * `RunDatasetRequest.runConfigTags`); empty when none.\n */\n runConfigTags: string[];\n /** Declared tags on this evaluator (`Evaluator.define({ tags })`); empty when none. */\n evaluatorTags: string[];\n}\n\nexport interface EvaluateArgs<TInput, TOutput = unknown, TCtx = Record<string, never>> {\n input: TInput;\n ctx: TCtx;\n output?: TOutput;\n /** Metadata about the current evaluator invocation. */\n meta: EvaluateMeta;\n /** Records a diff for this test case; stored in run artifact and shown by CLI */\n logDiff: (expected: unknown, actual: unknown, options?: CreateDiffLogEntryOptions) => void;\n /** Logs a message or object for this test case; stored in run artifact and shown by CLI */\n log: (message: unknown, options?: { label?: string }) => void;\n /**\n * Creates an Error from string/object payloads for `return createError(...)` (or `throw createError(...)`).\n * The payload is also logged and shown by the CLI when the evaluator fails.\n */\n createError: (message: unknown, options?: { label?: string }) => Error;\n}\n\ntype EvaluateFn<TInput, TOutput, TScore, TCtx> = (\n args: EvaluateArgs<TInput, TOutput, TCtx>,\n) => TScore | Error | Promise<TScore | Error>;\n\ninterface EvaluatorConfig<TInput, TOutput, TScore, TCtx> {\n name?: EvaluatorName;\n displayName?: string;\n tags: readonly string[];\n inputSchema?: S.Schema.Any;\n outputSchema?: S.Schema.Any;\n scoreSchema?: S.Schema.Any;\n middlewares: ReadonlyArray<EvalMiddleware<unknown>>;\n evaluateFn?: EvaluateFn<TInput, TOutput, TScore, TCtx>;\n passThreshold?: number;\n passCriterion?: (score: unknown) => boolean;\n /** Phantom field for TOutput type parameter */\n _outputType?: TOutput;\n}\n\ninterface EvaluatorDefineConfig<\n TI extends S.Schema.Any,\n TO extends S.Schema.Any,\n TS extends S.Schema.Any,\n> {\n /**\n * Stable id (letters, digits, `_`, `-`); used for discovery, name patterns, and `meta`.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI (any characters). */\n displayName?: string;\n inputSchema: TI;\n outputSchema: TO;\n scoreSchema: TS;\n passThreshold?: number;\n passCriterion?: (score: unknown) => boolean;\n /**\n * Declared tags for this evaluator (not dataset filter rules); echoed on every `evaluate` call as\n * `meta.evaluatorTags`.\n */\n tags?: ReadonlyArray<string>;\n}\n\nexport class Evaluator<\n TInput = unknown,\n TOutput = unknown,\n TScore = unknown,\n TCtx = Record<string, never>,\n> {\n private readonly _config: EvaluatorConfig<TInput, TOutput, TScore, TCtx>;\n\n private constructor(config: EvaluatorConfig<TInput, TOutput, TScore, TCtx>) {\n this._config = config;\n }\n\n private getState(): EvaluatorConfig<TInput, TOutput, TScore, TCtx> {\n return {\n name: this._config.name,\n displayName: this._config.displayName,\n tags: this._config.tags,\n inputSchema: this._config.inputSchema,\n outputSchema: this._config.outputSchema,\n scoreSchema: this._config.scoreSchema,\n middlewares: this._config.middlewares,\n evaluateFn: this._config.evaluateFn,\n passThreshold: this._config.passThreshold,\n passCriterion: this._config.passCriterion,\n };\n }\n\n static use<TCtx>(middleware: EvalMiddleware<TCtx>): Evaluator<unknown, unknown, unknown, TCtx> {\n return new Evaluator<unknown, unknown, unknown, TCtx>({\n middlewares: [middleware as EvalMiddleware<unknown>],\n tags: [],\n });\n }\n\n use<TNew>(middleware: EvalMiddleware<TNew>): Evaluator<TInput, TOutput, TScore, TCtx & TNew> {\n const state = this.getState();\n return new Evaluator<TInput, TOutput, TScore, TCtx & TNew>({\n ...(state as unknown as EvaluatorConfig<TInput, TOutput, TScore, TCtx & TNew>),\n middlewares: [...state.middlewares, middleware as EvalMiddleware<unknown>],\n });\n }\n\n define<TI extends S.Schema.Any, TO extends S.Schema.Any, TS extends S.Schema.Any>(\n config: EvaluatorDefineConfig<TI, TO, TS>,\n ): Evaluator<S.Schema.Type<TI>, S.Schema.Type<TO>, S.Schema.Type<TS>, TCtx> {\n const { middlewares } = this.getState();\n const name = validateEvaluatorName(config.name, 'Evaluator.define');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n const tags = config.tags !== undefined ? [...config.tags] : [];\n return new Evaluator<S.Schema.Type<TI>, S.Schema.Type<TO>, S.Schema.Type<TS>, TCtx>({\n name,\n displayName,\n tags,\n inputSchema: config.inputSchema,\n outputSchema: config.outputSchema,\n scoreSchema: config.scoreSchema,\n middlewares,\n passThreshold: config.passThreshold,\n passCriterion: config.passCriterion,\n });\n }\n\n evaluate(\n fn: EvaluateFn<TInput, TOutput, TScore, TCtx>,\n ): Evaluator<TInput, TOutput, TScore, TCtx> {\n return new Evaluator<TInput, TOutput, TScore, TCtx>({\n ...this.getState(),\n evaluateFn: fn,\n });\n }\n\n /** Canonical evaluator id when defined; otherwise undefined (middleware-only chain). */\n getName(): string | undefined {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n /** Label for CLI/TUI: {@link getDisplayName} if set, otherwise {@link getName}. Undefined if not yet defined. */\n getDisplayLabel(): string | undefined {\n const id = this._config.name;\n if (id === undefined) {\n return undefined;\n }\n return this._config.displayName ?? id;\n }\n\n /** Tags from `Evaluator.define({ tags })`; empty until defined. */\n getTags(): string[] {\n return [...this._config.tags];\n }\n\n getInputSchema(): S.Schema.Any | undefined {\n return this._config.inputSchema;\n }\n\n getOutputSchema(): S.Schema.Any | undefined {\n return this._config.outputSchema;\n }\n\n getScoreSchema(): S.Schema.Any | undefined {\n return this._config.scoreSchema;\n }\n\n getMiddlewares(): ReadonlyArray<EvalMiddleware<unknown>> {\n return this._config.middlewares;\n }\n\n getEvaluateFn(): EvaluateFn<TInput, TOutput, TScore, TCtx> | undefined {\n return this._config.evaluateFn;\n }\n\n getPassThreshold(): number | undefined {\n return this._config.passThreshold;\n }\n\n getPassCriterion(): ((score: unknown) => boolean) | undefined {\n return this._config.passCriterion;\n }\n\n async resolveContext(): Promise<TCtx> {\n const parts = await Promise.all(this._config.middlewares.map((mw) => mw.resolve()));\n return Object.assign({}, ...parts) as TCtx;\n }\n}\n\n/** CLI-friendly label: {@link Evaluator.getDisplayLabel} when present, else {@link Evaluator.getName} (supports plain evaluator-shaped objects from discovery). */\nexport function getEvaluatorDisplayLabel(evaluator: {\n getDisplayLabel?: () => string | undefined;\n getName?: () => string | undefined;\n}): string | undefined {\n if (typeof evaluator.getDisplayLabel === 'function') {\n const label = evaluator.getDisplayLabel();\n if (label !== undefined) {\n return label;\n }\n }\n return typeof evaluator.getName === 'function' ? evaluator.getName() : undefined;\n}\n\n/** Tags for evaluator `meta.evaluatorTags` (plain evaluator-shaped objects without `getTags` yield `[]`). */\nexport function getEvaluatorTagList(evaluator: {\n getTags?: () => ReadonlyArray<string>;\n}): string[] {\n return typeof evaluator.getTags === 'function' ? [...evaluator.getTags()] : [];\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nimport type { RunnerConfig } from './config';\nimport type { RunSnapshot } from './events';\n\nexport interface ParsedTestCaseProgress {\n testCaseId: string;\n testCaseName: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionId?: string;\n repetitionIndex?: number;\n repetitionCount?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<{\n id: string;\n data: unknown;\n passed?: boolean;\n name?: string;\n }>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<\n | { type: 'diff'; label?: string; expected: unknown; actual: unknown; diff: string }\n | { type: 'log'; label?: string; message: string }\n >;\n }>;\n}\n\nexport async function loadRunSnapshotsFromArtifacts(config: RunnerConfig): Promise<RunSnapshot[]> {\n const baseDir = resolve(config.artifactDirectory);\n let entries: string[];\n try {\n entries = await readdir(baseDir);\n } catch {\n return [];\n }\n\n const jsonlFiles = entries.filter((name) => name.endsWith('.jsonl'));\n const snapshots: RunSnapshot[] = [];\n\n for (const fileName of jsonlFiles) {\n const filePath = join(baseDir, fileName);\n try {\n const snapshot = await parseArtifactToSnapshot(filePath, config);\n if (snapshot) {\n snapshots.push(snapshot);\n }\n } catch {\n // Skip malformed or unreadable files\n }\n }\n\n return snapshots.sort((a, b) => b.queuedAt - a.queuedAt);\n}\n\nasync function parseArtifactToSnapshot(\n filePath: string,\n _config: RunnerConfig,\n): Promise<RunSnapshot | null> {\n const content = await readFile(filePath, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim().length > 0);\n if (lines.length === 0) {\n return null;\n }\n\n let runQueued: {\n runId: string;\n datasetId: string;\n datasetName: string;\n evaluatorIds: ReadonlyArray<string>;\n totalTestCases: number;\n artifactPath: string;\n ts?: number;\n } | null = null;\n\n let runCompleted: {\n passedTestCases: number;\n failedTestCases: number;\n totalTestCases: number;\n finishedAt: number;\n } | null = null;\n\n let runFailed: { finishedAt: number; errorMessage: string } | null = null;\n let runStarted: { startedAt: number } | null = null;\n\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n const type = event.type as string;\n\n if (type === 'RunQueued') {\n runQueued = {\n runId: event.runId as string,\n datasetId: event.datasetId as string,\n datasetName: event.datasetName as string,\n evaluatorIds: event.evaluatorIds as ReadonlyArray<string>,\n totalTestCases: (event.totalTestCases as number) ?? 0,\n artifactPath: (event.artifactPath as string) ?? filePath,\n ts: event.ts as number | undefined,\n };\n }\n if (type === 'RunStarted') {\n runStarted = { startedAt: event.startedAt as number };\n }\n if (type === 'RunCompleted') {\n runCompleted = {\n passedTestCases: event.passedTestCases as number,\n failedTestCases: event.failedTestCases as number,\n totalTestCases: event.totalTestCases as number,\n finishedAt: event.finishedAt as number,\n };\n }\n if (type === 'RunFailed') {\n runFailed = {\n finishedAt: event.finishedAt as number,\n errorMessage: event.errorMessage as string,\n };\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n if (!runQueued) {\n return null;\n }\n\n const artifactPath = filePath;\n\n const status = runFailed\n ? 'failed'\n : runCompleted\n ? 'completed'\n : runStarted\n ? 'running'\n : 'queued';\n\n const progress = aggregateTestCaseProgress(lines);\n const completedTestCases = runCompleted ? runQueued.totalTestCases : progress.completedTestCases;\n const passedTestCases = runCompleted?.passedTestCases ?? progress.passedTestCases;\n const failedTestCases = runCompleted?.failedTestCases ?? progress.failedTestCases;\n\n return {\n runId: runQueued.runId,\n datasetId: runQueued.datasetId,\n datasetName: runQueued.datasetName,\n evaluatorIds: runQueued.evaluatorIds,\n queuedAt: runQueued.ts ?? 0,\n startedAt: runStarted?.startedAt,\n finishedAt: runCompleted?.finishedAt ?? runFailed?.finishedAt,\n totalTestCases: runQueued.totalTestCases,\n completedTestCases,\n passedTestCases,\n failedTestCases,\n status,\n artifactPath,\n errorMessage: runFailed?.errorMessage,\n };\n}\n\nfunction aggregateTestCaseProgress(lines: string[]): {\n completedTestCases: number;\n passedTestCases: number;\n failedTestCases: number;\n} {\n let completedTestCases = 0;\n const testCasePassedBy = new Map<string, boolean>();\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n if (event.type === 'TestCaseProgress') {\n const ev = event as {\n testCaseId: string;\n completedTestCases: number;\n passed: boolean;\n };\n completedTestCases = ev.completedTestCases ?? completedTestCases;\n const id = ev.testCaseId;\n const current = testCasePassedBy.get(id);\n testCasePassedBy.set(id, current === undefined ? ev.passed : current && ev.passed);\n }\n } catch {\n // skip\n }\n }\n let passedTestCases = 0;\n let failedTestCases = 0;\n for (const passed of testCasePassedBy.values()) {\n if (passed) {\n passedTestCases += 1;\n } else {\n failedTestCases += 1;\n }\n }\n return { completedTestCases, passedTestCases, failedTestCases };\n}\n\nexport async function parseArtifactFile(artifactPath: string): Promise<ParsedTestCaseProgress[]> {\n try {\n const content = await readFile(artifactPath, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim().length > 0);\n const results: ParsedTestCaseProgress[] = [];\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Record<string, unknown>;\n if (event.type === 'TestCaseProgress') {\n const ev = event as {\n testCaseId: string;\n testCaseName: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionId?: string;\n repetitionIndex?: number;\n repetitionCount?: number;\n rerunIndex?: number;\n rerunTotal?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<{\n id: string;\n data: unknown;\n passed?: boolean;\n name?: string;\n }>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<\n | { type: 'diff'; label?: string; expected: unknown; actual: unknown; diff: string }\n | { type: 'log'; label?: string; message: string }\n >;\n }>;\n };\n const repetitionIndex = ev.repetitionIndex ?? ev.rerunIndex;\n const repetitionCount = ev.repetitionCount ?? ev.rerunTotal;\n results.push({\n testCaseId: ev.testCaseId,\n testCaseName: ev.testCaseName,\n completedTestCases: ev.completedTestCases,\n totalTestCases: ev.totalTestCases,\n repetitionId: ev.repetitionId,\n repetitionIndex,\n repetitionCount,\n passed: ev.passed,\n durationMs: ev.durationMs,\n evaluatorScores: ev.evaluatorScores ?? [],\n });\n }\n } catch {\n // skip malformed lines\n }\n }\n return results;\n } catch {\n return [];\n }\n}\n","export interface RunnerDiscoveryConfig {\n rootDir: string;\n datasetSuffixes: ReadonlyArray<string>;\n evaluatorSuffixes: ReadonlyArray<string>;\n runConfigSuffixes: ReadonlyArray<string>;\n testCaseSuffixes: ReadonlyArray<string>;\n excludeDirectories: ReadonlyArray<string>;\n}\n\nexport interface RunnerConfig {\n discovery: RunnerDiscoveryConfig;\n artifactDirectory: string;\n /** Max concurrent test cases per run. Default: 1 (sequential). */\n maxConcurrency: number;\n}\n\nexport type RunnerConfigOverrides = Omit<Partial<RunnerConfig>, 'discovery'> & {\n discovery?: Partial<RunnerDiscoveryConfig>;\n};\n\nexport interface M4trixEvalConfigDiscovery {\n rootDir?: string;\n datasetFilePatterns?: ReadonlyArray<string>;\n evaluatorFilePatterns?: ReadonlyArray<string>;\n runConfigFilePatterns?: ReadonlyArray<string>;\n testCaseFilePatterns?: ReadonlyArray<string>;\n datasetSuffixes?: ReadonlyArray<string>;\n evaluatorSuffixes?: ReadonlyArray<string>;\n runConfigSuffixes?: ReadonlyArray<string>;\n testCaseSuffixes?: ReadonlyArray<string>;\n excludeDirectories?: ReadonlyArray<string>;\n}\n\nexport interface M4trixEvalConfig {\n discovery?: M4trixEvalConfigDiscovery;\n artifactDirectory?: string;\n /** Max concurrent test cases per run. Default: 1 (sequential). */\n maxConcurrency?: number;\n}\n\nexport type ConfigType = M4trixEvalConfig;\n\nexport type M4trixEvalConfigFactory<TConfig extends ConfigType = ConfigType> = () => TConfig;\n\nexport function defineConfig<TConfig extends ConfigType>(\n factory: M4trixEvalConfigFactory<TConfig>,\n): M4trixEvalConfigFactory<TConfig> {\n return factory;\n}\n\nexport const defaultRunnerConfig: RunnerConfig = {\n discovery: {\n rootDir: process.cwd(),\n datasetSuffixes: ['.dataset.ts', '.dataset.tsx', '.dataset.js', '.dataset.mjs'],\n evaluatorSuffixes: ['.evaluator.ts', '.evaluator.tsx', '.evaluator.js', '.evaluator.mjs'],\n runConfigSuffixes: ['.run-config.ts', '.run-config.tsx', '.run-config.js', '.run-config.mjs'],\n testCaseSuffixes: ['.test-case.ts', '.test-case.tsx', '.test-case.js', '.test-case.mjs'],\n excludeDirectories: ['node_modules', 'dist', '.next', '.git', '.pnpm-store'],\n },\n artifactDirectory: '.eval-results',\n maxConcurrency: 1,\n};\n\nexport function toRunnerConfigOverrides(config?: ConfigType): RunnerConfigOverrides | undefined {\n if (!config) {\n return undefined;\n }\n\n const rawDiscovery = config.discovery;\n const discovery: Partial<RunnerDiscoveryConfig> = {};\n if (rawDiscovery?.rootDir !== undefined) {\n discovery.rootDir = rawDiscovery.rootDir;\n }\n if (rawDiscovery?.datasetFilePatterns !== undefined) {\n discovery.datasetSuffixes = rawDiscovery.datasetFilePatterns;\n } else if (rawDiscovery?.datasetSuffixes !== undefined) {\n discovery.datasetSuffixes = rawDiscovery.datasetSuffixes;\n }\n if (rawDiscovery?.evaluatorFilePatterns !== undefined) {\n discovery.evaluatorSuffixes = rawDiscovery.evaluatorFilePatterns;\n } else if (rawDiscovery?.evaluatorSuffixes !== undefined) {\n discovery.evaluatorSuffixes = rawDiscovery.evaluatorSuffixes;\n }\n if (rawDiscovery?.runConfigFilePatterns !== undefined) {\n discovery.runConfigSuffixes = rawDiscovery.runConfigFilePatterns;\n } else if (rawDiscovery?.runConfigSuffixes !== undefined) {\n discovery.runConfigSuffixes = rawDiscovery.runConfigSuffixes;\n }\n if (rawDiscovery?.testCaseFilePatterns !== undefined) {\n discovery.testCaseSuffixes = rawDiscovery.testCaseFilePatterns;\n } else if (rawDiscovery?.testCaseSuffixes !== undefined) {\n discovery.testCaseSuffixes = rawDiscovery.testCaseSuffixes;\n }\n if (rawDiscovery?.excludeDirectories !== undefined) {\n discovery.excludeDirectories = rawDiscovery.excludeDirectories;\n }\n\n const overrides: RunnerConfigOverrides = {};\n if (config.artifactDirectory !== undefined) {\n overrides.artifactDirectory = config.artifactDirectory;\n }\n if (config.maxConcurrency !== undefined) {\n overrides.maxConcurrency = config.maxConcurrency;\n }\n if (Object.keys(discovery).length > 0) {\n overrides.discovery = discovery;\n }\n return overrides;\n}\n\nexport function withRunnerConfig(overrides?: RunnerConfigOverrides): RunnerConfig {\n if (!overrides) {\n return defaultRunnerConfig;\n }\n const discovery = overrides.discovery\n ? {\n ...defaultRunnerConfig.discovery,\n ...overrides.discovery,\n }\n : defaultRunnerConfig.discovery;\n\n return {\n ...defaultRunnerConfig,\n ...overrides,\n discovery,\n };\n}\n","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport * as jitiModule from 'jiti';\n\nimport type { RunnerConfigOverrides } from './config';\nimport { type ConfigType, type M4trixEvalConfigFactory, toRunnerConfigOverrides } from './config';\n\nconst CONFIG_FILE_NAME = 'm4trix-eval.config.ts';\n\ntype JitiLoader = {\n (id: string): unknown;\n import?: (id: string) => Promise<unknown> | unknown;\n};\n\nlet cachedLoader: JitiLoader | undefined;\n\nfunction getJitiLoader(): JitiLoader {\n if (cachedLoader) {\n return cachedLoader;\n }\n const createJiti =\n (jitiModule as { createJiti?: unknown; default?: unknown }).createJiti ??\n (jitiModule as { default?: unknown }).default;\n if (typeof createJiti !== 'function') {\n throw new Error('Failed to initialize jiti for m4trix eval config loading.');\n }\n cachedLoader = (createJiti as (id: string, options?: Record<string, unknown>) => JitiLoader)(\n import.meta.url,\n {\n interopDefault: true,\n moduleCache: true,\n },\n );\n return cachedLoader;\n}\n\nfunction resolveConfigModuleExport(loadedModule: unknown): unknown {\n if (loadedModule && typeof loadedModule === 'object' && 'default' in loadedModule) {\n return (loadedModule as { default: unknown }).default;\n }\n return loadedModule;\n}\n\nfunction resolveConfigValue(value: unknown): ConfigType | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n if (typeof value === 'function') {\n return (value as M4trixEvalConfigFactory<ConfigType>)();\n }\n if (typeof value !== 'object') {\n throw new Error(\n 'Invalid m4trix eval config export. Expected an object or defineConfig(() => config).',\n );\n }\n return value as ConfigType;\n}\n\nexport function loadRunnerConfigFile(cwd = process.cwd()): RunnerConfigOverrides | undefined {\n const configPath = resolve(cwd, CONFIG_FILE_NAME);\n if (!existsSync(configPath)) {\n return undefined;\n }\n const loader = getJitiLoader();\n const loaded = loader(configPath);\n const exportedValue = resolveConfigModuleExport(loaded);\n const config = resolveConfigValue(exportedValue);\n return toRunnerConfigOverrides(config);\n}\n","import type { Dirent } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { Dataset } from '../evals/dataset';\nimport type { Evaluator } from '../evals/evaluator';\nimport type { RunConfig } from '../evals/run-config';\nimport type { TestCase } from '../evals/test-case';\nimport type { RunnerDiscoveryConfig } from './config';\nimport type {\n CollectedDataset,\n CollectedEvaluator,\n CollectedRunConfig,\n CollectedTestCase,\n} from './events';\n\ntype JitiModuleLoader = {\n (id: string): unknown;\n import?: (id: string) => Promise<unknown> | unknown;\n};\n\nlet jitiLoader: JitiModuleLoader | undefined;\n\nfunction toId(prefix: string, filePath: string, name?: string): string {\n const stable = name && name.trim().length > 0 ? name : filePath;\n return `${prefix}:${stable}`\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction hasMethod(value: unknown, methodName: string): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n methodName in value &&\n typeof (value as Record<string, unknown>)[methodName] === 'function'\n );\n}\n\nfunction isDatasetLike(value: unknown): value is Dataset {\n return hasMethod(value, 'getName') && hasMethod(value, 'matchesTestCase');\n}\n\nfunction isEvaluatorLike(value: unknown): value is Evaluator<unknown, unknown, unknown, unknown> {\n return (\n hasMethod(value, 'getName') &&\n hasMethod(value, 'resolveContext') &&\n hasMethod(value, 'getEvaluateFn')\n );\n}\n\nfunction isRunConfigLike(value: unknown): value is RunConfig {\n return (\n hasMethod(value, 'getName') &&\n hasMethod(value, 'getRuns') &&\n typeof (value as RunConfig).getRuns === 'function'\n );\n}\n\nfunction isTestCaseLike(value: unknown): value is TestCase<unknown> {\n return hasMethod(value, 'getName') && hasMethod(value, 'getTags') && hasMethod(value, 'getInput');\n}\n\nasync function walkDirectory(\n rootDir: string,\n excludeDirectories: ReadonlyArray<string>,\n): Promise<string[]> {\n const out: string[] = [];\n\n async function walk(currentDir: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n await Promise.all(\n entries.map(async (entry) => {\n const absolute = resolve(currentDir, entry.name);\n if (entry.isDirectory()) {\n if (excludeDirectories.includes(entry.name)) {\n return;\n }\n await walk(absolute);\n return;\n }\n\n if (entry.isFile()) {\n out.push(absolute);\n }\n }),\n );\n }\n\n await walk(rootDir);\n return out;\n}\n\nfunction hasOneSuffix(filePath: string, suffixes: ReadonlyArray<string>): boolean {\n return suffixes.some((suffix) => filePath.endsWith(suffix));\n}\n\nasync function loadModuleExports(filePath: string): Promise<unknown[]> {\n if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {\n if (!jitiLoader) {\n const jitiModule = (await import('jiti')) as unknown as {\n createJiti?: (filename: string, opts?: Record<string, unknown>) => JitiModuleLoader;\n default?: (filename: string, opts?: Record<string, unknown>) => JitiModuleLoader;\n };\n const createJiti = jitiModule.createJiti ?? jitiModule.default;\n if (!createJiti) {\n throw new Error('Failed to initialize jiti TypeScript loader');\n }\n jitiLoader = createJiti(import.meta.url, {\n interopDefault: true,\n moduleCache: true,\n }) as JitiModuleLoader;\n }\n const loaded = jitiLoader.import\n ? await jitiLoader.import(filePath)\n : await Promise.resolve(jitiLoader(filePath));\n return Object.values(loaded as Record<string, unknown>);\n }\n\n const moduleUrl = pathToFileURL(filePath).href;\n const loaded = (await import(moduleUrl)) as Record<string, unknown>;\n return Object.values(loaded);\n}\n\nexport async function collectDatasetsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedDataset>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.datasetSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const datasets = exports.filter(isDatasetLike);\n const relPath = relative(config.rootDir, absolutePath);\n return datasets.map((dataset) => ({\n id: toId('dataset', relPath, dataset.getName()),\n filePath: relPath,\n dataset,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectEvaluatorsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedEvaluator>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.evaluatorSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const evaluators = exports.filter(isEvaluatorLike);\n const relPath = relative(config.rootDir, absolutePath);\n return evaluators.map((evaluator) => ({\n id: toId('evaluator', relPath, evaluator.getName()),\n filePath: relPath,\n evaluator,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectRunConfigsFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedRunConfig>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.runConfigSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const runConfigs = exports.filter(isRunConfigLike);\n const relPath = relative(config.rootDir, absolutePath);\n return runConfigs.map((runConfig) => ({\n id: runConfig.getName(),\n filePath: relPath,\n runConfig,\n }));\n }),\n );\n\n return found.flat();\n}\n\nexport async function collectTestCasesFromFiles(\n config: RunnerDiscoveryConfig,\n): Promise<ReadonlyArray<CollectedTestCase>> {\n const files = await walkDirectory(config.rootDir, config.excludeDirectories);\n const matched = files.filter((filePath) => hasOneSuffix(filePath, config.testCaseSuffixes));\n\n const found = await Promise.all(\n matched.map(async (absolutePath) => {\n const exports = await loadModuleExports(absolutePath);\n const testCases = exports.filter(isTestCaseLike);\n const relPath = relative(config.rootDir, absolutePath);\n return testCases.map((testCase) => ({\n id: toId('test-case', relPath, testCase.getName()),\n filePath: relPath,\n testCase,\n }));\n }),\n );\n\n return found.flat();\n}\n","import { randomUUID } from 'node:crypto';\nimport { join } from 'node:path';\n\nimport { Effect, Queue, Ref } from 'effect';\nimport type { Dataset } from '../evals/dataset';\nimport type { CreateDiffLogEntryOptions, EvaluatorLogEntry } from '../evals/diff';\nimport { createDiffLogEntry, createLogEntry } from '../evals/diff';\nimport type { Evaluator } from '../evals/evaluator';\nimport { getEvaluatorTagList } from '../evals/evaluator';\nimport type { MetricItem } from '../evals/metric';\nimport type { ScoreItem } from '../evals/score';\nimport { getTestCaseDisplayLabel, getTestCaseTagList } from '../evals/test-case';\nimport type { CollectedTestCase, RunnerEvent, RunSnapshot } from './events';\nimport type { PersistenceMessage } from './persistence';\nimport { toNumericScoreFromScores } from './score-utils';\n\nconst evaluatorErrorLogEntryKey = '__m4trixEvaluatorLogEntry';\n\ntype EvaluatorCreatedError = Error & {\n [evaluatorErrorLogEntryKey]?: EvaluatorLogEntry;\n};\n\nfunction computeEvaluatorPassed(\n evaluator: Evaluator<unknown, unknown, unknown, unknown>,\n result: unknown,\n scores: ReadonlyArray<ScoreItem>,\n): boolean {\n const scoresWithPassed = scores.filter((s) => 'passed' in s && s.passed !== undefined);\n if (scoresWithPassed.length > 0) {\n return scoresWithPassed.every((s) => s.passed === true);\n }\n const passCriterion = evaluator.getPassCriterion();\n if (passCriterion) {\n return passCriterion(result);\n }\n const passThreshold = evaluator.getPassThreshold();\n if (passThreshold !== undefined) {\n const numeric = toNumericScoreFromScores(scores);\n return numeric !== undefined && numeric >= passThreshold;\n }\n return true;\n}\n\nfunction normalizeResult(result: unknown): {\n scores: ReadonlyArray<ScoreItem>;\n metrics?: ReadonlyArray<MetricItem>;\n} {\n if (typeof result !== 'object' || result === null) {\n return { scores: [] };\n }\n const obj = result as Record<string, unknown>;\n const scores = Array.isArray(obj.scores) ? (obj.scores as ReadonlyArray<ScoreItem>) : [];\n const metrics = Array.isArray(obj.metrics)\n ? (obj.metrics as ReadonlyArray<MetricItem>)\n : undefined;\n return { scores, metrics };\n}\n\nfunction readOutput(testCase: CollectedTestCase['testCase']): unknown {\n const candidate = testCase as unknown as { getOutput?: () => unknown };\n if (typeof candidate.getOutput !== 'function') {\n return undefined;\n }\n return candidate.getOutput();\n}\n\nexport interface RunTask {\n runId: string;\n triggerId: string;\n /** Same value as `meta.triggerTimestamp` for this run. */\n triggerTimestamp: number;\n datasetId: string;\n dataset: Dataset;\n evaluators: ReadonlyArray<{\n id: string;\n evaluator: Evaluator<unknown, unknown, unknown, unknown>;\n }>;\n testCases: ReadonlyArray<CollectedTestCase>;\n snapshot: RunSnapshot;\n maxConcurrency: number;\n /** When set, limits concurrent evaluation units across all runs sharing this semaphore. */\n globalEvaluationSemaphore?: ReturnType<typeof Effect.unsafeMakeSemaphore>;\n runConfigName: string;\n /** When set, forwarded as `experimentName` on evaluator `meta`. */\n experimentName?: string;\n /** Per job: tags from the run config or programmatic request; forwarded to evaluator callbacks. */\n runConfigTags: string[];\n /** Per scheduled job: how many times each dataset test case is executed. */\n repetitions: number;\n}\n\ninterface EvaluationUnit {\n testCaseItem: CollectedTestCase;\n repetitionId: string;\n repetitionIndex: number;\n repetitionCount: number;\n}\n\nfunction buildEvaluationUnits(\n testCases: ReadonlyArray<CollectedTestCase>,\n repetitionCount: number,\n): EvaluationUnit[] {\n const count = Math.max(1, repetitionCount);\n const units: EvaluationUnit[] = [];\n for (const testCaseItem of testCases) {\n const repetitionId = `rep-${randomUUID()}`;\n for (let r = 0; r < count; r++) {\n units.push({\n testCaseItem,\n repetitionId,\n repetitionIndex: r + 1,\n repetitionCount: count,\n });\n }\n }\n return units;\n}\n\nfunction nowIsoForFile(): string {\n return new Date().toISOString().replace(/[:.]/g, '-');\n}\n\nexport function createArtifactPath(\n artifactDirectory: string,\n datasetId: string,\n runId: string,\n): string {\n return join(artifactDirectory, `${datasetId}_${runId}_${nowIsoForFile()}.jsonl`);\n}\n\nfunction processOneEvaluation(\n task: RunTask,\n unit: EvaluationUnit,\n totalEvaluations: number,\n publishEvent: (event: RunnerEvent) => Effect.Effect<void, never, never>,\n persistenceQueue: Queue.Queue<PersistenceMessage>,\n updateSnapshot: (\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ) => Effect.Effect<void, never, never>,\n startedRef: Ref.Ref<number>,\n completedRef: Ref.Ref<number>,\n passedRef: Ref.Ref<number>,\n failedRef: Ref.Ref<number>,\n testCaseResultsRef: Ref.Ref<Map<string, { completedCount: number; results: boolean[] }>>,\n): Effect.Effect<void, never, never> {\n const { testCaseItem, repetitionId, repetitionIndex, repetitionCount } = unit;\n return Effect.gen(function* () {\n const evaluatorRunId = `run-${randomUUID()}`;\n const started = Date.now();\n const startedEvaluations = yield* Ref.modify(startedRef, (n) => [n + 1, n + 1]);\n yield* publishEvent({\n type: 'TestCaseStarted',\n runId: task.runId,\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n startedTestCases: startedEvaluations,\n totalTestCases: totalEvaluations,\n repetitionId,\n repetitionIndex,\n repetitionCount,\n });\n const evaluatorScores: Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<MetricItem>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n }> = [];\n let testCaseError: string | undefined;\n const output = readOutput(testCaseItem.testCase);\n\n for (const { id: evaluatorId, evaluator } of task.evaluators) {\n const evaluateFn = evaluator.getEvaluateFn();\n if (!evaluateFn) {\n continue;\n }\n\n const logs: EvaluatorLogEntry[] = [];\n const logDiff = (expected: unknown, actual: unknown, options?: CreateDiffLogEntryOptions) => {\n logs.push(createDiffLogEntry(expected, actual, options));\n };\n const log = (message: unknown, options?: { label?: string }) => {\n logs.push(createLogEntry(message, options));\n };\n const createError = (message: unknown, options?: { label?: string }): Error => {\n const entry = createLogEntry(message, options);\n const error = message instanceof Error ? message : new Error(entry.message);\n (error as EvaluatorCreatedError)[evaluatorErrorLogEntryKey] = entry;\n return error;\n };\n\n try {\n const ctx = yield* Effect.promise(() => Promise.resolve(evaluator.resolveContext()));\n const result = yield* Effect.promise(() =>\n Promise.resolve().then(() =>\n evaluateFn({\n input: testCaseItem.testCase.getInput(),\n ctx,\n output,\n meta: {\n triggerId: task.triggerId,\n triggerTimestamp: task.triggerTimestamp,\n triggeredAt: new Date(task.triggerTimestamp).toISOString(),\n runId: evaluatorRunId,\n datasetName: task.dataset.getDisplayLabel(),\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n repetitionId,\n repetitionIndex,\n repetitionCount,\n runConfigName: task.runConfigName,\n ...(task.experimentName !== undefined && task.experimentName !== ''\n ? { experimentName: task.experimentName }\n : {}),\n testCaseTags: getTestCaseTagList(testCaseItem.testCase),\n runConfigTags: task.runConfigTags,\n evaluatorTags: getEvaluatorTagList(evaluator),\n },\n logDiff,\n log,\n createError,\n }),\n ),\n );\n if (result instanceof Error) {\n const evaluatorError = result as EvaluatorCreatedError;\n const taggedEntry = evaluatorError[evaluatorErrorLogEntryKey];\n logs.push(taggedEntry ?? createLogEntry(result));\n testCaseError = result.message;\n evaluatorScores.push({\n evaluatorId,\n scores: [],\n passed: false,\n logs: logs.length > 0 ? logs : undefined,\n });\n continue;\n }\n const { scores, metrics } = normalizeResult(result);\n const passed = computeEvaluatorPassed(evaluator, result, scores);\n evaluatorScores.push({\n evaluatorId,\n scores,\n passed,\n metrics,\n logs: logs.length > 0 ? logs : undefined,\n });\n } catch (error) {\n if (error instanceof Error) {\n const taggedEntry = (error as EvaluatorCreatedError)[evaluatorErrorLogEntryKey];\n logs.push(taggedEntry ?? createLogEntry(error));\n }\n testCaseError = error instanceof Error ? error.message : 'Evaluator execution failed';\n evaluatorScores.push({\n evaluatorId,\n scores: [],\n passed: false,\n logs: logs.length > 0 ? logs : undefined,\n });\n }\n }\n\n const repetitionPassedThis = evaluatorScores.every((s) => s.passed);\n const completedEvaluations = yield* Ref.modify(completedRef, (n) => [n + 1, n + 1]);\n\n const progressEvent: RunnerEvent = {\n type: 'TestCaseProgress',\n runId: task.runId,\n testCaseId: testCaseItem.id,\n testCaseName: getTestCaseDisplayLabel(testCaseItem.testCase),\n completedTestCases: completedEvaluations,\n totalTestCases: totalEvaluations,\n repetitionId,\n repetitionIndex,\n repetitionCount,\n passed: repetitionPassedThis,\n durationMs: Date.now() - started,\n evaluatorScores,\n output,\n errorMessage: testCaseError,\n };\n\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n completedTestCases: completedEvaluations,\n }));\n\n yield* publishEvent(progressEvent);\n yield* Queue.offer(persistenceQueue, {\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n payload: progressEvent,\n });\n\n const testCaseCompleted = yield* Ref.modify(\n testCaseResultsRef,\n (map): [boolean | null, Map<string, { completedCount: number; results: boolean[] }>] => {\n const key = testCaseItem.id;\n const existing = map.get(key) ?? { completedCount: 0, results: [] };\n const newResults = [...existing.results, repetitionPassedThis];\n const newCompletedCount = existing.completedCount + 1;\n const isLast = newCompletedCount === repetitionCount;\n const newMap = new Map(map);\n newMap.set(key, {\n completedCount: newCompletedCount,\n results: newResults,\n });\n const outcome: boolean | null = isLast ? newResults.every(Boolean) : null;\n return [outcome, newMap];\n },\n );\n\n if (testCaseCompleted !== null) {\n if (testCaseCompleted) {\n yield* Ref.update(passedRef, (n) => n + 1);\n } else {\n yield* Ref.update(failedRef, (n) => n + 1);\n }\n const [passed, failed] = yield* Effect.all([Ref.get(passedRef), Ref.get(failedRef)]);\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n passedTestCases: passed,\n failedTestCases: failed,\n }));\n }\n });\n}\n\nexport const executeRunTask = (\n task: RunTask,\n publishEvent: (event: RunnerEvent) => Effect.Effect<void, never, never>,\n persistenceQueue: Queue.Queue<PersistenceMessage>,\n updateSnapshot: (\n runId: string,\n updater: (snapshot: RunSnapshot) => RunSnapshot,\n ) => Effect.Effect<void, never, never>,\n): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const startedAt = Date.now();\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n status: 'running',\n startedAt,\n }));\n yield* publishEvent({\n type: 'RunStarted',\n runId: task.runId,\n startedAt,\n });\n\n const totalEvaluations = task.testCases.length * Math.max(1, task.repetitions);\n const maxConcurrency = Math.max(1, task.maxConcurrency ?? 1);\n\n const completedRef = yield* Ref.make(0);\n const startedRef = yield* Ref.make(0);\n const passedRef = yield* Ref.make(0);\n const failedRef = yield* Ref.make(0);\n const testCaseResultsRef = yield* Ref.make(\n new Map<string, { completedCount: number; results: boolean[] }>(),\n );\n\n const evaluationUnits = buildEvaluationUnits(task.testCases, task.repetitions);\n\n const processEvaluation = (unit: EvaluationUnit) =>\n processOneEvaluation(\n task,\n unit,\n totalEvaluations,\n publishEvent,\n persistenceQueue,\n updateSnapshot,\n startedRef,\n completedRef,\n passedRef,\n failedRef,\n testCaseResultsRef,\n );\n\n const globalSem = task.globalEvaluationSemaphore;\n if (globalSem !== undefined) {\n yield* Effect.forEach(\n evaluationUnits,\n (unit) => globalSem.withPermits(1)(processEvaluation(unit)),\n { concurrency: 'unbounded', discard: true },\n );\n } else {\n yield* Effect.forEach(\n evaluationUnits,\n processEvaluation,\n maxConcurrency > 1 ? { concurrency: maxConcurrency } : undefined,\n );\n }\n\n const [completedEvaluations, passedUniqueTestCases, failedUniqueTestCases] = yield* Effect.all([\n Ref.get(completedRef),\n Ref.get(passedRef),\n Ref.get(failedRef),\n ]);\n\n const finishedAt = Date.now();\n const completedEvent: RunnerEvent = {\n type: 'RunCompleted',\n runId: task.runId,\n finishedAt,\n passedTestCases: passedUniqueTestCases,\n failedTestCases: failedUniqueTestCases,\n totalTestCases: task.testCases.length,\n artifactPath: task.snapshot.artifactPath,\n };\n\n yield* updateSnapshot(task.runId, (snapshot) => ({\n ...snapshot,\n status: 'completed',\n completedTestCases: completedEvaluations,\n passedTestCases: passedUniqueTestCases,\n failedTestCases: failedUniqueTestCases,\n finishedAt,\n }));\n\n yield* publishEvent(completedEvent);\n yield* Queue.offer(persistenceQueue, {\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n payload: completedEvent,\n });\n yield* publishEvent({\n type: 'ArtifactFlushed',\n runId: task.runId,\n artifactPath: task.snapshot.artifactPath,\n });\n });\n","import { diffLines } from 'diff';\nimport stringify from 'fast-json-stable-stringify';\n\n/**\n * Options for customizing JSON diff output. Passed to logDiff, createDiffLogEntry, and printJsonDiff.\n */\nexport interface JsonDiffOptions {\n /** Include equal sections of the document, not just deltas (always true with current implementation) */\n full?: boolean;\n /** Sort primitive values in arrays before comparing */\n sort?: boolean;\n /** Compare only keys, ignore value differences */\n keysOnly?: boolean;\n /** Always output these keys when their parent object has any diff (comma-separated or array) */\n outputKeys?: string | string[];\n /** Output only new/updated values (no - lines) */\n outputNewOnly?: boolean;\n /** Exclude these keys from comparison (comma-separated or array) */\n excludeKeys?: string | string[];\n /** Include unchanged values in output */\n keepUnchangedValues?: boolean;\n /** Round floats to this many decimals before comparing */\n precision?: number;\n /** Max ... elisions in a row before collapsing */\n maxElisions?: number;\n}\n\nfunction preprocessForDiff(value: unknown, options?: JsonDiffOptions): unknown {\n if (options?.sort && Array.isArray(value)) {\n return [...value]\n .sort((a, b) => {\n const aStr = stringify(preprocessForDiff(a, options));\n const bStr = stringify(preprocessForDiff(b, options));\n return aStr.localeCompare(bStr);\n })\n .map((item) => preprocessForDiff(item, options));\n }\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n options?.excludeKeys\n ) {\n const keys = Array.isArray(options.excludeKeys)\n ? options.excludeKeys\n : options.excludeKeys.split(',').map((k) => k.trim());\n const filtered: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n if (!keys.includes(k)) {\n filtered[k] = preprocessForDiff(v, options);\n }\n }\n return filtered;\n }\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = preprocessForDiff(v, options);\n }\n return result;\n }\n if (typeof value === 'number' && options?.precision !== undefined) {\n return Number(value.toFixed(options.precision));\n }\n return value;\n}\n\nfunction toPrettyJson(value: unknown): string {\n const str = stringify(value);\n try {\n const parsed = JSON.parse(str) as unknown;\n return JSON.stringify(parsed, null, 2);\n } catch {\n return str;\n }\n}\n\nfunction formatDiffParts(\n parts: Array<{ added?: boolean; removed?: boolean; value: string }>,\n): string {\n const lines: string[] = [];\n for (const part of parts) {\n const prefix = part.added ? '+ ' : part.removed ? '- ' : '';\n const partLines = part.value.split('\\n');\n for (let i = 0; i < partLines.length; i++) {\n const line = partLines[i]!;\n if (i === partLines.length - 1 && line === '') continue;\n lines.push(prefix + line);\n }\n }\n return lines.join('\\n');\n}\n\nfunction createDiffString(\n expected: unknown,\n actual: unknown,\n diffOptions?: JsonDiffOptions,\n): string {\n const expectedProcessed = preprocessForDiff(expected, diffOptions);\n const actualProcessed = preprocessForDiff(actual, diffOptions);\n\n if (diffOptions?.keysOnly) {\n const expectedKeys = JSON.stringify(extractKeys(expectedProcessed), null, 2);\n const actualKeys = JSON.stringify(extractKeys(actualProcessed), null, 2);\n const parts = diffLines(expectedKeys, actualKeys);\n return formatDiffParts(parts);\n }\n\n const expectedStr = toPrettyJson(expectedProcessed);\n const actualStr = toPrettyJson(actualProcessed);\n\n if (expectedStr === actualStr) {\n return '';\n }\n\n const parts = diffLines(expectedStr, actualStr);\n\n if (diffOptions?.outputNewOnly) {\n const filtered = parts.filter((p: { added?: boolean }) => p.added === true);\n return formatDiffParts(filtered);\n }\n\n return formatDiffParts(parts);\n}\n\nfunction extractKeys(value: unknown): unknown {\n if (value === null || typeof value !== 'object') {\n return '·';\n }\n if (Array.isArray(value)) {\n return value.map(extractKeys);\n }\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = extractKeys(v);\n }\n return result;\n}\n\nexport interface DiffLogEntry {\n type: 'diff';\n label?: string;\n expected: unknown;\n actual: unknown;\n diff: string;\n}\n\nexport interface LogEntry {\n type: 'log';\n label?: string;\n message: string;\n}\n\nexport type EvaluatorLogEntry = DiffLogEntry | LogEntry;\n\nfunction formatLogMessage(msg: unknown): string {\n if (typeof msg === 'string') return msg;\n if (msg instanceof Error) return msg.stack ?? msg.message;\n try {\n if (msg !== null && typeof msg === 'object') {\n return JSON.stringify(msg, null, 2);\n }\n return String(msg);\n } catch {\n return String(msg);\n }\n}\n\n/**\n * Creates a LogEntry for storage in run artifacts. Use for logging objects or text.\n */\nexport function createLogEntry(message: unknown, options?: { label?: string }): LogEntry {\n return {\n type: 'log',\n label: options?.label,\n message: formatLogMessage(message),\n };\n}\n\n/**\n * Returns lines from a log entry for display.\n */\nexport function getLogLines(entry: LogEntry): string[] {\n return entry.message.split('\\n');\n}\n\nexport interface CreateDiffLogEntryOptions extends JsonDiffOptions {\n label?: string;\n}\n\nexport interface PrintJsonDiffOptions extends JsonDiffOptions {\n /** Enable ANSI colors (default: true) */\n color?: boolean;\n}\n\n/**\n * Creates a DiffLogEntry for storage in run artifacts (plain text, no ANSI).\n */\nexport function createDiffLogEntry(\n expected: unknown,\n actual: unknown,\n options?: CreateDiffLogEntryOptions,\n): DiffLogEntry {\n const { label, ...diffOpts } = options ?? {};\n const diff = createDiffString(expected, actual, diffOpts);\n return {\n type: 'diff',\n label,\n expected,\n actual,\n diff: diff || '(no differences)',\n };\n}\n\n/**\n * Returns the plain diff string. Use for storage or when applying colors separately.\n */\nexport function getDiffString(entry: DiffLogEntry): string {\n return entry.diff || '(no differences)';\n}\n\n/**\n * Returns lines from the diff, each with a type for color application.\n */\nexport function getDiffLines(\n entry: DiffLogEntry,\n): Array<{ type: 'add' | 'remove' | 'context'; line: string }> {\n const raw = entry.diff || '(no differences)';\n return raw.split('\\n').map((line) => {\n const trimmed = line.trimStart();\n if (trimmed.startsWith('-') && !trimmed.startsWith('---')) {\n return { type: 'remove' as const, line };\n }\n if (trimmed.startsWith('+') && !trimmed.startsWith('+++')) {\n return { type: 'add' as const, line };\n }\n return { type: 'context' as const, line };\n });\n}\n\n/**\n * Prints a colorized JSON diff between two values to stdout.\n * Useful in evaluators to show expected vs actual output differences.\n * @param expected - The expected/reference value (shown as removed with -)\n * @param actual - The actual value (shown as added with +)\n * @returns The diff string (also printed to console)\n */\nexport function printJsonDiff(\n expected: unknown,\n actual: unknown,\n options: PrintJsonDiffOptions = {},\n): string {\n const { color = true, ...diffOpts } = options;\n const diff = createDiffString(expected, actual, diffOpts);\n if (color) {\n const lines = diff.split('\\n').map((line) => {\n const trimmed = line.trimStart();\n if (trimmed.startsWith('-') && !trimmed.startsWith('---')) {\n return `\\x1b[31m${line}\\x1b[0m`;\n }\n if (trimmed.startsWith('+') && !trimmed.startsWith('+++')) {\n return `\\x1b[32m${line}\\x1b[0m`;\n }\n return line;\n });\n const colored = lines.join('\\n');\n console.log(colored || '(no differences)');\n return colored;\n }\n console.log(diff || '(no differences)');\n return diff;\n}\n","import type { Schema as S } from 'effect';\nimport {\n normalizeOptionalDisplayName,\n type TestCaseName,\n validateTestCaseName,\n} from './entity-name';\n\ntype InputOrBuilder<T> = T | (() => T);\n\ninterface TestCaseConfig<TInput, TOutput> {\n name: TestCaseName;\n displayName?: string;\n tags: string[];\n inputSchema: S.Schema.Any;\n input: InputOrBuilder<TInput>;\n outputSchema?: S.Schema.Any;\n output?: InputOrBuilder<TOutput>;\n}\n\ninterface TestCaseDescribeConfig<\n TI extends S.Schema.Any,\n TO extends S.Schema.Any = S.Schema<unknown>,\n> {\n /**\n * Stable id (letters, digits, `_`, `-`); used in discovery and matching.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI and evaluator args (any characters). */\n displayName?: string;\n /**\n * Declared tags on this test case (not `Dataset` filter options). Use `Dataset` `includedTags` /\n * `excludedTags` to select which cases belong to a dataset; evaluators read the resolved tags as\n * `meta.testCaseTags`.\n */\n tags?: ReadonlyArray<string>;\n inputSchema: TI;\n input: InputOrBuilder<S.Schema.Type<TI>>;\n outputSchema?: TO;\n output?: InputOrBuilder<S.Schema.Type<TO>>;\n}\n\nfunction resolve<T>(value: InputOrBuilder<T>): T {\n return typeof value === 'function' ? (value as () => T)() : value;\n}\n\nexport class TestCase<TInput = unknown, TOutput = unknown> {\n private readonly _config: TestCaseConfig<TInput, TOutput>;\n\n private constructor(config: TestCaseConfig<TInput, TOutput>) {\n this._config = config;\n }\n\n static describe<TI extends S.Schema.Any, TO extends S.Schema.Any = S.Schema<unknown>>(\n config: TestCaseDescribeConfig<TI, TO>,\n ): TestCase<S.Schema.Type<TI>, S.Schema.Type<TO>> {\n const name = validateTestCaseName(config.name, 'TestCase.describe');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n const tags = config.tags !== undefined ? [...config.tags] : [];\n return new TestCase<S.Schema.Type<TI>, S.Schema.Type<TO>>({\n name,\n displayName,\n tags,\n inputSchema: config.inputSchema,\n input: config.input,\n outputSchema: config.outputSchema,\n output: config.output,\n });\n }\n\n getName(): string {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n getDisplayLabel(): string {\n return this._config.displayName ?? this._config.name;\n }\n\n getTags(): string[] {\n return [...this._config.tags];\n }\n\n getInputSchema(): S.Schema.Any {\n return this._config.inputSchema;\n }\n\n getInput(): TInput {\n return resolve(this._config.input);\n }\n\n getOutputSchema(): S.Schema.Any | undefined {\n return this._config.outputSchema;\n }\n\n getOutput(): TOutput | undefined {\n if (this._config.output === undefined) {\n return undefined;\n }\n return resolve(this._config.output);\n }\n}\n\n/** CLI-friendly label: {@link TestCase.getDisplayLabel} when present, else {@link TestCase.getName} (supports plain test-case-shaped objects). */\nexport function getTestCaseDisplayLabel(testCase: {\n getDisplayLabel?: () => string;\n getName?: () => string;\n}): string {\n if (typeof testCase.getDisplayLabel === 'function') {\n return testCase.getDisplayLabel();\n }\n return typeof testCase.getName === 'function' ? testCase.getName() : '';\n}\n\n/** Tags for evaluator `meta.testCaseTags` (supports plain test-case-shaped objects without `getTags`). */\nexport function getTestCaseTagList(testCase: { getTags?: () => ReadonlyArray<string> }): string[] {\n return typeof testCase.getTags === 'function' ? [...testCase.getTags()] : [];\n}\n","import { type DatasetName, normalizeOptionalDisplayName, validateDatasetName } from './entity-name';\nimport type { TestCase } from './test-case';\nimport type { PathMatcher, TagMatcher } from './types';\n\ninterface DatasetConfig {\n name: DatasetName;\n displayName?: string;\n includedTags: ReadonlyArray<TagMatcher>;\n excludedTags: ReadonlyArray<TagMatcher>;\n includedPaths: ReadonlyArray<PathMatcher>;\n excludedPaths: ReadonlyArray<PathMatcher>;\n}\n\nexport interface DatasetDefineConfig {\n /**\n * Stable id (letters, digits, `_`, `-`); used for discovery ids and `resolveDatasetByName`.\n * For an unrestricted UI label, set {@link displayName}.\n */\n name: string;\n /** Optional human-readable label for CLI/TUI (any characters). */\n displayName?: string;\n includedTags?: TagMatcher[];\n excludedTags?: TagMatcher[];\n includedPaths?: PathMatcher[];\n excludedPaths?: PathMatcher[];\n}\n\nfunction matchesAny(value: string, matchers: ReadonlyArray<string | RegExp>): boolean {\n return matchers.some((matcher) =>\n typeof matcher === 'string' ? value === matcher : matcher.test(value),\n );\n}\n\nfunction matchesAnyPath(filePath: string, matchers: ReadonlyArray<string | RegExp>): boolean {\n return matchers.some((matcher) => {\n if (typeof matcher === 'string') {\n return simpleGlobMatch(matcher, filePath);\n }\n return matcher.test(filePath);\n });\n}\n\nfunction simpleGlobMatch(pattern: string, value: string): boolean {\n const escaped = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\?/g, '[^/]')\n .replace(/\\*\\*\\//g, '(?:.*/)?')\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*');\n return new RegExp(`^${escaped}$`).test(value);\n}\n\nexport class Dataset {\n private readonly _config: DatasetConfig;\n\n private constructor(config: DatasetConfig) {\n this._config = config;\n }\n\n static define(config: DatasetDefineConfig): Dataset {\n const name = validateDatasetName(config.name, 'Dataset.define');\n const displayName = normalizeOptionalDisplayName(config.displayName);\n return new Dataset({\n name,\n displayName,\n includedTags: config.includedTags ?? [],\n excludedTags: config.excludedTags ?? [],\n includedPaths: config.includedPaths ?? [],\n excludedPaths: config.excludedPaths ?? [],\n });\n }\n\n /** Canonical dataset id (same rules as `RunConfig` / `TestCase` `name`). */\n getName(): string {\n return this._config.name;\n }\n\n getDisplayName(): string | undefined {\n return this._config.displayName;\n }\n\n /** Label for CLI/TUI and evaluator `meta.datasetName`: {@link getDisplayName} if set, otherwise {@link getName}. */\n getDisplayLabel(): string {\n return this._config.displayName ?? this._config.name;\n }\n\n getIncludedTags(): ReadonlyArray<TagMatcher> {\n return this._config.includedTags;\n }\n\n getExcludedTags(): ReadonlyArray<TagMatcher> {\n return this._config.excludedTags;\n }\n\n getIncludedPaths(): ReadonlyArray<PathMatcher> {\n return this._config.includedPaths;\n }\n\n getExcludedPaths(): ReadonlyArray<PathMatcher> {\n return this._config.excludedPaths;\n }\n\n matchesTestCase(testCase: TestCase<unknown>, filePath: string): boolean {\n const tags = testCase.getTags();\n\n if (this._config.excludedTags.length > 0) {\n if (tags.some((tag) => matchesAny(tag, this._config.excludedTags))) {\n return false;\n }\n }\n\n if (this._config.excludedPaths.length > 0) {\n if (matchesAnyPath(filePath, this._config.excludedPaths)) {\n return false;\n }\n }\n\n const tagMatch =\n this._config.includedTags.length === 0 ||\n tags.some((tag) => matchesAny(tag, this._config.includedTags));\n\n const pathMatch =\n this._config.includedPaths.length === 0 ||\n matchesAnyPath(filePath, this._config.includedPaths);\n\n return tagMatch && pathMatch;\n }\n}\n\n/** CLI / runner: display label for a dataset-shaped object (supports discovery duck-types). */\nexport function getDatasetDisplayLabel(dataset: {\n getDisplayLabel?: () => string;\n getName?: () => string;\n}): string {\n if (typeof dataset.getDisplayLabel === 'function') {\n return dataset.getDisplayLabel();\n }\n return typeof dataset.getName === 'function' ? dataset.getName() : '';\n}\n","const registry = new Map<string, MetricDef<unknown>>();\n\nexport interface MetricItem<TData = unknown> {\n readonly id: string;\n readonly data: TData;\n /** Per-item display name override (wins over def.name in rendering) */\n readonly name?: string;\n}\n\nexport interface FormatMetricOptions {\n isAggregated?: boolean;\n}\n\nexport interface MetricDef<TData = unknown> {\n readonly id: string;\n readonly name?: string;\n readonly aggregate?: (values: ReadonlyArray<TData>) => TData;\n format(data: TData, options?: FormatMetricOptions): string;\n make(data: TData, options?: { name?: string }): MetricItem<TData>;\n}\n\nexport const Metric = {\n of<TData>(config: {\n id: string;\n name?: string;\n format: (data: TData, options?: FormatMetricOptions) => string;\n aggregate?: (values: ReadonlyArray<TData>) => TData;\n }): MetricDef<TData> {\n const def: MetricDef<TData> = {\n id: config.id,\n name: config.name,\n aggregate: config.aggregate,\n format: config.format,\n make: (data: TData, options?: { name?: string }) => ({\n id: config.id,\n data,\n ...(options?.name !== undefined && { name: options.name }),\n }),\n };\n registry.set(config.id, def as MetricDef<unknown>);\n return def;\n },\n};\n\nexport function getMetricById(id: string): MetricDef<unknown> | undefined {\n return registry.get(id);\n}\n","/** Average of numeric `value` fields (e.g. for percentScore) */\nexport function aggregateAverage(values: ReadonlyArray<{ value: number }>): {\n value: number;\n} {\n if (values.length === 0) {\n return { value: 0 };\n }\n const sum = values.reduce((s, v) => s + v.value, 0);\n return { value: sum / values.length };\n}\n\n/** Average with sample std dev (for percentScore when aggregated) */\nexport function aggregateAverageWithVariance(values: ReadonlyArray<{ value: number }>): {\n value: number;\n stdDev?: number;\n count: number;\n} {\n if (values.length === 0) {\n return { value: 0, count: 0 };\n }\n const sum = values.reduce((s, v) => s + v.value, 0);\n const sumSq = values.reduce((s, v) => s + v.value * v.value, 0);\n const mean = sum / values.length;\n let stdDev: number | undefined;\n if (values.length >= 2) {\n const variance = (sumSq - values.length * mean * mean) / (values.length - 1);\n stdDev = variance > 0 ? Math.sqrt(variance) : 0;\n }\n return { value: mean, stdDev, count: values.length };\n}\n\n/** All runs must pass (for binaryScore). Returns passed and count for spread display. */\nexport function aggregateAll(values: ReadonlyArray<{ passed: boolean }>): {\n passed: boolean;\n passedCount?: number;\n totalCount?: number;\n} {\n const total = values.length;\n const passedCount = values.filter((v) => v.passed).length;\n return {\n passed: total > 0 && values.every((v) => v.passed),\n passedCount,\n totalCount: total,\n };\n}\n\ntype TokenCountSum = {\n input: number;\n output: number;\n inputCached: number;\n outputCached: number;\n};\n\n/** Sum token counts across repetitions of the same test case */\nexport function aggregateTokenCountSum(\n values: ReadonlyArray<{\n input?: number;\n output?: number;\n inputCached?: number;\n outputCached?: number;\n }>,\n): TokenCountSum {\n const initial: TokenCountSum = {\n input: 0,\n output: 0,\n inputCached: 0,\n outputCached: 0,\n };\n return values.reduce<TokenCountSum>(\n (acc, v) => ({\n input: acc.input + (v.input ?? 0),\n output: acc.output + (v.output ?? 0),\n inputCached: acc.inputCached + (v.inputCached ?? 0),\n outputCached: acc.outputCached + (v.outputCached ?? 0),\n }),\n initial,\n );\n}\n\n/** Average latency across repetitions of the same test case */\nexport function aggregateLatencyAverage(values: ReadonlyArray<{ ms: number }>): { ms: number } {\n if (values.length === 0) {\n return { ms: 0 };\n }\n const sum = values.reduce((s, v) => s + v.ms, 0);\n return { ms: sum / values.length };\n}\n","import { aggregateLatencyAverage, aggregateTokenCountSum } from '../aggregators';\nimport { Metric } from '../metric';\n\nexport interface TokenCountData {\n input?: number;\n output?: number;\n inputCached?: number;\n outputCached?: number;\n}\n\nexport const tokenCountMetric = Metric.of<TokenCountData>({\n id: 'token-count',\n name: 'Tokens',\n aggregate: aggregateTokenCountSum,\n format: (data, options) => {\n const input = data.input ?? 0;\n const output = data.output ?? 0;\n const inputCached = data.inputCached ?? 0;\n const outputCached = data.outputCached ?? 0;\n const cached = inputCached + outputCached;\n const base = `in:${input} out:${output} cached:${cached}`;\n return options?.isAggregated ? `Total: ${base}` : base;\n },\n});\n\nexport interface LatencyData {\n ms: number;\n}\n\nexport const latencyMetric = Metric.of<LatencyData>({\n id: 'latency',\n name: 'Latency',\n aggregate: aggregateLatencyAverage,\n format: (data, options) => (options?.isAggregated ? `Avg: ${data.ms}ms` : `${data.ms}ms`),\n});\n","const registry = new Map<string, ScoreDef<unknown>>();\n\nexport type ScoreDisplayStrategy = 'bar' | 'number' | 'passFail';\n\nexport interface ScoreItem<TData = unknown> {\n readonly id: string;\n readonly data: TData;\n readonly passed?: boolean;\n /** Per-item display name override (wins over def.name in rendering) */\n readonly name?: string;\n /** Attached def for formatting/aggregation without registry lookup (avoids n/a across module boundaries) */\n readonly def?: ScoreDef<TData>;\n}\n\nexport interface FormatScoreOptions {\n isAggregated?: boolean;\n}\n\nexport interface ScoreDef<TData = unknown> {\n readonly id: string;\n readonly name?: string;\n readonly displayStrategy: ScoreDisplayStrategy;\n readonly formatValue: (data: TData) => string;\n readonly formatAggregate: (data: TData) => string;\n readonly aggregateValues: (values: ReadonlyArray<TData>) => TData;\n make(\n data: TData,\n options?: { definePassed?: (data: TData) => boolean; name?: string },\n ): ScoreItem<TData>;\n}\n\n/** Helper to format using the right method based on isAggregated (for consumers that need a single entry point) */\nexport function formatScoreData<TData>(\n def: ScoreDef<TData>,\n data: TData,\n options?: FormatScoreOptions,\n): string {\n return options?.isAggregated ? def.formatAggregate(data) : def.formatValue(data);\n}\n\n/** Aggregate helpers for common patterns. Use with aggregateValues in Score.of(). */\nexport const ScoreAggregate = {\n /** Average numeric fields. Use for scores like { value, delta }. */\n averageFields<K extends string>(\n fields: readonly K[],\n ): (values: ReadonlyArray<Record<K, number>>) => Record<K, number> {\n return (values) => {\n const count = values.length || 1;\n const result = {} as Record<string, number>;\n for (const field of fields) {\n result[field] =\n values.reduce((s, v) => s + ((v as Record<string, number>)[field] ?? 0), 0) / count;\n }\n return result as unknown as Record<K, number>;\n };\n },\n\n /** Average selected numeric fields, with sample std dev tracked for `value`. */\n averageWithVariance<K extends string>(\n fields: readonly K[],\n ): (\n values: ReadonlyArray<Record<K, number>>,\n ) => Record<K, number> & { stdDev?: number; count: number } {\n return (values) => {\n const count = values.length;\n const result = {} as Record<string, number>;\n\n for (const field of fields) {\n result[field] =\n count === 0\n ? 0\n : values.reduce(\n (sum, item) => sum + ((item as Record<string, number>)[field] ?? 0),\n 0,\n ) / count;\n }\n\n const valueField = 'value' as K;\n const hasValueField = fields.includes(valueField);\n\n if (count === 0) {\n if (hasValueField) {\n result[valueField] = 0;\n }\n return {\n ...(result as Record<K, number>),\n stdDev: undefined,\n count: 0,\n };\n }\n\n let stdDev: number | undefined;\n if (hasValueField && count >= 2) {\n const sum = values.reduce(\n (s, v) => s + ((v as Record<string, number>)[valueField] ?? 0),\n 0,\n );\n const sumSq = values.reduce((s, v) => {\n const value = (v as Record<string, number>)[valueField] ?? 0;\n return s + value * value;\n }, 0);\n const mean = sum / count;\n const variance = (sumSq - count * mean * mean) / (count - 1);\n stdDev = variance > 0 ? Math.sqrt(variance) : 0;\n }\n\n return {\n ...values[0],\n ...(result as Record<K, number>),\n stdDev,\n count,\n };\n };\n },\n\n /** All runs must pass. Use for binary scores. */\n all<T extends { passed: boolean }>(\n values: ReadonlyArray<T>,\n ): T & { passedCount?: number; totalCount?: number } {\n const total = values.length;\n const passedCount = values.filter((v) => v.passed).length;\n return {\n ...values[0],\n passed: total > 0 && values.every((v) => v.passed),\n passedCount,\n totalCount: total,\n } as T & { passedCount?: number; totalCount?: number };\n },\n\n /** Take last value (no aggregation). Use when aggregation is not meaningful. */\n last<T>(values: ReadonlyArray<T>): T {\n return values[values.length - 1] ?? ({} as T);\n },\n};\n\nexport const Score = {\n aggregate: ScoreAggregate,\n\n of<TData>(config: {\n id: string;\n name?: string;\n displayStrategy: ScoreDisplayStrategy;\n formatValue: (data: TData) => string;\n formatAggregate: (data: TData) => string;\n aggregateValues: (values: ReadonlyArray<TData>) => TData;\n }): ScoreDef<TData> {\n const def: ScoreDef<TData> = {\n id: config.id,\n name: config.name,\n displayStrategy: config.displayStrategy,\n formatValue: config.formatValue,\n formatAggregate: config.formatAggregate,\n aggregateValues: config.aggregateValues,\n make: (data: TData, options?: { definePassed?: (data: TData) => boolean; name?: string }) => {\n const passed = options?.definePassed !== undefined ? options.definePassed(data) : undefined;\n return {\n id: config.id,\n data,\n ...(passed !== undefined && { passed }),\n ...(options?.name !== undefined && { name: options.name }),\n def, // Attach def so rendering/aggregation works without registry lookup\n };\n },\n };\n registry.set(config.id, def as ScoreDef<unknown>);\n return def;\n },\n};\n\nexport function getScoreById(id: string): ScoreDef<unknown> | undefined {\n return registry.get(id);\n}\n","import { Score } from '../score';\n\nexport interface PercentScoreData {\n value: number;\n stdDev?: number;\n count?: number;\n}\n\nexport const percentScore = Score.of<PercentScoreData>({\n id: 'percent',\n name: 'Score',\n displayStrategy: 'bar',\n formatValue: (data) => data.value.toFixed(2),\n formatAggregate: (data) =>\n data.stdDev != null\n ? `Avg: ${data.value.toFixed(2)} ± ${data.stdDev.toFixed(2)}`\n : `Avg: ${data.value.toFixed(2)}`,\n aggregateValues: Score.aggregate.averageWithVariance(['value']),\n});\n\nexport interface DeltaScoreData {\n value: number;\n delta: number;\n}\n\nexport const deltaScore = Score.of<DeltaScoreData>({\n id: 'delta',\n name: 'Delta',\n displayStrategy: 'number',\n formatValue: (data) =>\n `${data.value.toFixed(2)} (${data.delta >= 0 ? '+' : ''}${data.delta.toFixed(2)} vs baseline)`,\n formatAggregate: (data) =>\n `Avg: ${data.value.toFixed(2)} (Delta: ${data.delta >= 0 ? '+' : ''}${data.delta.toFixed(2)})`,\n aggregateValues: Score.aggregate.averageFields(['value', 'delta']),\n});\n\nexport interface BinaryScoreData {\n passed: boolean;\n passedCount?: number;\n totalCount?: number;\n}\n\nexport const binaryScore = Score.of<BinaryScoreData>({\n id: 'binary',\n name: 'Result',\n displayStrategy: 'passFail',\n formatValue: (data) => (data.passed ? 'PASSED' : 'NOT PASSED'),\n formatAggregate: (data) => {\n const base = data.passed ? 'All: PASSED' : 'Some: FAILED';\n if (data.passedCount != null && data.totalCount != null && data.totalCount > 1) {\n return `${base} (${data.passedCount}/${data.totalCount})`;\n }\n return base;\n },\n aggregateValues: Score.aggregate.all,\n});\n","import type { MetricItem } from '../evals/metric';\nimport type { ScoreDef, ScoreItem } from '../evals/score';\nimport { getMetricById, getScoreById } from '../evals';\n\nfunction getScoreDef(item: ScoreItem): ScoreDef<unknown> | undefined {\n return item.def ?? getScoreById(item.id);\n}\n\nfunction lastNonEmptyName(items: ReadonlyArray<{ name?: string }>): string | undefined {\n for (let i = items.length - 1; i >= 0; i--) {\n const n = items[i].name;\n if (n != null && n.trim().length > 0) return n;\n }\n return undefined;\n}\n\nexport function aggregateScoreItems(items: ReadonlyArray<ScoreItem>): ScoreItem | undefined {\n if (items.length === 0) return undefined;\n const def = getScoreDef(items[0]);\n if (!def?.aggregateValues) return items[items.length - 1];\n const aggregated = def.aggregateValues(items.map((i) => i.data as never));\n const nameOverride = lastNonEmptyName(items);\n return {\n ...items[0],\n data: aggregated,\n def,\n ...(nameOverride !== undefined && { name: nameOverride }),\n };\n}\n\nexport function aggregateMetricItems(items: ReadonlyArray<MetricItem>): MetricItem | undefined {\n if (items.length === 0) return undefined;\n const def = getMetricById(items[0].id);\n if (!def?.aggregate) return items[items.length - 1];\n const aggregated = def.aggregate(items.map((i) => i.data as never));\n const nameOverride = lastNonEmptyName(items);\n return {\n ...items[0],\n data: aggregated,\n ...(nameOverride !== undefined && { name: nameOverride }),\n };\n}\n\nexport function toNumericScoreFromScores(scores: ReadonlyArray<ScoreItem>): number | undefined {\n for (const item of scores) {\n const def = getScoreDef(item);\n if (\n def &&\n def.displayStrategy === 'bar' &&\n typeof item.data === 'object' &&\n item.data !== null &&\n 'value' in item.data\n ) {\n const value = (item.data as { value: unknown }).value;\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n }\n const numeric = toNumericScore(item.data);\n if (numeric !== undefined) {\n return numeric;\n }\n }\n return undefined;\n}\n\nexport function toNumericScore(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value !== 'object' || value === null) {\n return undefined;\n }\n const obj = value as Record<string, unknown>;\n if ('score' in obj && typeof obj.score === 'number' && Number.isFinite(obj.score)) {\n return obj.score;\n }\n const numberValues = Object.values(value).filter(\n (entry): entry is number => typeof entry === 'number' && Number.isFinite(entry),\n );\n if (numberValues.length === 0) {\n return undefined;\n }\n return numberValues.reduce((sum, entry) => sum + entry, 0) / numberValues.length;\n}\n","export function parseRegexLiteral(pattern: string): { source: string; flags: string } | undefined {\n if (!pattern.startsWith('/')) {\n return undefined;\n }\n const lastSlash = pattern.lastIndexOf('/');\n if (lastSlash <= 0) {\n return undefined;\n }\n return {\n source: pattern.slice(1, lastSlash),\n flags: pattern.slice(lastSlash + 1),\n };\n}\n\n/** Same matching rules as `RunnerApi.resolveEvaluatorsByNamePattern` (RunConfig `evaluatorPattern`, etc.). */\nexport function createNameMatcher(pattern: string): (value: string) => boolean {\n const normalizedPattern = pattern.trim();\n const regexLiteral = parseRegexLiteral(normalizedPattern);\n if (regexLiteral) {\n const regex = new RegExp(regexLiteral.source, regexLiteral.flags);\n return (value: string) => regex.test(value);\n }\n\n if (normalizedPattern.includes('*')) {\n const escaped = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n const regex = new RegExp(`^${escaped}$`, 'i');\n return (value: string) => regex.test(value);\n }\n\n return (value: string) => value.toLowerCase() === normalizedPattern.toLowerCase();\n}\n","import { appendFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport { Effect, Queue } from 'effect';\n\nexport interface PersistenceMessage {\n runId: string;\n artifactPath: string;\n payload: unknown;\n}\n\nasync function appendJsonLine(artifactPath: string, payload: unknown): Promise<void> {\n await mkdir(dirname(artifactPath), { recursive: true });\n await appendFile(artifactPath, `${JSON.stringify(payload)}\\n`, 'utf8');\n}\n\nexport const createPersistenceWorker = (\n queue: Queue.Queue<PersistenceMessage>,\n): Effect.Effect<never, never, never> =>\n Effect.forever(\n Effect.gen(function* () {\n const message = yield* Queue.take(queue);\n yield* Effect.promise(() =>\n appendJsonLine(message.artifactPath, {\n runId: message.runId,\n ts: Date.now(),\n ...(typeof message.payload === 'object' &&\n message.payload !== null &&\n !Array.isArray(message.payload)\n ? message.payload\n : {}),\n }),\n );\n }),\n );\n","import type { CollectedTestCase, SearchTestCasesQuery } from './events';\n\nfunction matchesAny(value: string, matchers: ReadonlyArray<string | RegExp> | undefined): boolean {\n if (!matchers || matchers.length === 0) {\n return true;\n }\n return matchers.some((matcher) =>\n typeof matcher === 'string' ? matcher === value : matcher.test(value),\n );\n}\n\nfunction matchesPath(value: string, matchers: ReadonlyArray<string | RegExp> | undefined): boolean {\n if (!matchers || matchers.length === 0) {\n return true;\n }\n return matchers.some((matcher) => {\n if (typeof matcher === 'string') {\n return value.includes(matcher);\n }\n return matcher.test(value);\n });\n}\n\nexport function searchCollectedTestCases(\n all: ReadonlyArray<CollectedTestCase>,\n query?: SearchTestCasesQuery,\n): ReadonlyArray<CollectedTestCase> {\n if (!query) {\n return all;\n }\n\n return all.filter((item) => {\n const tags = item.testCase.getTags();\n\n if (query.excludedTags && tags.some((tag) => matchesAny(tag, query.excludedTags))) {\n return false;\n }\n if (query.excludedPaths && matchesPath(item.filePath, query.excludedPaths)) {\n return false;\n }\n\n const includedTagsMatch =\n !query.includedTags ||\n query.includedTags.length === 0 ||\n tags.some((tag) => matchesAny(tag, query.includedTags));\n\n const includedPathsMatch =\n !query.includedPaths ||\n query.includedPaths.length === 0 ||\n matchesPath(item.filePath, query.includedPaths);\n\n return includedTagsMatch && includedPathsMatch;\n });\n}\n","export type SimpleCliCommand = 'run' | 'generate';\n\nexport interface SimpleCliArgs {\n command?: SimpleCliCommand;\n /** For `generate` only. */\n datasetName?: string;\n /** Repeatable: each `--run-config` adds a RunConfig to execute (expanded jobs run with shared concurrency). */\n runConfigNames: string[];\n /** Max concurrent evaluations. Default: 4. Use 1 for sequential. */\n concurrency?: number;\n /** Optional label passed to evaluator `meta.experimentName` for this CLI run. */\n experimentName?: string;\n /**\n * When set (typically for `run`), exit with code 1 if any test case fails.\n * Ignored for `generate`.\n */\n ci: boolean;\n help: boolean;\n unknownArgs: string[];\n}\n\n/** Default concurrency for I/O-bound evals (e.g. LLM API calls). Node is single-threaded, so CPU count is not meaningful. */\nexport function getDefaultConcurrency(): number {\n return 4;\n}\n\nexport function parseSimpleCliArgs(argv: string[]): SimpleCliArgs {\n const args: SimpleCliArgs = {\n help: false,\n ci: false,\n runConfigNames: [],\n unknownArgs: [],\n };\n let index = 0;\n if (argv[0] === 'run' || argv[0] === 'generate') {\n args.command = argv[0];\n index = 1;\n }\n\n for (; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === '--help' || token === '-h') {\n args.help = true;\n continue;\n }\n if (token === '--ci') {\n args.ci = true;\n continue;\n }\n if ((token === '--dataset' || token === '--datasetName') && argv[index + 1]) {\n args.datasetName = argv[index + 1];\n index += 1;\n continue;\n }\n if ((token === '--run-config' || token === '--runConfig') && argv[index + 1]) {\n const next = argv[index + 1];\n if (typeof next === 'string') {\n args.runConfigNames.push(next);\n }\n index += 1;\n continue;\n }\n if ((token === '--concurrency' || token === '-c') && argv[index + 1]) {\n const nextConc = argv[index + 1];\n const n = typeof nextConc === 'string' ? parseInt(nextConc, 10) : Number.NaN;\n if (!Number.isNaN(n) && n >= 1) {\n args.concurrency = n;\n }\n index += 1;\n continue;\n }\n if (token === '--experiment' && argv[index + 1]) {\n const raw = argv[index + 1];\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n if (trimmed.length > 0) {\n args.experimentName = trimmed;\n }\n }\n index += 1;\n continue;\n }\n args.unknownArgs.push(token);\n }\n\n return args;\n}\n\nexport function getSimpleCliUsage(): string {\n return [\n 'Usage:',\n ' eval-agents-simple run --run-config <name> [--run-config <name> ...] [--concurrency N] [--experiment <name>] [--ci]',\n ' eval-agents-simple generate --dataset <datasetId>',\n '',\n 'Options:',\n ' --ci With run: exit with code 1 if any test case fails.',\n ' --concurrency, -c N Max concurrent evaluations (default: 4). Use 1 for sequential.',\n ' --experiment <name> With run: set evaluator meta.experimentName for this invocation.',\n ].join('\\n');\n}\n","const ansi = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n cyan: '\\x1b[36m',\n} as const;\n\nexport function printBanner(): void {\n const c = (s: string) => `${ansi.cyan}${s}${ansi.reset}`;\n const d = (s: string) => `${ansi.dim}${s}${ansi.reset}`;\n\n const lines = [\n '',\n ` ${c('╭─────────────────────────────────────────────╮')}`,\n ` ${c('│')} ${d('@m4trix/evals')} ${c('·')} ${d('eval-agents-simple')} ${c('│')}`,\n ` ${c('╰─────────────────────────────────────────────╯')}`,\n '',\n ];\n\n console.log(lines.join('\\n'));\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport { writeFile } from 'node:fs/promises';\nimport { join, parse, resolve } from 'node:path';\n\nimport { getDatasetDisplayLabel } from '../evals/dataset';\nimport { getTestCaseDisplayLabel } from '../evals/test-case';\nimport type { RunnerApi } from '../runner';\nimport { GenerateView } from './views/GenerateView';\n\ninterface GeneratedDatasetCase {\n name: string;\n input: unknown;\n output?: unknown;\n}\n\nfunction readOutput(testCase: { getOutput?: () => unknown }): unknown {\n if (typeof testCase.getOutput !== 'function') {\n return undefined;\n }\n return testCase.getOutput();\n}\n\nfunction createOutputPath(datasetFilePath: string): string {\n const parsed = parse(datasetFilePath);\n return join(parsed.dir, `${parsed.name}.cases.json`);\n}\n\nexport async function generateDatasetJsonCommandPlain(\n runner: RunnerApi,\n datasetName: string,\n): Promise<void> {\n const dataset = await runner.resolveDatasetByName(datasetName);\n if (!dataset) {\n throw new Error(`Dataset \"${datasetName}\" not found.`);\n }\n\n const testCases = await runner.collectDatasetTestCases(dataset.id);\n const payload: GeneratedDatasetCase[] = testCases.map((item) => ({\n name: getTestCaseDisplayLabel(item.testCase),\n input: item.testCase.getInput(),\n output: readOutput(item.testCase),\n }));\n\n const absoluteDatasetPath = resolve(process.cwd(), dataset.filePath);\n const outputPath = createOutputPath(absoluteDatasetPath);\n\n await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n\n console.log(`Generated ${payload.length} test cases for dataset \"${getDatasetDisplayLabel(dataset.dataset)}\".`);\n console.log(`Wrote ${outputPath}`);\n}\n\nexport async function generateDatasetJsonCommandInk(\n runner: RunnerApi,\n datasetName: string,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const app = render(\n React.createElement(GenerateView, {\n runner,\n datasetName,\n onComplete: (err) => {\n app.unmount();\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n },\n }),\n );\n });\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\n\nimport { getDatasetDisplayLabel } from '../../evals/dataset';\nimport { getTestCaseDisplayLabel } from '../../evals/test-case';\nimport type { RunnerApi } from '../../runner';\nimport { Banner } from './Banner';\n\ninterface GenerateViewProps {\n runner: RunnerApi;\n datasetName: string;\n onComplete: (error?: Error) => void;\n}\n\nexport function GenerateView({\n runner,\n datasetName,\n onComplete,\n}: GenerateViewProps): React.ReactNode {\n const [result, setResult] = useState<{\n count: number;\n datasetName: string;\n outputPath: string;\n } | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n async function run() {\n const dataset = await runner.resolveDatasetByName(datasetName);\n if (!dataset) {\n setError(new Error(`Dataset \"${datasetName}\" not found.`));\n onComplete(new Error(`Dataset \"${datasetName}\" not found.`));\n return;\n }\n\n const { writeFile } = await import('node:fs/promises');\n const { join, parse, resolve } = await import('node:path');\n\n const testCases = await runner.collectDatasetTestCases(dataset.id);\n const payload = testCases.map((item) => {\n const tc = item.testCase as { getOutput?: () => unknown };\n return {\n name: getTestCaseDisplayLabel(item.testCase),\n input: item.testCase.getInput(),\n output: typeof tc.getOutput === 'function' ? tc.getOutput() : undefined,\n };\n });\n\n const absoluteDatasetPath = resolve(process.cwd(), dataset.filePath);\n const parsed = parse(absoluteDatasetPath);\n const outputPath = join(parsed.dir, `${parsed.name}.cases.json`);\n\n await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n\n if (!cancelled) {\n setResult({\n count: payload.length,\n datasetName: getDatasetDisplayLabel(dataset.dataset),\n outputPath,\n });\n setTimeout(() => onComplete(), 200);\n }\n }\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [runner, datasetName, onComplete]);\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Banner />\n <Text color=\"red\">{error.message}</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Banner />\n </Box>\n {result && (\n <Box flexDirection=\"column\">\n <Text color=\"green\">\n Generated {result.count} test cases for dataset \"{result.datasetName}\".\n </Text>\n <Text color=\"gray\">Wrote {result.outputPath}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { Box, Text } from 'ink';\n\nexport function Banner(): React.ReactNode {\n return (\n <Box borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} paddingY={0}>\n <Text color=\"gray\">@m4trix/evals</Text>\n <Text color=\"cyan\"> · </Text>\n <Text color=\"gray\">eval-agents-simple</Text>\n </Box>\n );\n}\n","import { render } from 'ink';\nimport * as React from 'react';\nimport {\n type EvaluatorLogEntry,\n formatScoreData,\n getDiffLines,\n getEvaluatorDisplayLabel,\n getLogLines,\n getMetricById,\n getScoreById,\n type LogEntry,\n} from '../evals';\nimport type { ScoreItem } from '../evals/score';\nimport type { RunnerApi, RunnerEvent } from '../runner';\nimport {\n aggregateMetricItems,\n aggregateScoreItems,\n toNumericScore,\n toNumericScoreFromScores,\n} from '../runner/score-utils';\nimport { RunView } from './views/RunView';\n\ninterface EvaluatorAggregate {\n total: number;\n sumSq: number;\n count: number;\n passed: number;\n failed: number;\n}\n\nfunction sampleStdDev(sum: number, sumSq: number, n: number): number | undefined {\n if (n < 2) return undefined;\n const mean = sum / n;\n const variance = (sumSq - n * mean * mean) / (n - 1);\n return variance > 0 ? Math.sqrt(variance) : 0;\n}\n\ninterface TestCaseScoreSummary {\n name: string;\n averageScore?: number;\n stdDev?: number;\n aggregatedScoreItem?: ScoreItem;\n isAggregated: boolean;\n durationMs: number;\n passed: boolean;\n}\n\ninterface TestCaseEventAcc {\n name: string;\n events: Array<{\n averageScore?: number;\n passed: boolean;\n durationMs: number;\n evaluatorScores: ReadonlyArray<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n }>;\n }>;\n}\n\nfunction buildTestCaseSummaries(byId: Map<string, TestCaseEventAcc>): TestCaseScoreSummary[] {\n const summaries: TestCaseScoreSummary[] = [];\n for (const { name, events } of byId.values()) {\n const passed = events.every((e) => e.passed);\n const durationMs = events.reduce((sum, e) => sum + e.durationMs, 0);\n const isAggregated = events.length > 1;\n const allScores = events.flatMap((ev) =>\n ev.evaluatorScores\n .map((es) => toNumericScoreFromScores(es.scores))\n .filter((n): n is number => n !== undefined),\n );\n const averageScore =\n allScores.length > 0 ? allScores.reduce((a, b) => a + b, 0) / allScores.length : undefined;\n const sumSq = allScores.length > 0 ? allScores.reduce((s, v) => s + v * v, 0) : 0;\n const total = allScores.reduce((a, b) => a + b, 0);\n const stdDev = sampleStdDev(total, sumSq, allScores.length);\n let firstAggregatedScore: ScoreItem | undefined;\n for (const evaluatorScores of events[0]?.evaluatorScores ?? []) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorScores.evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n }\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg && firstAggregatedScore === undefined) {\n firstAggregatedScore = agg;\n break;\n }\n }\n if (firstAggregatedScore !== undefined) break;\n }\n summaries.push({\n name,\n averageScore,\n stdDev: stdDev ?? undefined,\n aggregatedScoreItem: firstAggregatedScore,\n isAggregated,\n durationMs,\n passed,\n });\n }\n return summaries;\n}\n\nconst ansi = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n cyan: '\\x1b[36m',\n magenta: '\\x1b[35m',\n} as const;\n\nfunction colorize(text: string, color: string): string {\n return `${color}${text}${ansi.reset}`;\n}\n\nfunction scoreToColor(score: number): string {\n if (score >= 80) {\n return ansi.green;\n }\n if (score >= 50) {\n return ansi.yellow;\n }\n return ansi.red;\n}\n\nfunction getEvaluatorSummaryLines(\n evaluatorId: string,\n evaluatorName: string,\n aggregate: EvaluatorAggregate | undefined,\n scoreItemsByKey: Map<string, ScoreItem[]>,\n): string[] {\n const lines: string[] = [];\n const scoreKeys = [...scoreItemsByKey.keys()].filter((k) => k.startsWith(`${evaluatorId}:`));\n if (scoreKeys.length === 0) {\n lines.push(`- ${evaluatorName.padEnd(28)} no scores`);\n return lines;\n }\n const passedFailed =\n aggregate != null ? ` passed=${aggregate.passed} failed=${aggregate.failed}` : '';\n const scoreLines: string[] = [];\n for (const key of scoreKeys) {\n const items = scoreItemsByKey.get(key) ?? [];\n const agg = aggregateScoreItems(items);\n if (!agg) continue;\n const def = agg.def ?? getScoreById(agg.id);\n const label = agg.name ?? def?.name ?? def?.id ?? agg.id;\n const formatted = def ? def.formatAggregate(agg.data) : 'n/a';\n const numeric = toNumericScore(agg.data);\n const colored = numeric !== undefined ? colorize(formatted, scoreToColor(numeric)) : formatted;\n scoreLines.push(` ${label}: ${colored}`);\n }\n if (scoreLines.length > 0) {\n lines.push(`- ${evaluatorName.padEnd(28)}${passedFailed}`);\n lines.push(...scoreLines);\n } else {\n lines.push(`- ${evaluatorName.padEnd(28)} no numeric scores${passedFailed}`);\n }\n return lines;\n}\n\nfunction createBar(value: number, max = 100, width = 20): string {\n const safe = Math.max(0, Math.min(max, value));\n const filled = Math.round((safe / max) * width);\n return `${'█'.repeat(filled)}${'░'.repeat(width - filled)}`;\n}\n\nfunction aggregateEvaluatorScoresFromEvents(\n events: TestCaseEventAcc['events'],\n _evaluatorNameById: Map<string, string>,\n): Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n}> {\n if (events.length === 0) return [];\n const evaluatorIds = new Set(events.flatMap((e) => e.evaluatorScores.map((x) => x.evaluatorId)));\n const result: Array<{\n evaluatorId: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown }>;\n }> = [];\n for (const evaluatorId of evaluatorIds) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n const metricIdToItems = new Map<string, Array<{ id: string; data: unknown }>>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n for (const m of es?.metrics ?? []) {\n const list = metricIdToItems.get(m.id) ?? [];\n list.push(m);\n metricIdToItems.set(m.id, list);\n }\n }\n const aggregatedScores: ScoreItem[] = [];\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg) aggregatedScores.push(agg);\n }\n const aggregatedMetrics = Array.from(metricIdToItems.entries())\n .map(([, items]) => aggregateMetricItems(items as never))\n .filter((m): m is { id: string; data: unknown } => m !== undefined);\n const passed = events.every((ev) => {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n return es?.passed ?? false;\n });\n result.push({\n evaluatorId,\n scores: aggregatedScores,\n passed,\n metrics: aggregatedMetrics.length > 0 ? aggregatedMetrics : undefined,\n });\n }\n return result;\n}\n\nfunction formatEvaluatorScoreLine(\n name: string,\n scores: ReadonlyArray<ScoreItem>,\n passed: boolean,\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>,\n options?: { isAggregated?: boolean },\n): string[] {\n const passLabel = passed\n ? colorize('PASS', `${ansi.bold}${ansi.green}`)\n : colorize('FAIL', `${ansi.bold}${ansi.red}`);\n const metricParts: string[] = [];\n if (metrics && metrics.length > 0) {\n for (const m of metrics) {\n const def = getMetricById(m.id);\n if (def) {\n const formatted = def.format(m.data, options);\n const label = m.name ?? def.name;\n metricParts.push(label ? `[${label}: ${formatted}]` : `[${formatted}]`);\n }\n }\n }\n const scoreLines: string[] = [];\n for (const item of scores) {\n const def = item.def ?? getScoreById(item.id);\n const scoreLabel = item.name ?? def?.name ?? def?.id ?? item.id;\n let formatted: string;\n if (!def) {\n const numeric = toNumericScore(item.data);\n formatted =\n numeric !== undefined ? colorize(numeric.toFixed(2), scoreToColor(numeric)) : 'n/a';\n } else {\n const raw = formatScoreData(def, item.data, options);\n switch (def.displayStrategy) {\n case 'bar': {\n const numeric =\n typeof item.data === 'object' && item.data !== null && 'value' in item.data\n ? (item.data as { value: unknown }).value\n : toNumericScore(item.data);\n if (typeof numeric === 'number' && Number.isFinite(numeric)) {\n formatted = `${colorize(raw, scoreToColor(numeric))} ${colorize(createBar(numeric), ansi.dim)}`;\n } else {\n formatted = raw;\n }\n break;\n }\n case 'number':\n formatted = raw;\n break;\n case 'passFail':\n formatted = colorize(\n raw,\n item.passed === true\n ? `${ansi.bold}${ansi.green}`\n : item.passed === false\n ? `${ansi.bold}${ansi.red}`\n : ansi.dim,\n );\n break;\n }\n }\n scoreLines.push(` ${scoreLabel}: ${formatted}`);\n }\n const lines: string[] = [];\n const metricStr = metricParts.length > 0 ? ` ${metricParts.join(' ')}` : '';\n lines.push(` ${name}: ${passLabel}${metricStr}`);\n if (scoreLines.length > 0) {\n lines.push(...scoreLines);\n } else {\n lines.push(` n/a`);\n }\n return lines;\n}\n\n/** @returns `0` if every completed run had zero failed test cases; `1` otherwise. */\nexport async function runSimpleEvalRunConfigsPlain(\n runner: RunnerApi,\n runConfigNames: ReadonlyArray<string>,\n concurrency: number,\n experimentName?: string,\n triggerTimestamp?: number,\n): Promise<0 | 1> {\n const jobs = await runner.expandRunConfigNamesToJobs(runConfigNames);\n if (jobs.length === 0) {\n throw new Error('No jobs expanded from RunConfigs.');\n }\n\n const evaluators = await runner.collectEvaluators();\n const evaluatorNameById = new Map(\n evaluators.map((item) => [item.id, getEvaluatorDisplayLabel(item.evaluator) ?? item.id]),\n );\n\n const aggregates = new Map<string, EvaluatorAggregate>();\n const scoreItemsByEvaluatorScore = new Map<string, ScoreItem[]>();\n const testCaseByTestId = new Map<string, TestCaseEventAcc>();\n let overallScoreTotal = 0;\n let overallScoreSumSq = 0;\n let overallScoreCount = 0;\n let globalStartedUnits = 0;\n let globalCompletedUnits = 0;\n let totalCount = 0;\n let runFinished = false;\n const inFlightRepetitions = new Set<string>();\n const spinnerFrames = ['⠋', '⠙', '⠸', '⠴', '⠦', '⠇'];\n let spinnerIndex = 0;\n\n function clearLine(): void {\n if (!process.stdout.isTTY) {\n return;\n }\n process.stdout.write('\\r\\x1b[2K');\n }\n\n function cursorUp(n: number): void {\n if (!process.stdout.isTTY || n <= 0) return;\n process.stdout.write(`\\x1b[${n}A`);\n }\n\n function drawSpinner(): void {\n if (!process.stdout.isTTY || runFinished) {\n return;\n }\n const frame = spinnerFrames[spinnerIndex % spinnerFrames.length];\n spinnerIndex += 1;\n process.stdout.write(\n `\\r${colorize(frame, ansi.cyan)} Running evaluations ${colorize(\n `${globalCompletedUnits}/${totalCount}`,\n ansi.bold,\n )} completed ${colorize(`${globalStartedUnits}/${totalCount}`, ansi.bold)} started ${colorize(`(${inFlightRepetitions.size} running)`, ansi.dim)}`,\n );\n }\n\n let lastPrintedTestCaseId: string | null = null;\n let lastPrintedLineCount = 0;\n\n let spinnerTimer: NodeJS.Timeout | undefined;\n\n const batchPendingRunIds = new Set<string>();\n const runIdToLabel = new Map<string, string>();\n let batchReady = false;\n\n const completedRuns = new Map<string, Extract<RunnerEvent, { type: 'RunCompleted' }>>();\n\n const done = new Promise<void>((resolve, reject) => {\n const unsubscribe = runner.subscribeRunEvents((event) => {\n if (\n batchReady &&\n 'runId' in event &&\n typeof event.runId === 'string' &&\n !batchPendingRunIds.has(event.runId)\n ) {\n return;\n }\n\n const rowPrefix = typeof event.runId === 'string' ? runIdToLabel.get(event.runId) : undefined;\n const pfx = rowPrefix !== undefined ? `${colorize(`[${rowPrefix}]`, ansi.dim)} ` : '';\n\n if (event.type === 'TestCaseStarted') {\n globalStartedUnits += 1;\n inFlightRepetitions.add(\n `${event.runId}:${event.testCaseId}:${event.repetitionId}:${event.repetitionIndex}`,\n );\n clearLine();\n process.stdout.write(\n `${pfx}${colorize(`[started ${event.startedTestCases}/${event.totalTestCases}]`, ansi.cyan)} ${event.testCaseName} ${colorize(`(${event.repetitionIndex}/${event.repetitionCount})`, ansi.cyan)} ${colorize('(running)', ansi.dim)}\\n`,\n );\n drawSpinner();\n }\n if (event.type === 'TestCaseProgress') {\n globalCompletedUnits += 1;\n inFlightRepetitions.delete(\n `${event.runId}:${event.testCaseId}:${event.repetitionId}:${event.repetitionIndex}`,\n );\n const numericScores = event.evaluatorScores\n .map((item) => toNumericScoreFromScores(item.scores))\n .filter((item): item is number => item !== undefined);\n const averageScore =\n numericScores.length > 0\n ? numericScores.reduce((sum, value) => sum + value, 0) / numericScores.length\n : undefined;\n\n const compositeId = `${event.runId}:${event.testCaseId}`;\n const existing = testCaseByTestId.get(compositeId) ?? {\n name: event.testCaseName,\n events: [],\n };\n existing.events.push({\n averageScore,\n passed: event.passed,\n durationMs: event.durationMs,\n evaluatorScores: event.evaluatorScores,\n });\n testCaseByTestId.set(compositeId, existing);\n\n for (const item of event.evaluatorScores) {\n const numeric = toNumericScoreFromScores(item.scores);\n if (numeric !== undefined) {\n const current = aggregates.get(item.evaluatorId) ?? {\n total: 0,\n sumSq: 0,\n count: 0,\n passed: 0,\n failed: 0,\n };\n aggregates.set(item.evaluatorId, {\n total: current.total + numeric,\n sumSq: current.sumSq + numeric * numeric,\n count: current.count + 1,\n passed: current.passed + (item.passed ? 1 : 0),\n failed: current.failed + (item.passed ? 0 : 1),\n });\n overallScoreTotal += numeric;\n overallScoreSumSq += numeric * numeric;\n overallScoreCount += 1;\n }\n for (const s of item.scores) {\n const key = `${item.evaluatorId}:${s.id}`;\n const list = scoreItemsByEvaluatorScore.get(key) ?? [];\n list.push(s);\n scoreItemsByEvaluatorScore.set(key, list);\n }\n }\n\n const isSameTestCase = lastPrintedTestCaseId === compositeId;\n const isLastRepetition = event.repetitionIndex >= event.repetitionCount;\n const isNonTty = !process.stdout.isTTY;\n const skipPrintNonTty = isNonTty && event.repetitionCount > 1 && !isLastRepetition;\n\n if (isSameTestCase && lastPrintedLineCount > 0 && !skipPrintNonTty) {\n cursorUp(lastPrintedLineCount);\n }\n\n const aggregatedScores = aggregateEvaluatorScoresFromEvents(\n existing.events,\n evaluatorNameById,\n );\n const isAggregated = existing.events.length > 1;\n const durationMs = existing.events.reduce((s, e) => s + e.durationMs, 0);\n\n const lines: string[] = [];\n const statusSuffix = event.errorMessage\n ? ` ${colorize('ERROR', `${ansi.bold}${ansi.red}`)}`\n : '';\n lines.push(\n `${pfx}${colorize(`[${event.completedTestCases}/${event.totalTestCases}]`, ansi.cyan)} ${event.testCaseName} ${colorize(`(${event.repetitionIndex}/${event.repetitionCount})`, ansi.cyan)} ${colorize(`(${durationMs}ms)`, ansi.dim)}${statusSuffix}`,\n );\n if (event.errorMessage) {\n lines.push(colorize(event.errorMessage, ansi.red));\n }\n for (const item of aggregatedScores) {\n const name = evaluatorNameById.get(item.evaluatorId) ?? item.evaluatorId;\n lines.push(\n ...formatEvaluatorScoreLine(name, item.scores, item.passed, item.metrics, {\n isAggregated,\n }),\n );\n const lastEvent = existing.events[existing.events.length - 1];\n const lastEs = lastEvent?.evaluatorScores.find((x) => x.evaluatorId === item.evaluatorId);\n if (!item.passed && lastEs?.logs && lastEs.logs.length > 0) {\n for (const log of lastEs.logs) {\n if (log.type === 'diff') {\n const useColor = process.stdout.isTTY;\n for (const { type, line } of getDiffLines(log)) {\n const colored =\n useColor && type === 'remove'\n ? colorize(` ${line}`, ansi.red)\n : useColor && type === 'add'\n ? colorize(` ${line}`, ansi.green)\n : ` ${line}`;\n lines.push(colored);\n }\n } else if (log.type === 'log') {\n for (const line of getLogLines(log as LogEntry)) {\n lines.push(` ${line}`);\n }\n }\n }\n }\n }\n\n if (!skipPrintNonTty) {\n for (let i = 0; i < lines.length; i += 1) {\n process.stdout.write(`\\r\\x1b[2K${lines[i]}\\n`);\n }\n lastPrintedTestCaseId = compositeId;\n lastPrintedLineCount = lines.length;\n }\n\n drawSpinner();\n }\n if (event.type === 'RunFailed') {\n if (batchReady && !batchPendingRunIds.has(event.runId)) {\n return;\n }\n runFinished = true;\n clearLine();\n unsubscribe();\n reject(new Error(`Run failed: ${event.errorMessage}`));\n return;\n }\n if (event.type === 'RunCompleted') {\n if (!batchPendingRunIds.has(event.runId)) {\n return;\n }\n completedRuns.set(event.runId, event);\n batchPendingRunIds.delete(event.runId);\n if (batchPendingRunIds.size === 0) {\n runFinished = true;\n clearLine();\n unsubscribe();\n resolve();\n }\n }\n });\n });\n\n console.log(colorize('=== Eval Run Started (RunConfigs) ===', `${ansi.bold}${ansi.cyan}`));\n for (const name of runConfigNames) {\n const collected = await runner.resolveRunConfigByName(name);\n const label = collected?.runConfig.getDisplayLabel() ?? name;\n console.log(`RunConfig: ${colorize(label, ansi.bold)}`);\n }\n console.log(`Jobs: ${colorize(String(jobs.length), ansi.bold)}`);\n console.log(`Shared concurrency: ${colorize(String(concurrency), ansi.bold)}`);\n console.log('');\n\n const snapshots = await runner.runDatasetJobsWithSharedConcurrency({\n jobs,\n globalConcurrency: concurrency,\n experimentName,\n triggerTimestamp,\n });\n for (let i = 0; i < snapshots.length; i += 1) {\n const snap = snapshots[i];\n const job = jobs[i];\n if (snap && job) {\n runIdToLabel.set(\n snap.runId,\n `${job.runConfigDisplayLabel ?? job.runConfigName} · ${snap.datasetName}`,\n );\n batchPendingRunIds.add(snap.runId);\n }\n }\n totalCount = snapshots.reduce((sum, s) => sum + s.totalTestCases, 0);\n console.log(`Total evaluation units: ${colorize(String(totalCount), ansi.bold)}`);\n console.log('');\n batchReady = true;\n\n drawSpinner();\n spinnerTimer = setInterval(drawSpinner, 100);\n\n await done;\n if (spinnerTimer) {\n clearInterval(spinnerTimer);\n }\n\n console.log('');\n console.log(colorize('=== Run Summary (all jobs) ===', `${ansi.bold}${ansi.cyan}`));\n for (const snap of snapshots) {\n const completed = completedRuns.get(snap.runId);\n if (!completed) {\n continue;\n }\n const label = runIdToLabel.get(snap.runId) ?? snap.runId;\n console.log('');\n console.log(colorize(`— ${label}`, ansi.magenta));\n console.log(\n `- passed: ${colorize(`${completed.passedTestCases}/${completed.totalTestCases}`, ansi.green)}`,\n );\n console.log(\n `- failed: ${colorize(\n `${completed.failedTestCases}/${completed.totalTestCases}`,\n completed.failedTestCases > 0 ? ansi.red : ansi.dim,\n )}`,\n );\n console.log(`- artifact: ${colorize(completed.artifactPath, ansi.dim)}`);\n }\n\n if (overallScoreCount > 0) {\n const overallAverage = overallScoreTotal / overallScoreCount;\n const overallSd = sampleStdDev(overallScoreTotal, overallScoreSumSq, overallScoreCount);\n const avgStr =\n overallSd !== undefined\n ? `${overallAverage.toFixed(2)} ± ${overallSd.toFixed(2)}`\n : overallAverage.toFixed(2);\n console.log('');\n console.log(\n `- overall avg score (all jobs): ${colorize(\n avgStr,\n scoreToColor(overallAverage),\n )} ${colorize(createBar(overallAverage), ansi.dim)}`,\n );\n }\n console.log(colorize('- evaluator averages:', ansi.magenta));\n for (const [evaluatorId, evaluatorName] of evaluatorNameById.entries()) {\n const evaluatorLines = getEvaluatorSummaryLines(\n evaluatorId,\n evaluatorName,\n aggregates.get(evaluatorId),\n scoreItemsByEvaluatorScore,\n );\n for (const line of evaluatorLines) {\n console.log(line);\n }\n }\n const testCaseSummaries = buildTestCaseSummaries(testCaseByTestId);\n if (testCaseSummaries.length > 0) {\n console.log(colorize('- test case scores:', ansi.magenta));\n for (const summary of testCaseSummaries) {\n const status = summary.passed ? colorize('PASS', ansi.green) : colorize('FAIL', ansi.red);\n if (summary.averageScore === undefined) {\n console.log(\n ` ${status} ${summary.name.padEnd(24)} score=n/a ${colorize(`(${summary.durationMs}ms)`, ansi.dim)}`,\n );\n continue;\n }\n const scoreLabel =\n summary.isAggregated && summary.aggregatedScoreItem\n ? (() => {\n const def =\n summary.aggregatedScoreItem.def ?? getScoreById(summary.aggregatedScoreItem.id);\n return def\n ? def.formatAggregate(summary.aggregatedScoreItem.data)\n : summary.averageScore!.toFixed(2);\n })()\n : summary.stdDev !== undefined && summary.isAggregated\n ? `${summary.averageScore.toFixed(2)} ± ${summary.stdDev.toFixed(2)}`\n : summary.averageScore.toFixed(2);\n console.log(\n ` ${status} ${summary.name.padEnd(24)} score=${colorize(\n scoreLabel,\n scoreToColor(summary.averageScore),\n )} ${colorize(createBar(summary.averageScore, 100, 14), ansi.dim)} ${colorize(`(${summary.durationMs}ms)`, ansi.dim)}`,\n );\n }\n }\n\n let failedTestCasesTotal = 0;\n for (const snap of snapshots) {\n const completed = completedRuns.get(snap.runId);\n if (completed) {\n failedTestCasesTotal += completed.failedTestCases;\n }\n }\n return failedTestCasesTotal > 0 ? 1 : 0;\n}\n\nexport async function runSimpleEvalRunConfigsInk(\n runner: RunnerApi,\n runConfigNames: ReadonlyArray<string>,\n concurrency: number,\n experimentName?: string,\n triggerTimestamp?: number,\n): Promise<0 | 1> {\n return new Promise<0 | 1>((resolve, reject) => {\n const app = render(\n React.createElement(RunView, {\n runner,\n runConfigNames,\n concurrency,\n experimentName,\n triggerTimestamp,\n onComplete: (err?: Error, exitCode?: 0 | 1) => {\n app.unmount();\n if (err) {\n reject(err);\n } else {\n resolve(exitCode ?? 0);\n }\n },\n }),\n );\n });\n}\n","/** @jsxImportSource react */\n\nimport { Box, Text } from 'ink';\nimport { type ReactNode, useCallback, useEffect, useState } from 'react';\nimport { TextBar } from '../../cli/components/TextBar';\nimport {\n formatScoreData,\n getDiffLines,\n getEvaluatorDisplayLabel,\n getLogLines,\n getMetricById,\n getScoreById,\n} from '../../evals';\nimport type { EvaluatorLogEntry } from '../../evals/diff';\nimport type { ScoreItem } from '../../evals/score';\nimport type { RunDatasetJob, RunnerApi, RunnerEvent } from '../../runner';\nimport {\n aggregateMetricItems,\n aggregateScoreItems,\n toNumericScore,\n toNumericScoreFromScores,\n} from '../../runner/score-utils';\nimport { Banner } from './Banner';\nimport { Spinner } from './Spinner';\n\ninterface EvaluatorScoreRow {\n evaluatorId: string;\n evaluatorName: string;\n scores: ReadonlyArray<ScoreItem>;\n passed: boolean;\n metrics?: ReadonlyArray<{ id: string; data: unknown; name?: string }>;\n logs?: ReadonlyArray<EvaluatorLogEntry>;\n}\n\n/** One displayed block per unique test case, updated in place as repetitions complete */\ninterface TestCaseDisplay {\n name: string;\n testCaseId: string;\n completedTestCases: number;\n totalTestCases: number;\n repetitionIndex: number;\n repetitionCount: number;\n durationMs: number;\n passed: boolean;\n errorMessage?: string;\n events: Array<{\n evaluatorScores: EvaluatorScoreRow[];\n passed: boolean;\n durationMs: number;\n }>;\n aggregatedEvaluatorScores: EvaluatorScoreRow[];\n isAggregated: boolean;\n}\n\ninterface RunningEvaluationDisplay {\n runId?: string;\n testCaseId: string;\n name: string;\n repetitionId: string;\n repetitionIndex: number;\n repetitionCount: number;\n startedTestCases: number;\n totalTestCases: number;\n}\n\ninterface EvaluatorAggregate {\n total: number;\n sumSq: number;\n count: number;\n passed: number;\n failed: number;\n}\n\nfunction sampleStdDev(sum: number, sumSq: number, n: number): number | undefined {\n if (n < 2) return undefined;\n const mean = sum / n;\n const variance = (sumSq - n * mean * mean) / (n - 1);\n return variance > 0 ? Math.sqrt(variance) : 0;\n}\n\nfunction scoreColor(score: number): 'green' | 'yellow' | 'red' {\n if (score >= 80) return 'green';\n if (score >= 50) return 'yellow';\n return 'red';\n}\n\nfunction createBar(value: number, max = 100, width = 20): string {\n const safe = Math.max(0, Math.min(max, value));\n const filled = Math.round((safe / max) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction aggregateEvaluatorScores(\n events: Array<{ evaluatorScores: EvaluatorScoreRow[] }>,\n nameById: Map<string, string>,\n): EvaluatorScoreRow[] {\n if (events.length === 0) return [];\n const evaluatorIds = new Set(events.flatMap((e) => e.evaluatorScores.map((x) => x.evaluatorId)));\n const result: EvaluatorScoreRow[] = [];\n for (const evaluatorId of evaluatorIds) {\n const scoreIdToItems = new Map<string, ScoreItem[]>();\n const metricIdToItems = new Map<string, Array<{ id: string; data: unknown }>>();\n for (const ev of events) {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n for (const s of es?.scores ?? []) {\n const list = scoreIdToItems.get(s.id) ?? [];\n list.push(s);\n scoreIdToItems.set(s.id, list);\n }\n for (const m of es?.metrics ?? []) {\n const list = metricIdToItems.get(m.id) ?? [];\n list.push(m);\n metricIdToItems.set(m.id, list);\n }\n }\n const aggregatedScores: ScoreItem[] = [];\n for (const items of scoreIdToItems.values()) {\n const agg = aggregateScoreItems(items);\n if (agg) aggregatedScores.push(agg);\n }\n const aggregatedMetrics = Array.from(metricIdToItems.entries())\n .map(([, items]) => aggregateMetricItems(items))\n .filter((m): m is { id: string; data: unknown } => m !== undefined);\n const passed = events.every((ev) => {\n const es = ev.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n return es?.passed ?? false;\n });\n const lastEvent = events[events.length - 1];\n const lastEs = lastEvent?.evaluatorScores.find((x) => x.evaluatorId === evaluatorId);\n result.push({\n evaluatorId,\n evaluatorName: nameById.get(evaluatorId) ?? evaluatorId,\n scores: aggregatedScores,\n passed,\n metrics: aggregatedMetrics.length > 0 ? aggregatedMetrics : undefined,\n logs: lastEs?.logs,\n });\n }\n return result;\n}\n\nfunction formatScorePart(\n item: ScoreItem,\n _scoreToColor: (n: number) => 'green' | 'yellow' | 'red',\n options?: { isAggregated?: boolean },\n): string {\n const def = item.def ?? getScoreById(item.id);\n if (!def) {\n const numeric = toNumericScore(item.data);\n return numeric !== undefined ? `${numeric.toFixed(2)}` : 'n/a';\n }\n const formatted = formatScoreData(def, item.data, options);\n if (def.displayStrategy === 'bar') {\n const numeric =\n typeof item.data === 'object' && item.data !== null && 'value' in item.data\n ? (item.data as { value: unknown }).value\n : toNumericScore(item.data);\n if (typeof numeric === 'number' && Number.isFinite(numeric)) {\n return `${formatted} ${createBar(numeric)}`;\n }\n }\n return formatted;\n}\n\ninterface RunViewProps {\n runner: RunnerApi;\n runConfigNames: ReadonlyArray<string>;\n concurrency: number;\n /** Forwarded to evaluator `meta.experimentName` for this run. */\n experimentName?: string;\n /** `Date.now()` when the CLI run command started; forwarded as `meta.triggerTimestamp`. */\n triggerTimestamp?: number;\n /**\n * Error ends the run unsuccessfully; on success `exitCode` is 0 when all test cases passed\n * across completed runs, or 1 when any had failures (`RunCompleted.failedTestCases`).\n */\n onComplete: (error?: Error, exitCode?: 0 | 1) => void;\n}\n\ninterface RunInfoState {\n names: string[];\n jobs: number;\n totalTestCases: number;\n}\n\nexport function RunView({\n runner,\n runConfigNames,\n concurrency,\n experimentName,\n triggerTimestamp,\n onComplete,\n}: RunViewProps): ReactNode {\n const [phase, setPhase] = useState<'loading' | 'running' | 'completed'>('loading');\n const [runInfo, setRunInfo] = useState<RunInfoState | null>(null);\n const [testCases, setTestCases] = useState<TestCaseDisplay[]>([]);\n const [startedEvaluations, setStartedEvaluations] = useState(0);\n const [completedEvaluations, setCompletedEvaluations] = useState(0);\n const [runningEvaluations, setRunningEvaluations] = useState<RunningEvaluationDisplay[]>([]);\n const [summary, setSummary] = useState<{\n passedTestCases: number;\n failedTestCases: number;\n totalTestCases: number;\n overallScoreTotal: number;\n overallScoreSumSq: number;\n overallScoreCount: number;\n aggregates: Map<string, EvaluatorAggregate>;\n scoreItemsByEvaluatorScore: Map<string, ScoreItem[]>;\n artifactPath: string;\n } | null>(null);\n const [evaluatorNameById, setEvaluatorNameById] = useState<Map<string, string>>(new Map());\n\n const runEval = useCallback(async () => {\n const rcList = runConfigNames.filter((n) => n.trim().length > 0);\n if (rcList.length === 0) {\n onComplete(new Error('At least one RunConfig name is required.'));\n return;\n }\n\n setStartedEvaluations(0);\n setCompletedEvaluations(0);\n setTestCases([]);\n setRunningEvaluations([]);\n setSummary(null);\n\n let jobs: ReadonlyArray<RunDatasetJob>;\n try {\n jobs = await runner.expandRunConfigNamesToJobs(rcList);\n } catch (err) {\n onComplete(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n if (jobs.length === 0) {\n onComplete(new Error('No jobs expanded from RunConfigs.'));\n return;\n }\n\n const allEvaluators = await runner.collectEvaluators();\n const nameById = new Map(\n allEvaluators.map((item) => [item.id, getEvaluatorDisplayLabel(item.evaluator) ?? item.id]),\n );\n setEvaluatorNameById(nameById);\n\n const aggregates = new Map<string, EvaluatorAggregate>();\n const scoreItemsByEvaluatorScore = new Map<string, ScoreItem[]>();\n let overallScoreTotal = 0;\n let overallScoreSumSq = 0;\n let overallScoreCount = 0;\n\n const batchPendingRunIds = new Set<string>();\n const runIdToLabel = new Map<string, string>();\n let batchReady = false;\n const completedRuns = new Map<string, Extract<RunnerEvent, { type: 'RunCompleted' }>>();\n\n const done = new Promise<void>((resolve, reject) => {\n const unsubscribe = runner.subscribeRunEvents((event) => {\n if (\n batchReady &&\n 'runId' in event &&\n typeof event.runId === 'string' &&\n !batchPendingRunIds.has(event.runId)\n ) {\n return;\n }\n\n if (event.type === 'TestCaseStarted') {\n setStartedEvaluations((c) => c + 1);\n setRunningEvaluations((prev) => {\n const withoutDuplicate = prev.filter(\n (item) =>\n !(\n item.testCaseId === event.testCaseId &&\n item.repetitionIndex === event.repetitionIndex &&\n item.runId === event.runId\n ),\n );\n return [\n ...withoutDuplicate,\n {\n runId: event.runId,\n testCaseId: event.testCaseId,\n name: event.testCaseName,\n repetitionId: event.repetitionId,\n repetitionIndex: event.repetitionIndex,\n repetitionCount: event.repetitionCount,\n startedTestCases: event.startedTestCases,\n totalTestCases: event.totalTestCases,\n },\n ];\n });\n }\n\n if (event.type === 'TestCaseProgress') {\n for (const item of event.evaluatorScores) {\n const numeric = toNumericScoreFromScores(item.scores);\n if (numeric !== undefined) {\n const current = aggregates.get(item.evaluatorId) ?? {\n total: 0,\n sumSq: 0,\n count: 0,\n passed: 0,\n failed: 0,\n };\n aggregates.set(item.evaluatorId, {\n total: current.total + numeric,\n sumSq: current.sumSq + numeric * numeric,\n count: current.count + 1,\n passed: current.passed + (item.passed ? 1 : 0),\n failed: current.failed + (item.passed ? 0 : 1),\n });\n overallScoreTotal += numeric;\n overallScoreSumSq += numeric * numeric;\n overallScoreCount += 1;\n }\n for (const s of item.scores) {\n const key = `${item.evaluatorId}:${s.id}`;\n const list = scoreItemsByEvaluatorScore.get(key) ?? [];\n list.push(s);\n scoreItemsByEvaluatorScore.set(key, list);\n }\n }\n\n const label = runIdToLabel.get(event.runId);\n const compositeId = `${event.runId}:${event.testCaseId}`;\n const displayName =\n label !== undefined ? `${label} › ${event.testCaseName}` : event.testCaseName;\n\n setTestCases((prev) => {\n const byId = new Map(prev.map((tc) => [tc.testCaseId, tc]));\n const existing = byId.get(compositeId);\n const newEvent = {\n evaluatorScores: event.evaluatorScores.map((item) => ({\n evaluatorId: item.evaluatorId,\n evaluatorName: nameById.get(item.evaluatorId) ?? item.evaluatorId,\n scores: item.scores,\n passed: item.passed,\n metrics: item.metrics,\n logs: item.logs,\n })),\n passed: event.passed,\n durationMs: event.durationMs,\n };\n const events = existing ? [...existing.events, newEvent] : [newEvent];\n const isAggregated = events.length > 1;\n const aggregatedEvaluatorScores = aggregateEvaluatorScores(events, nameById);\n const merged: TestCaseDisplay = {\n name: displayName,\n testCaseId: compositeId,\n completedTestCases: event.completedTestCases,\n totalTestCases: event.totalTestCases,\n repetitionIndex: event.repetitionIndex,\n repetitionCount: event.repetitionCount,\n durationMs: events.reduce((s, e) => s + e.durationMs, 0),\n passed: events.every((e) => e.passed),\n errorMessage: event.errorMessage,\n events,\n aggregatedEvaluatorScores,\n isAggregated,\n };\n byId.set(compositeId, merged);\n return Array.from(byId.values());\n });\n setCompletedEvaluations((c) => c + 1);\n setRunningEvaluations((running) =>\n running.filter(\n (item) =>\n !(\n item.testCaseId === event.testCaseId &&\n item.repetitionIndex === event.repetitionIndex &&\n item.runId === event.runId\n ),\n ),\n );\n }\n\n if (event.type === 'RunFailed') {\n if (batchReady && !batchPendingRunIds.has(event.runId)) {\n return;\n }\n unsubscribe();\n reject(new Error(`Run failed: ${event.errorMessage}`));\n return;\n }\n\n if (event.type === 'RunCompleted') {\n if (!batchPendingRunIds.has(event.runId)) {\n return;\n }\n completedRuns.set(event.runId, event);\n batchPendingRunIds.delete(event.runId);\n if (batchPendingRunIds.size === 0) {\n unsubscribe();\n resolve();\n }\n }\n });\n });\n\n const snapshots = await runner.runDatasetJobsWithSharedConcurrency({\n jobs,\n globalConcurrency: concurrency,\n experimentName,\n triggerTimestamp,\n });\n for (let i = 0; i < snapshots.length; i += 1) {\n const snap = snapshots[i];\n const job = jobs[i];\n if (snap && job) {\n runIdToLabel.set(\n snap.runId,\n `${job.runConfigDisplayLabel ?? job.runConfigName} · ${snap.datasetName}`,\n );\n batchPendingRunIds.add(snap.runId);\n }\n }\n const totalUnits = snapshots.reduce((sum, s) => sum + s.totalTestCases, 0);\n batchReady = true;\n\n const runConfigLabels = await Promise.all(\n rcList.map(async (n) => {\n const collected = await runner.resolveRunConfigByName(n);\n return collected?.runConfig.getDisplayLabel() ?? n;\n }),\n );\n\n setRunInfo({\n names: runConfigLabels,\n jobs: jobs.length,\n totalTestCases: totalUnits,\n });\n setPhase('running');\n\n try {\n await done;\n } catch (err) {\n onComplete(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n let passedTestCases = 0;\n let failedTestCases = 0;\n let totalTestCases = 0;\n const artifacts: string[] = [];\n for (const ev of completedRuns.values()) {\n passedTestCases += ev.passedTestCases;\n failedTestCases += ev.failedTestCases;\n totalTestCases += ev.totalTestCases;\n artifacts.push(ev.artifactPath);\n }\n\n setSummary({\n passedTestCases,\n failedTestCases,\n totalTestCases,\n overallScoreTotal,\n overallScoreSumSq,\n overallScoreCount,\n aggregates: new Map(aggregates),\n scoreItemsByEvaluatorScore: new Map(scoreItemsByEvaluatorScore),\n artifactPath: artifacts.join('\\n'),\n });\n setPhase('completed');\n const exitCode: 0 | 1 = failedTestCases > 0 ? 1 : 0;\n setTimeout(() => onComplete(undefined, exitCode), 200);\n }, [runner, runConfigNames, concurrency, experimentName, triggerTimestamp, onComplete]);\n\n useEffect(() => {\n void runEval();\n }, [runEval]);\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Banner />\n </Box>\n\n {runInfo && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"cyan\" bold>\n RunConfigs{' '}\n </Text>\n <Text color=\"gray\">{runInfo.names.join(', ')}</Text>\n <Text>\n <Text color=\"cyan\" bold>\n Jobs{' '}\n </Text>\n {runInfo.jobs}\n </Text>\n <Text>\n <Text color=\"cyan\" bold>\n Evaluation units{' '}\n </Text>\n {runInfo.totalTestCases}\n </Text>\n </Box>\n )}\n\n {phase === 'running' && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Spinner\n label={`Evaluations ${completedEvaluations}/${runInfo?.totalTestCases ?? 0} completed • ${startedEvaluations}/${runInfo?.totalTestCases ?? 0} started`}\n />\n {runningEvaluations.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n {runningEvaluations.map((item) => (\n <Text\n key={`${item.runId ?? ''}:${item.testCaseId}:${item.repetitionId}:${item.repetitionIndex}`}\n color=\"yellow\"\n >\n [running {item.startedTestCases}/{item.totalTestCases}] {item.name}{' '}\n <Text color=\"gray\">\n ({item.repetitionIndex}/{item.repetitionCount})\n </Text>\n </Text>\n ))}\n </Box>\n )}\n </Box>\n )}\n\n {testCases.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {testCases.map((tc) => (\n <Box key={tc.testCaseId} flexDirection=\"column\" marginBottom={0}>\n <Text>\n <Text color=\"cyan\">\n [{tc.completedTestCases}/{tc.totalTestCases}]\n </Text>{' '}\n {tc.name}{' '}\n <Text color=\"cyan\">\n ({tc.repetitionIndex}/{tc.repetitionCount})\n </Text>\n <Text color=\"gray\"> ({tc.durationMs}ms)</Text>\n {tc.errorMessage ? (\n <Text color=\"red\" bold>\n {' '}\n ERROR\n </Text>\n ) : null}\n </Text>\n {tc.errorMessage ? <Text color=\"red\">{tc.errorMessage}</Text> : null}\n {tc.aggregatedEvaluatorScores.map((item) => (\n <Box key={item.evaluatorId} flexDirection=\"column\" marginLeft={2}>\n <Text>\n {item.evaluatorName}:{' '}\n <Text color={item.passed ? 'green' : 'red'} bold>\n {item.passed ? 'PASS' : 'FAIL'}\n </Text>\n {item.metrics && item.metrics.length > 0 ? (\n <>\n {' '}\n {item.metrics.map((m) => {\n const def = getMetricById(m.id);\n if (!def) return null;\n const formatted = def.format(m.data, {\n isAggregated: tc.isAggregated,\n });\n const label = m.name ?? def.name;\n return (\n <Text key={m.id} color=\"gray\">\n [{label ? `${label}: ` : ''}\n {formatted}]{' '}\n </Text>\n );\n })}\n </>\n ) : null}\n </Text>\n {item.scores.length > 0 ? (\n item.scores.map((s) => {\n const def = s.def ?? getScoreById(s.id);\n const scoreLabel = s.name ?? def?.name ?? def?.id ?? s.id;\n return (\n <Text\n key={`${item.evaluatorId}-${s.id}-${scoreLabel}`}\n color={scoreColor(toNumericScore(s.data) ?? 0)}\n >\n {' '}\n {scoreLabel}:{' '}\n {formatScorePart(s, scoreColor, {\n isAggregated: tc.isAggregated,\n })}\n </Text>\n );\n })\n ) : (\n <Text color=\"gray\"> n/a</Text>\n )}\n {!item.passed && item.logs && item.logs.length > 0 && (\n <Box marginLeft={2} flexDirection=\"column\">\n {item.logs.map((log) =>\n log.type === 'diff' ? (\n <Box\n key={`diff:${getDiffLines(log)\n .map((x) => x.line)\n .join('|')}`}\n flexDirection=\"column\"\n >\n {getDiffLines(log).map(({ type, line }) => (\n <Text\n key={`${type}:${line}`}\n color={\n type === 'remove' ? 'red' : type === 'add' ? 'green' : 'gray'\n }\n >\n {line}\n </Text>\n ))}\n </Box>\n ) : log.type === 'log' ? (\n <Box key={`log:${getLogLines(log).join('\\n')}`} flexDirection=\"column\">\n {getLogLines(log).map((line) => (\n <Text key={line} color=\"gray\">\n {line}\n </Text>\n ))}\n </Box>\n ) : null,\n )}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n ))}\n </Box>\n )}\n\n {phase === 'completed' && summary && (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Run Summary\n </Text>\n <Box marginTop={1}>\n <Text color=\"green\">passed</Text>\n <Text>\n {' '}\n {summary.passedTestCases}/{summary.totalTestCases}\n </Text>\n </Box>\n <Box>\n <Text color={summary.failedTestCases > 0 ? 'red' : 'gray'}>failed</Text>\n <Text>\n {' '}\n {summary.failedTestCases}/{summary.totalTestCases}\n </Text>\n </Box>\n {summary.overallScoreCount > 0 && (\n <Box marginTop={1}>\n <TextBar\n label=\"overall avg\"\n value={summary.overallScoreTotal / summary.overallScoreCount}\n barWidth={20}\n format={(v) => {\n const sd = sampleStdDev(\n summary.overallScoreTotal,\n summary.overallScoreSumSq,\n summary.overallScoreCount,\n );\n return sd !== undefined ? `${v.toFixed(2)} ± ${sd.toFixed(2)}` : v.toFixed(2);\n }}\n />\n </Box>\n )}\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"magenta\">evaluator averages</Text>\n {Array.from(evaluatorNameById.entries()).map(([id, name]) => {\n const agg = summary.aggregates.get(id);\n const scoreKeys = [...(summary.scoreItemsByEvaluatorScore?.keys() ?? [])].filter(\n (k) => k.startsWith(`${id}:`),\n );\n if (scoreKeys.length === 0) {\n return (\n <Text key={id} color=\"gray\">\n - {name.padEnd(28)} no scores\n </Text>\n );\n }\n const passedFailed =\n agg != null ? (\n <Text>\n {' '}\n passed={agg.passed} failed={agg.failed}\n </Text>\n ) : null;\n return (\n <Box key={id} flexDirection=\"column\">\n <Text>\n - {name.padEnd(28)}\n {passedFailed}\n </Text>\n {scoreKeys.map((key) => {\n const items = summary.scoreItemsByEvaluatorScore?.get(key) ?? [];\n const aggregated = aggregateScoreItems(items);\n if (!aggregated) return null;\n const def = aggregated.def ?? getScoreById(aggregated.id);\n const label = aggregated.name ?? def?.name ?? def?.id ?? aggregated.id;\n const formatted = def ? def.formatAggregate(aggregated.data) : 'n/a';\n const numeric = toNumericScore(aggregated.data);\n return (\n <Text key={key} color={numeric !== undefined ? scoreColor(numeric) : 'gray'}>\n {' '}\n {label}: {formatted}\n </Text>\n );\n })}\n </Box>\n );\n })}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"magenta\">test case scores</Text>\n {testCases.map((tc) => {\n const allScores = tc.events.flatMap((ev) =>\n ev.evaluatorScores\n .map((es) => toNumericScoreFromScores(es.scores))\n .filter((n): n is number => n !== undefined),\n );\n const averageScore =\n allScores.length > 0\n ? allScores.reduce((a, b) => a + b, 0) / allScores.length\n : undefined;\n const sumSq = allScores.length > 0 ? allScores.reduce((s, v) => s + v * v, 0) : 0;\n const total = allScores.reduce((a, b) => a + b, 0);\n const tcStdDev = sampleStdDev(total, sumSq, allScores.length);\n const firstScore = tc.aggregatedEvaluatorScores[0]?.scores[0];\n const scoreLabel =\n firstScore && tc.isAggregated\n ? formatScorePart(firstScore, scoreColor, {\n isAggregated: true,\n })\n : averageScore !== undefined\n ? tcStdDev !== undefined && tc.isAggregated\n ? `${averageScore.toFixed(2)} ± ${tcStdDev.toFixed(2)}`\n : averageScore.toFixed(2)\n : 'n/a';\n return (\n <Box key={tc.testCaseId}>\n <Text color={tc.passed ? 'green' : 'red'}>{tc.passed ? 'PASS' : 'FAIL'}</Text>\n <Text> {tc.name.padEnd(24)}</Text>\n {averageScore !== undefined ? (\n <>\n <Text color={scoreColor(averageScore)}>score={scoreLabel}</Text>\n <Text color=\"gray\"> {createBar(averageScore, 100, 14)}</Text>\n </>\n ) : (\n <Text color=\"gray\">score=n/a</Text>\n )}\n <Text color=\"gray\"> ({tc.durationMs}ms)</Text>\n </Box>\n );\n })}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\">artifact(s):</Text>\n {summary.artifactPath.split('\\n').map((line) => (\n <Text key={line} color=\"gray\">\n {line}\n </Text>\n ))}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { Text } from 'ink';\n\ninterface TextBarProps {\n label: string;\n value: number;\n max?: number;\n /** Label width (default 14 to match inspiration) */\n labelWidth?: number;\n /** Bar width in chars (default 20) */\n barWidth?: number;\n /** Format value for display (e.g. v => `${v}%`) */\n format?: (v: number) => string;\n /** Color bar by value: green > 70, yellow 40-70, red < 40 */\n colorByValue?: boolean;\n}\n\nfunction barColor(pct: number): 'green' | 'yellow' | 'red' | undefined {\n if (pct >= 70) return 'green';\n if (pct >= 40) return 'yellow';\n return 'red';\n}\n\nexport function TextBar({\n label,\n value,\n max = 100,\n labelWidth = 14,\n barWidth = 20,\n format = (v) => String(v),\n colorByValue = true,\n}: TextBarProps): React.ReactNode {\n const clamped = Math.max(0, Math.min(max, value));\n const pct = max > 0 ? (clamped / max) * 100 : 0;\n const filled = Math.round((clamped / max) * barWidth);\n const filledBar = '█'.repeat(filled);\n const emptyBar = '░'.repeat(Math.max(0, barWidth - filled));\n const color = colorByValue ? barColor(pct) : undefined;\n\n return (\n <Text>\n <Text color=\"gray\">{label.padEnd(labelWidth)}</Text>\n {' ['}\n {color ? (\n <>\n <Text color={color}>{filledBar}</Text>\n <Text color=\"gray\">{emptyBar}</Text>\n </>\n ) : (\n filledBar + emptyBar\n )}\n {'] '}\n <Text color={color ?? 'white'} bold>\n {format(value)}\n </Text>\n </Text>\n );\n}\n","/** @jsxImportSource react */\nimport type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Text } from 'ink';\n\nconst FRAMES = ['⠋', '⠙', '⠸', '⠴', '⠦', '⠇'];\n\ninterface SpinnerProps {\n label?: string;\n}\n\nexport function Spinner({ label = 'Running' }: SpinnerProps): React.ReactNode {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame((f) => (f + 1) % FRAMES.length);\n }, 100);\n return () => clearInterval(timer);\n }, []);\n\n return (\n <Text color=\"cyan\">\n {FRAMES[frame]} {label}\n </Text>\n );\n}\n","#!/usr/bin/env node\n\nimport { createRunner } from '../runner';\nimport { getDefaultConcurrency, getSimpleCliUsage, parseSimpleCliArgs } from './args';\nimport { printBanner } from './banner';\nimport { generateDatasetJsonCommandInk, generateDatasetJsonCommandPlain } from './generate';\nimport { runSimpleEvalRunConfigsInk, runSimpleEvalRunConfigsPlain } from './run';\n\nfunction printUsageAndExit(exitCode: number): never {\n const printer = exitCode === 0 ? console.log : console.error;\n printer(getSimpleCliUsage());\n process.exit(exitCode);\n}\n\nasync function main(): Promise<void> {\n const args = parseSimpleCliArgs(process.argv.slice(2));\n\n if (args.help) {\n printUsageAndExit(0);\n }\n if (args.unknownArgs.length > 0) {\n console.error(`Unknown arguments: ${args.unknownArgs.join(', ')}`);\n printUsageAndExit(1);\n }\n if (!args.command) {\n printUsageAndExit(1);\n }\n\n if (args.command === 'run') {\n if (args.runConfigNames.length === 0) {\n console.error(\n 'Missing required --run-config <name> (repeat the flag to queue multiple RunConfigs).',\n );\n printUsageAndExit(1);\n }\n if (args.datasetName !== undefined) {\n console.error(\n 'The run command no longer accepts --dataset; use --run-config <RunConfig name>.',\n );\n printUsageAndExit(1);\n }\n }\n\n if (args.command === 'generate' && args.runConfigNames.length > 0) {\n console.error('generate does not accept --run-config.');\n printUsageAndExit(1);\n }\n\n const useInk = process.stdout.isTTY === true;\n if (!useInk) {\n printBanner();\n }\n\n const runner = createRunner();\n try {\n if (args.command === 'run') {\n const concurrency = args.concurrency ?? getDefaultConcurrency();\n const triggerTimestamp = Date.now();\n const exitCode = await (useInk ? runSimpleEvalRunConfigsInk : runSimpleEvalRunConfigsPlain)(\n runner,\n args.runConfigNames,\n concurrency,\n args.experimentName,\n triggerTimestamp,\n );\n if (args.ci && exitCode !== 0) {\n process.exit(1);\n }\n return;\n }\n\n const genDataset = args.datasetName;\n if (!genDataset) {\n console.error('Missing required --dataset <datasetId> argument.');\n printUsageAndExit(1);\n }\n await (useInk ? generateDatasetJsonCommandInk : generateDatasetJsonCommandPlain)(\n runner,\n genDataset,\n );\n } finally {\n await runner.shutdown();\n }\n}\n\nvoid main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : 'Command failed');\n process.exit(1);\n});\n"]}
|