/** * transcript — the conversation, read back out of the event stream. * * A maintainer opening a bug report reads the conversation first: what was * asked, what the model said, which tools ran, what came back. All of that is * already in the typed events — `agent.turn_start` carries the prompt, * `stream.llm_end` the model's content, `stream.tool_start` / `tool_end` the * call and its result, `agent.turn_end` the final answer — so `conversation.json` * is DERIVED, never a second copy the reporter has to keep in sync. * * ## Derivable, and when it is not * * Turn markers come from the Agent loop. A bare `LLMCall`, a `Sequence` of * them, a pattern — none of those fire `turn_start`, so the walk falls back to * ONE synthetic turn holding the model and tool steps in order, and says so on * the turn (`derived: 'no-turn-markers'`). A recording with no LLM and no tool * events yields no transcript at all, and the manifest carries a note rather * than an empty file that reads like an empty conversation. * * ## What it does NOT do * * It does not summarize, truncate or scrub. Whatever the events carry is what * this writes — including tool arguments and results. Redaction is upstream, at * commit time; the manifest lists the keys that were scrubbed so the reporter * can see it happened. Anything that must never leave must never reach the * event stream in the first place. */ /** One model or tool step inside a turn. */ export type TranscriptStep = { readonly kind: 'assistant'; readonly content: string; readonly stopReason?: string; readonly toolCallCount?: number; } | { readonly kind: 'tool'; readonly name: string; readonly toolCallId?: string; readonly args?: unknown; readonly result?: unknown; readonly error?: boolean; }; /** One turn: what the user asked, what happened, what came back. */ export interface TranscriptTurn { readonly index: number; readonly user?: string; readonly steps: readonly TranscriptStep[]; readonly final?: string; /** Present when there were no turn markers and this turn was inferred. */ readonly derived?: 'no-turn-markers'; } /** One conversation's readable transcript. */ export interface Transcript { readonly turns: readonly TranscriptTurn[]; } /** * Walk one conversation's events into turns. * * @returns the transcript, or `undefined` when nothing conversational * happened — which the manifest reports as a note. */ export declare function deriveTranscript(events: readonly unknown[]): Transcript | undefined;