/** * AG-UI wire protocol interpretation. * * TORUK Core streams predictions in one of two wire formats. The legacy format is * `{ event, data }` frames; the AG-UI format is flat `{ type, ... }` frames carrying Dynamic UI * blocks as `CUSTOM` events named `toruk.*`. The server picks AG-UI only when Dynamic UI is * enabled AND the client sent `streamProtocol: 'agui'`, and in that mode it emits *no* legacy * frames at all (see Core's `sse-streamer.ts`) — so a client must handle the format wholesale. * * This module is the whole protocol boundary: it turns one wire frame into a typed intent and * knows nothing about widget state, Solid signals or rendering. `interpretAguiFrame` is pure, * which is what makes the wire contract testable without a browser or a live stream. * * Frame shapes mirror Core's `packages/server/src/dynamic-ui/agui-encoder.ts`; the sideband * name → intent mapping mirrors `aguiEventHandlers.js` in Core's UI. */ import type { BlockWithId } from './split-blocks'; import type { ActivityStep } from './message-blocks'; import { type FlowNodeEvent } from './node-activity'; /** The `streamProtocol` value that asks Core for the AG-UI wire. */ export declare const AGUI_STREAM_PROTOCOL = "agui"; /** A parsed SSE frame, before we know whether it is AG-UI or legacy. */ type UnknownFrame = Record; /** * Sideband payloads the SDK acts on. Core emits more (`toruk.usageMetadata`, `toruk.nextAgent`, * `toruk.artifactGeneration*`); those have no widget surface, so they resolve to `ignore` * rather than being silently mishandled. */ export type AguiSidebandField = 'metadata' | 'action' | 'sourceDocuments' | 'artifacts' | 'fileAnnotations' | 'agentReasoning' | 'agentFlowStatus' | 'agentFlowExecutedData' | 'artifactGenerationStart' | 'artifactGenerationEnd'; export type AguiIntent = { kind: 'run-started'; } | { kind: 'text'; delta: string; } | { kind: 'block'; block: BlockWithId; } | { kind: 'block-pending'; id: string; componentType: string; } | { kind: 'block-pending-update'; id: string; componentType: string; } | { kind: 'activity'; step: ActivityStep; } /** * A `toruk.agentflow.node` frame. Kept distinct from `activity` because Core's reducer for it * needs the message's existing steps to work out which run of that node this is — see * `upsertNodeActivityStep`. */ | { kind: 'node-activity'; node: FlowNodeEvent; } | { kind: 'sideband'; field: AguiSidebandField; value: unknown; } | { kind: 'error'; message: string; } | { kind: 'finished'; } | { kind: 'ignore'; }; /** * True when a parsed SSE payload is an AG-UI frame rather than a legacy `{ event, data }` one. * AG-UI frames are identified by an upper-snake `type` discriminator and the absence of the * legacy `event` key, so a legacy frame can never be misread as AG-UI. */ export declare function isAguiFrame(payload: unknown): payload is UnknownFrame; /** * Map one AG-UI frame to an intent. Unrecognised frames resolve to `ignore` so a newer Core * emitting frames this SDK version predates degrades quietly instead of breaking the turn. */ export declare function interpretAguiFrame(frame: UnknownFrame): AguiIntent; export {};