import type { ModelTurn, ModelRequest } from "./core/harness-driver.js"; export type { ModelTurn, ModelRequest } from "./core/harness-driver.js"; /** Build a scripted model from an ordered list of turns. */ export declare function scriptModel(turns: readonly ModelTurn[]): ModelTurn[]; export interface TurnInfo { readonly n: number; readonly stream: boolean; readonly hasToolResult: boolean; } export interface MockHandle { readonly url: string; close(): void; /** * Number of SCRIPT turns served so far — MAIN-LOOP requests only. A * side-channel request is answered without touching the script and is not * counted here, so this is the agent's turn count rather than the CLI's * HTTP-call count. (Before 2026-08-12 it was the latter: a 3-entry script * against Claude Code 2.1.228 reported 27.) */ readonly count: number; /** Side-channel requests answered so far — never script-consuming. */ readonly sideChannelCount: number; /** Every `/v1/messages` request the mock received, in order. */ readonly requests: readonly ModelRequest[]; } /** * Is this request the AGENT LOOP asking for its next turn (as opposed to a * side-channel call the CLI makes for its own bookkeeping)? * * Pure and exported so the classification is unit-tested without HTTP. See the * block above for the measurement and for what the criterion does not settle. */ export declare function isMainLoopRequest(body: { tools?: unknown; }): boolean; /** * The stated residual risk of keying on `tools`, made LOUD instead of silent. * * If a future main-loop request ever arrives WITHOUT tool declarations it is * misrouted to the side channel, the script is never consumed, and the agent * loops on `{}` — a failure with no symptom except a test that mysteriously * asserts against an empty run. Every real run that reached the model at all * consumes at least one script turn, so "side-channel requests arrived and * script turns did not" cannot happen in the healthy case. Returns the warning * line, or `undefined` when there is nothing to say (including the run that * never reached the model at all — that has its own, visible, failure). */ export declare function scriptUnconsumedWarning(count: number, sideChannelCount: number): string | undefined; /** * Recover the main-loop / side-channel split from a captured request LOG. * * 🔴 THIS EXISTS BECAUSE `Trace.turns` MEANT TWO DIFFERENT THINGS. The * in-process handle carries the split as `count` / `sideChannelCount`, and the * direct path reads `mock.count` — the agent's own turns. A SANDBOXED run has * the mock in another process, so all that crosses the boundary is the tagged * ndjson request log (`mock-entry.ts` → `parseRequestLog`); counting its lines * counted the CLI's bookkeeping calls as agent turns. MEASURED on Claude Code * 2.1.228, a 3-entry script: 27 requests for 9 turns — `assertTurnsAtLeast(10)` * would have passed on a 9-turn run, and only when sandboxed. One number with * two meanings depending on the execution path is worse than either meaning. * * The tag is what makes this recoverable at all: `sideChannel` survives * `JSON.stringify` into the log, so the counts here are equal by construction to * the ones the handle would have reported in-process. */ export declare function splitRequestCounts(requests: readonly ModelRequest[]): { count: number; sideChannelCount: number; }; /** * Extract a {@link ModelRequest} from a request body — the `system` prompt and * `messages`, each flattened to text. Pure and exported so the capture logic is * testable without the HTTP server. */ export declare function extractRequest(body: { system?: unknown; messages?: unknown; }): ModelRequest; /** * Start the scripted mock on a free port. Each MAIN-LOOP `/v1/messages` POST * consumes the next turn; one past the end of the script is answered with a * non-retryable API error, never a copy of the last turn (#340 — a looping * agent would pass on turns nobody scripted), and `runHarnessTest` then fails * the test from the recorded requests ({@link findScriptOverrun}); * a SIDE-CHANNEL POST — the CLI's own bookkeeping calls, see * {@link isMainLoopRequest} — is answered from outside the script and consumes * nothing. Resolves to a handle with the base `url` and a `close()`. */ export declare function startMock(script: readonly ModelTurn[], opts?: { onTurn?: (info: TurnInfo) => void; /** Called with each `/v1/messages` request as it arrives — used by the * in-sandbox mock entry to stream requests to a file for the parent. */ onRequest?: (req: ModelRequest) => void; }): Promise; //# sourceMappingURL=mock-model.d.ts.map