/** * Provider stream parsers. * * Converts raw stdout/stderr chunks from provider CLIs into normalized * StreamEvent objects that the runner can forward to the orchestrator, and * the UI can surface as live agent activity. * * Two parsers are shipped: * * - Claude `-p --output-format stream-json --verbose` emits newline- * delimited JSON. We parse each event (content_block_start with tool_use, * content_block_delta with text, etc.) and emit a StreamEvent per * meaningful item. * * - Codex `exec` emits plain text on stdout and tool invocations on * stderr. We heuristically pick out shell commands (`$ cmd …`) and emit * text_delta for stdout bursts. * * Unknown providers fall back to emitting text_delta with a short preview of * each chunk — enough for the UI to show "something is happening". */ export type StreamEvent = { kind: 'tool_use'; tool: string; target?: string; } | { kind: 'shell'; command: string; } /** * Assistant text delta. * * - `preview` is a short, whitespace-collapsed, length-capped string for * the UI activity indicator. * - `text` (when present) is the full, un-truncated delta as emitted by * the provider. The runner forwards this to the message-stream pipeline * instead of the raw provider output when the provider emits structured * JSON rather than plain text (e.g. Claude `--output-format stream-json`). */ | { kind: 'text_delta'; preview: string; text?: string; }; export interface StreamParser { /** Feed a raw chunk from the given stream; returns the events extracted. */ feed(chunk: string, stream: 'stdout' | 'stderr'): StreamEvent[]; } /** Default maximum length of a text preview rendered in the UI. */ export declare const DEFAULT_PREVIEW_LENGTH = 60; /** Build the right parser for a provider command. */ export declare function parserForCommand(command: string, previewLength?: number): StreamParser; export declare function isClaudeStreamJson(command: string): boolean; export declare function isCodexExec(command: string): boolean; /** * Inspect each provider command and return human-readable warnings for * provider commands that do not request a streaming output format. Idle- * timeout enforcement and the live activity indicator rely on a streaming * provider; a provider that buffers silently cannot be protected. */ export declare function collectNonStreamingProviderWarnings(providers: Record): string[]; /** * Claude `--output-format stream-json --verbose` parser. * * The Claude Code CLI emits newline-delimited JSON with events shaped like: * * { type: "system", subtype: "init", … } — ignored * { type: "rate_limit_event", … } — ignored * { type: "assistant", message: { content: [ { type: "thinking" | "tool_use" | "text", … } ] } } * { type: "user", message: { content: [ { type: "tool_result", … } ] } } * { type: "result", subtype: "success", result: "", … } * * For each assistant event we walk `message.content` and emit: * - tool_use blocks → StreamEvent.tool_use * - text blocks → StreamEvent.text_delta with the full text in `text` and a * short `preview` for the UI activity indicator. * * Chunks may split mid-line; we buffer by newline and parse each complete * line as JSON. */ export declare class ClaudeStreamJsonParser implements StreamParser { private previewLength; private buffer; constructor(previewLength: number); feed(chunk: string, stream: 'stdout' | 'stderr'): StreamEvent[]; private tryParseLine; private buildTextEvent; } /** * Extract the final agent text from a Claude stream-json stdout buffer. * * Looks for the last `{ "type": "result", … }` line; if present returns its * `result` string. Falls back to concatenating all `assistant.text` blocks. * If nothing sensible can be extracted, returns `null` and the caller should * fall back to the raw buffer. */ export declare function extractClaudeStreamJsonFinal(buffer: string): string | null; /** * Codex `exec` parser. * * Teepee runs `codex exec` with `--json` added automatically (see * prepareCommandParts in command.ts). Codex then emits newline-delimited * JSON on stdout with shapes like: * * { "type": "thread.started", "thread_id": "…" } * { "type": "item.added", "item": { "type": "command_execution", "command": "rg --files .", … } } * { "type": "item.completed", "item": { "type": "command_execution", "exit_code": 0, … } } * { "type": "item.added", "item": { "type": "agent_message_delta", "delta": "Part of the answer " } } * { "type": "item.completed", "item": { "type": "agent_message", "text": "Full final answer." } } * * We parse each line, emit `shell` events for command_execution, and * `text_delta` events for agent_message / agent_message_delta items. * stderr is parsed only for `$ cmd` shell-prompt lines (legacy non-json * mode, plus a safety net). */ export declare class CodexParser implements StreamParser { private previewLength; private stdoutBuffer; private stderrBuffer; /** True once any `agent_message_delta` has been emitted with its text; we * then suppress the `text` field on the matching `item.completed` event to * avoid duplicating the final message in the live stream body. */ private deltaTextEmitted; constructor(previewLength: number); feed(chunk: string, stream: 'stdout' | 'stderr'): StreamEvent[]; private feedStderr; private feedStdout; private parseJsonLine; } /** * Generic fallback: emit a text_delta preview for any stdout chunk. * Stderr chunks are ignored unless they have the `$ cmd` shape (which many * CLI-driven providers adopt). */ export declare class GenericTextParser implements StreamParser { private previewLength; constructor(previewLength: number); feed(chunk: string, stream: 'stdout' | 'stderr'): StreamEvent[]; } //# sourceMappingURL=stream-parsers.d.ts.map