import type { AgentAdapter, CallLLM, Eval, EvalResult, Middleware, Recording } from './types.js'; export type RunnerConfig = { adapter: AgentAdapter; middleware?: readonly Middleware[]; callLLM?: CallLLM; /** Override the upstream URL the proxy forwards to. */ upstream?: string; /** * Whether `runner.close()` (and the SIGINT/SIGTERM/exit handlers * installed at `startRunner`) should recursively remove * `/.eval_runs/`. Defaults to `true`. * * Set to `false` when multiple runner processes might be running * concurrently against the same project tree (e.g. parallel test * runners), since one runner's cleanup would yank the scratch dirs * out from under another's in-flight evals. In that case, do the * cleanup yourself once all runners are done — for tests, a * `posttest` script is the natural place. */ cleanupOnClose?: boolean; }; export type EvalRunOpts = { /** * Wall-clock budget for this run. When elapsed, the run aborts: the * agent process is killed and `runner.run()` rejects with a timeout * error. Default is no timeout (only the adapter's own per-spawn * timeout, e.g. claude's 30m, applies). */ timeoutMs?: number; /** * Capture every upstream round-trip (raw request + response bytes) * and expose them on `EvalResult.recording`. Pass that recording to * a later `runner.run(ev, { replay })` to reproduce the same * conversation deterministically up to a cutoff point. */ record?: boolean; /** * Replay a prior `EvalResult.recording` for the first `upTo` upstream * exchanges, then forward to the live upstream after. The proxy * auto-short-circuits any tool calls that occur during the replayed * prefix, splicing in the recorded tool_results — so the agent sees * the original conversation byte-for-byte until the cutoff, then * makes real LLM calls with whatever new tools/MCPs/config you've * added. * * const ran = await runner.run(ev, { record: true }); * const ran2 = await runner.run(ev, { replay: { recording: ran.recording!, upTo: 5 } }); */ replay?: { recording: Recording; upTo: number; }; /** * Stream agent stdout chunks (claude/codex stream-json, opencode JSON) * as they arrive — useful for watching the conversation live. Chunks * are Buffers and not line-aligned; accumulate and split on `\n` * before parsing JSON. */ onStdout?: (chunk: Buffer) => void; /** * Stream agent stderr chunks as they arrive — surface MCP server boot * errors, tool dispatch failures, etc. When set, the adapter does NOT * also forward stderr to `process.stderr`. */ onStderr?: (chunk: Buffer) => void; }; export type EvalRunner = { run(ev: Eval, opts?: EvalRunOpts): Promise; close(): Promise; }; export declare function startRunner(config: RunnerConfig): Promise; //# sourceMappingURL=runner.d.ts.map