/** * renderLocalRun — the pure mapper from a local stub run's per-step traces * ({@link LocalStepTrace}[], streamed as NDJSON by `POST /api/runs/local`) to * the same {@link RunView} the canvas renders for prod runs. Its twin is * {@link renderRunState} (prod / local-backend); both emit the identical * cost-free {@link StepView} shape, so ONE inspector renders every run source. * * Pure and deterministic: no LLM, no I/O, no clock. Every field is derived from * the traces (plus the caller-supplied execution id and terminal outcome), so * the same function can map a partial trace mid-stream and the final trace at * the end — only the input grows, never this mapping. It is a Stryker target; * the tests are mutation-first. * * Honest absence, matching renderRunState and the SDK's "null is honest absence, * never a fabricated value" contract: * - **No cost** — local runs are stubbed and free by construction; a StepView * from here never carries `costUsd` (so the inspector reads "local run · * free", never "$0.00"). * - **Timing is evidence-backed** — new traces carry start/finish timestamps * and produce latency; legacy traces without them keep `latencyMs` absent. * - **Output** is present only when the trace captured one (a step that threw, * or a `continue` with no value, carries none) — but ABSENCE is `undefined` * on the trace, and a genuine `null`/`false`/`0`/`""` output is a real value * that passes through. * - **Input** is always carried by a trace (every attempt ran on some input, * even `undefined`); it is surfaced whenever it isn't `undefined`. * - **Logs and errors** collapse to the same `logSlice`/`error` fields prod * uses, via the shared formatter. * - **Stub signal (WB15-2)** is RUN-LEVEL. A local run is stub-served by * construction, so the run carries `stubbed: true` (prod's renderRunState * never does) and the inspector marks each executed step with a "stubbed" * chip. Recorded calls additionally carry their own `stubUsed` attribution; * the run-level flag remains useful for steps that made no call. The terminal * summary's `unusedStubs` (a supplied key * that matched nothing) and `stubWarnings` (a wrong-shape value) pass through * only when NON-empty, so a clean run surfaces no notice at all. */ import type { LocalStepTrace, LocalRunOutcome } from "@sapiom/agent-core"; import type { RunView, UnusedStubView } from "../shared/types.js"; /** * Options carrying the run-level facts a `LocalStepTrace[]` alone can't provide. * Both are optional so the mapper can render a live, still-streaming trace (no * terminal summary yet) exactly as it renders the final one. */ export interface RenderLocalRunOptions { /** * The execution id to stamp on the {@link RunView}. A local run has no * server-issued id, so the caller (the SPA's run store) synthesizes and owns * one; the mapper stays pure by taking it rather than minting time/randomness. * Defaults to an empty string when the caller has none yet. */ executionId?: string; /** * The run's terminal outcome from the NDJSON summary line, when it has * arrived. Absent while the stream is still open — the mapper then reports the * run as `running` (steps may still be coming). Passing it flips the run to * its settled status. */ outcome?: LocalRunOutcome; /** * Supplied stub keys that matched no capability call this run — from the * terminal summary line. A no-op mock (typo'd path, wrong plural/singular) * otherwise fails silently; surfacing it is the whole point of WB15-2. Only a * NON-empty list reaches the {@link RunView} (honest absence), so pass it as-is * from the summary and the mapper decides. Absent while the stream is open. */ unusedStubs?: UnusedStubView[]; /** * Warnings about stub values that matched a key but carried the wrong shape — * from the terminal summary line. Same honest-absence handling as * {@link RenderLocalRunOptions.unusedStubs}: an empty list is dropped. */ stubWarnings?: string[]; input?: unknown; output?: unknown; error?: unknown; startedAt?: string; finishedAt?: string; } /** * Map a local stub run's traces (plus the caller-owned execution id and, once * known, terminal outcome) to the {@link RunView} the canvas renders. Order- * preserving over `traces` (execution order); total — never throws, mirroring * renderRunState — because the traces are already the decoded wire shape. */ export declare function renderLocalRun(traces: LocalStepTrace[], options?: RenderLocalRunOptions): RunView; //# sourceMappingURL=render-local-run.d.ts.map