/** * Arrays of blocks, nested deltas and payload-discriminated records do not fit * the flat descriptor match/field spec used by identity decoding. */ import type { CompactionState, CompactionTrigger, HarnessName, LimitCode } from "../knowledge/descriptor.js"; import { type UsageEvent } from "./usage.js"; export interface ToolEvent { readonly kind: "tool"; readonly name: string; readonly input?: unknown; readonly callId?: string; } export interface ToolResultEvent { readonly kind: "tool-result"; readonly name?: string; readonly callId?: string; readonly result?: unknown; readonly isError?: boolean; } export interface ToolDenial { readonly tool: string; readonly reason: string; readonly callId?: string; /** JSON input preview, limited to 512 characters; it may be truncated. */ readonly inputSummary?: string; } export type ContentEvent = ToolEvent | ToolResultEvent | UsageEvent | { readonly kind: "token"; readonly text: string; } | { readonly kind: "message"; readonly role: string; readonly text: string; } | { readonly kind: "progress"; readonly label: string; } /** ADR 0009: the harness compacted its own context. Passes through * `decode.ts` unchanged, so this shape matches the HarnessEvent arm. */ | { readonly kind: "compaction"; readonly state: CompactionState; readonly trigger?: CompactionTrigger; readonly tokensBefore?: number; readonly tokensAfter?: number; readonly durationMs?: number; readonly detail?: string; } /** `terminal: true` marks an error that ended the turn (a failed result * record); the runner turns it into a task failure. Other errors are * informational and the turn goes on. `provisional: true` qualifies a * terminal error: the harness may still supersede it with a successful * assistant message in the same run (pi retries a stopReason-error * attempt in-process), so the decoder holds the verdict and settles it * at stream/turn end (see `settleProvisionalError`). */ | { readonly kind: "error"; readonly message: string; readonly terminal?: boolean; readonly provisional?: boolean; /** A refused tool call or rejected question: * the native tool name and the harness's reason, which may be * empty. Machine consumers branch on presence, never on prose. */ readonly denial?: ToolDenial; } | { readonly kind: "budget"; readonly detail: string; } /** A structured limit record on the stream (claude's rate_limit_event); * the runner turns it into a limit-class failure. `resetsAt` is epoch * milliseconds when the harness reported one. */ | { readonly kind: "limit"; readonly code: LimitCode; readonly detail: string; readonly resetsAt?: number; }; /** Opaque per-reader decoder state (cursor only in v1): pending tool * call ids, tombstoned ids evicted from pending that must never re-emit * a tool event, completed ids that must not re-emit on a duplicate * completion, and query args by toolCallId for completions that arrive * with no preceding start. Owned by interpretation, threaded by execution * without inspection; reset per turn. Each collection is bounded * (drop-oldest) so a pathological turn cannot grow memory without bound. * Completions land in their own set precisely so settling normal calls * never pushes an evicted id out of the tombstones. */ export interface CursorReaderState { readonly pending: readonly string[]; readonly tombstones: readonly string[]; readonly completed: readonly string[]; readonly queryArgs: readonly { readonly toolCallId: string; readonly args: unknown; }[]; } export declare const freshCursorReaderState: () => CursorReaderState; /** Per-harness reader state: cursor state for cursor, null otherwise. * Execution holds it without inspection (ADR 0005). */ export type ReaderState = CursorReaderState | null; export declare const freshReaderState: (harness: HarnessName) => ReaderState; /** Stateful entry point: every harness returns { events, state }. * decode.ts is the one production call site; contentEventsOf below keeps * the array shape for stateless callers. */ export declare const contentEventsWithState: (harness: HarnessName, raw: unknown, state: ReaderState) => { readonly events: ContentEvent[]; readonly state: ReaderState; }; export declare const contentEventsOf: (harness: HarnessName, raw: unknown) => ContentEvent[]; //# sourceMappingURL=content.d.ts.map