zidane 5.10.13 → 5.11.1

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.
Files changed (118) hide show
  1. package/README.md +31 -5
  2. package/dist/{agent-BHkvYIH9.d.ts → agent-D0W9yClt.d.ts} +114 -27
  3. package/dist/agent-D0W9yClt.d.ts.map +1 -0
  4. package/dist/chat/pure.d.ts +3 -3
  5. package/dist/chat.d.ts +7 -7
  6. package/dist/chat.js +2 -2
  7. package/dist/contexts/docker.d.ts +1 -1
  8. package/dist/contexts/docker.d.ts.map +1 -1
  9. package/dist/contexts/docker.js +53 -14
  10. package/dist/contexts/docker.js.map +1 -1
  11. package/dist/contexts/e2b.d.ts +168 -0
  12. package/dist/contexts/e2b.d.ts.map +1 -0
  13. package/dist/contexts/e2b.js +261 -0
  14. package/dist/contexts/e2b.js.map +1 -0
  15. package/dist/{contexts-BJVgG0LY.js → contexts-DglWSzmR.js} +59 -9
  16. package/dist/contexts-DglWSzmR.js.map +1 -0
  17. package/dist/contexts.d.ts +3 -3
  18. package/dist/contexts.js +1 -1
  19. package/dist/eval.d.ts +1 -1
  20. package/dist/eval.js +5 -5
  21. package/dist/eval.js.map +1 -1
  22. package/dist/{headless-CPaunZsU.js → headless-Bb5gU8AR.js} +6 -6
  23. package/dist/{headless-CPaunZsU.js.map → headless-Bb5gU8AR.js.map} +1 -1
  24. package/dist/headless.d.ts +1 -1
  25. package/dist/headless.js +1 -1
  26. package/dist/{index-C_t8tW_X.d.ts → index-CrMb8jCE.d.ts} +2 -2
  27. package/dist/{index-C_t8tW_X.d.ts.map → index-CrMb8jCE.d.ts.map} +1 -1
  28. package/dist/{index-BIo67xLV.d.ts → index-D60tX5XC.d.ts} +10 -3
  29. package/dist/index-D60tX5XC.d.ts.map +1 -0
  30. package/dist/{index-C4aT2kO_.d.ts → index-DZR99FD4.d.ts} +30 -111
  31. package/dist/index-DZR99FD4.d.ts.map +1 -0
  32. package/dist/index.d.ts +7 -6
  33. package/dist/index.js +11 -10
  34. package/dist/index.js.map +1 -1
  35. package/dist/{interpolate-Dy7Lunvg.js → interpolate-CTfr0GdR.js} +19 -1
  36. package/dist/{interpolate-Dy7Lunvg.js.map → interpolate-CTfr0GdR.js.map} +1 -1
  37. package/dist/logger-Ktm-lj1s.js +300 -0
  38. package/dist/logger-Ktm-lj1s.js.map +1 -0
  39. package/dist/logger-n4LsLISE.d.ts +102 -0
  40. package/dist/logger-n4LsLISE.d.ts.map +1 -0
  41. package/dist/{login-0jP1pnSJ.js → login-BHhOdTp9.js} +4 -301
  42. package/dist/login-BHhOdTp9.js.map +1 -0
  43. package/dist/{mcp-tevNihk_.js → mcp-Cy9mgCcr.js} +22 -9
  44. package/dist/mcp-Cy9mgCcr.js.map +1 -0
  45. package/dist/mcp.d.ts +1 -1
  46. package/dist/mcp.js +1 -1
  47. package/dist/{messages-C_1AmSpk.js → messages-RPKrEPvH.js} +6 -2
  48. package/dist/messages-RPKrEPvH.js.map +1 -0
  49. package/dist/output/stream-json.d.ts +2 -2
  50. package/dist/output/stream-json.js +1 -1
  51. package/dist/output/terminal.d.ts +2 -2
  52. package/dist/output/terminal.js +1 -0
  53. package/dist/output/terminal.js.map +1 -1
  54. package/dist/{presets-Cm2BPJaU.js → presets-D5ibZTml.js} +2 -2
  55. package/dist/{presets-Cm2BPJaU.js.map → presets-D5ibZTml.js.map} +1 -1
  56. package/dist/presets.d.ts +2 -2
  57. package/dist/presets.js +1 -1
  58. package/dist/{providers-BGBB18zz.js → providers-C2cxujp_.js} +85 -20
  59. package/dist/providers-C2cxujp_.js.map +1 -0
  60. package/dist/providers.d.ts +1 -1
  61. package/dist/providers.js +2 -2
  62. package/dist/restate.d.ts +2 -2
  63. package/dist/restate.js +4 -1
  64. package/dist/restate.js.map +1 -1
  65. package/dist/session/sqlite.d.ts +1 -1
  66. package/dist/session/sqlite.d.ts.map +1 -1
  67. package/dist/session/sqlite.js +36 -4
  68. package/dist/session/sqlite.js.map +1 -1
  69. package/dist/{session-CtAWwwkn.js → session-Do_TQV7c.js} +70 -22
  70. package/dist/session-Do_TQV7c.js.map +1 -0
  71. package/dist/session.d.ts +2 -2
  72. package/dist/session.js +3 -3
  73. package/dist/shell-quote-BmnhZmdM.js +33 -0
  74. package/dist/shell-quote-BmnhZmdM.js.map +1 -0
  75. package/dist/skills.d.ts +3 -3
  76. package/dist/skills.js +1 -1
  77. package/dist/skills.js.map +1 -1
  78. package/dist/{tool-formatters-D_fX6FGl.d.ts → tool-formatters-RT5-gyE2.d.ts} +2 -2
  79. package/dist/{tool-formatters-D_fX6FGl.d.ts.map → tool-formatters-RT5-gyE2.d.ts.map} +1 -1
  80. package/dist/tools/fetch-url.d.ts +1 -1
  81. package/dist/tools/web-search.d.ts +1 -1
  82. package/dist/{tools-NxnEmzYg.js → tools-ZHKOh44k.js} +342 -123
  83. package/dist/tools-ZHKOh44k.js.map +1 -0
  84. package/dist/tools.d.ts +2 -2
  85. package/dist/tools.js +1 -1
  86. package/dist/{transcript-anchors-DA6XawEU.d.ts → transcript-anchors-B4FxkG-8.d.ts} +10 -4
  87. package/dist/transcript-anchors-B4FxkG-8.d.ts.map +1 -0
  88. package/dist/{transcript-anchors-B_c7gWot.js → transcript-anchors-CS46ul6X.js} +10 -10
  89. package/dist/transcript-anchors-CS46ul6X.js.map +1 -0
  90. package/dist/tui.d.ts +3 -3
  91. package/dist/tui.d.ts.map +1 -1
  92. package/dist/tui.js +167 -41
  93. package/dist/tui.js.map +1 -1
  94. package/dist/{turn-operations-CCl7rpbT.d.ts → turn-operations-CoRj3mYZ.d.ts} +3 -3
  95. package/dist/{turn-operations-CCl7rpbT.d.ts.map → turn-operations-CoRj3mYZ.d.ts.map} +1 -1
  96. package/dist/{types-BibzMDjX.d.ts → types-B39tBba1.d.ts} +69 -2
  97. package/dist/types-B39tBba1.d.ts.map +1 -0
  98. package/dist/types-BiobHM1D.js.map +1 -1
  99. package/dist/types.d.ts +5 -5
  100. package/docs/ARCHITECTURE.md +1 -1
  101. package/docs/CHAT.md +3 -3
  102. package/docs/EXECUTION_CONTEXT.md +257 -0
  103. package/docs/RUN_IN_BACKGROUND.md +8 -0
  104. package/docs/SKILL.md +3 -3
  105. package/package.json +57 -24
  106. package/dist/agent-BHkvYIH9.d.ts.map +0 -1
  107. package/dist/contexts-BJVgG0LY.js.map +0 -1
  108. package/dist/index-BIo67xLV.d.ts.map +0 -1
  109. package/dist/index-C4aT2kO_.d.ts.map +0 -1
  110. package/dist/login-0jP1pnSJ.js.map +0 -1
  111. package/dist/mcp-tevNihk_.js.map +0 -1
  112. package/dist/messages-C_1AmSpk.js.map +0 -1
  113. package/dist/providers-BGBB18zz.js.map +0 -1
  114. package/dist/session-CtAWwwkn.js.map +0 -1
  115. package/dist/tools-NxnEmzYg.js.map +0 -1
  116. package/dist/transcript-anchors-B_c7gWot.js.map +0 -1
  117. package/dist/transcript-anchors-DA6XawEU.d.ts.map +0 -1
  118. package/dist/types-BibzMDjX.d.ts.map +0 -1
package/dist/eval.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"eval.js","names":["shellQuote"],"sources":["../src/eval.ts"],"sourcesContent":["import type { ExecutionContext, ExecutionHandle } from './contexts'\nimport type { HeadlessEvent, HeadlessOptions, HeadlessResult } from './headless'\nimport type { Provider, ToolCall, ToolSpec } from './providers'\nimport type { Session, SessionStore } from './session'\nimport type { McpServerConfig, SessionTurn } from './types'\nimport { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join, relative, resolve } from 'node:path'\nimport chalk from 'chalk'\nimport { createProcessContext } from './contexts'\nimport { headlessEventToJsonl, runHeadless } from './headless'\nimport { createMemoryStore, createSession } from './session'\nimport { alwaysQuote as shellQuote } from './tools/shell-quote'\n\nexport interface EvalWorkspaceOptions {\n /**\n * Working directory inside the execution context. When omitted, process-based\n * evals get a fresh host temp dir; Docker evals use the context default.\n *\n * Note: under the shared-Docker harness (`withDocker`), per-case working dirs\n * are assigned by the container (`/workspace/case-N`) and a custom `cwd` is\n * ignored — `withDocker` strips it so cases stay isolated.\n */\n cwd?: string\n /**\n * Directory visible inside the execution context, copied into the workspace\n * before the agent runs. For Docker, mount local fixtures read-only and point\n * this at the container path, e.g. `/fixtures/react-empty`.\n */\n seedDir?: string\n /** Relative destination inside the workspace. Defaults to `.`. */\n seedTarget?: string\n /** Relative files/directories to capture after the run. Defaults to `.`. */\n capture?: string[]\n /** Max text chars retained per captured file. Defaults to 256 KiB. */\n maxFileChars?: number\n /** Keep a temp process workspace on disk after the eval completes. */\n retain?: boolean\n}\n\nexport interface EvalWorkspaceFile {\n path: string\n size: number\n content?: string\n truncated?: boolean\n binary?: boolean\n}\n\nexport interface EvalWorkspaceSnapshot {\n cwd: string\n files: EvalWorkspaceFile[]\n}\n\nexport interface EvalScore {\n name: string\n passed: boolean\n score?: number\n details?: string | Record<string, unknown>\n}\n\nexport type MetricDirection = 'higher-is-better' | 'lower-is-better'\n\n/** Declared metric: a raw signal plus how to normalize it to a `0..1` score. */\nexport interface MetricSpec {\n min: number\n max: number\n direction: MetricDirection\n /** Grouping tags, e.g. `@efficiency`, `@functionality`, `@quality`. */\n tags?: string[]\n description?: string\n}\n\nexport type MetricSpecMap = Record<string, MetricSpec>\n\n/** A normalized metric value attached to one eval case. */\nexport interface EvalMetric {\n id: string\n raw: number\n normalized: number\n direction: MetricDirection\n min: number\n max: number\n tags: string[]\n description?: string\n /**\n * True when the metric was declared but never emitted (e.g. its scorer threw\n * before calling `ctx.metric`). Recorded as `normalized: 0` so the run still\n * produces results instead of crashing.\n */\n missing?: boolean\n}\n\n/** Emit a raw metric value during a run. */\nexport type MetricEmitter = (id: string, raw: number) => void\n\nexport interface EvalScorerContext {\n id: string\n suite?: string\n tags: string[]\n result: HeadlessResult\n events: readonly HeadlessEvent[]\n workspace?: EvalWorkspaceSnapshot\n artifactDir?: string\n /** Emit a declared metric's raw value. Unknown ids throw at run end. */\n metric: MetricEmitter\n}\n\nexport type EvalScorer = (ctx: EvalScorerContext) => EvalScore | Promise<EvalScore>\n\n/**\n * Declare an eval's metric set. Returns the same map, typed; pass it to\n * `EvalCaseOptions.metrics`. Declared metrics that are not emitted are recorded\n * as missing with a normalized score of 0; emitting an undeclared metric is an\n * authoring error and throws.\n */\nexport function defineMetrics<T extends MetricSpecMap>(spec: T): T {\n return spec\n}\n\n/** Always-available efficiency metrics derived from `HeadlessResult`. */\nexport const EFFICIENCY_METRICS = {\n 'execution-time': { min: 0, max: 300_000, direction: 'lower-is-better', tags: ['@efficiency'], description: 'Wall-clock run time (ms).' },\n 'provider-tokens': { min: 0, max: 200_000, direction: 'lower-is-better', tags: ['@efficiency'], description: 'Input + output tokens.' },\n 'cache-read-rate': { min: 0, max: 1, direction: 'higher-is-better', tags: ['@efficiency'], description: 'Cache-read tokens / input tokens.' },\n} satisfies MetricSpecMap\n\nexport function normalizeMetric(raw: number, spec: MetricSpec): number {\n const span = spec.max - spec.min\n if (span === 0)\n return 1\n const clamped = Math.min(spec.max, Math.max(spec.min, raw))\n const normalized = (clamped - spec.min) / span\n return spec.direction === 'lower-is-better' ? 1 - normalized : normalized\n}\n\nexport interface LlmJudgeOptions {\n name?: string\n provider: Provider\n model?: string\n system?: string\n rubric: string\n maxTokens?: number\n /** Wall-clock cap for the judge provider call. Defaults to 60s. */\n timeoutMs?: number\n /** Select what the judge sees. Defaults to final text plus captured workspace files. */\n input?: (ctx: EvalScorerContext) => string\n /** Declared metric id to emit the judge's `0..1` score into. */\n metric?: string\n}\n\n/**\n * Thrown by `runEvalCase` when a scorer emits a metric id that was not declared\n * in `defineMetrics`. This is an authoring error (a typo'd or stale metric id),\n * not a low score — it fails the eval test rather than being recorded as a\n * failed scorer. Exported so downstream harnesses can type-narrow on it.\n */\nexport class EvalMetricError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'EvalMetricError'\n }\n}\n\nexport interface ReusableExecutionContext {\n /**\n * Execution context facade that reuses one underlying handle. Its\n * `destroy()` is intentionally a no-op; call `dispose()` when the surrounding\n * fixture/run owns teardown.\n */\n execution: ExecutionContext\n /** Destroy the underlying handle if it was spawned. Idempotent. */\n dispose: () => Promise<void>\n /** Current underlying handle, if the agent has spawned one. */\n handle: () => ExecutionHandle | undefined\n}\n\n/**\n * Wrap an execution context so repeated agent runs share one handle until the\n * caller disposes it. This is useful for eval fixtures that want per-test\n * Docker/process lifetime while still using `runHeadless()` per turn.\n */\nexport function createReusableExecutionContext(base: ExecutionContext): ReusableExecutionContext {\n let handle: ExecutionHandle | undefined\n let spawnPromise: Promise<ExecutionHandle> | undefined\n let disposed = false\n let disposePromise: Promise<void> | undefined\n\n const ensureHandle = (config?: Parameters<ExecutionContext['spawn']>[0]): Promise<ExecutionHandle> => {\n if (disposed)\n throw new Error('Reusable execution context has been disposed')\n if (handle)\n return Promise.resolve(handle)\n spawnPromise ??= base.spawn(config).then((next) => {\n handle = next\n return next\n }, (err) => {\n spawnPromise = undefined\n throw err\n })\n return spawnPromise\n }\n\n const execution: ExecutionContext = {\n ...base,\n async spawn(config) {\n return ensureHandle(config)\n },\n async destroy() {\n // Agent-level destroy means \"end this turn\"; the eval fixture owns the\n // actual execution lifetime and calls dispose() at test teardown.\n },\n }\n\n return {\n execution,\n // Memoize so concurrent dispose()/asyncDispose() calls share one teardown\n // and never run base.destroy twice or orphan an in-flight spawn.\n dispose() {\n disposePromise ??= (async () => {\n disposed = true\n const active = handle ?? await spawnPromise?.catch(() => undefined)\n handle = undefined\n spawnPromise = undefined\n if (active)\n await base.destroy(active)\n })()\n return disposePromise\n },\n handle: () => handle,\n }\n}\n\nexport interface EvalAgentRunStats extends EvalRunUsage {\n durationMs: number\n turns: number\n toolCalls: number\n}\n\nexport interface EvalAgentStats extends EvalRunUsage {\n /** Number of completed `run()` calls. */\n runs: number\n /** Sum of per-run agent turns. */\n turns: number\n /** Sum of per-run tool calls. */\n toolCalls: number\n /** Sum of per-run wall-clock durations. */\n durationMs: number\n}\n\nexport interface EvalAgentRunResult {\n /** Full headless result. Its transcript is scoped to this run. */\n result: HeadlessResult\n /** Per-run usage and trajectory counters. */\n stats: EvalAgentRunStats\n /** Transcript turns added by this run (same view as `result.transcript`). */\n newTranscript: SessionTurn[]\n}\n\nexport type EvalAgentMcpServers\n = | readonly McpServerConfig[]\n | (() => readonly McpServerConfig[] | Promise<readonly McpServerConfig[]>)\n\nexport interface CreateEvalAgentOptions extends Omit<HeadlessOptions, 'prompt' | 'provider' | 'execution' | 'cwd' | 'session' | 'store' | 'mcpServers' | 'onEvent' | 'signal'> {\n provider: Provider\n /**\n * Working directory for the default process context. Ignored when\n * `execution` is supplied.\n */\n cwd?: string\n /**\n * Execution context for agent tools. Wrapped with\n * `createReusableExecutionContext` so runs share one handle until `dispose`.\n */\n execution?: ExecutionContext\n /** Session to reuse across runs. When omitted, one in-memory session is created. */\n session?: Session\n /** Store used for the auto-created session. Defaults to an in-memory store. */\n store?: SessionStore\n /** Static or lazily resolved MCP servers. Resolved fresh before each run. */\n mcpServers?: EvalAgentMcpServers\n /** Live event callback for every run. */\n onEvent?: (event: HeadlessEvent) => void\n}\n\nexport interface EvalAgentRunOptions extends Omit<HeadlessOptions, 'provider' | 'execution' | 'cwd' | 'session' | 'store'> {\n prompt: HeadlessOptions['prompt']\n}\n\nexport interface EvalAgent {\n run: (options: EvalAgentRunOptions) => Promise<EvalAgentRunResult>\n readonly stats: EvalAgentStats\n session: () => Promise<Session>\n dispose: () => Promise<void>\n [Symbol.asyncDispose]: () => Promise<void>\n}\n\n/**\n * Multi-turn eval agent over the low-level headless runner. It keeps session\n * and execution lifetime outside any Playwright/Bolt-specific fixture layer,\n * so downstream platforms can wrap it with their own `agent.run(...)` shape.\n */\nexport function createEvalAgent(options: CreateEvalAgentOptions): EvalAgent {\n const {\n cwd,\n execution,\n session: initialSession,\n store: initialStore,\n mcpServers: baseMcpServers,\n onEvent: baseOnEvent,\n ...headlessDefaults\n } = options\n const executionOwner = createReusableExecutionContext(execution ?? createProcessContext({ cwd }))\n const store = initialStore ?? createMemoryStore()\n let sessionPromise: Promise<Session> | undefined = initialSession ? Promise.resolve(initialSession) : undefined\n let disposed = false\n let runInFlight = false\n let disposePromise: Promise<void> | undefined\n\n const stats: EvalAgentStats = {\n runs: 0,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheCreation: 0,\n cost: 0,\n turns: 0,\n toolCalls: 0,\n durationMs: 0,\n }\n\n async function getSession(): Promise<Session> {\n if (disposed)\n throw new Error('Eval agent has been disposed')\n sessionPromise ??= createSession({ store })\n return sessionPromise\n }\n\n async function resolveMcpServers(\n runServers: HeadlessOptions['mcpServers'] | undefined,\n ): Promise<McpServerConfig[] | undefined> {\n const base = typeof baseMcpServers === 'function'\n ? await baseMcpServers()\n : baseMcpServers\n const merged = [\n ...(base ?? []),\n ...(runServers ?? []),\n ]\n return merged.length > 0 ? [...merged] : undefined\n }\n\n async function run(runOptions: EvalAgentRunOptions): Promise<EvalAgentRunResult> {\n if (runInFlight)\n throw new Error('Eval agent already has a run in progress')\n runInFlight = true\n try {\n const session = await getSession()\n const { mcpServers: runMcpServers, onEvent: runOnEvent, ...restRunOptions } = runOptions\n const mcpServers = await resolveMcpServers(runMcpServers)\n\n const result = await runHeadless({\n ...headlessDefaults,\n ...restRunOptions,\n session,\n execution: executionOwner.execution,\n ...(mcpServers ? { mcpServers } : {}),\n onEvent(event) {\n baseOnEvent?.(event)\n runOnEvent?.(event)\n },\n })\n\n // `result.transcript` is already scoped to this run (runHeadless slices\n // from the resumed session's prior length), so it IS the new turns.\n const newTranscript = result.transcript.slice()\n const runStats: EvalAgentRunStats = {\n input: result.usage.input,\n output: result.usage.output,\n cacheRead: result.usage.cacheRead,\n cacheCreation: result.usage.cacheCreation,\n cost: result.usage.cost ?? 0,\n durationMs: result.durationMs,\n turns: result.turns,\n toolCalls: countToolCallsInTurns(newTranscript),\n }\n accumulateEvalAgentStats(stats, runStats)\n\n return { result, stats: runStats, newTranscript }\n }\n finally {\n runInFlight = false\n }\n }\n\n function dispose(): Promise<void> {\n // Memoize: concurrent dispose()/asyncDispose() share one teardown.\n disposePromise ??= (async () => {\n disposed = true\n await executionOwner.dispose()\n })()\n return disposePromise\n }\n\n return {\n run,\n stats,\n session: getSession,\n dispose,\n [Symbol.asyncDispose]: dispose,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Trajectory\n// ---------------------------------------------------------------------------\n\nexport type TrajectoryStepKind = 'think' | 'text' | 'tool'\n\n/**\n * One grouped step in an eval trajectory. Consecutive blocks of the same kind\n * (and, for tools, the same tool name) collapse into a single step with a\n * `count`. A different kind interrupting the run breaks the group.\n *\n * Serializable by design so trajectories round-trip to disk and can be diffed\n * or replayed by other tooling.\n */\nexport interface TrajectoryStep {\n kind: TrajectoryStepKind\n /** Tool name for `kind: 'tool'` steps (canonical, e.g. `read_file`). */\n name?: string\n /** Number of consecutive occurrences grouped into this step. */\n count: number\n /** Approx wall-clock ms attributed to this step's turns, when derivable. */\n durationMs?: number\n}\n\nexport interface Trajectory {\n steps: TrajectoryStep[]\n /** Total blocks across all steps (sum of `count`). */\n totalBlocks: number\n}\n\n/**\n * Build an ordered, grouped trajectory from a transcript. Walks assistant\n * turns in order, emitting `think` / `text` / `tool:<name>` steps, grouping\n * only consecutive identical kinds. Per-step duration is approximated from the\n * owning turn's `createdAt` delta to the next turn.\n */\nexport function buildTrajectory(transcript: SessionTurn[]): Trajectory {\n const steps: TrajectoryStep[] = []\n let total = 0\n\n const push = (kind: TrajectoryStepKind, name: string | undefined, durationMs: number): void => {\n total++\n const last = steps[steps.length - 1]\n if (last && last.kind === kind && last.name === name) {\n last.count++\n if (durationMs > 0)\n last.durationMs = (last.durationMs ?? 0) + durationMs\n return\n }\n steps.push({ kind, ...(name ? { name } : {}), count: 1, ...(durationMs > 0 ? { durationMs } : {}) })\n }\n\n for (let i = 0; i < transcript.length; i++) {\n const turn = transcript[i]\n if (turn.role !== 'assistant')\n continue\n const next = transcript[i + 1]\n const turnDuration = next ? Math.max(0, next.createdAt - turn.createdAt) : 0\n const blocks = turn.content.filter(b => b.type === 'thinking' || b.type === 'redacted_thinking' || b.type === 'text' || b.type === 'tool_call')\n // Attribute the turn's elapsed time to its tool calls — that's where the\n // wall-clock actually goes (provider stream + tool execution). think/text\n // blocks within the turn carry no separate timing. Split evenly across the\n // turn's tool calls and round to whole ms so the timeline reads cleanly.\n const toolBlocks = blocks.filter(b => b.type === 'tool_call').length\n const perTool = toolBlocks > 0 ? Math.round(turnDuration / toolBlocks) : 0\n for (const block of blocks) {\n if (block.type === 'thinking' || block.type === 'redacted_thinking')\n push('think', undefined, 0)\n else if (block.type === 'text')\n push('text', undefined, 0)\n else if (block.type === 'tool_call')\n push('tool', block.name, perTool)\n }\n }\n\n return { steps, totalBlocks: total }\n}\n\n/** Render a trajectory as a one-line timeline string (no color). */\nexport function formatTrajectoryLine(trajectory: Trajectory): string {\n return trajectory.steps.map(stepLabel).join(' → ')\n}\n\nfunction stepLabel(step: TrajectoryStep): string {\n const base = step.kind === 'tool' ? (step.name ?? 'tool') : step.kind\n return step.count > 1 ? `${base} ×${step.count}` : base\n}\n\nexport interface EvalArtifacts {\n dir: string\n result?: string\n events?: string\n transcript?: string\n workspace?: string\n}\n\nexport interface EvalCaseResult {\n id: string\n suite?: string\n /** Run variant this result belongs to (e.g. `baseten:zai-org/GLM-5.1`). */\n variant?: string\n tags: string[]\n result: HeadlessResult\n /** Mean normalized metric score in [0, 1] when metrics are declared; otherwise mean scorer score. */\n score: number\n /** True when every scorer passed. */\n passed: boolean\n scores: EvalScore[]\n /** Normalized metrics for this case (empty when no metrics declared). */\n metrics: EvalMetric[]\n /** Mean normalized score per tag, e.g. `{ '@efficiency': 0.8 }`. */\n tagScores: Record<string, number>\n /** Ordered, grouped step timeline derived from the transcript. */\n trajectory: Trajectory\n events: HeadlessEvent[]\n artifacts?: EvalArtifacts\n workspace?: EvalWorkspaceSnapshot\n workspaceError?: string\n /** Absolute path to the eval definition file, for editor links. */\n sourceFile?: string\n}\n\nexport interface EvalCaseOptions extends Omit<HeadlessOptions, 'onEvent'> {\n id: string\n suite?: string\n /**\n * Run variant label when the same eval runs against several provider/model\n * targets in one run (e.g. `baseten:zai-org/GLM-5.1`). Flows into\n * {@link EvalCaseResult.variant}, namespaces artifacts, and drives the\n * reporter's per-variant tables + comparison matrix.\n */\n variant?: string\n tags?: string[]\n artifactDir?: string\n workspace?: EvalWorkspaceOptions\n scorers?: EvalScorer[]\n /**\n * Declared metric set. Auto-merged with {@link EFFICIENCY_METRICS} so every\n * eval gets comparable efficiency metrics for free. All declared metrics must\n * be emitted (via auto-emit or `ctx.metric`) or the run throws.\n */\n metrics?: MetricSpecMap\n onEvent?: (event: HeadlessEvent) => void\n /** Absolute path to the eval definition file. Set via `import.meta.url`. */\n sourceFile?: string\n}\n\nexport interface EvalRunUsage {\n input: number\n output: number\n cacheRead: number\n cacheCreation: number\n cost: number\n}\n\nexport interface EvalRunSummaryCase {\n id: string\n suite?: string\n variant?: string\n passed: boolean\n score: number\n status: HeadlessResult['status']\n durationMs: number\n scores: EvalScore[]\n metrics: EvalMetric[]\n tagScores: Record<string, number>\n trajectory: Trajectory\n}\n\nexport interface MetricStats {\n mean: number\n min: number\n max: number\n p50: number\n p90: number\n zeroCount: number\n values: number[]\n}\n\nexport interface EvalRunMetricAggregate {\n id: string\n direction: MetricDirection\n tags: string[]\n raw: MetricStats\n normalized: MetricStats\n}\n\n/** Aggregate rollup for one run variant (provider/model target). */\nexport interface EvalVariantSummary {\n variant: string\n count: number\n passed: number\n score: number\n durationMs: number\n usage: EvalRunUsage\n}\n\nexport interface EvalRunSummary {\n count: number\n passed: number\n score: number\n durationMs: number\n usage: EvalRunUsage\n cases: EvalRunSummaryCase[]\n /** Per-metric stats across every case that emitted the metric. */\n metrics: EvalRunMetricAggregate[]\n /** Mean normalized score per tag across all cases. */\n tagScores: Record<string, number>\n /** Per-variant rollups, present when any case carries a variant label. */\n variants?: EvalVariantSummary[]\n}\n\nexport interface EvalRunReporterOptions {\n /** Directory where per-case results and `run-summary.json` are written. */\n outputDir?: string\n /** Enable ANSI colors. Defaults to TTY-aware auto color. */\n color?: boolean\n}\n\nexport interface EvalRunReporter {\n readonly results: readonly EvalCaseResult[]\n record: (result: EvalCaseResult) => Promise<void>\n flush: () => Promise<EvalRunSummary>\n format: () => string\n}\n\n/** Context handed to an eval definition factory at registration time. */\nexport interface EvalDefinitionContext {\n /** Agent-under-test provider. */\n provider: Provider\n /** Provider used by `llmJudge` scorers. Defaults to `provider`. */\n judge: Provider\n /** Optional agent model override; evals should pass it to `EvalCaseOptions.model`. */\n model?: string\n /** Optional judge model override; evals should pass it to `llmJudge({ model })`. */\n judgeModel?: string\n}\n\nexport type EvalDefinition = (ctx: EvalDefinitionContext) => EvalCaseOptions\n\ninterface RegisteredEval {\n id: string\n define: EvalDefinition\n}\n\nconst evalRegistry: RegisteredEval[] = []\n\nconst STUB_PROVIDER = {\n name: 'stub',\n meta: { defaultModel: 'stub' },\n formatTools: (tools: unknown[]) => tools,\n userMessage: () => ({ role: 'user' as const, content: [] }),\n assistantMessage: () => ({ role: 'assistant' as const, content: [] }),\n toolResultsMessage: () => ({ role: 'user' as const, content: [] }),\n stream: async () => {\n throw new Error('stub provider is not runnable')\n },\n} as unknown as Provider\n\n/**\n * Register an eval definition. Eval files call this at module load; the harness\n * (`buildRegisteredEvals`) materializes them with a provider at run time. The\n * factory keeps definitions lazy so a single registry serves any provider/judge\n * pairing without re-importing eval files.\n *\n * Returns the same factory so a file can also `export default` it for direct,\n * registry-free use (e.g. hermetic unit tests).\n */\nexport function defineEval(define: EvalDefinition): EvalDefinition {\n // De-dupe by materializing once with a stub provider to read the id. The stub\n // is never streamed; it only exists so the registry can key on suite/id and a\n // re-imported module doesn't double-register.\n const id = safeRegistryId(define)\n if (!evalRegistry.some(entry => entry.id === id))\n evalRegistry.push({ id, define })\n return define\n}\n\n/** Snapshot of every registered eval, materialized for one provider/judge pair. */\nexport function buildRegisteredEvals(ctx: EvalDefinitionContext): EvalCaseOptions[] {\n return evalRegistry.map(entry => entry.define(ctx))\n}\n\n/** Drop every registered eval — test isolation helper. */\nexport function clearRegisteredEvals(): void {\n evalRegistry.length = 0\n}\n\nfunction safeRegistryId(define: EvalDefinition): string {\n try {\n const stub = define({ provider: STUB_PROVIDER, judge: STUB_PROVIDER })\n return `${stub.suite ?? 'eval'}/${stub.id}`\n }\n catch {\n return `eval/${evalRegistry.length}`\n }\n}\n\nconst DEFAULT_JUDGE_SYSTEM = [\n 'You are a strict software eval judge.',\n 'Grade only the supplied output against the rubric.',\n 'Call the `submit_grade` tool with your score and reasoning.',\n 'The score must be between 0 and 1.',\n].join('\\n')\n\n/** Forced-output tool the judge must call — the schema-enforcement path. */\nconst JUDGE_TOOL: ToolSpec = {\n name: 'submit_grade',\n description: 'Submit the grade for the output under evaluation.',\n inputSchema: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1, description: 'Quality score from 0 (worst) to 1 (best).' },\n reasoning: { type: 'string', description: 'Brief justification for the score.' },\n feedback: { type: 'string', description: 'Optional actionable feedback.' },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n },\n}\n\nexport async function runEvalCase(options: EvalCaseOptions): Promise<EvalCaseResult> {\n const {\n id,\n suite,\n variant,\n tags = [],\n artifactDir,\n workspace,\n scorers = [],\n onEvent,\n ...headless\n } = options\n\n const { metrics: declaredMetrics, sourceFile, ...headlessRest } = headless\n const events: HeadlessEvent[] = []\n // Variant-aware artifact layout: <dir>[/<variant>]/<suite>/<id> so the same\n // case run against two models never overwrites its own output.\n const caseArtifactDir = artifactDir\n ? join(artifactDir, ...(variant ? [safeSegment(variant)] : []), safeSegment(suite ?? 'eval'), safeSegment(id))\n : undefined\n const workspaceState = await prepareWorkspace(headlessRest.execution, workspace)\n const caseMetricIds = new Set(Object.keys(declaredMetrics ?? {}))\n const hasCaseMetrics = caseMetricIds.size > 0\n\n // Merge declared metrics with the always-on efficiency set.\n const metricSpecs: MetricSpecMap = { ...EFFICIENCY_METRICS, ...declaredMetrics }\n const rawMetrics = new Map<string, number>()\n const emitMetric: MetricEmitter = (metricId, raw) => {\n if (!(metricId in metricSpecs))\n throw new EvalMetricError(`Eval ${id}: metric \"${metricId}\" emitted but not declared in defineMetrics`)\n if (!Number.isFinite(raw))\n throw new EvalMetricError(`Eval ${id}: metric \"${metricId}\" emitted a non-finite value (${raw}); scores require finite numbers`)\n rawMetrics.set(metricId, raw)\n }\n\n try {\n const result = await runHeadless({\n ...headlessRest,\n ...(workspaceState.execution ? { execution: workspaceState.execution } : {}),\n onEvent(event) {\n events.push(event)\n onEvent?.(event)\n },\n })\n\n // Auto-emit efficiency metrics from the headless result.\n emitEfficiencyMetrics(emitMetric, result)\n\n const workspaceSnapshot = workspaceState.snapshot()\n const workspaceError = workspaceState.error()\n const scorerContext: EvalScorerContext = {\n id,\n ...(suite ? { suite } : {}),\n tags,\n result,\n events,\n metric: emitMetric,\n ...(workspaceSnapshot ? { workspace: workspaceSnapshot } : {}),\n ...(caseArtifactDir ? { artifactDir: caseArtifactDir } : {}),\n }\n const scores = await runScorers(scorerContext, scorers)\n\n const metrics = finalizeEvalMetrics(metricSpecs, rawMetrics)\n const tagScores = computeEvalTagScores(metrics)\n // Score is metric-driven when metrics are declared beyond efficiency;\n // otherwise fall back to scorer aggregation for back-compat. If the declared\n // set somehow filters to empty, fall back too (avoid a meaningless 0 score).\n const caseMetrics = metrics.filter(metric => caseMetricIds.has(metric.id))\n const score = hasCaseMetrics && caseMetrics.length > 0\n ? meanNormalized(caseMetrics)\n : aggregateScore(scores)\n\n const evalResult: EvalCaseResult = {\n id,\n ...(suite ? { suite } : {}),\n ...(variant ? { variant } : {}),\n tags,\n result,\n score,\n passed: result.status === 'completed' && scores.every(score => score.passed),\n scores,\n metrics,\n tagScores,\n trajectory: buildTrajectory(result.transcript),\n events,\n ...(sourceFile ? { sourceFile } : {}),\n ...(workspaceSnapshot ? { workspace: workspaceSnapshot } : {}),\n ...(workspaceError ? { workspaceError } : {}),\n }\n\n const artifacts = caseArtifactDir\n ? await writeEvalArtifacts(caseArtifactDir, evalResult)\n : undefined\n\n return {\n ...evalResult,\n ...(artifacts ? { artifacts } : {}),\n }\n }\n finally {\n await workspaceState.cleanup()\n }\n}\n\nexport function statusCompleted(name = 'status.completed'): EvalScorer {\n return ({ result }) => ({\n name,\n passed: result.status === 'completed',\n score: result.status === 'completed' ? 1 : 0,\n details: result.status === 'completed' ? undefined : { status: result.status, error: result.error },\n })\n}\n\nexport function fileExists(path: string, name = `file.exists:${path}`): EvalScorer {\n return ({ workspace }) => {\n const found = workspace?.files.some(file => file.path === path) ?? false\n return {\n name,\n passed: found,\n score: found ? 1 : 0,\n details: found ? undefined : `Missing ${path}`,\n }\n }\n}\n\nexport function fileExistsOneOf(paths: string[], name = `file.existsOneOf:${paths.join('|')}`): EvalScorer {\n return ({ workspace }) => {\n const found = paths.find(path => workspace?.files.some(file => file.path === path))\n return {\n name,\n passed: Boolean(found),\n score: found ? 1 : 0,\n details: found ? undefined : `Missing one of: ${paths.join(', ')}`,\n }\n }\n}\n\nexport function fileContains(path: string, expected: string | RegExp, name = `file.contains:${path}`): EvalScorer {\n return ({ workspace }) => {\n const file = workspace?.files.find(file => file.path === path)\n const content = file?.content ?? ''\n const passed = typeof expected === 'string' ? content.includes(expected) : expected.test(content)\n return {\n name,\n passed,\n score: passed ? 1 : 0,\n details: passed\n ? undefined\n : file\n ? `Expected ${path} to contain ${String(expected)}`\n : `Missing ${path}`,\n }\n }\n}\n\nexport function fileContentQuality(\n path: string,\n expected: string,\n name = `file.quality:${path}`,\n): EvalScorer {\n return ({ workspace }) => {\n const file = workspace?.files.find(file => file.path === path)\n const content = file?.content\n if (content === undefined) {\n return {\n name,\n passed: false,\n score: 0,\n details: `Missing ${path}`,\n }\n }\n\n const normalized = content.trim()\n const expectedNormalized = expected.trim()\n const score = normalized === expectedNormalized\n ? 1\n : normalized.includes(expectedNormalized)\n ? 0.75\n : content.includes(expected)\n ? 0.5\n : 0\n\n return {\n name,\n passed: score >= 0.75,\n score,\n details: score >= 0.75 ? undefined : `Expected ${path} to closely match ${JSON.stringify(expectedNormalized)}`,\n }\n }\n}\n\nexport function llmJudge(options: LlmJudgeOptions): EvalScorer {\n const name = options.name ?? 'llm.judge'\n const model = options.model ?? options.provider.meta.defaultModel\n return async (ctx) => {\n const userMessage = options.provider.userMessage(renderJudgePrompt({\n rubric: options.rubric,\n input: options.input?.(ctx) ?? defaultJudgeInput(ctx),\n }))\n\n // Primary: forced structured output via a single tool call. This is the\n // same enforcement the agent loop uses for `schema`, and it works on any\n // tool-calling provider (Anthropic, OpenAI, Cerebras, OpenRouter, ...).\n let text = ''\n const controller = new AbortController()\n const timeoutMs = options.timeoutMs ?? 60_000\n let timedOut = false\n const timer = timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true\n controller.abort(new Error(`LLM judge timed out after ${timeoutMs}ms`))\n }, timeoutMs)\n : undefined\n\n try {\n const streamPromise = options.provider.stream({\n model,\n system: options.system ?? DEFAULT_JUDGE_SYSTEM,\n tools: options.provider.formatTools([JUDGE_TOOL]),\n messages: [userMessage],\n maxTokens: options.maxTokens ?? 600,\n cache: false,\n signal: controller.signal,\n toolChoice: { type: 'tool', name: JUDGE_TOOL.name },\n }, {\n onText(delta) {\n text += delta\n },\n })\n const timeoutPromise = timeoutMs > 0\n ? new Promise<never>((_resolve, reject) => {\n controller.signal.addEventListener('abort', () => {\n if (timedOut)\n reject(new Error(`LLM judge timed out after ${timeoutMs}ms`))\n }, { once: true })\n })\n : undefined\n const result = timeoutPromise\n ? await Promise.race([streamPromise, timeoutPromise])\n : await streamPromise\n\n const parsed = readJudgeResult(result.toolCalls, text || result.text)\n if (options.metric)\n ctx.metric(options.metric, parsed.score)\n return {\n name,\n passed: parsed.score >= 0.7,\n score: parsed.score,\n details: {\n reasoning: parsed.reasoning,\n ...(parsed.feedback ? { feedback: parsed.feedback } : {}),\n ...(parsed.raw ? { raw: parsed.raw } : {}),\n usage: result.usage,\n },\n }\n }\n finally {\n if (timer)\n clearTimeout(timer)\n }\n }\n}\n\nfunction readJudgeResult(\n toolCalls: ToolCall[],\n fallbackText: string,\n): { score: number, reasoning: string, feedback?: string, raw?: string } {\n // Preferred: the forced tool call carries typed fields.\n const call = toolCalls.find(tc => tc.name === JUDGE_TOOL.name)\n if (call) {\n const input = call.input as { score?: unknown, reasoning?: unknown, feedback?: unknown }\n return {\n score: clampScore(input.score),\n reasoning: typeof input.reasoning === 'string' ? input.reasoning : '',\n ...(typeof input.feedback === 'string' ? { feedback: input.feedback } : {}),\n }\n }\n // Fallback: a provider that ignored tool-forcing and returned text. The\n // lenient parser recovers a score from JSON/prose/bare-number output.\n return parseJudgeOutput(fallbackText)\n}\n\n/**\n * Aggregate a group of boolean scorers into a single `0..1` functionality\n * metric (fraction passed) and emit it. Useful for \"N of M files present\".\n */\nexport function functionalityMetric(metricId: string, scorers: EvalScorer[], name = metricId): EvalScorer {\n return async (ctx) => {\n const results = await runScorers(ctx, scorers)\n const passed = results.filter(r => r.passed).length\n const fraction = results.length === 0 ? 1 : passed / results.length\n ctx.metric(metricId, fraction)\n return {\n name,\n passed: passed === results.length,\n score: fraction,\n details: { passed, total: results.length, checks: results.map(r => ({ name: r.name, passed: r.passed })) },\n }\n }\n}\n\nexport function formatEvalCaseSummary(result: EvalCaseResult): string {\n const lines = [\n `Eval ${result.suite ? `${result.suite}/` : ''}${result.id}`,\n ...(result.variant ? [`variant: ${result.variant}`] : []),\n `status: ${result.result.status}`,\n `passed: ${result.passed}`,\n `score: ${result.score.toFixed(2)}`,\n `duration: ${result.result.durationMs}ms`,\n `turns: ${result.result.turns}`,\n `tool calls: ${result.result.numToolCalls}`,\n `usage: input=${result.result.usage.input} output=${result.result.usage.output} cacheRead=${result.result.usage.cacheRead} cacheCreation=${result.result.usage.cacheCreation}${result.result.usage.cost !== undefined ? ` cost=$${result.result.usage.cost.toFixed(6)}` : ''}`,\n ]\n\n if (result.workspace) {\n lines.push(`workspace files: ${result.workspace.files.length}`)\n }\n if (result.workspaceError) {\n lines.push(`workspace error: ${result.workspaceError}`)\n }\n if (result.artifacts) {\n lines.push(`artifacts: ${result.artifacts.dir}`)\n }\n\n if (result.scores.length > 0) {\n lines.push('scores:')\n for (const score of result.scores) {\n const value = score.score !== undefined ? score.score.toFixed(2) : score.passed ? '1.00' : '0.00'\n lines.push(` - ${score.name}: ${value} ${score.passed ? 'pass' : 'fail'}`)\n if (typeof score.details === 'string' && score.details.length > 0)\n lines.push(` ${score.details}`)\n else if (isRecord(score.details) && typeof score.details.reasoning === 'string')\n lines.push(` ${score.details.reasoning}`)\n }\n }\n\n return lines.join('\\n')\n}\n\nexport function formatEvalRunSummary(results: readonly EvalCaseResult[]): string {\n return formatEvalRunSummaryWithOptions(results)\n}\n\n/** Minimal subset of a test runner's API the eval harness needs. */\nexport interface EvalTestRunner {\n it: (name: string, fn: () => Promise<void> | void) => void\n afterAll: (fn: () => Promise<void> | void) => void\n}\n\nexport interface RegisterEvalTestsOptions {\n cases: EvalCaseOptions[]\n runner: EvalTestRunner\n reporter?: EvalRunReporter\n artifactDir?: string\n /**\n * When true (default), each case asserts only that the agent run reached a\n * terminal `completed` status — scores are recorded but never fail the test.\n * Evals are scoring tools, not deterministic assertions.\n */\n failOnIncomplete?: boolean\n /** Print the aggregated run summary after all cases. Default true. */\n printSummary?: boolean\n /** Repeat each case N times (each repetition is its own test). Default 1. */\n repeat?: number\n /** Teardown run once after all cases (e.g. dispose a shared container). */\n dispose?: () => Promise<void> | void\n /**\n * Max eval cases to run concurrently. Each case keeps its own workspace dir,\n * so a shared container runs them in parallel safely. Default 1 (sequential).\n */\n concurrency?: number\n}\n\n/**\n * Register one test per eval case against a test runner, funnel every result\n * into a shared reporter, and print the aggregated summary once after all cases.\n *\n * A failing test means the agent run itself broke (provider/tool/timeout). Low\n * scores are reported, not asserted — see {@link RegisterEvalTestsOptions.failOnIncomplete}.\n */\nexport function registerEvalTests(options: RegisterEvalTestsOptions): EvalRunReporter {\n const reporter = options.reporter ?? createEvalRunReporter()\n const failOnIncomplete = options.failOnIncomplete ?? true\n const printSummary = options.printSummary ?? true\n const repeat = Math.max(1, options.repeat ?? 1)\n const concurrency = Math.max(1, options.concurrency ?? 1)\n\n options.runner.afterAll(async () => {\n await reporter.flush()\n if (printSummary)\n console.log(`\\n${reporter.format()}\\n`)\n if (options.dispose)\n await options.dispose()\n })\n\n // Build the (case × repeat) work list. Each entry runs exactly once; the\n // matching `it` test awaits its already-scheduled promise so bun still shows\n // per-case pass/fail while the pool drives real parallelism.\n const work: Array<{ label: string, run: () => Promise<EvalCaseResult> }> = []\n for (const evalCase of options.cases) {\n const caseLabel = `${evalCase.suite ? `${evalCase.suite}/` : ''}${evalCase.id}`\n const baseLabel = evalCase.variant ? `[${evalCase.variant}] ${caseLabel}` : caseLabel\n for (let run = 1; run <= repeat; run++) {\n const label = repeat > 1 ? `${baseLabel} #${run}` : baseLabel\n const caseId = repeat > 1 ? `${evalCase.id}-repeat-${run}` : evalCase.id\n work.push({\n label,\n run: () => runEvalCase({\n ...evalCase,\n id: caseId,\n ...(options.artifactDir ? { artifactDir: options.artifactDir } : {}),\n }),\n })\n }\n }\n\n const schedule = createLazyPool(concurrency)\n\n work.forEach((w) => {\n options.runner.it(w.label, async () => {\n const result = await schedule(w.run)\n await reporter.record(result)\n if (failOnIncomplete && result.result.status !== 'completed') {\n throw new Error(`Eval ${w.label} did not complete: ${JSON.stringify(result.result.error ?? { status: result.result.status }, null, 2)}`)\n }\n })\n })\n\n return reporter\n}\n\n/**\n * Lazily run tasks with a bounded concurrency `limit`. Nothing starts until a\n * runner invokes the corresponding test callback, so filtered/skipped tests do\n * not leak model or Docker work in the background.\n */\nfunction createLazyPool(limit: number): <T>(task: () => Promise<T>) => Promise<T> {\n const queue: Array<() => void> = []\n let active = 0\n\n const drain = (): void => {\n const available = Math.min(limit - active, queue.length)\n for (let i = 0; i < available; i++)\n queue.shift()?.()\n }\n\n return <T>(task: () => Promise<T>) => new Promise<T>((resolve, reject) => {\n const run = async (): Promise<void> => {\n active++\n try {\n resolve(await task())\n }\n catch (err) {\n reject(err)\n }\n finally {\n active--\n drain()\n }\n }\n queue.push(() => void run())\n drain()\n })\n}\n\nexport function createEvalRunReporter(options: EvalRunReporterOptions = {}): EvalRunReporter {\n const results: EvalCaseResult[] = []\n\n return {\n get results() {\n return results\n },\n async record(result) {\n results.push(result)\n if (options.outputDir) {\n const segments = [\n ...(result.variant ? [safeSegment(result.variant)] : []),\n safeSegment(result.suite ?? 'eval'),\n safeSegment(result.id),\n ]\n const casePath = join(options.outputDir, 'cases', `${segments.join('--')}.json`)\n await mkdir(join(options.outputDir, 'cases'), { recursive: true })\n await writeFile(casePath, `${JSON.stringify(result, null, 2)}\\n`)\n }\n },\n async flush() {\n const summary = buildEvalRunSummary(results)\n if (options.outputDir) {\n await mkdir(options.outputDir, { recursive: true })\n await writeFile(join(options.outputDir, 'run-summary.json'), `${JSON.stringify(summary, null, 2)}\\n`)\n }\n return summary\n },\n format() {\n return formatEvalRunSummaryWithOptions(results, { color: options.color })\n },\n }\n}\n\n/** Stable ordering by `variant`, then `suite/id`, so parallel completion order doesn't shuffle output. */\nfunction sortCases(results: readonly EvalCaseResult[]): EvalCaseResult[] {\n return [...results].sort((a, b) => {\n const va = a.variant ?? ''\n const vb = b.variant ?? ''\n if (va !== vb)\n return va.localeCompare(vb)\n const ka = `${a.suite ?? ''}/${a.id}`\n const kb = `${b.suite ?? ''}/${b.id}`\n return ka.localeCompare(kb)\n })\n}\n\n/** Distinct variant labels across results, in sorted order. */\nfunction distinctVariants(results: readonly EvalCaseResult[]): string[] {\n return [...new Set(results.map(r => r.variant).filter((v): v is string => Boolean(v)))].sort()\n}\n\nexport function buildEvalRunSummary(input: readonly EvalCaseResult[]): EvalRunSummary {\n const results = sortCases(input)\n const usage = results.reduce((acc, result) => {\n acc.input += result.result.usage.input\n acc.output += result.result.usage.output\n acc.cacheRead += result.result.usage.cacheRead\n acc.cacheCreation += result.result.usage.cacheCreation\n acc.cost += result.result.usage.cost ?? 0\n return acc\n }, { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, cost: 0 })\n const totalScore = results.reduce((sum, result) => sum + result.score, 0)\n\n return {\n count: results.length,\n passed: results.filter(result => result.passed).length,\n score: results.length > 0 ? totalScore / results.length : 0,\n durationMs: results.reduce((sum, result) => sum + result.result.durationMs, 0),\n usage,\n cases: results.map(result => ({\n id: result.id,\n ...(result.suite ? { suite: result.suite } : {}),\n ...(result.variant ? { variant: result.variant } : {}),\n passed: result.passed,\n score: result.score,\n status: result.result.status,\n durationMs: result.result.durationMs,\n scores: result.scores,\n metrics: result.metrics,\n tagScores: result.tagScores,\n trajectory: result.trajectory,\n })),\n metrics: aggregateMetrics(results),\n tagScores: aggregateTagScores(results),\n ...(distinctVariants(results).length > 0 ? { variants: aggregateVariants(results) } : {}),\n }\n}\n\nfunction aggregateVariants(results: readonly EvalCaseResult[]): EvalVariantSummary[] {\n return distinctVariants(results).map((variant) => {\n const group = results.filter(r => r.variant === variant)\n const usage = group.reduce((acc, result) => {\n acc.input += result.result.usage.input\n acc.output += result.result.usage.output\n acc.cacheRead += result.result.usage.cacheRead\n acc.cacheCreation += result.result.usage.cacheCreation\n acc.cost += result.result.usage.cost ?? 0\n return acc\n }, { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, cost: 0 })\n return {\n variant,\n count: group.length,\n passed: group.filter(r => r.passed).length,\n score: mean(group.map(r => r.score)),\n durationMs: group.reduce((sum, r) => sum + r.result.durationMs, 0),\n usage,\n }\n })\n}\n\nfunction aggregateMetrics(results: readonly EvalCaseResult[]): EvalRunMetricAggregate[] {\n const byId = new Map<string, EvalMetric[]>()\n for (const result of results) {\n for (const metric of result.metrics) {\n const list = byId.get(metric.id) ?? []\n list.push(metric)\n byId.set(metric.id, list)\n }\n }\n return [...byId.entries()].map(([id, metrics]) => ({\n id,\n direction: metrics[0].direction,\n tags: metrics[0].tags,\n raw: metricStats(metrics.map(m => m.raw)),\n normalized: metricStats(metrics.map(m => m.normalized)),\n }))\n}\n\nfunction aggregateTagScores(results: readonly EvalCaseResult[]): Record<string, number> {\n const byTag = new Map<string, number[]>()\n for (const result of results) {\n for (const [tag, value] of Object.entries(result.tagScores)) {\n const list = byTag.get(tag) ?? []\n list.push(value)\n byTag.set(tag, list)\n }\n }\n const out: Record<string, number> = {}\n for (const [tag, values] of byTag)\n out[tag] = mean(values)\n return out\n}\n\nfunction metricStats(values: number[]): MetricStats {\n const sorted = [...values].sort((a, b) => a - b)\n return {\n mean: mean(values),\n min: sorted[0] ?? 0,\n max: sorted[sorted.length - 1] ?? 0,\n p50: percentile(sorted, 0.5),\n p90: percentile(sorted, 0.9),\n zeroCount: values.filter(v => v === 0).length,\n values,\n }\n}\n\nfunction percentile(sorted: number[], q: number): number {\n if (sorted.length === 0)\n return 0\n const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(q * sorted.length) - 1))\n return sorted[idx]\n}\n\nfunction formatEvalRunSummaryWithOptions(\n input: readonly EvalCaseResult[],\n options: { color?: boolean } = {},\n): string {\n const results = sortCases(input)\n const color = createEvalColors(options.color)\n if (results.length === 0)\n return `${color.heading('Eval run summary')}\\n${color.muted('no evals ran')}`\n\n const summary = buildEvalRunSummary(results)\n const out: string[] = []\n const variants = distinctVariants(results)\n\n out.push(color.heading('Eval run summary'))\n if (variants.length > 1) {\n // Multi-target run: lead with the cross-variant comparison matrix, then\n // one results table per variant so each target stays fully inspectable.\n out.push(renderComparisonTable(results, variants, color))\n for (const variant of variants) {\n const group = results.filter(r => r.variant === variant)\n out.push('')\n out.push(color.heading(variant))\n out.push(renderResultsTable(group, buildEvalRunSummary(group), color))\n }\n }\n else {\n out.push(renderResultsTable(results, summary, color))\n }\n\n const tagTable = renderTagTable(summary.tagScores, color)\n if (tagTable) {\n out.push('')\n out.push(tagTable)\n }\n out.push('')\n\n // Per-eval breakdown beneath the tables.\n const hyperlinks = options.color !== false\n const linkText = (target: string): string => {\n const abs = absPath(target)\n return hyperlinks ? oscLink(abs, abs) : abs\n }\n\n for (const result of results) {\n const caseLabel = `${result.suite ? `${result.suite}/` : ''}${result.id}`\n const label = result.variant ? `[${result.variant}] ${caseLabel}` : caseLabel\n out.push(`${color.dot(result.passed)} ${color.caseStatus(result.passed, label)}`)\n out.push(`${color.muted('score')} ${color.score(result.score)}`)\n\n const tagEntries = Object.entries(result.tagScores)\n if (tagEntries.length > 0)\n out.push(`${color.muted('tags:')} ${tagEntries.map(([tag, value]) => `${color.tag(tag)} ${color.score(value)}`).join(' ')}`)\n\n for (const metric of result.metrics) {\n const note = metric.missing ? color.fail(' (not emitted)') : color.muted(` (${formatMetricRaw(metric)})`)\n out.push(`${color.muted(padEnd(metric.id, 28))} ${color.score(metric.normalized)}${note}`)\n }\n\n for (const score of result.scores) {\n const detail = scoreDetailLine(score)\n if (!score.passed && detail)\n out.push(`${color.dot(score.passed)} ${color.muted(`${score.name}: ${truncate(detail, 140)}`)}`)\n }\n\n // Links — full absolute paths so they work in every terminal.\n if (result.sourceFile)\n out.push(`${color.muted('case:')} ${color.muted(linkText(result.sourceFile))}`)\n const resultTarget = caseLinkTarget(result)\n if (resultTarget)\n out.push(`${color.muted('result:')} ${color.muted(linkText(resultTarget))}`)\n\n // Turns last — can be very long.\n if (result.trajectory.steps.length > 0)\n out.push(`${color.muted(`turns: ${result.trajectory.totalBlocks}`)} ${formatTrajectoryColored(result.trajectory, color)}`)\n\n out.push('')\n }\n\n return out.join('\\n').replace(/\\n+$/, '')\n}\n\nfunction renderTagTable(tagScores: Record<string, number>, color: EvalColors): string | undefined {\n const entries = Object.entries(tagScores)\n if (entries.length === 0)\n return undefined\n const tagWidth = Math.max('TAG'.length, ...entries.map(([tag]) => tag.length))\n const top = `┌${'─'.repeat(tagWidth + 2)}┬${'─'.repeat(9)}┐`\n const mid = `├${'─'.repeat(tagWidth + 2)}┼${'─'.repeat(9)}┤`\n const bot = `└${'─'.repeat(tagWidth + 2)}┴${'─'.repeat(9)}┘`\n const lines = [\n top,\n `│ ${color.heading(padEnd('TAG', tagWidth))} │ ${color.heading('SCORE')} │`,\n mid,\n ...entries.map(([tag, value]) => `│ ${color.muted(padEnd(tag, tagWidth))} │ ${color.score(value)} │`),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction formatMetricRaw(metric: EvalMetric): string {\n const raw = Number.isInteger(metric.raw) ? formatInt(metric.raw) : metric.raw.toFixed(3)\n const arrow = metric.direction === 'lower-is-better' ? '↓' : '↑'\n return `raw ${raw} ${arrow}`\n}\n\n/**\n * Resolve a filesystem target to link an eval case to. Prefers the written\n * artifact (`result.json` → its dir), so the link opens the case's output.\n * Returns `undefined` when no artifacts were written.\n */\nfunction caseLinkTarget(result: EvalCaseResult): string | undefined {\n return result.artifacts?.result ?? result.artifacts?.dir\n}\n\n/** Wrap text in an OSC 8 terminal hyperlink to a local path or URL. */\nfunction oscLink(target: string, text: string): string {\n const url = /^(?:file|https?):\\/\\//.test(target)\n ? target\n : `file://${resolve(target)}`\n const OSC = '\\u001B]8;;'\n const ST = '\\u001B\\\\'\n return `${OSC}${url}${ST}${text}${OSC}${ST}`\n}\n\n/** Absolute filesystem path (strips any `file://` prefix, resolves relatives). */\nfunction absPath(target: string): string {\n const clean = target.replace(/^file:\\/\\//, '')\n return resolve(clean)\n}\n\n/**\n * Case key used to line up the same eval across variants in the comparison\n * matrix. Strips the `-repeat-N` suffix `registerEvalTests` appends so a\n * repeated case aggregates into one row (mean score, x/y passed).\n */\nfunction comparisonCaseKey(result: EvalCaseResult): string {\n const id = result.id.replace(/-repeat-\\d+$/, '')\n return `${result.suite ? `${result.suite}/` : ''}${id}`\n}\n\n/**\n * Cross-variant comparison matrix: one row per eval case, one column per\n * variant (provider/model target), plus rollup rows (score / passed / cost /\n * time) so two models can be read side by side at a glance.\n */\nfunction renderComparisonTable(\n input: readonly EvalCaseResult[],\n variants: string[],\n color: EvalColors,\n): string {\n const results = sortCases(input)\n const caseKeys = [...new Set(results.map(comparisonCaseKey))].sort()\n const byCell = new Map<string, EvalCaseResult[]>()\n for (const result of results) {\n const key = `${comparisonCaseKey(result)}\\u0000${result.variant ?? ''}`\n const list = byCell.get(key) ?? []\n list.push(result)\n byCell.set(key, list)\n }\n\n interface Cell { text: string, score?: number, passed?: boolean }\n const cellFor = (caseKey: string, variant: string): Cell => {\n const group = byCell.get(`${caseKey}\\u0000${variant}`)\n if (!group || group.length === 0)\n return { text: '-' }\n const score = mean(group.map(r => r.score))\n const passedCount = group.filter(r => r.passed).length\n const allPassed = passedCount === group.length\n const status = group.length > 1\n ? `${passedCount}/${group.length}`\n : allPassed ? 'pass' : 'fail'\n return { text: `${score.toFixed(2)} ${status}`, score, passed: allPassed }\n }\n\n const variantSummaries = aggregateVariants(results)\n const summaryOf = (variant: string): EvalVariantSummary | undefined =>\n variantSummaries.find(s => s.variant === variant)\n\n const rows: Array<{ label: string, cells: Cell[], rollup?: boolean }> = caseKeys.map(key => ({\n label: key,\n cells: variants.map(variant => cellFor(key, variant)),\n }))\n const rollups: Array<{ label: string, cells: Cell[], rollup: true }> = [\n {\n label: 'SCORE',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return s ? { text: s.score.toFixed(2), score: s.score } : { text: '-' }\n }),\n },\n {\n label: 'PASSED',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return s ? { text: `${s.passed}/${s.count}`, passed: s.passed === s.count } : { text: '-' }\n }),\n },\n {\n label: 'COST',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return { text: formatCost(s?.usage.cost ?? 0) }\n }),\n },\n {\n label: 'TIME',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return { text: s ? formatDuration(s.durationMs) : '-' }\n }),\n },\n ]\n\n const header = ['EVAL', ...variants]\n const allRows = [...rows, ...rollups]\n const widths = header.map((h, i) => Math.max(\n h.length,\n ...allRows.map(row => (i === 0 ? row.label : row.cells[i - 1].text).length),\n ))\n\n const top = `┌${widths.map(w => '─'.repeat(w + 2)).join('┬')}┐`\n const mid = `├${widths.map(w => '─'.repeat(w + 2)).join('┼')}┤`\n const bot = `└${widths.map(w => '─'.repeat(w + 2)).join('┴')}┘`\n\n const paintComparisonCell = (cell: Cell, padded: string): string => {\n if (cell.score === undefined && cell.passed === undefined)\n return color.muted(padded)\n // Re-render the score fragment colored; status colored by pass/fail.\n if (cell.score !== undefined) {\n const scoreText = cell.score.toFixed(2)\n const rest = cell.text.slice(scoreText.length)\n const coloredRest = cell.passed === undefined\n ? color.muted(rest)\n : cell.passed ? color.pass(rest) : color.fail(rest)\n return padded.replace(cell.text, `${color.score(cell.score)}${coloredRest}`)\n }\n return padded.replace(cell.text, cell.passed ? color.pass(cell.text) : color.fail(cell.text))\n }\n\n const renderRow = (row: { label: string, cells: Cell[], rollup?: boolean }): string => {\n const labelPadded = padEnd(row.label, widths[0])\n const labelPainted = row.rollup ? color.heading(labelPadded) : color.muted(labelPadded)\n const cellParts = row.cells.map((cell, i) => {\n const padded = padStart(cell.text, widths[i + 1])\n return ` ${paintComparisonCell(cell, padded)} `\n })\n return `│ ${labelPainted} │${cellParts.join('│')}│`\n }\n\n const lines = [\n top,\n `│ ${color.heading(padEnd(header[0], widths[0]))} │${variants.map((v, i) => ` ${color.heading(padStart(v, widths[i + 1]))} `).join('│')}│`,\n mid,\n ...rows.map(renderRow),\n mid,\n ...rollups.map(renderRow),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction renderResultsTable(\n results: readonly EvalCaseResult[],\n summary: EvalRunSummary,\n color: EvalColors,\n): string {\n const header = ['EVAL', 'STATUS', 'SCORE', 'IN', 'OUT', 'CACHE R', 'CACHE W', 'COST', 'TIME']\n const rows = results.map((result) => {\n const label = `${result.suite ? `${result.suite}/` : ''}${result.id}`\n const u = result.result.usage\n return {\n passed: result.passed,\n cells: [\n label,\n result.passed ? 'pass' : 'fail',\n result.score.toFixed(2),\n formatInt(u.input),\n formatInt(u.output),\n formatInt(u.cacheRead),\n formatInt(u.cacheCreation),\n formatCost(u.cost ?? 0),\n formatDuration(result.result.durationMs),\n ],\n score: result.score,\n }\n })\n\n const totals = {\n cells: [\n `TOTAL (${summary.passed}/${summary.count})`,\n summary.passed === summary.count ? 'pass' : 'fail',\n summary.score.toFixed(2),\n formatInt(summary.usage.input),\n formatInt(summary.usage.output),\n formatInt(summary.usage.cacheRead),\n formatInt(summary.usage.cacheCreation),\n formatCost(summary.usage.cost),\n formatDuration(summary.durationMs),\n ],\n passed: summary.passed === summary.count,\n score: summary.score,\n }\n\n // Right-align numeric columns (everything after STATUS).\n const aligns: Array<'left' | 'right'> = ['left', 'left', 'right', 'right', 'right', 'right', 'right', 'right', 'right']\n const widths = header.map((h, i) =>\n Math.max(h.length, ...rows.map(r => r.cells[i].length), totals.cells[i].length),\n )\n\n const top = `┌${widths.map(w => '─'.repeat(w + 2)).join('┬')}┐`\n const mid = `├${widths.map(w => '─'.repeat(w + 2)).join('┼')}┤`\n const bot = `└${widths.map(w => '─'.repeat(w + 2)).join('┴')}┘`\n\n const renderRow = (cells: string[], paint?: (i: number, raw: string, padded: string) => string): string => {\n const parts = cells.map((cell, i) => {\n const padded = aligns[i] === 'right' ? padStart(cell, widths[i]) : padEnd(cell, widths[i])\n return ` ${paint ? paint(i, cell, padded) : padded} `\n })\n return `│${parts.join('│')}│`\n }\n\n const lines = [\n top,\n renderRow(header, (_i, _raw, padded) => color.heading(padded)),\n mid,\n ...rows.map(r => renderRow(r.cells, (i, raw, padded) => paintCell(i, raw, padded, r.passed, r.score, color))),\n mid,\n renderRow(totals.cells, (i, raw, padded) => paintCell(i, raw, padded, totals.passed, totals.score, color, true)),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction paintCell(\n col: number,\n raw: string,\n padded: string,\n passed: boolean,\n score: number,\n color: EvalColors,\n bold = false,\n): string {\n // EVAL\n if (col === 0)\n return bold ? color.heading(padded) : color.caseStatus(passed, padded)\n // STATUS\n if (col === 1)\n return padded.replace(raw, color.status(passed))\n // SCORE\n if (col === 2)\n return padded.replace(raw, color.score(score))\n // COST\n if (col === 7)\n return color.cost(padded)\n return color.muted(padded)\n}\n\nfunction scoreDetailLine(score: EvalScore): string | undefined {\n if (typeof score.details === 'string')\n return score.details\n if (isRecord(score.details) && typeof score.details.reasoning === 'string')\n return score.details.reasoning\n return undefined\n}\n\nfunction formatInt(value: number): string {\n return value.toLocaleString('en-US')\n}\n\nfunction formatCost(value: number): string {\n return value > 0 ? `$${value.toFixed(4)}` : '-'\n}\n\nfunction formatDuration(ms: number): string {\n const rounded = Math.round(ms)\n if (rounded < 1000)\n return `${rounded}ms`\n const s = rounded / 1000\n // Drop a trailing `.0` so `4.0s` reads as `4s`.\n return `${Number.isInteger(s) ? s : s.toFixed(1)}s`\n}\n\nfunction padEnd(value: string, width: number): string {\n return value.length >= width ? value : value + ' '.repeat(width - value.length)\n}\n\nfunction padStart(value: string, width: number): string {\n return value.length >= width ? value : ' '.repeat(width - value.length) + value\n}\n\nfunction truncate(value: string, max: number): string {\n const oneLine = value.replace(/\\s+/g, ' ').trim()\n return oneLine.length > max ? `${oneLine.slice(0, max - 1)}…` : oneLine\n}\n\ninterface WorkspaceState {\n execution?: ExecutionContext\n snapshot: () => EvalWorkspaceSnapshot | undefined\n error: () => string | undefined\n cleanup: () => Promise<void>\n}\n\nasync function prepareWorkspace(\n execution: ExecutionContext | undefined,\n workspace: EvalWorkspaceOptions | undefined,\n): Promise<WorkspaceState> {\n if (!workspace) {\n return {\n snapshot: () => undefined,\n error: () => undefined,\n cleanup: async () => {},\n }\n }\n\n let tempDir: string | undefined\n let baseExecution = execution\n if (!baseExecution) {\n const cwd = workspace.cwd ?? await mkdtemp(join(tmpdir(), 'zidane-eval-'))\n if (!workspace.cwd)\n tempDir = cwd\n baseExecution = createProcessContext({ cwd })\n }\n\n const captured: { snapshot?: EvalWorkspaceSnapshot, error?: string } = {}\n const wrapped = withWorkspaceLifecycle(baseExecution, workspace, captured)\n\n return {\n execution: wrapped,\n snapshot: () => captured.snapshot,\n error: () => captured.error,\n cleanup: async () => {\n if (tempDir && !workspace.retain)\n await rm(tempDir, { recursive: true, force: true })\n },\n }\n}\n\nfunction withWorkspaceLifecycle(\n execution: ExecutionContext,\n workspace: EvalWorkspaceOptions,\n captured: { snapshot?: EvalWorkspaceSnapshot, error?: string },\n): ExecutionContext {\n return {\n ...execution,\n async spawn(config) {\n const handle = await execution.spawn({\n ...config,\n ...(workspace.cwd && !config?.cwd ? { cwd: workspace.cwd } : {}),\n })\n if (workspace.seedDir)\n await seedWorkspace(execution, handle, workspace)\n return handle\n },\n async destroy(handle) {\n try {\n captured.snapshot = await captureWorkspace(execution, handle, workspace)\n }\n catch (err) {\n captured.error = err instanceof Error ? err.message : String(err)\n }\n finally {\n await execution.destroy(handle)\n }\n },\n }\n}\n\nasync function seedWorkspace(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n workspace: EvalWorkspaceOptions,\n): Promise<void> {\n const target = workspace.seedTarget ?? '.'\n const result = await execution.exec(\n handle,\n `mkdir -p ${shellQuote(target)} && cp -R ${shellQuote(`${workspace.seedDir!}/.`)} ${shellQuote(target)}`,\n )\n if (result.exitCode !== 0)\n throw new Error(`Failed to seed eval workspace: ${result.stderr || result.stdout}`)\n}\n\nasync function captureWorkspace(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n workspace: EvalWorkspaceOptions,\n): Promise<EvalWorkspaceSnapshot> {\n const capturePaths = workspace.capture?.length ? workspace.capture : ['.']\n // `-print0` (NUL-delimited) so filenames containing newlines or spaces don't\n // corrupt the listing. Dedup in JS rather than `sort -u`, which has no\n // portable NUL-record mode across GNU (`-z`) and BSD `sort`.\n const command = [\n `cd ${shellQuote(handle.cwd)}`,\n '&&',\n 'for p in',\n capturePaths.map(shellQuote).join(' '),\n '; do',\n 'if [ -e \"$p\" ]; then',\n 'find \"$p\" \\\\( -path \"*/node_modules/*\" -o -path \"*/.git/*\" \\\\) -prune -o -type f -print0',\n '; fi',\n 'done',\n ].join(' ')\n\n const listed = await execution.exec(handle, command)\n if (listed.exitCode !== 0)\n throw new Error(`Failed to list eval workspace: ${listed.stderr || listed.stdout}`)\n\n const maxFileChars = workspace.maxFileChars ?? 256 * 1024\n const files: EvalWorkspaceFile[] = []\n const seen = new Set<string>()\n for (const rawPath of listed.stdout.split('\\0').filter(Boolean)) {\n const path = normalizeSnapshotPath(rawPath)\n if (seen.has(path))\n continue\n seen.add(path)\n const content = await execution.readFile(handle, path)\n const binary = content.includes('\\0')\n const truncated = content.length > maxFileChars\n files.push({\n path,\n size: content.length,\n ...(binary ? { binary: true } : { content: truncated ? content.slice(0, maxFileChars) : content }),\n ...(truncated ? { truncated: true } : {}),\n })\n }\n\n return { cwd: handle.cwd, files }\n}\n\nasync function runScorers(ctx: EvalScorerContext, scorers: EvalScorer[]): Promise<EvalScore[]> {\n const scores: EvalScore[] = []\n for (const scorer of scorers) {\n try {\n scores.push(await scorer(ctx))\n }\n catch (err) {\n if (err instanceof EvalMetricError)\n throw err\n scores.push({\n name: scorer.name || 'anonymous-scorer',\n passed: false,\n score: 0,\n details: err instanceof Error ? err.message : String(err),\n })\n }\n }\n return scores\n}\n\nfunction aggregateScore(scores: EvalScore[]): number {\n if (scores.length === 0)\n return 1\n const total = scores.reduce((sum, score) => sum + (score.score ?? (score.passed ? 1 : 0)), 0)\n return total / scores.length\n}\n\nexport function efficiencyMetricValues(result: HeadlessResult): Record<keyof typeof EFFICIENCY_METRICS, number> {\n const u = result.usage\n // Fraction of read-side input served from cache. cacheRead is reported on top\n // of `input`, so the denominator is cacheRead + input (not input alone).\n const readTotal = u.input + u.cacheRead\n return {\n 'execution-time': result.durationMs,\n 'provider-tokens': u.input + u.output,\n 'cache-read-rate': readTotal > 0 ? u.cacheRead / readTotal : 0,\n }\n}\n\nexport function emitEfficiencyMetrics(emit: MetricEmitter, result: HeadlessResult): void {\n const values = efficiencyMetricValues(result)\n for (const [id, raw] of Object.entries(values))\n emit(id, raw)\n}\n\nexport function finalizeEvalMetrics(\n specs: MetricSpecMap,\n raw: Map<string, number>,\n): EvalMetric[] {\n // A declared-but-unemitted metric (e.g. a judge that threw mid-run) records\n // as a missing 0 rather than crashing the whole case — evals score what they\n // can and surface the gap, they don't abort the run.\n return Object.entries(specs).map(([metricId, spec]) => {\n const emitted = raw.has(metricId)\n const value = emitted ? raw.get(metricId)! : spec.min\n return {\n id: metricId,\n raw: emitted ? value : 0,\n normalized: emitted ? normalizeMetric(value, spec) : 0,\n direction: spec.direction,\n min: spec.min,\n max: spec.max,\n tags: spec.tags ?? [],\n ...(spec.description ? { description: spec.description } : {}),\n ...(emitted ? {} : { missing: true }),\n }\n })\n}\n\nexport function computeEvalTagScores(metrics: EvalMetric[]): Record<string, number> {\n const byTag = new Map<string, number[]>()\n for (const metric of metrics) {\n for (const tag of metric.tags) {\n const list = byTag.get(tag) ?? []\n list.push(metric.normalized)\n byTag.set(tag, list)\n }\n }\n const out: Record<string, number> = {}\n for (const [tag, values] of byTag)\n out[tag] = mean(values)\n return out\n}\n\nfunction meanNormalized(metrics: EvalMetric[]): number {\n return metrics.length === 0 ? 0 : mean(metrics.map(m => m.normalized))\n}\n\nfunction accumulateEvalAgentStats(acc: EvalAgentStats, turn: EvalAgentRunStats): void {\n acc.runs += 1\n acc.input += turn.input\n acc.output += turn.output\n acc.cacheRead += turn.cacheRead\n acc.cacheCreation += turn.cacheCreation\n acc.cost += turn.cost\n acc.turns += turn.turns\n acc.toolCalls += turn.toolCalls\n acc.durationMs += turn.durationMs\n}\n\nfunction countToolCallsInTurns(turns: readonly SessionTurn[]): number {\n let count = 0\n for (const turn of turns) {\n if (turn.role !== 'assistant')\n continue\n count += turn.content.filter(block => block.type === 'tool_call').length\n }\n return count\n}\n\nfunction mean(values: number[]): number {\n return values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\ninterface EvalColors {\n heading: (value: string) => string\n pass: (value: string) => string\n fail: (value: string) => string\n muted: (value: string) => string\n cost: (value: string) => string\n status: (passed: boolean) => string\n score: (value: number) => string\n caseStatus: (passed: boolean, value: string) => string\n dot: (passed: boolean) => string\n tag: (value: string) => string\n step: (kind: TrajectoryStepKind, value: string) => string\n}\n\nfunction createEvalColors(enabled = shouldUseColor()): EvalColors {\n if (!enabled) {\n return {\n heading: value => value,\n pass: value => value,\n fail: value => value,\n muted: value => value,\n cost: value => value,\n status: passed => passed ? 'pass' : 'fail',\n score: value => value.toFixed(2),\n caseStatus: (_passed, value) => value,\n dot: passed => passed ? '+' : 'x',\n tag: value => value,\n step: (_kind, value) => value,\n }\n }\n return {\n heading: value => chalk.bold(value),\n pass: value => chalk.green(value),\n fail: value => chalk.red(value),\n muted: value => chalk.gray(value),\n cost: value => chalk.cyan(value),\n status: passed => passed ? chalk.green('pass') : chalk.red('fail'),\n score: value => value >= 0.9 ? chalk.green(value.toFixed(2)) : value >= 0.7 ? chalk.yellow(value.toFixed(2)) : chalk.red(value.toFixed(2)),\n caseStatus: (passed, value) => passed ? chalk.green(value) : chalk.red(value),\n dot: passed => passed ? chalk.green('●') : chalk.red('●'),\n // Distinct from the step palette (which uses magenta/blue/cyan/yellow/green).\n tag: value => chalk.bold(chalk.whiteBright(value)),\n step: (kind, value) => paintStep(kind, value),\n }\n}\n\n/** Per-kind trajectory colors: think=magenta, text=blue, tools by family. */\nfunction paintStep(kind: TrajectoryStepKind, value: string): string {\n if (kind === 'think')\n return chalk.magenta(value)\n if (kind === 'text')\n return chalk.blue(value)\n // tool step — color by intent so a timeline reads at a glance.\n if (/write|edit|create/.test(value))\n return chalk.green(value)\n if (/read|list|glob|grep|search/.test(value))\n return chalk.cyan(value)\n if (/shell|bash|exec|run/.test(value))\n return chalk.yellow(value)\n if (/spawn|task|agent/.test(value))\n return chalk.magentaBright(value)\n return chalk.white(value)\n}\n\nfunction formatTrajectoryColored(trajectory: Trajectory, color: EvalColors): string {\n return trajectory.steps\n .map((step) => {\n const base = step.kind === 'tool' ? (step.name ?? 'tool') : step.kind\n const labelWithCount = step.count > 1 ? `${base} ×${step.count}` : base\n const painted = color.step(step.kind, labelWithCount)\n const timing = step.durationMs && step.durationMs >= 100 ? color.muted(`(${formatDuration(step.durationMs)})`) : ''\n return timing ? `${painted} ${timing}` : painted\n })\n .join(color.muted(' → '))\n}\n\nfunction shouldUseColor(): boolean {\n return Boolean(process.stdout.isTTY && !process.env.NO_COLOR)\n}\n\nfunction renderJudgePrompt(input: { rubric: string, input: string }): string {\n return [\n 'Rubric:',\n input.rubric,\n '',\n 'Output to grade:',\n input.input,\n '',\n 'Return JSON only.',\n ].join('\\n')\n}\n\nfunction defaultJudgeInput(ctx: EvalScorerContext): string {\n const chunks = [\n `Final answer:\\n${ctx.result.finalText}`,\n ]\n if (ctx.workspace) {\n chunks.push(`Workspace files:\\n${ctx.workspace.files.map(file => [\n `--- ${file.path}${file.truncated ? ' (truncated)' : ''} ---`,\n file.binary ? '[binary omitted]' : file.content ?? '',\n ].join('\\n')).join('\\n')}`)\n }\n return chunks.join('\\n\\n')\n}\n\nfunction parseJudgeOutput(raw: string): { score: number, reasoning: string, feedback?: string, raw?: string } {\n const trimmed = stripCodeFences(raw.trim())\n\n // Preferred path: a JSON object somewhere in the output.\n const jsonText = extractJsonObject(trimmed)\n if (jsonText) {\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>\n if (parsed.score !== undefined || parsed.reasoning !== undefined) {\n return {\n score: clampScore(parsed.score),\n reasoning: typeof parsed.reasoning === 'string' ? parsed.reasoning : '',\n ...(typeof parsed.feedback === 'string' ? { feedback: parsed.feedback } : {}),\n ...(jsonText === trimmed ? {} : { raw: trimmed }),\n }\n }\n }\n catch {\n // fall through to lenient parsing\n }\n }\n\n // Lenient fallbacks for models that don't honor strict JSON:\n // 1) a `\"score\": 0.8` / `score = 0.8` fragment anywhere.\n const scoreFragment = trimmed.match(/score[\"']?\\s*[:=]\\s*(-?\\d+(?:\\.\\d+)?)/i)\n if (scoreFragment) {\n return { score: clampScore(Number(scoreFragment[1])), reasoning: trimmed.slice(0, 500), raw: trimmed }\n }\n // 2) the whole output is just a number (`0.8` or `8/10`).\n const bareFraction = trimmed.match(/^(-?\\d+(?:\\.\\d+)?)\\s*\\/\\s*(\\d+(?:\\.\\d+)?)$/)\n if (bareFraction) {\n const denom = Number(bareFraction[2])\n return { score: clampScore(denom === 0 ? 0 : Number(bareFraction[1]) / denom), reasoning: trimmed, raw: trimmed }\n }\n const bareNumber = trimmed.match(/^-?\\d+(?:\\.\\d+)?$/)\n if (bareNumber) {\n return { score: clampScore(Number(trimmed)), reasoning: '', raw: trimmed }\n }\n\n return { score: 0, reasoning: 'Judge did not return a parseable score.', raw: trimmed }\n}\n\n/** Strip a leading/trailing markdown code fence (``` or ```json). */\nfunction stripCodeFences(text: string): string {\n const fence = text.match(/^```(?:json)?[ \\t]*\\n([\\s\\S]*?)\\n```$/i)\n return fence ? fence[1].trim() : text\n}\n\n/** Extract the first balanced `{...}` object, ignoring braces inside strings. */\nfunction extractJsonObject(text: string): string | undefined {\n const start = text.indexOf('{')\n if (start === -1)\n return undefined\n let depth = 0\n let inString = false\n let escaped = false\n for (let i = start; i < text.length; i++) {\n const ch = text[i]\n if (inString) {\n if (escaped)\n escaped = false\n else if (ch === '\\\\')\n escaped = true\n else if (ch === '\"')\n inString = false\n continue\n }\n if (ch === '\"') {\n inString = true\n }\n else if (ch === '{') {\n depth++\n }\n else if (ch === '}') {\n depth--\n if (depth === 0)\n return text.slice(start, i + 1)\n }\n }\n return undefined\n}\n\nfunction clampScore(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(n))\n return 0\n return Math.max(0, Math.min(1, n))\n}\n\nasync function writeEvalArtifacts(dir: string, result: EvalCaseResult): Promise<EvalArtifacts> {\n await mkdir(dir, { recursive: true })\n const resultPath = join(dir, 'result.json')\n const eventsPath = join(dir, 'events.jsonl')\n const transcriptPath = join(dir, 'transcript.json')\n const workspacePath = result.workspace ? join(dir, 'workspace.json') : undefined\n\n await writeFile(resultPath, `${JSON.stringify(result, null, 2)}\\n`)\n await writeFile(eventsPath, result.events.map(headlessEventToJsonl).join(''))\n await writeFile(transcriptPath, `${JSON.stringify(result.result.transcript, null, 2)}\\n`)\n if (workspacePath)\n await writeFile(workspacePath, `${JSON.stringify(result.workspace, null, 2)}\\n`)\n\n return {\n dir,\n result: resultPath,\n events: eventsPath,\n transcript: transcriptPath,\n ...(workspacePath ? { workspace: workspacePath } : {}),\n }\n}\n\nfunction normalizeSnapshotPath(path: string): string {\n const normalized = path.startsWith('./') ? path.slice(2) : path\n return normalized === '' ? '.' : normalized\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = value.replace(/[^\\w.-]+/g, '-').replace(/^-+|-+$/g, '')\n // If sanitizing changed the value, distinct ids can collapse to the same\n // segment (e.g. `a b`, `a/b`, `a@b` → `a-b`) and overwrite each other's\n // artifacts. Append a short, stable hash of the original to disambiguate.\n if (sanitized === value && sanitized.length > 0)\n return sanitized\n return `${sanitized || 'eval'}-${shortHash(value)}`\n}\n\nfunction shortHash(value: string): string {\n // Tiny FNV-1a; only used to disambiguate filesystem segments, not security.\n let hash = 0x811C9DC5\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 0x01000193)\n }\n return (hash >>> 0).toString(36).padStart(7, '0').slice(0, 7)\n}\n\nexport function artifactPath(root: string, result: EvalCaseResult): string {\n return resolve(root, safeSegment(result.suite ?? 'eval'), safeSegment(result.id))\n}\n\nexport function relativeArtifactPath(root: string, path: string): string {\n return relative(root, path)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"eval.js","names":["shellQuote"],"sources":["../src/eval.ts"],"sourcesContent":["import type { ExecutionContext, ExecutionHandle } from './contexts'\nimport type { HeadlessEvent, HeadlessOptions, HeadlessResult } from './headless'\nimport type { Provider, ToolCall, ToolSpec } from './providers'\nimport type { Session, SessionStore } from './session'\nimport type { McpServerConfig, SessionTurn } from './types'\nimport { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join, relative, resolve } from 'node:path'\nimport chalk from 'chalk'\nimport { createProcessContext } from './contexts'\nimport { headlessEventToJsonl, runHeadless } from './headless'\nimport { createMemoryStore, createSession } from './session'\nimport { alwaysQuote as shellQuote } from './tools/shell-quote'\n\nexport interface EvalWorkspaceOptions {\n /**\n * Working directory inside the execution context. When omitted, process-based\n * evals get a fresh host temp dir; Docker evals use the context default.\n *\n * Note: under the shared-Docker harness (`withDocker`), per-case working dirs\n * are assigned by the container (`/workspace/case-N`) and a custom `cwd` is\n * ignored — `withDocker` strips it so cases stay isolated.\n */\n cwd?: string\n /**\n * Directory visible inside the execution context, copied into the workspace\n * before the agent runs. For Docker, mount local fixtures read-only and point\n * this at the container path, e.g. `/fixtures/react-empty`.\n */\n seedDir?: string\n /** Relative destination inside the workspace. Defaults to `.`. */\n seedTarget?: string\n /** Relative files/directories to capture after the run. Defaults to `.`. */\n capture?: string[]\n /** Max text chars retained per captured file. Defaults to 256 KiB. */\n maxFileChars?: number\n /** Keep a temp process workspace on disk after the eval completes. */\n retain?: boolean\n}\n\nexport interface EvalWorkspaceFile {\n path: string\n size: number\n content?: string\n truncated?: boolean\n binary?: boolean\n}\n\nexport interface EvalWorkspaceSnapshot {\n cwd: string\n files: EvalWorkspaceFile[]\n}\n\nexport interface EvalScore {\n name: string\n passed: boolean\n score?: number\n details?: string | Record<string, unknown>\n}\n\nexport type MetricDirection = 'higher-is-better' | 'lower-is-better'\n\n/** Declared metric: a raw signal plus how to normalize it to a `0..1` score. */\nexport interface MetricSpec {\n min: number\n max: number\n direction: MetricDirection\n /** Grouping tags, e.g. `@efficiency`, `@functionality`, `@quality`. */\n tags?: string[]\n description?: string\n}\n\nexport type MetricSpecMap = Record<string, MetricSpec>\n\n/** A normalized metric value attached to one eval case. */\nexport interface EvalMetric {\n id: string\n raw: number\n normalized: number\n direction: MetricDirection\n min: number\n max: number\n tags: string[]\n description?: string\n /**\n * True when the metric was declared but never emitted (e.g. its scorer threw\n * before calling `ctx.metric`). Recorded as `normalized: 0` so the run still\n * produces results instead of crashing.\n */\n missing?: boolean\n}\n\n/** Emit a raw metric value during a run. */\nexport type MetricEmitter = (id: string, raw: number) => void\n\nexport interface EvalScorerContext {\n id: string\n suite?: string\n tags: string[]\n result: HeadlessResult\n events: readonly HeadlessEvent[]\n workspace?: EvalWorkspaceSnapshot\n artifactDir?: string\n /** Emit a declared metric's raw value. Unknown ids throw at run end. */\n metric: MetricEmitter\n}\n\nexport type EvalScorer = (ctx: EvalScorerContext) => EvalScore | Promise<EvalScore>\n\n/**\n * Declare an eval's metric set. Returns the same map, typed; pass it to\n * `EvalCaseOptions.metrics`. Declared metrics that are not emitted are recorded\n * as missing with a normalized score of 0; emitting an undeclared metric is an\n * authoring error and throws.\n */\nexport function defineMetrics<T extends MetricSpecMap>(spec: T): T {\n return spec\n}\n\n/** Always-available efficiency metrics derived from `HeadlessResult`. */\nexport const EFFICIENCY_METRICS = {\n 'execution-time': { min: 0, max: 300_000, direction: 'lower-is-better', tags: ['@efficiency'], description: 'Wall-clock run time (ms).' },\n 'provider-tokens': { min: 0, max: 200_000, direction: 'lower-is-better', tags: ['@efficiency'], description: 'Input + output tokens.' },\n 'cache-read-rate': { min: 0, max: 1, direction: 'higher-is-better', tags: ['@efficiency'], description: 'Cache-read tokens / input tokens.' },\n} satisfies MetricSpecMap\n\nexport function normalizeMetric(raw: number, spec: MetricSpec): number {\n const span = spec.max - spec.min\n if (span === 0)\n return 1\n const clamped = Math.min(spec.max, Math.max(spec.min, raw))\n const normalized = (clamped - spec.min) / span\n return spec.direction === 'lower-is-better' ? 1 - normalized : normalized\n}\n\nexport interface LlmJudgeOptions {\n name?: string\n provider: Provider\n model?: string\n system?: string\n rubric: string\n maxTokens?: number\n /** Wall-clock cap for the judge provider call. Defaults to 60s. */\n timeoutMs?: number\n /** Select what the judge sees. Defaults to final text plus captured workspace files. */\n input?: (ctx: EvalScorerContext) => string\n /** Declared metric id to emit the judge's `0..1` score into. */\n metric?: string\n}\n\n/**\n * Thrown by `runEvalCase` when a scorer emits a metric id that was not declared\n * in `defineMetrics`. This is an authoring error (a typo'd or stale metric id),\n * not a low score — it fails the eval test rather than being recorded as a\n * failed scorer. Exported so downstream harnesses can type-narrow on it.\n */\nexport class EvalMetricError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'EvalMetricError'\n }\n}\n\nexport interface ReusableExecutionContext {\n /**\n * Execution context facade that reuses one underlying handle. Its\n * `destroy()` is intentionally a no-op; call `dispose()` when the surrounding\n * fixture/run owns teardown.\n */\n execution: ExecutionContext\n /** Destroy the underlying handle if it was spawned. Idempotent. */\n dispose: () => Promise<void>\n /** Current underlying handle, if the agent has spawned one. */\n handle: () => ExecutionHandle | undefined\n}\n\n/**\n * Wrap an execution context so repeated agent runs share one handle until the\n * caller disposes it. This is useful for eval fixtures that want per-test\n * Docker/process lifetime while still using `runHeadless()` per turn.\n */\nexport function createReusableExecutionContext(base: ExecutionContext): ReusableExecutionContext {\n let handle: ExecutionHandle | undefined\n let spawnPromise: Promise<ExecutionHandle> | undefined\n let disposed = false\n let disposePromise: Promise<void> | undefined\n\n const ensureHandle = (config?: Parameters<ExecutionContext['spawn']>[0]): Promise<ExecutionHandle> => {\n if (disposed)\n throw new Error('Reusable execution context has been disposed')\n if (handle)\n return Promise.resolve(handle)\n spawnPromise ??= base.spawn(config).then((next) => {\n handle = next\n return next\n }, (err) => {\n spawnPromise = undefined\n throw err\n })\n return spawnPromise\n }\n\n const execution: ExecutionContext = {\n ...base,\n async spawn(config) {\n return ensureHandle(config)\n },\n async destroy() {\n // Agent-level destroy means \"end this turn\"; the eval fixture owns the\n // actual execution lifetime and calls dispose() at test teardown.\n },\n }\n\n return {\n execution,\n // Memoize so concurrent dispose()/asyncDispose() calls share one teardown\n // and never run base.destroy twice or orphan an in-flight spawn.\n dispose() {\n disposePromise ??= (async () => {\n disposed = true\n const active = handle ?? await spawnPromise?.catch(() => undefined)\n handle = undefined\n spawnPromise = undefined\n if (active)\n await base.destroy(active)\n })()\n return disposePromise\n },\n handle: () => handle,\n }\n}\n\nexport interface EvalAgentRunStats extends EvalRunUsage {\n durationMs: number\n turns: number\n toolCalls: number\n}\n\nexport interface EvalAgentStats extends EvalRunUsage {\n /** Number of completed `run()` calls. */\n runs: number\n /** Sum of per-run agent turns. */\n turns: number\n /** Sum of per-run tool calls. */\n toolCalls: number\n /** Sum of per-run wall-clock durations. */\n durationMs: number\n}\n\nexport interface EvalAgentRunResult {\n /** Full headless result. Its transcript is scoped to this run. */\n result: HeadlessResult\n /** Per-run usage and trajectory counters. */\n stats: EvalAgentRunStats\n /** Transcript turns added by this run (same view as `result.transcript`). */\n newTranscript: SessionTurn[]\n}\n\nexport type EvalAgentMcpServers\n = | readonly McpServerConfig[]\n | (() => readonly McpServerConfig[] | Promise<readonly McpServerConfig[]>)\n\nexport interface CreateEvalAgentOptions extends Omit<HeadlessOptions, 'prompt' | 'provider' | 'execution' | 'cwd' | 'session' | 'store' | 'mcpServers' | 'onEvent' | 'signal'> {\n provider: Provider\n /**\n * Working directory for the default process context. Ignored when\n * `execution` is supplied.\n */\n cwd?: string\n /**\n * Execution context for agent tools. Wrapped with\n * `createReusableExecutionContext` so runs share one handle until `dispose`.\n */\n execution?: ExecutionContext\n /** Session to reuse across runs. When omitted, one in-memory session is created. */\n session?: Session\n /** Store used for the auto-created session. Defaults to an in-memory store. */\n store?: SessionStore\n /** Static or lazily resolved MCP servers. Resolved fresh before each run. */\n mcpServers?: EvalAgentMcpServers\n /** Live event callback for every run. */\n onEvent?: (event: HeadlessEvent) => void\n}\n\nexport interface EvalAgentRunOptions extends Omit<HeadlessOptions, 'provider' | 'execution' | 'cwd' | 'session' | 'store'> {\n prompt: HeadlessOptions['prompt']\n}\n\nexport interface EvalAgent {\n run: (options: EvalAgentRunOptions) => Promise<EvalAgentRunResult>\n readonly stats: EvalAgentStats\n session: () => Promise<Session>\n dispose: () => Promise<void>\n [Symbol.asyncDispose]: () => Promise<void>\n}\n\n/**\n * Multi-turn eval agent over the low-level headless runner. It keeps session\n * and execution lifetime outside any Playwright-specific fixture layer,\n * so downstream platforms can wrap it with their own `agent.run(...)` shape.\n */\nexport function createEvalAgent(options: CreateEvalAgentOptions): EvalAgent {\n const {\n cwd,\n execution,\n session: initialSession,\n store: initialStore,\n mcpServers: baseMcpServers,\n onEvent: baseOnEvent,\n ...headlessDefaults\n } = options\n const executionOwner = createReusableExecutionContext(execution ?? createProcessContext({ cwd }))\n const store = initialStore ?? createMemoryStore()\n let sessionPromise: Promise<Session> | undefined = initialSession ? Promise.resolve(initialSession) : undefined\n let disposed = false\n let runInFlight = false\n let disposePromise: Promise<void> | undefined\n\n const stats: EvalAgentStats = {\n runs: 0,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheCreation: 0,\n cost: 0,\n turns: 0,\n toolCalls: 0,\n durationMs: 0,\n }\n\n async function getSession(): Promise<Session> {\n if (disposed)\n throw new Error('Eval agent has been disposed')\n sessionPromise ??= createSession({ store })\n return sessionPromise\n }\n\n async function resolveMcpServers(\n runServers: HeadlessOptions['mcpServers'] | undefined,\n ): Promise<McpServerConfig[] | undefined> {\n const base = typeof baseMcpServers === 'function'\n ? await baseMcpServers()\n : baseMcpServers\n const merged = [\n ...(base ?? []),\n ...(runServers ?? []),\n ]\n return merged.length > 0 ? [...merged] : undefined\n }\n\n async function run(runOptions: EvalAgentRunOptions): Promise<EvalAgentRunResult> {\n if (runInFlight)\n throw new Error('Eval agent already has a run in progress')\n runInFlight = true\n try {\n const session = await getSession()\n const { mcpServers: runMcpServers, onEvent: runOnEvent, ...restRunOptions } = runOptions\n const mcpServers = await resolveMcpServers(runMcpServers)\n\n const result = await runHeadless({\n ...headlessDefaults,\n ...restRunOptions,\n session,\n execution: executionOwner.execution,\n ...(mcpServers ? { mcpServers } : {}),\n onEvent(event) {\n baseOnEvent?.(event)\n runOnEvent?.(event)\n },\n })\n\n // `result.transcript` is already scoped to this run (runHeadless slices\n // from the resumed session's prior length), so it IS the new turns.\n const newTranscript = result.transcript.slice()\n const runStats: EvalAgentRunStats = {\n input: result.usage.input,\n output: result.usage.output,\n cacheRead: result.usage.cacheRead,\n cacheCreation: result.usage.cacheCreation,\n cost: result.usage.cost ?? 0,\n durationMs: result.durationMs,\n turns: result.turns,\n toolCalls: countToolCallsInTurns(newTranscript),\n }\n accumulateEvalAgentStats(stats, runStats)\n\n return { result, stats: runStats, newTranscript }\n }\n finally {\n runInFlight = false\n }\n }\n\n function dispose(): Promise<void> {\n // Memoize: concurrent dispose()/asyncDispose() share one teardown.\n disposePromise ??= (async () => {\n disposed = true\n await executionOwner.dispose()\n })()\n return disposePromise\n }\n\n return {\n run,\n stats,\n session: getSession,\n dispose,\n [Symbol.asyncDispose]: dispose,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Trajectory\n// ---------------------------------------------------------------------------\n\nexport type TrajectoryStepKind = 'think' | 'text' | 'tool'\n\n/**\n * One grouped step in an eval trajectory. Consecutive blocks of the same kind\n * (and, for tools, the same tool name) collapse into a single step with a\n * `count`. A different kind interrupting the run breaks the group.\n *\n * Serializable by design so trajectories round-trip to disk and can be diffed\n * or replayed by other tooling.\n */\nexport interface TrajectoryStep {\n kind: TrajectoryStepKind\n /** Tool name for `kind: 'tool'` steps (canonical, e.g. `read_file`). */\n name?: string\n /** Number of consecutive occurrences grouped into this step. */\n count: number\n /** Approx wall-clock ms attributed to this step's turns, when derivable. */\n durationMs?: number\n}\n\nexport interface Trajectory {\n steps: TrajectoryStep[]\n /** Total blocks across all steps (sum of `count`). */\n totalBlocks: number\n}\n\n/**\n * Build an ordered, grouped trajectory from a transcript. Walks assistant\n * turns in order, emitting `think` / `text` / `tool:<name>` steps, grouping\n * only consecutive identical kinds. Per-step duration is approximated from the\n * owning turn's `createdAt` delta to the next turn.\n */\nexport function buildTrajectory(transcript: SessionTurn[]): Trajectory {\n const steps: TrajectoryStep[] = []\n let total = 0\n\n const push = (kind: TrajectoryStepKind, name: string | undefined, durationMs: number): void => {\n total++\n const last = steps[steps.length - 1]\n if (last && last.kind === kind && last.name === name) {\n last.count++\n if (durationMs > 0)\n last.durationMs = (last.durationMs ?? 0) + durationMs\n return\n }\n steps.push({ kind, ...(name ? { name } : {}), count: 1, ...(durationMs > 0 ? { durationMs } : {}) })\n }\n\n for (let i = 0; i < transcript.length; i++) {\n const turn = transcript[i]\n if (turn.role !== 'assistant')\n continue\n const next = transcript[i + 1]\n const turnDuration = next ? Math.max(0, next.createdAt - turn.createdAt) : 0\n const blocks = turn.content.filter(b => b.type === 'thinking' || b.type === 'redacted_thinking' || b.type === 'text' || b.type === 'tool_call')\n // Attribute the turn's elapsed time to its tool calls — that's where the\n // wall-clock actually goes (provider stream + tool execution). think/text\n // blocks within the turn carry no separate timing. Split evenly across the\n // turn's tool calls and round to whole ms so the timeline reads cleanly.\n const toolBlocks = blocks.filter(b => b.type === 'tool_call').length\n const perTool = toolBlocks > 0 ? Math.round(turnDuration / toolBlocks) : 0\n for (const block of blocks) {\n if (block.type === 'thinking' || block.type === 'redacted_thinking')\n push('think', undefined, 0)\n else if (block.type === 'text')\n push('text', undefined, 0)\n else if (block.type === 'tool_call')\n push('tool', block.name, perTool)\n }\n }\n\n return { steps, totalBlocks: total }\n}\n\n/** Render a trajectory as a one-line timeline string (no color). */\nexport function formatTrajectoryLine(trajectory: Trajectory): string {\n return trajectory.steps.map(stepLabel).join(' → ')\n}\n\nfunction stepLabel(step: TrajectoryStep): string {\n const base = step.kind === 'tool' ? (step.name ?? 'tool') : step.kind\n return step.count > 1 ? `${base} ×${step.count}` : base\n}\n\nexport interface EvalArtifacts {\n dir: string\n result?: string\n events?: string\n transcript?: string\n workspace?: string\n}\n\nexport interface EvalCaseResult {\n id: string\n suite?: string\n /** Run variant this result belongs to (e.g. `baseten:zai-org/GLM-5.1`). */\n variant?: string\n tags: string[]\n result: HeadlessResult\n /** Mean normalized metric score in [0, 1] when metrics are declared; otherwise mean scorer score. */\n score: number\n /** True when every scorer passed. */\n passed: boolean\n scores: EvalScore[]\n /** Normalized metrics for this case (empty when no metrics declared). */\n metrics: EvalMetric[]\n /** Mean normalized score per tag, e.g. `{ '@efficiency': 0.8 }`. */\n tagScores: Record<string, number>\n /** Ordered, grouped step timeline derived from the transcript. */\n trajectory: Trajectory\n events: HeadlessEvent[]\n artifacts?: EvalArtifacts\n workspace?: EvalWorkspaceSnapshot\n workspaceError?: string\n /** Absolute path to the eval definition file, for editor links. */\n sourceFile?: string\n}\n\nexport interface EvalCaseOptions extends Omit<HeadlessOptions, 'onEvent'> {\n id: string\n suite?: string\n /**\n * Run variant label when the same eval runs against several provider/model\n * targets in one run (e.g. `baseten:zai-org/GLM-5.1`). Flows into\n * {@link EvalCaseResult.variant}, namespaces artifacts, and drives the\n * reporter's per-variant tables + comparison matrix.\n */\n variant?: string\n tags?: string[]\n artifactDir?: string\n workspace?: EvalWorkspaceOptions\n scorers?: EvalScorer[]\n /**\n * Declared metric set. Auto-merged with {@link EFFICIENCY_METRICS} so every\n * eval gets comparable efficiency metrics for free. All declared metrics must\n * be emitted (via auto-emit or `ctx.metric`) or the run throws.\n */\n metrics?: MetricSpecMap\n onEvent?: (event: HeadlessEvent) => void\n /** Absolute path to the eval definition file. Set via `import.meta.url`. */\n sourceFile?: string\n}\n\nexport interface EvalRunUsage {\n input: number\n output: number\n cacheRead: number\n cacheCreation: number\n cost: number\n}\n\nexport interface EvalRunSummaryCase {\n id: string\n suite?: string\n variant?: string\n passed: boolean\n score: number\n status: HeadlessResult['status']\n durationMs: number\n scores: EvalScore[]\n metrics: EvalMetric[]\n tagScores: Record<string, number>\n trajectory: Trajectory\n}\n\nexport interface MetricStats {\n mean: number\n min: number\n max: number\n p50: number\n p90: number\n zeroCount: number\n values: number[]\n}\n\nexport interface EvalRunMetricAggregate {\n id: string\n direction: MetricDirection\n tags: string[]\n raw: MetricStats\n normalized: MetricStats\n}\n\n/** Aggregate rollup for one run variant (provider/model target). */\nexport interface EvalVariantSummary {\n variant: string\n count: number\n passed: number\n score: number\n durationMs: number\n usage: EvalRunUsage\n}\n\nexport interface EvalRunSummary {\n count: number\n passed: number\n score: number\n durationMs: number\n usage: EvalRunUsage\n cases: EvalRunSummaryCase[]\n /** Per-metric stats across every case that emitted the metric. */\n metrics: EvalRunMetricAggregate[]\n /** Mean normalized score per tag across all cases. */\n tagScores: Record<string, number>\n /** Per-variant rollups, present when any case carries a variant label. */\n variants?: EvalVariantSummary[]\n}\n\nexport interface EvalRunReporterOptions {\n /** Directory where per-case results and `run-summary.json` are written. */\n outputDir?: string\n /** Enable ANSI colors. Defaults to TTY-aware auto color. */\n color?: boolean\n}\n\nexport interface EvalRunReporter {\n readonly results: readonly EvalCaseResult[]\n record: (result: EvalCaseResult) => Promise<void>\n flush: () => Promise<EvalRunSummary>\n format: () => string\n}\n\n/** Context handed to an eval definition factory at registration time. */\nexport interface EvalDefinitionContext {\n /** Agent-under-test provider. */\n provider: Provider\n /** Provider used by `llmJudge` scorers. Defaults to `provider`. */\n judge: Provider\n /** Optional agent model override; evals should pass it to `EvalCaseOptions.model`. */\n model?: string\n /** Optional judge model override; evals should pass it to `llmJudge({ model })`. */\n judgeModel?: string\n}\n\nexport type EvalDefinition = (ctx: EvalDefinitionContext) => EvalCaseOptions\n\ninterface RegisteredEval {\n id: string\n define: EvalDefinition\n}\n\nconst evalRegistry: RegisteredEval[] = []\n\nconst STUB_PROVIDER = {\n name: 'stub',\n meta: { defaultModel: 'stub' },\n formatTools: (tools: unknown[]) => tools,\n userMessage: () => ({ role: 'user' as const, content: [] }),\n assistantMessage: () => ({ role: 'assistant' as const, content: [] }),\n toolResultsMessage: () => ({ role: 'user' as const, content: [] }),\n stream: async () => {\n throw new Error('stub provider is not runnable')\n },\n} as unknown as Provider\n\n/**\n * Register an eval definition. Eval files call this at module load; the harness\n * (`buildRegisteredEvals`) materializes them with a provider at run time. The\n * factory keeps definitions lazy so a single registry serves any provider/judge\n * pairing without re-importing eval files.\n *\n * Returns the same factory so a file can also `export default` it for direct,\n * registry-free use (e.g. hermetic unit tests).\n */\nexport function defineEval(define: EvalDefinition): EvalDefinition {\n // De-dupe by materializing once with a stub provider to read the id. The stub\n // is never streamed; it only exists so the registry can key on suite/id and a\n // re-imported module doesn't double-register.\n const id = safeRegistryId(define)\n if (!evalRegistry.some(entry => entry.id === id))\n evalRegistry.push({ id, define })\n return define\n}\n\n/** Snapshot of every registered eval, materialized for one provider/judge pair. */\nexport function buildRegisteredEvals(ctx: EvalDefinitionContext): EvalCaseOptions[] {\n return evalRegistry.map(entry => entry.define(ctx))\n}\n\n/** Drop every registered eval — test isolation helper. */\nexport function clearRegisteredEvals(): void {\n evalRegistry.length = 0\n}\n\nfunction safeRegistryId(define: EvalDefinition): string {\n try {\n const stub = define({ provider: STUB_PROVIDER, judge: STUB_PROVIDER })\n return `${stub.suite ?? 'eval'}/${stub.id}`\n }\n catch {\n return `eval/${evalRegistry.length}`\n }\n}\n\nconst DEFAULT_JUDGE_SYSTEM = [\n 'You are a strict software eval judge.',\n 'Grade only the supplied output against the rubric.',\n 'Call the `submit_grade` tool with your score and reasoning.',\n 'The score must be between 0 and 1.',\n].join('\\n')\n\n/** Forced-output tool the judge must call — the schema-enforcement path. */\nconst JUDGE_TOOL: ToolSpec = {\n name: 'submit_grade',\n description: 'Submit the grade for the output under evaluation.',\n inputSchema: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1, description: 'Quality score from 0 (worst) to 1 (best).' },\n reasoning: { type: 'string', description: 'Brief justification for the score.' },\n feedback: { type: 'string', description: 'Optional actionable feedback.' },\n },\n required: ['score', 'reasoning'],\n additionalProperties: false,\n },\n}\n\nexport async function runEvalCase(options: EvalCaseOptions): Promise<EvalCaseResult> {\n const {\n id,\n suite,\n variant,\n tags = [],\n artifactDir,\n workspace,\n scorers = [],\n onEvent,\n ...headless\n } = options\n\n const { metrics: declaredMetrics, sourceFile, ...headlessRest } = headless\n const events: HeadlessEvent[] = []\n // Variant-aware artifact layout: <dir>[/<variant>]/<suite>/<id> so the same\n // case run against two models never overwrites its own output.\n const caseArtifactDir = artifactDir\n ? join(artifactDir, ...(variant ? [safeSegment(variant)] : []), safeSegment(suite ?? 'eval'), safeSegment(id))\n : undefined\n const workspaceState = await prepareWorkspace(headlessRest.execution, workspace)\n const caseMetricIds = new Set(Object.keys(declaredMetrics ?? {}))\n const hasCaseMetrics = caseMetricIds.size > 0\n\n // Merge declared metrics with the always-on efficiency set.\n const metricSpecs: MetricSpecMap = { ...EFFICIENCY_METRICS, ...declaredMetrics }\n const rawMetrics = new Map<string, number>()\n const emitMetric: MetricEmitter = (metricId, raw) => {\n if (!(metricId in metricSpecs))\n throw new EvalMetricError(`Eval ${id}: metric \"${metricId}\" emitted but not declared in defineMetrics`)\n if (!Number.isFinite(raw))\n throw new EvalMetricError(`Eval ${id}: metric \"${metricId}\" emitted a non-finite value (${raw}); scores require finite numbers`)\n rawMetrics.set(metricId, raw)\n }\n\n try {\n const result = await runHeadless({\n ...headlessRest,\n ...(workspaceState.execution ? { execution: workspaceState.execution } : {}),\n onEvent(event) {\n events.push(event)\n onEvent?.(event)\n },\n })\n\n // Auto-emit efficiency metrics from the headless result.\n emitEfficiencyMetrics(emitMetric, result)\n\n const workspaceSnapshot = workspaceState.snapshot()\n const workspaceError = workspaceState.error()\n const scorerContext: EvalScorerContext = {\n id,\n ...(suite ? { suite } : {}),\n tags,\n result,\n events,\n metric: emitMetric,\n ...(workspaceSnapshot ? { workspace: workspaceSnapshot } : {}),\n ...(caseArtifactDir ? { artifactDir: caseArtifactDir } : {}),\n }\n const scores = await runScorers(scorerContext, scorers)\n\n const metrics = finalizeEvalMetrics(metricSpecs, rawMetrics)\n const tagScores = computeEvalTagScores(metrics)\n // Score is metric-driven when metrics are declared beyond efficiency;\n // otherwise fall back to scorer aggregation for back-compat. If the declared\n // set somehow filters to empty, fall back too (avoid a meaningless 0 score).\n const caseMetrics = metrics.filter(metric => caseMetricIds.has(metric.id))\n const score = hasCaseMetrics && caseMetrics.length > 0\n ? meanNormalized(caseMetrics)\n : aggregateScore(scores)\n\n const evalResult: EvalCaseResult = {\n id,\n ...(suite ? { suite } : {}),\n ...(variant ? { variant } : {}),\n tags,\n result,\n score,\n passed: result.status === 'completed' && scores.every(score => score.passed),\n scores,\n metrics,\n tagScores,\n trajectory: buildTrajectory(result.transcript),\n events,\n ...(sourceFile ? { sourceFile } : {}),\n ...(workspaceSnapshot ? { workspace: workspaceSnapshot } : {}),\n ...(workspaceError ? { workspaceError } : {}),\n }\n\n const artifacts = caseArtifactDir\n ? await writeEvalArtifacts(caseArtifactDir, evalResult)\n : undefined\n\n return {\n ...evalResult,\n ...(artifacts ? { artifacts } : {}),\n }\n }\n finally {\n await workspaceState.cleanup()\n }\n}\n\nexport function statusCompleted(name = 'status.completed'): EvalScorer {\n return ({ result }) => ({\n name,\n passed: result.status === 'completed',\n score: result.status === 'completed' ? 1 : 0,\n details: result.status === 'completed' ? undefined : { status: result.status, error: result.error },\n })\n}\n\nexport function fileExists(path: string, name = `file.exists:${path}`): EvalScorer {\n return ({ workspace }) => {\n const found = workspace?.files.some(file => file.path === path) ?? false\n return {\n name,\n passed: found,\n score: found ? 1 : 0,\n details: found ? undefined : `Missing ${path}`,\n }\n }\n}\n\nexport function fileExistsOneOf(paths: string[], name = `file.existsOneOf:${paths.join('|')}`): EvalScorer {\n return ({ workspace }) => {\n const found = paths.find(path => workspace?.files.some(file => file.path === path))\n return {\n name,\n passed: Boolean(found),\n score: found ? 1 : 0,\n details: found ? undefined : `Missing one of: ${paths.join(', ')}`,\n }\n }\n}\n\nexport function fileContains(path: string, expected: string | RegExp, name = `file.contains:${path}`): EvalScorer {\n return ({ workspace }) => {\n const file = workspace?.files.find(file => file.path === path)\n const content = file?.content ?? ''\n const passed = typeof expected === 'string' ? content.includes(expected) : expected.test(content)\n return {\n name,\n passed,\n score: passed ? 1 : 0,\n details: passed\n ? undefined\n : file\n ? `Expected ${path} to contain ${String(expected)}`\n : `Missing ${path}`,\n }\n }\n}\n\nexport function fileContentQuality(\n path: string,\n expected: string,\n name = `file.quality:${path}`,\n): EvalScorer {\n return ({ workspace }) => {\n const file = workspace?.files.find(file => file.path === path)\n const content = file?.content\n if (content === undefined) {\n return {\n name,\n passed: false,\n score: 0,\n details: `Missing ${path}`,\n }\n }\n\n const normalized = content.trim()\n const expectedNormalized = expected.trim()\n const score = normalized === expectedNormalized\n ? 1\n : normalized.includes(expectedNormalized)\n ? 0.75\n : content.includes(expected)\n ? 0.5\n : 0\n\n return {\n name,\n passed: score >= 0.75,\n score,\n details: score >= 0.75 ? undefined : `Expected ${path} to closely match ${JSON.stringify(expectedNormalized)}`,\n }\n }\n}\n\nexport function llmJudge(options: LlmJudgeOptions): EvalScorer {\n const name = options.name ?? 'llm.judge'\n const model = options.model ?? options.provider.meta.defaultModel\n return async (ctx) => {\n const userMessage = options.provider.userMessage(renderJudgePrompt({\n rubric: options.rubric,\n input: options.input?.(ctx) ?? defaultJudgeInput(ctx),\n }))\n\n // Primary: forced structured output via a single tool call. This is the\n // same enforcement the agent loop uses for `schema`, and it works on any\n // tool-calling provider (Anthropic, OpenAI, Cerebras, OpenRouter, ...).\n let text = ''\n const controller = new AbortController()\n const timeoutMs = options.timeoutMs ?? 60_000\n let timedOut = false\n const timer = timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true\n controller.abort(new Error(`LLM judge timed out after ${timeoutMs}ms`))\n }, timeoutMs)\n : undefined\n\n try {\n const streamPromise = options.provider.stream({\n model,\n system: options.system ?? DEFAULT_JUDGE_SYSTEM,\n tools: options.provider.formatTools([JUDGE_TOOL]),\n messages: [userMessage],\n maxTokens: options.maxTokens ?? 600,\n cache: false,\n signal: controller.signal,\n toolChoice: { type: 'tool', name: JUDGE_TOOL.name },\n }, {\n onText(delta) {\n text += delta\n },\n })\n const timeoutPromise = timeoutMs > 0\n ? new Promise<never>((_resolve, reject) => {\n controller.signal.addEventListener('abort', () => {\n if (timedOut)\n reject(new Error(`LLM judge timed out after ${timeoutMs}ms`))\n }, { once: true })\n })\n : undefined\n const result = timeoutPromise\n ? await Promise.race([streamPromise, timeoutPromise])\n : await streamPromise\n\n const parsed = readJudgeResult(result.toolCalls, text || result.text)\n if (options.metric)\n ctx.metric(options.metric, parsed.score)\n return {\n name,\n passed: parsed.score >= 0.7,\n score: parsed.score,\n details: {\n reasoning: parsed.reasoning,\n ...(parsed.feedback ? { feedback: parsed.feedback } : {}),\n ...(parsed.raw ? { raw: parsed.raw } : {}),\n usage: result.usage,\n },\n }\n }\n finally {\n if (timer)\n clearTimeout(timer)\n }\n }\n}\n\nfunction readJudgeResult(\n toolCalls: ToolCall[],\n fallbackText: string,\n): { score: number, reasoning: string, feedback?: string, raw?: string } {\n // Preferred: the forced tool call carries typed fields.\n const call = toolCalls.find(tc => tc.name === JUDGE_TOOL.name)\n if (call) {\n const input = call.input as { score?: unknown, reasoning?: unknown, feedback?: unknown }\n return {\n score: clampScore(input.score),\n reasoning: typeof input.reasoning === 'string' ? input.reasoning : '',\n ...(typeof input.feedback === 'string' ? { feedback: input.feedback } : {}),\n }\n }\n // Fallback: a provider that ignored tool-forcing and returned text. The\n // lenient parser recovers a score from JSON/prose/bare-number output.\n return parseJudgeOutput(fallbackText)\n}\n\n/**\n * Aggregate a group of boolean scorers into a single `0..1` functionality\n * metric (fraction passed) and emit it. Useful for \"N of M files present\".\n */\nexport function functionalityMetric(metricId: string, scorers: EvalScorer[], name = metricId): EvalScorer {\n return async (ctx) => {\n const results = await runScorers(ctx, scorers)\n const passed = results.filter(r => r.passed).length\n const fraction = results.length === 0 ? 1 : passed / results.length\n ctx.metric(metricId, fraction)\n return {\n name,\n passed: passed === results.length,\n score: fraction,\n details: { passed, total: results.length, checks: results.map(r => ({ name: r.name, passed: r.passed })) },\n }\n }\n}\n\nexport function formatEvalCaseSummary(result: EvalCaseResult): string {\n const lines = [\n `Eval ${result.suite ? `${result.suite}/` : ''}${result.id}`,\n ...(result.variant ? [`variant: ${result.variant}`] : []),\n `status: ${result.result.status}`,\n `passed: ${result.passed}`,\n `score: ${result.score.toFixed(2)}`,\n `duration: ${result.result.durationMs}ms`,\n `turns: ${result.result.turns}`,\n `tool calls: ${result.result.numToolCalls}`,\n `usage: input=${result.result.usage.input} output=${result.result.usage.output} cacheRead=${result.result.usage.cacheRead} cacheCreation=${result.result.usage.cacheCreation}${result.result.usage.cost !== undefined ? ` cost=$${result.result.usage.cost.toFixed(6)}` : ''}`,\n ]\n\n if (result.workspace) {\n lines.push(`workspace files: ${result.workspace.files.length}`)\n }\n if (result.workspaceError) {\n lines.push(`workspace error: ${result.workspaceError}`)\n }\n if (result.artifacts) {\n lines.push(`artifacts: ${result.artifacts.dir}`)\n }\n\n if (result.scores.length > 0) {\n lines.push('scores:')\n for (const score of result.scores) {\n const value = score.score !== undefined ? score.score.toFixed(2) : score.passed ? '1.00' : '0.00'\n lines.push(` - ${score.name}: ${value} ${score.passed ? 'pass' : 'fail'}`)\n if (typeof score.details === 'string' && score.details.length > 0)\n lines.push(` ${score.details}`)\n else if (isRecord(score.details) && typeof score.details.reasoning === 'string')\n lines.push(` ${score.details.reasoning}`)\n }\n }\n\n return lines.join('\\n')\n}\n\nexport function formatEvalRunSummary(results: readonly EvalCaseResult[]): string {\n return formatEvalRunSummaryWithOptions(results)\n}\n\n/** Minimal subset of a test runner's API the eval harness needs. */\nexport interface EvalTestRunner {\n it: (name: string, fn: () => Promise<void> | void) => void\n afterAll: (fn: () => Promise<void> | void) => void\n}\n\nexport interface RegisterEvalTestsOptions {\n cases: EvalCaseOptions[]\n runner: EvalTestRunner\n reporter?: EvalRunReporter\n artifactDir?: string\n /**\n * When true (default), each case asserts only that the agent run reached a\n * terminal `completed` status — scores are recorded but never fail the test.\n * Evals are scoring tools, not deterministic assertions.\n */\n failOnIncomplete?: boolean\n /** Print the aggregated run summary after all cases. Default true. */\n printSummary?: boolean\n /** Repeat each case N times (each repetition is its own test). Default 1. */\n repeat?: number\n /** Teardown run once after all cases (e.g. dispose a shared container). */\n dispose?: () => Promise<void> | void\n /**\n * Max eval cases to run concurrently. Each case keeps its own workspace dir,\n * so a shared container runs them in parallel safely. Default 1 (sequential).\n */\n concurrency?: number\n}\n\n/**\n * Register one test per eval case against a test runner, funnel every result\n * into a shared reporter, and print the aggregated summary once after all cases.\n *\n * A failing test means the agent run itself broke (provider/tool/timeout). Low\n * scores are reported, not asserted — see {@link RegisterEvalTestsOptions.failOnIncomplete}.\n */\nexport function registerEvalTests(options: RegisterEvalTestsOptions): EvalRunReporter {\n const reporter = options.reporter ?? createEvalRunReporter()\n const failOnIncomplete = options.failOnIncomplete ?? true\n const printSummary = options.printSummary ?? true\n const repeat = Math.max(1, options.repeat ?? 1)\n const concurrency = Math.max(1, options.concurrency ?? 1)\n\n options.runner.afterAll(async () => {\n await reporter.flush()\n if (printSummary)\n console.log(`\\n${reporter.format()}\\n`)\n if (options.dispose)\n await options.dispose()\n })\n\n // Build the (case × repeat) work list. Each entry runs exactly once; the\n // matching `it` test awaits its already-scheduled promise so bun still shows\n // per-case pass/fail while the pool drives real parallelism.\n const work: Array<{ label: string, run: () => Promise<EvalCaseResult> }> = []\n for (const evalCase of options.cases) {\n const caseLabel = `${evalCase.suite ? `${evalCase.suite}/` : ''}${evalCase.id}`\n const baseLabel = evalCase.variant ? `[${evalCase.variant}] ${caseLabel}` : caseLabel\n for (let run = 1; run <= repeat; run++) {\n const label = repeat > 1 ? `${baseLabel} #${run}` : baseLabel\n const caseId = repeat > 1 ? `${evalCase.id}-repeat-${run}` : evalCase.id\n work.push({\n label,\n run: () => runEvalCase({\n ...evalCase,\n id: caseId,\n ...(options.artifactDir ? { artifactDir: options.artifactDir } : {}),\n }),\n })\n }\n }\n\n const schedule = createLazyPool(concurrency)\n\n work.forEach((w) => {\n options.runner.it(w.label, async () => {\n const result = await schedule(w.run)\n await reporter.record(result)\n if (failOnIncomplete && result.result.status !== 'completed') {\n throw new Error(`Eval ${w.label} did not complete: ${JSON.stringify(result.result.error ?? { status: result.result.status }, null, 2)}`)\n }\n })\n })\n\n return reporter\n}\n\n/**\n * Lazily run tasks with a bounded concurrency `limit`. Nothing starts until a\n * runner invokes the corresponding test callback, so filtered/skipped tests do\n * not leak model or Docker work in the background.\n */\nfunction createLazyPool(limit: number): <T>(task: () => Promise<T>) => Promise<T> {\n const queue: Array<() => void> = []\n let active = 0\n\n const drain = (): void => {\n const available = Math.min(limit - active, queue.length)\n for (let i = 0; i < available; i++)\n queue.shift()?.()\n }\n\n return <T>(task: () => Promise<T>) => new Promise<T>((resolve, reject) => {\n const run = async (): Promise<void> => {\n active++\n try {\n resolve(await task())\n }\n catch (err) {\n reject(err)\n }\n finally {\n active--\n drain()\n }\n }\n queue.push(() => void run())\n drain()\n })\n}\n\nexport function createEvalRunReporter(options: EvalRunReporterOptions = {}): EvalRunReporter {\n const results: EvalCaseResult[] = []\n\n return {\n get results() {\n return results\n },\n async record(result) {\n results.push(result)\n if (options.outputDir) {\n const segments = [\n ...(result.variant ? [safeSegment(result.variant)] : []),\n safeSegment(result.suite ?? 'eval'),\n safeSegment(result.id),\n ]\n const casePath = join(options.outputDir, 'cases', `${segments.join('--')}.json`)\n await mkdir(join(options.outputDir, 'cases'), { recursive: true })\n await writeFile(casePath, `${JSON.stringify(result, null, 2)}\\n`)\n }\n },\n async flush() {\n const summary = buildEvalRunSummary(results)\n if (options.outputDir) {\n await mkdir(options.outputDir, { recursive: true })\n await writeFile(join(options.outputDir, 'run-summary.json'), `${JSON.stringify(summary, null, 2)}\\n`)\n }\n return summary\n },\n format() {\n return formatEvalRunSummaryWithOptions(results, { color: options.color })\n },\n }\n}\n\n/** Stable ordering by `variant`, then `suite/id`, so parallel completion order doesn't shuffle output. */\nfunction sortCases(results: readonly EvalCaseResult[]): EvalCaseResult[] {\n return [...results].sort((a, b) => {\n const va = a.variant ?? ''\n const vb = b.variant ?? ''\n if (va !== vb)\n return va.localeCompare(vb)\n const ka = `${a.suite ?? ''}/${a.id}`\n const kb = `${b.suite ?? ''}/${b.id}`\n return ka.localeCompare(kb)\n })\n}\n\n/** Distinct variant labels across results, in sorted order. */\nfunction distinctVariants(results: readonly EvalCaseResult[]): string[] {\n return [...new Set(results.map(r => r.variant).filter((v): v is string => Boolean(v)))].sort()\n}\n\nexport function buildEvalRunSummary(input: readonly EvalCaseResult[]): EvalRunSummary {\n const results = sortCases(input)\n const usage = results.reduce((acc, result) => {\n acc.input += result.result.usage.input\n acc.output += result.result.usage.output\n acc.cacheRead += result.result.usage.cacheRead\n acc.cacheCreation += result.result.usage.cacheCreation\n acc.cost += result.result.usage.cost ?? 0\n return acc\n }, { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, cost: 0 })\n const totalScore = results.reduce((sum, result) => sum + result.score, 0)\n\n return {\n count: results.length,\n passed: results.filter(result => result.passed).length,\n score: results.length > 0 ? totalScore / results.length : 0,\n durationMs: results.reduce((sum, result) => sum + result.result.durationMs, 0),\n usage,\n cases: results.map(result => ({\n id: result.id,\n ...(result.suite ? { suite: result.suite } : {}),\n ...(result.variant ? { variant: result.variant } : {}),\n passed: result.passed,\n score: result.score,\n status: result.result.status,\n durationMs: result.result.durationMs,\n scores: result.scores,\n metrics: result.metrics,\n tagScores: result.tagScores,\n trajectory: result.trajectory,\n })),\n metrics: aggregateMetrics(results),\n tagScores: aggregateTagScores(results),\n ...(distinctVariants(results).length > 0 ? { variants: aggregateVariants(results) } : {}),\n }\n}\n\nfunction aggregateVariants(results: readonly EvalCaseResult[]): EvalVariantSummary[] {\n return distinctVariants(results).map((variant) => {\n const group = results.filter(r => r.variant === variant)\n const usage = group.reduce((acc, result) => {\n acc.input += result.result.usage.input\n acc.output += result.result.usage.output\n acc.cacheRead += result.result.usage.cacheRead\n acc.cacheCreation += result.result.usage.cacheCreation\n acc.cost += result.result.usage.cost ?? 0\n return acc\n }, { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, cost: 0 })\n return {\n variant,\n count: group.length,\n passed: group.filter(r => r.passed).length,\n score: mean(group.map(r => r.score)),\n durationMs: group.reduce((sum, r) => sum + r.result.durationMs, 0),\n usage,\n }\n })\n}\n\nfunction aggregateMetrics(results: readonly EvalCaseResult[]): EvalRunMetricAggregate[] {\n const byId = new Map<string, EvalMetric[]>()\n for (const result of results) {\n for (const metric of result.metrics) {\n const list = byId.get(metric.id) ?? []\n list.push(metric)\n byId.set(metric.id, list)\n }\n }\n return [...byId.entries()].map(([id, metrics]) => ({\n id,\n direction: metrics[0].direction,\n tags: metrics[0].tags,\n raw: metricStats(metrics.map(m => m.raw)),\n normalized: metricStats(metrics.map(m => m.normalized)),\n }))\n}\n\nfunction aggregateTagScores(results: readonly EvalCaseResult[]): Record<string, number> {\n const byTag = new Map<string, number[]>()\n for (const result of results) {\n for (const [tag, value] of Object.entries(result.tagScores)) {\n const list = byTag.get(tag) ?? []\n list.push(value)\n byTag.set(tag, list)\n }\n }\n const out: Record<string, number> = {}\n for (const [tag, values] of byTag)\n out[tag] = mean(values)\n return out\n}\n\nfunction metricStats(values: number[]): MetricStats {\n const sorted = [...values].sort((a, b) => a - b)\n return {\n mean: mean(values),\n min: sorted[0] ?? 0,\n max: sorted[sorted.length - 1] ?? 0,\n p50: percentile(sorted, 0.5),\n p90: percentile(sorted, 0.9),\n zeroCount: values.filter(v => v === 0).length,\n values,\n }\n}\n\nfunction percentile(sorted: number[], q: number): number {\n if (sorted.length === 0)\n return 0\n const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(q * sorted.length) - 1))\n return sorted[idx]\n}\n\nfunction formatEvalRunSummaryWithOptions(\n input: readonly EvalCaseResult[],\n options: { color?: boolean } = {},\n): string {\n const results = sortCases(input)\n const color = createEvalColors(options.color)\n if (results.length === 0)\n return `${color.heading('Eval run summary')}\\n${color.muted('no evals ran')}`\n\n const summary = buildEvalRunSummary(results)\n const out: string[] = []\n const variants = distinctVariants(results)\n\n out.push(color.heading('Eval run summary'))\n if (variants.length > 1) {\n // Multi-target run: lead with the cross-variant comparison matrix, then\n // one results table per variant so each target stays fully inspectable.\n out.push(renderComparisonTable(results, variants, color))\n for (const variant of variants) {\n const group = results.filter(r => r.variant === variant)\n out.push('')\n out.push(color.heading(variant))\n out.push(renderResultsTable(group, buildEvalRunSummary(group), color))\n }\n }\n else {\n out.push(renderResultsTable(results, summary, color))\n }\n\n const tagTable = renderTagTable(summary.tagScores, color)\n if (tagTable) {\n out.push('')\n out.push(tagTable)\n }\n out.push('')\n\n // Per-eval breakdown beneath the tables.\n const hyperlinks = options.color !== false\n const linkText = (target: string): string => {\n const abs = absPath(target)\n return hyperlinks ? oscLink(abs, abs) : abs\n }\n\n for (const result of results) {\n const caseLabel = `${result.suite ? `${result.suite}/` : ''}${result.id}`\n const label = result.variant ? `[${result.variant}] ${caseLabel}` : caseLabel\n out.push(`${color.dot(result.passed)} ${color.caseStatus(result.passed, label)}`)\n out.push(`${color.muted('score')} ${color.score(result.score)}`)\n\n const tagEntries = Object.entries(result.tagScores)\n if (tagEntries.length > 0)\n out.push(`${color.muted('tags:')} ${tagEntries.map(([tag, value]) => `${color.tag(tag)} ${color.score(value)}`).join(' ')}`)\n\n for (const metric of result.metrics) {\n const note = metric.missing ? color.fail(' (not emitted)') : color.muted(` (${formatMetricRaw(metric)})`)\n out.push(`${color.muted(padEnd(metric.id, 28))} ${color.score(metric.normalized)}${note}`)\n }\n\n for (const score of result.scores) {\n const detail = scoreDetailLine(score)\n if (!score.passed && detail)\n out.push(`${color.dot(score.passed)} ${color.muted(`${score.name}: ${truncate(detail, 140)}`)}`)\n }\n\n // Links — full absolute paths so they work in every terminal.\n if (result.sourceFile)\n out.push(`${color.muted('case:')} ${color.muted(linkText(result.sourceFile))}`)\n const resultTarget = caseLinkTarget(result)\n if (resultTarget)\n out.push(`${color.muted('result:')} ${color.muted(linkText(resultTarget))}`)\n\n // Turns last — can be very long.\n if (result.trajectory.steps.length > 0)\n out.push(`${color.muted(`turns: ${result.trajectory.totalBlocks}`)} ${formatTrajectoryColored(result.trajectory, color)}`)\n\n out.push('')\n }\n\n return out.join('\\n').replace(/\\n+$/, '')\n}\n\nfunction renderTagTable(tagScores: Record<string, number>, color: EvalColors): string | undefined {\n const entries = Object.entries(tagScores)\n if (entries.length === 0)\n return undefined\n const tagWidth = Math.max('TAG'.length, ...entries.map(([tag]) => tag.length))\n const top = `┌${'─'.repeat(tagWidth + 2)}┬${'─'.repeat(9)}┐`\n const mid = `├${'─'.repeat(tagWidth + 2)}┼${'─'.repeat(9)}┤`\n const bot = `└${'─'.repeat(tagWidth + 2)}┴${'─'.repeat(9)}┘`\n const lines = [\n top,\n `│ ${color.heading(padEnd('TAG', tagWidth))} │ ${color.heading('SCORE')} │`,\n mid,\n ...entries.map(([tag, value]) => `│ ${color.muted(padEnd(tag, tagWidth))} │ ${color.score(value)} │`),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction formatMetricRaw(metric: EvalMetric): string {\n const raw = Number.isInteger(metric.raw) ? formatInt(metric.raw) : metric.raw.toFixed(3)\n const arrow = metric.direction === 'lower-is-better' ? '↓' : '↑'\n return `raw ${raw} ${arrow}`\n}\n\n/**\n * Resolve a filesystem target to link an eval case to. Prefers the written\n * artifact (`result.json` → its dir), so the link opens the case's output.\n * Returns `undefined` when no artifacts were written.\n */\nfunction caseLinkTarget(result: EvalCaseResult): string | undefined {\n return result.artifacts?.result ?? result.artifacts?.dir\n}\n\n/** Wrap text in an OSC 8 terminal hyperlink to a local path or URL. */\nfunction oscLink(target: string, text: string): string {\n const url = /^(?:file|https?):\\/\\//.test(target)\n ? target\n : `file://${resolve(target)}`\n const OSC = '\\u001B]8;;'\n const ST = '\\u001B\\\\'\n return `${OSC}${url}${ST}${text}${OSC}${ST}`\n}\n\n/** Absolute filesystem path (strips any `file://` prefix, resolves relatives). */\nfunction absPath(target: string): string {\n const clean = target.replace(/^file:\\/\\//, '')\n return resolve(clean)\n}\n\n/**\n * Case key used to line up the same eval across variants in the comparison\n * matrix. Strips the `-repeat-N` suffix `registerEvalTests` appends so a\n * repeated case aggregates into one row (mean score, x/y passed).\n */\nfunction comparisonCaseKey(result: EvalCaseResult): string {\n const id = result.id.replace(/-repeat-\\d+$/, '')\n return `${result.suite ? `${result.suite}/` : ''}${id}`\n}\n\n/**\n * Cross-variant comparison matrix: one row per eval case, one column per\n * variant (provider/model target), plus rollup rows (score / passed / cost /\n * time) so two models can be read side by side at a glance.\n */\nfunction renderComparisonTable(\n input: readonly EvalCaseResult[],\n variants: string[],\n color: EvalColors,\n): string {\n const results = sortCases(input)\n const caseKeys = [...new Set(results.map(comparisonCaseKey))].sort()\n const byCell = new Map<string, EvalCaseResult[]>()\n for (const result of results) {\n const key = `${comparisonCaseKey(result)}\\u0000${result.variant ?? ''}`\n const list = byCell.get(key) ?? []\n list.push(result)\n byCell.set(key, list)\n }\n\n interface Cell { text: string, score?: number, passed?: boolean }\n const cellFor = (caseKey: string, variant: string): Cell => {\n const group = byCell.get(`${caseKey}\\u0000${variant}`)\n if (!group || group.length === 0)\n return { text: '-' }\n const score = mean(group.map(r => r.score))\n const passedCount = group.filter(r => r.passed).length\n const allPassed = passedCount === group.length\n const status = group.length > 1\n ? `${passedCount}/${group.length}`\n : allPassed ? 'pass' : 'fail'\n return { text: `${score.toFixed(2)} ${status}`, score, passed: allPassed }\n }\n\n const variantSummaries = aggregateVariants(results)\n const summaryOf = (variant: string): EvalVariantSummary | undefined =>\n variantSummaries.find(s => s.variant === variant)\n\n const rows: Array<{ label: string, cells: Cell[], rollup?: boolean }> = caseKeys.map(key => ({\n label: key,\n cells: variants.map(variant => cellFor(key, variant)),\n }))\n const rollups: Array<{ label: string, cells: Cell[], rollup: true }> = [\n {\n label: 'SCORE',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return s ? { text: s.score.toFixed(2), score: s.score } : { text: '-' }\n }),\n },\n {\n label: 'PASSED',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return s ? { text: `${s.passed}/${s.count}`, passed: s.passed === s.count } : { text: '-' }\n }),\n },\n {\n label: 'COST',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return { text: formatCost(s?.usage.cost ?? 0) }\n }),\n },\n {\n label: 'TIME',\n rollup: true,\n cells: variants.map((variant) => {\n const s = summaryOf(variant)\n return { text: s ? formatDuration(s.durationMs) : '-' }\n }),\n },\n ]\n\n const header = ['EVAL', ...variants]\n const allRows = [...rows, ...rollups]\n const widths = header.map((h, i) => Math.max(\n h.length,\n ...allRows.map(row => (i === 0 ? row.label : row.cells[i - 1].text).length),\n ))\n\n const top = `┌${widths.map(w => '─'.repeat(w + 2)).join('┬')}┐`\n const mid = `├${widths.map(w => '─'.repeat(w + 2)).join('┼')}┤`\n const bot = `└${widths.map(w => '─'.repeat(w + 2)).join('┴')}┘`\n\n const paintComparisonCell = (cell: Cell, padded: string): string => {\n if (cell.score === undefined && cell.passed === undefined)\n return color.muted(padded)\n // Re-render the score fragment colored; status colored by pass/fail.\n if (cell.score !== undefined) {\n const scoreText = cell.score.toFixed(2)\n const rest = cell.text.slice(scoreText.length)\n const coloredRest = cell.passed === undefined\n ? color.muted(rest)\n : cell.passed ? color.pass(rest) : color.fail(rest)\n return padded.replace(cell.text, `${color.score(cell.score)}${coloredRest}`)\n }\n return padded.replace(cell.text, cell.passed ? color.pass(cell.text) : color.fail(cell.text))\n }\n\n const renderRow = (row: { label: string, cells: Cell[], rollup?: boolean }): string => {\n const labelPadded = padEnd(row.label, widths[0])\n const labelPainted = row.rollup ? color.heading(labelPadded) : color.muted(labelPadded)\n const cellParts = row.cells.map((cell, i) => {\n const padded = padStart(cell.text, widths[i + 1])\n return ` ${paintComparisonCell(cell, padded)} `\n })\n return `│ ${labelPainted} │${cellParts.join('│')}│`\n }\n\n const lines = [\n top,\n `│ ${color.heading(padEnd(header[0], widths[0]))} │${variants.map((v, i) => ` ${color.heading(padStart(v, widths[i + 1]))} `).join('│')}│`,\n mid,\n ...rows.map(renderRow),\n mid,\n ...rollups.map(renderRow),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction renderResultsTable(\n results: readonly EvalCaseResult[],\n summary: EvalRunSummary,\n color: EvalColors,\n): string {\n const header = ['EVAL', 'STATUS', 'SCORE', 'IN', 'OUT', 'CACHE R', 'CACHE W', 'COST', 'TIME']\n const rows = results.map((result) => {\n const label = `${result.suite ? `${result.suite}/` : ''}${result.id}`\n const u = result.result.usage\n return {\n passed: result.passed,\n cells: [\n label,\n result.passed ? 'pass' : 'fail',\n result.score.toFixed(2),\n formatInt(u.input),\n formatInt(u.output),\n formatInt(u.cacheRead),\n formatInt(u.cacheCreation),\n formatCost(u.cost ?? 0),\n formatDuration(result.result.durationMs),\n ],\n score: result.score,\n }\n })\n\n const totals = {\n cells: [\n `TOTAL (${summary.passed}/${summary.count})`,\n summary.passed === summary.count ? 'pass' : 'fail',\n summary.score.toFixed(2),\n formatInt(summary.usage.input),\n formatInt(summary.usage.output),\n formatInt(summary.usage.cacheRead),\n formatInt(summary.usage.cacheCreation),\n formatCost(summary.usage.cost),\n formatDuration(summary.durationMs),\n ],\n passed: summary.passed === summary.count,\n score: summary.score,\n }\n\n // Right-align numeric columns (everything after STATUS).\n const aligns: Array<'left' | 'right'> = ['left', 'left', 'right', 'right', 'right', 'right', 'right', 'right', 'right']\n const widths = header.map((h, i) =>\n Math.max(h.length, ...rows.map(r => r.cells[i].length), totals.cells[i].length),\n )\n\n const top = `┌${widths.map(w => '─'.repeat(w + 2)).join('┬')}┐`\n const mid = `├${widths.map(w => '─'.repeat(w + 2)).join('┼')}┤`\n const bot = `└${widths.map(w => '─'.repeat(w + 2)).join('┴')}┘`\n\n const renderRow = (cells: string[], paint?: (i: number, raw: string, padded: string) => string): string => {\n const parts = cells.map((cell, i) => {\n const padded = aligns[i] === 'right' ? padStart(cell, widths[i]) : padEnd(cell, widths[i])\n return ` ${paint ? paint(i, cell, padded) : padded} `\n })\n return `│${parts.join('│')}│`\n }\n\n const lines = [\n top,\n renderRow(header, (_i, _raw, padded) => color.heading(padded)),\n mid,\n ...rows.map(r => renderRow(r.cells, (i, raw, padded) => paintCell(i, raw, padded, r.passed, r.score, color))),\n mid,\n renderRow(totals.cells, (i, raw, padded) => paintCell(i, raw, padded, totals.passed, totals.score, color, true)),\n bot,\n ]\n return lines.join('\\n')\n}\n\nfunction paintCell(\n col: number,\n raw: string,\n padded: string,\n passed: boolean,\n score: number,\n color: EvalColors,\n bold = false,\n): string {\n // EVAL\n if (col === 0)\n return bold ? color.heading(padded) : color.caseStatus(passed, padded)\n // STATUS\n if (col === 1)\n return padded.replace(raw, color.status(passed))\n // SCORE\n if (col === 2)\n return padded.replace(raw, color.score(score))\n // COST\n if (col === 7)\n return color.cost(padded)\n return color.muted(padded)\n}\n\nfunction scoreDetailLine(score: EvalScore): string | undefined {\n if (typeof score.details === 'string')\n return score.details\n if (isRecord(score.details) && typeof score.details.reasoning === 'string')\n return score.details.reasoning\n return undefined\n}\n\nfunction formatInt(value: number): string {\n return value.toLocaleString('en-US')\n}\n\nfunction formatCost(value: number): string {\n return value > 0 ? `$${value.toFixed(4)}` : '-'\n}\n\nfunction formatDuration(ms: number): string {\n const rounded = Math.round(ms)\n if (rounded < 1000)\n return `${rounded}ms`\n const s = rounded / 1000\n // Drop a trailing `.0` so `4.0s` reads as `4s`.\n return `${Number.isInteger(s) ? s : s.toFixed(1)}s`\n}\n\nfunction padEnd(value: string, width: number): string {\n return value.length >= width ? value : value + ' '.repeat(width - value.length)\n}\n\nfunction padStart(value: string, width: number): string {\n return value.length >= width ? value : ' '.repeat(width - value.length) + value\n}\n\nfunction truncate(value: string, max: number): string {\n const oneLine = value.replace(/\\s+/g, ' ').trim()\n return oneLine.length > max ? `${oneLine.slice(0, max - 1)}…` : oneLine\n}\n\ninterface WorkspaceState {\n execution?: ExecutionContext\n snapshot: () => EvalWorkspaceSnapshot | undefined\n error: () => string | undefined\n cleanup: () => Promise<void>\n}\n\nasync function prepareWorkspace(\n execution: ExecutionContext | undefined,\n workspace: EvalWorkspaceOptions | undefined,\n): Promise<WorkspaceState> {\n if (!workspace) {\n return {\n snapshot: () => undefined,\n error: () => undefined,\n cleanup: async () => {},\n }\n }\n\n let tempDir: string | undefined\n let baseExecution = execution\n if (!baseExecution) {\n const cwd = workspace.cwd ?? await mkdtemp(join(tmpdir(), 'zidane-eval-'))\n if (!workspace.cwd)\n tempDir = cwd\n baseExecution = createProcessContext({ cwd })\n }\n\n const captured: { snapshot?: EvalWorkspaceSnapshot, error?: string } = {}\n const wrapped = withWorkspaceLifecycle(baseExecution, workspace, captured)\n\n return {\n execution: wrapped,\n snapshot: () => captured.snapshot,\n error: () => captured.error,\n cleanup: async () => {\n if (tempDir && !workspace.retain)\n await rm(tempDir, { recursive: true, force: true })\n },\n }\n}\n\nfunction withWorkspaceLifecycle(\n execution: ExecutionContext,\n workspace: EvalWorkspaceOptions,\n captured: { snapshot?: EvalWorkspaceSnapshot, error?: string },\n): ExecutionContext {\n return {\n ...execution,\n async spawn(config) {\n const handle = await execution.spawn({\n ...config,\n ...(workspace.cwd && !config?.cwd ? { cwd: workspace.cwd } : {}),\n })\n if (workspace.seedDir)\n await seedWorkspace(execution, handle, workspace)\n return handle\n },\n async destroy(handle) {\n try {\n captured.snapshot = await captureWorkspace(execution, handle, workspace)\n }\n catch (err) {\n captured.error = err instanceof Error ? err.message : String(err)\n }\n finally {\n await execution.destroy(handle)\n }\n },\n }\n}\n\nasync function seedWorkspace(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n workspace: EvalWorkspaceOptions,\n): Promise<void> {\n const target = workspace.seedTarget ?? '.'\n const result = await execution.exec(\n handle,\n `mkdir -p ${shellQuote(target)} && cp -R ${shellQuote(`${workspace.seedDir!}/.`)} ${shellQuote(target)}`,\n )\n if (result.exitCode !== 0)\n throw new Error(`Failed to seed eval workspace: ${result.stderr || result.stdout}`)\n}\n\nasync function captureWorkspace(\n execution: ExecutionContext,\n handle: ExecutionHandle,\n workspace: EvalWorkspaceOptions,\n): Promise<EvalWorkspaceSnapshot> {\n const capturePaths = workspace.capture?.length ? workspace.capture : ['.']\n // `-print0` (NUL-delimited) so filenames containing newlines or spaces don't\n // corrupt the listing. Dedup in JS rather than `sort -u`, which has no\n // portable NUL-record mode across GNU (`-z`) and BSD `sort`.\n const command = [\n `cd ${shellQuote(handle.cwd)}`,\n '&&',\n 'for p in',\n capturePaths.map(shellQuote).join(' '),\n '; do',\n 'if [ -e \"$p\" ]; then',\n 'find \"$p\" \\\\( -path \"*/node_modules/*\" -o -path \"*/.git/*\" \\\\) -prune -o -type f -print0',\n '; fi',\n 'done',\n ].join(' ')\n\n const listed = await execution.exec(handle, command)\n if (listed.exitCode !== 0)\n throw new Error(`Failed to list eval workspace: ${listed.stderr || listed.stdout}`)\n\n const maxFileChars = workspace.maxFileChars ?? 256 * 1024\n const files: EvalWorkspaceFile[] = []\n const seen = new Set<string>()\n for (const rawPath of listed.stdout.split('\\0').filter(Boolean)) {\n const path = normalizeSnapshotPath(rawPath)\n if (seen.has(path))\n continue\n seen.add(path)\n const content = await execution.readFile(handle, path)\n const binary = content.includes('\\0')\n const truncated = content.length > maxFileChars\n files.push({\n path,\n size: content.length,\n ...(binary ? { binary: true } : { content: truncated ? content.slice(0, maxFileChars) : content }),\n ...(truncated ? { truncated: true } : {}),\n })\n }\n\n return { cwd: handle.cwd, files }\n}\n\nasync function runScorers(ctx: EvalScorerContext, scorers: EvalScorer[]): Promise<EvalScore[]> {\n const scores: EvalScore[] = []\n for (const scorer of scorers) {\n try {\n scores.push(await scorer(ctx))\n }\n catch (err) {\n if (err instanceof EvalMetricError)\n throw err\n scores.push({\n name: scorer.name || 'anonymous-scorer',\n passed: false,\n score: 0,\n details: err instanceof Error ? err.message : String(err),\n })\n }\n }\n return scores\n}\n\nfunction aggregateScore(scores: EvalScore[]): number {\n if (scores.length === 0)\n return 1\n const total = scores.reduce((sum, score) => sum + (score.score ?? (score.passed ? 1 : 0)), 0)\n return total / scores.length\n}\n\nexport function efficiencyMetricValues(result: HeadlessResult): Record<keyof typeof EFFICIENCY_METRICS, number> {\n const u = result.usage\n // Fraction of read-side input served from cache. cacheRead is reported on top\n // of `input`, so the denominator is cacheRead + input (not input alone).\n const readTotal = u.input + u.cacheRead\n return {\n 'execution-time': result.durationMs,\n 'provider-tokens': u.input + u.output,\n 'cache-read-rate': readTotal > 0 ? u.cacheRead / readTotal : 0,\n }\n}\n\nexport function emitEfficiencyMetrics(emit: MetricEmitter, result: HeadlessResult): void {\n const values = efficiencyMetricValues(result)\n for (const [id, raw] of Object.entries(values))\n emit(id, raw)\n}\n\nexport function finalizeEvalMetrics(\n specs: MetricSpecMap,\n raw: Map<string, number>,\n): EvalMetric[] {\n // A declared-but-unemitted metric (e.g. a judge that threw mid-run) records\n // as a missing 0 rather than crashing the whole case — evals score what they\n // can and surface the gap, they don't abort the run.\n return Object.entries(specs).map(([metricId, spec]) => {\n const emitted = raw.has(metricId)\n const value = emitted ? raw.get(metricId)! : spec.min\n return {\n id: metricId,\n raw: emitted ? value : 0,\n normalized: emitted ? normalizeMetric(value, spec) : 0,\n direction: spec.direction,\n min: spec.min,\n max: spec.max,\n tags: spec.tags ?? [],\n ...(spec.description ? { description: spec.description } : {}),\n ...(emitted ? {} : { missing: true }),\n }\n })\n}\n\nexport function computeEvalTagScores(metrics: EvalMetric[]): Record<string, number> {\n const byTag = new Map<string, number[]>()\n for (const metric of metrics) {\n for (const tag of metric.tags) {\n const list = byTag.get(tag) ?? []\n list.push(metric.normalized)\n byTag.set(tag, list)\n }\n }\n const out: Record<string, number> = {}\n for (const [tag, values] of byTag)\n out[tag] = mean(values)\n return out\n}\n\nfunction meanNormalized(metrics: EvalMetric[]): number {\n return metrics.length === 0 ? 0 : mean(metrics.map(m => m.normalized))\n}\n\nfunction accumulateEvalAgentStats(acc: EvalAgentStats, turn: EvalAgentRunStats): void {\n acc.runs += 1\n acc.input += turn.input\n acc.output += turn.output\n acc.cacheRead += turn.cacheRead\n acc.cacheCreation += turn.cacheCreation\n acc.cost += turn.cost\n acc.turns += turn.turns\n acc.toolCalls += turn.toolCalls\n acc.durationMs += turn.durationMs\n}\n\nfunction countToolCallsInTurns(turns: readonly SessionTurn[]): number {\n let count = 0\n for (const turn of turns) {\n if (turn.role !== 'assistant')\n continue\n count += turn.content.filter(block => block.type === 'tool_call').length\n }\n return count\n}\n\nfunction mean(values: number[]): number {\n return values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\ninterface EvalColors {\n heading: (value: string) => string\n pass: (value: string) => string\n fail: (value: string) => string\n muted: (value: string) => string\n cost: (value: string) => string\n status: (passed: boolean) => string\n score: (value: number) => string\n caseStatus: (passed: boolean, value: string) => string\n dot: (passed: boolean) => string\n tag: (value: string) => string\n step: (kind: TrajectoryStepKind, value: string) => string\n}\n\nfunction createEvalColors(enabled = shouldUseColor()): EvalColors {\n if (!enabled) {\n return {\n heading: value => value,\n pass: value => value,\n fail: value => value,\n muted: value => value,\n cost: value => value,\n status: passed => passed ? 'pass' : 'fail',\n score: value => value.toFixed(2),\n caseStatus: (_passed, value) => value,\n dot: passed => passed ? '+' : 'x',\n tag: value => value,\n step: (_kind, value) => value,\n }\n }\n return {\n heading: value => chalk.bold(value),\n pass: value => chalk.green(value),\n fail: value => chalk.red(value),\n muted: value => chalk.gray(value),\n cost: value => chalk.cyan(value),\n status: passed => passed ? chalk.green('pass') : chalk.red('fail'),\n score: value => value >= 0.9 ? chalk.green(value.toFixed(2)) : value >= 0.7 ? chalk.yellow(value.toFixed(2)) : chalk.red(value.toFixed(2)),\n caseStatus: (passed, value) => passed ? chalk.green(value) : chalk.red(value),\n dot: passed => passed ? chalk.green('●') : chalk.red('●'),\n // Distinct from the step palette (which uses magenta/blue/cyan/yellow/green).\n tag: value => chalk.bold(chalk.whiteBright(value)),\n step: (kind, value) => paintStep(kind, value),\n }\n}\n\n/** Per-kind trajectory colors: think=magenta, text=blue, tools by family. */\nfunction paintStep(kind: TrajectoryStepKind, value: string): string {\n if (kind === 'think')\n return chalk.magenta(value)\n if (kind === 'text')\n return chalk.blue(value)\n // tool step — color by intent so a timeline reads at a glance.\n if (/write|edit|create/.test(value))\n return chalk.green(value)\n if (/read|list|glob|grep|search/.test(value))\n return chalk.cyan(value)\n if (/shell|bash|exec|run/.test(value))\n return chalk.yellow(value)\n if (/spawn|task|agent/.test(value))\n return chalk.magentaBright(value)\n return chalk.white(value)\n}\n\nfunction formatTrajectoryColored(trajectory: Trajectory, color: EvalColors): string {\n return trajectory.steps\n .map((step) => {\n const base = step.kind === 'tool' ? (step.name ?? 'tool') : step.kind\n const labelWithCount = step.count > 1 ? `${base} ×${step.count}` : base\n const painted = color.step(step.kind, labelWithCount)\n const timing = step.durationMs && step.durationMs >= 100 ? color.muted(`(${formatDuration(step.durationMs)})`) : ''\n return timing ? `${painted} ${timing}` : painted\n })\n .join(color.muted(' → '))\n}\n\nfunction shouldUseColor(): boolean {\n return Boolean(process.stdout.isTTY && !process.env.NO_COLOR)\n}\n\nfunction renderJudgePrompt(input: { rubric: string, input: string }): string {\n return [\n 'Rubric:',\n input.rubric,\n '',\n 'Output to grade:',\n input.input,\n '',\n 'Return JSON only.',\n ].join('\\n')\n}\n\nfunction defaultJudgeInput(ctx: EvalScorerContext): string {\n const chunks = [\n `Final answer:\\n${ctx.result.finalText}`,\n ]\n if (ctx.workspace) {\n chunks.push(`Workspace files:\\n${ctx.workspace.files.map(file => [\n `--- ${file.path}${file.truncated ? ' (truncated)' : ''} ---`,\n file.binary ? '[binary omitted]' : file.content ?? '',\n ].join('\\n')).join('\\n')}`)\n }\n return chunks.join('\\n\\n')\n}\n\nfunction parseJudgeOutput(raw: string): { score: number, reasoning: string, feedback?: string, raw?: string } {\n const trimmed = stripCodeFences(raw.trim())\n\n // Preferred path: a JSON object somewhere in the output.\n const jsonText = extractJsonObject(trimmed)\n if (jsonText) {\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>\n if (parsed.score !== undefined || parsed.reasoning !== undefined) {\n return {\n score: clampScore(parsed.score),\n reasoning: typeof parsed.reasoning === 'string' ? parsed.reasoning : '',\n ...(typeof parsed.feedback === 'string' ? { feedback: parsed.feedback } : {}),\n ...(jsonText === trimmed ? {} : { raw: trimmed }),\n }\n }\n }\n catch {\n // fall through to lenient parsing\n }\n }\n\n // Lenient fallbacks for models that don't honor strict JSON:\n // 1) a `\"score\": 0.8` / `score = 0.8` fragment anywhere.\n const scoreFragment = trimmed.match(/score[\"']?\\s*[:=]\\s*(-?\\d+(?:\\.\\d+)?)/i)\n if (scoreFragment) {\n return { score: clampScore(Number(scoreFragment[1])), reasoning: trimmed.slice(0, 500), raw: trimmed }\n }\n // 2) the whole output is just a number (`0.8` or `8/10`).\n const bareFraction = trimmed.match(/^(-?\\d+(?:\\.\\d+)?)\\s*\\/\\s*(\\d+(?:\\.\\d+)?)$/)\n if (bareFraction) {\n const denom = Number(bareFraction[2])\n return { score: clampScore(denom === 0 ? 0 : Number(bareFraction[1]) / denom), reasoning: trimmed, raw: trimmed }\n }\n const bareNumber = trimmed.match(/^-?\\d+(?:\\.\\d+)?$/)\n if (bareNumber) {\n return { score: clampScore(Number(trimmed)), reasoning: '', raw: trimmed }\n }\n\n return { score: 0, reasoning: 'Judge did not return a parseable score.', raw: trimmed }\n}\n\n/** Strip a leading/trailing markdown code fence (``` or ```json). */\nfunction stripCodeFences(text: string): string {\n const fence = text.match(/^```(?:json)?[ \\t]*\\n([\\s\\S]*?)\\n```$/i)\n return fence ? fence[1].trim() : text\n}\n\n/** Extract the first balanced `{...}` object, ignoring braces inside strings. */\nfunction extractJsonObject(text: string): string | undefined {\n const start = text.indexOf('{')\n if (start === -1)\n return undefined\n let depth = 0\n let inString = false\n let escaped = false\n for (let i = start; i < text.length; i++) {\n const ch = text[i]\n if (inString) {\n if (escaped)\n escaped = false\n else if (ch === '\\\\')\n escaped = true\n else if (ch === '\"')\n inString = false\n continue\n }\n if (ch === '\"') {\n inString = true\n }\n else if (ch === '{') {\n depth++\n }\n else if (ch === '}') {\n depth--\n if (depth === 0)\n return text.slice(start, i + 1)\n }\n }\n return undefined\n}\n\nfunction clampScore(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(n))\n return 0\n return Math.max(0, Math.min(1, n))\n}\n\nasync function writeEvalArtifacts(dir: string, result: EvalCaseResult): Promise<EvalArtifacts> {\n await mkdir(dir, { recursive: true })\n const resultPath = join(dir, 'result.json')\n const eventsPath = join(dir, 'events.jsonl')\n const transcriptPath = join(dir, 'transcript.json')\n const workspacePath = result.workspace ? join(dir, 'workspace.json') : undefined\n\n await writeFile(resultPath, `${JSON.stringify(result, null, 2)}\\n`)\n await writeFile(eventsPath, result.events.map(headlessEventToJsonl).join(''))\n await writeFile(transcriptPath, `${JSON.stringify(result.result.transcript, null, 2)}\\n`)\n if (workspacePath)\n await writeFile(workspacePath, `${JSON.stringify(result.workspace, null, 2)}\\n`)\n\n return {\n dir,\n result: resultPath,\n events: eventsPath,\n transcript: transcriptPath,\n ...(workspacePath ? { workspace: workspacePath } : {}),\n }\n}\n\nfunction normalizeSnapshotPath(path: string): string {\n const normalized = path.startsWith('./') ? path.slice(2) : path\n return normalized === '' ? '.' : normalized\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = value.replace(/[^\\w.-]+/g, '-').replace(/^-+|-+$/g, '')\n // If sanitizing changed the value, distinct ids can collapse to the same\n // segment (e.g. `a b`, `a/b`, `a@b` → `a-b`) and overwrite each other's\n // artifacts. Append a short, stable hash of the original to disambiguate.\n if (sanitized === value && sanitized.length > 0)\n return sanitized\n return `${sanitized || 'eval'}-${shortHash(value)}`\n}\n\nfunction shortHash(value: string): string {\n // Tiny FNV-1a; only used to disambiguate filesystem segments, not security.\n let hash = 0x811C9DC5\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 0x01000193)\n }\n return (hash >>> 0).toString(36).padStart(7, '0').slice(0, 7)\n}\n\nexport function artifactPath(root: string, result: EvalCaseResult): string {\n return resolve(root, safeSegment(result.suite ?? 'eval'), safeSegment(result.id))\n}\n\nexport function relativeArtifactPath(root: string, path: string): string {\n return relative(root, path)\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { d as createAgent } from "./tools-NxnEmzYg.js";
2
- import { f as toAnthropic, s as ensureToolResultPairing } from "./messages-C_1AmSpk.js";
1
+ import { d as createAgent } from "./tools-ZHKOh44k.js";
2
+ import { f as toAnthropic, s as ensureToolResultPairing } from "./messages-RPKrEPvH.js";
3
3
  import { a as toolResultToText, n as documentBlockMarker } from "./types-BiobHM1D.js";
4
- import { r as createProcessContext } from "./contexts-BJVgG0LY.js";
4
+ import { r as createProcessContext } from "./contexts-DglWSzmR.js";
5
5
  import { i as statsByModel } from "./stats-DAKBEKjc.js";
6
- import { i as basic_default } from "./presets-Cm2BPJaU.js";
7
- import { i as createMemoryStore, t as createSession } from "./session-CtAWwwkn.js";
6
+ import { i as basic_default } from "./presets-D5ibZTml.js";
7
+ import { a as createMemoryStore, t as createSession } from "./session-Do_TQV7c.js";
8
8
  //#region src/run-summary.ts
9
9
  /**
10
10
  * Build a run-summary collector. State is created fresh inside each
@@ -630,4 +630,4 @@ function installHeadlessEventAdapter(hooks, onEvent) {
630
630
  //#endregion
631
631
  export { headlessEventToJsonl as a, runHeadless as c, createRunSummaryCollector as d, formattedHeadlessTurnEventToJsonl as i, transcriptToOpenAIMessages as l, formatHeadlessResult as n, installHeadlessEventAdapter as o, formatHeadlessTurnEvent as r, providerTranscriptFormatForProvider as s, exitCodeForHeadlessResult as t, transcriptToProviderMessages as u };
632
632
 
633
- //# sourceMappingURL=headless-CPaunZsU.js.map
633
+ //# sourceMappingURL=headless-Bb5gU8AR.js.map