/** A streamed text segment. Structurally assignable to blocks' `ChatMessagePart` (`text`). */ export interface A2uiStreamTextPart { type: 'text'; text: string; } /** A streamed A2UI segment. `payload` is the accumulated envelope array (assignable to `ChatMessagePart` `a2ui`). */ export interface A2uiStreamUiPart { type: 'a2ui'; payload: unknown[]; } export type A2uiStreamPart = A2uiStreamTextPart | A2uiStreamUiPart; /** A non-fatal finding from the split (a malformed JSONL line, an unterminated fence). */ export interface A2uiStreamIssue { code: 'UNPARSEABLE_LINE' | 'UNTERMINATED_FENCE'; message: string; /** The offending source line, when applicable. */ line?: string; } /** * The info string that marks a fence as A2UI. Shared by the parser and by * `a2uiFencedTransportSection()` so the prompt can never name a different tag * than the splitter accepts. */ export declare const A2UI_FENCE_TAG = "a2ui"; export declare class A2uiStreamSplitter { /** Committed parts (immutable; replaced wholesale on every mutation). */ private committed; private mode; /** * When in text mode inside a *regular* (non-a2ui) markdown code fence, the * marker that opened it. A `` ```a2ui `` line inside such a block is literal * code, NOT a surface — this is what stops a quoted example from executing. */ private codeFence; /** Buffered trailing line that has not yet seen its newline. */ private pending; private rawText; private readonly issueList; /** * Raw lines of an in-progress multi-line envelope (a pretty-printed object * spanning several fence lines), plus the depth-scanner state that tracks * whether the object has closed. Empty/zeroed while envelopes arrive as * proper single-line JSONL. */ private objLines; private objDepth; private objInString; private objEscape; /** Feed the next token / chunk of model output. */ push(chunk: string): void; /** Signal end of stream: flush the trailing partial line and settle state. */ end(): void; private asText; private resetObjBuffer; /** * Advance the depth scanner across one line: brace/bracket depth outside of * strings, with `\"`-escape handling inside them. Returns `false` when the * buffer can never become valid JSON — depth underflow, or a string left * open at end-of-line (raw newlines are illegal inside JSON strings). */ private scanDepth; /** * Abandon the current a2ui fence: drop an empty surface, record an issue and * re-emit the buffered lines (plus the offending one, if any) as text inside * a synthetic ``` code block. `codeFence` is armed so the fence's real * closing ``` closes that block instead of opening a stray one downstream. */ private fenceFallback; private processLine; /** * The current parts, including the buffered trailing text tail for a * responsive stream. A partial line that might still become a fence marker is * held back (never flashed). a2ui parts are carried by reference so A2UIView * consumes them incrementally. */ snapshot(): A2uiStreamPart[]; /** The raw model output fed so far (fences included) — the faithful wire form. */ get raw(): string; /** Accumulated non-fatal issues (malformed JSONL, unterminated fence). */ get issues(): A2uiStreamIssue[]; } /** Options for {@link a2uiFencedTransportSection}. */ export interface A2uiTransportSectionOptions { /** * Prefix your client puts on a user turn that reports an action, followed by * the JSON `A2uiActionEvent`. Set to `false` if actions reach the agent some * other way (a tool result, a structured field) — the round-channel paragraph * is then omitted. @default '[ui-action]' */ actionPrefix?: string | false; /** * Prefix for a turn that reports validation issues as JSON, so the agent can * repair the surface. `false` omits it. @default '[ui-error]' */ errorPrefix?: string | false; } /** * The transport half of the fenced-JSONL contract: the prompt section that makes * an agent emit exactly what {@link A2uiStreamSplitter} parses. * * `a2uiSystemPrompt()` deliberately says nothing about transport, because how * envelopes travel is the app's business. This is the transport for apps that * take the model's ordinary text stream and let it open a ` ```a2ui ` fence — * the setup the splitter exists for. Append it after `a2uiSystemPrompt()` (and * after `a2uiDataSchemaSection()`, if you use one). * * Anything domain-specific — which tools to call, what never to invent — stays * yours to append; this covers only the wire format and the return path. * * @example * ```ts * const system = [ * a2uiSystemPrompt({ catalog: urbiconA2uiCatalogSpec }), * a2uiDataSchemaSection(MY_SCHEMA), * a2uiFencedTransportSection(), * MY_DOMAIN_RULES * ].join('\n\n'); * ``` */ export declare function a2uiFencedTransportSection(options?: A2uiTransportSectionOptions): string;