/** * SSE Resume Helpers (v1.8.0) * * Utilities for streaming with resume support */ import type { SseEvent, ResumeToken, ResumeOptions, ResumeResult, DraftGraphRequest, RequestOptions } from "./types.js"; /** * Configuration for SSE streaming */ export interface SseStreamConfig { baseUrl: string; apiKey?: string; hmacSecret?: string; timeout?: number; onDegraded?: (kind: string) => void; } /** * Extract resume token from SSE event stream * * Scans SSE events for the resume token (emitted as second event, seq=1) * * @param event - SSE event to check * @returns Resume token if found, null otherwise * * @example * ```typescript * for await (const event of streamDraftGraph(...)) { * const token = extractResumeTokenFromEvent(event); * if (token) { * localStorage.setItem('resumeToken', token); * } * } * ``` */ export declare function extractResumeTokenFromEvent(event: SseEvent): ResumeToken | null; /** * Stream draft-graph with SSE * * Returns an async iterable of SSE events. Automatically captures resume token * on first event (seq=1). * * @param config - SSE stream configuration * @param request - Draft graph request * @param options - Request options (signal, timeout) * @returns Async iterable of SSE events * * @example * ```typescript * const events = streamDraftGraph( * { baseUrl, apiKey }, * { brief: "Create a todo app" }, * { signal: abortController.signal } * ); * * let resumeToken: string | null = null; * for await (const event of events) { * // Capture resume token * const token = extractResumeTokenFromEvent(event); * if (token) resumeToken = token; * * // Handle stage events * if (event.type === 'stage') { * console.log('Stage:', event.data.stage); * } * } * ``` */ export declare function streamDraftGraph(config: SseStreamConfig, request: DraftGraphRequest, options?: RequestOptions): AsyncIterable; /** * Resume an interrupted draft-graph stream * * Replays buffered events from the last sequence number in the resume token. * * ⚠️ **Important - Replay-Only Behavior (v1.8.0)** * * The resume endpoint implements **replay-only** behavior: * 1. Server replays all buffered events since the token sequence * 2. For **completed streams**: Final `complete` event is sent, then connection closes * 3. For **in-progress streams**: Buffered events are replayed, heartbeat sent, then connection closes * * **This means:** * - Resume does NOT keep the connection open for live events * - Clients must reconnect to the main stream endpoint for ongoing updates * - Resume is designed for recovering missed events after disconnection * * @param config - SSE stream configuration * @param options - Resume options (token, signal, timeout) * @returns Resume result with replayed events * * @example * ```typescript * try { * const result = await resumeDraftGraph( * { baseUrl, apiKey }, * { token: savedToken, signal: abortController.signal } * ); * * console.log(`Replayed ${result.replayedCount} events`); * if (result.completed) { * console.log('Stream completed'); * } else { * console.log('Need to reconnect for live events'); * // Reconnect to main stream endpoint * } * } catch (error) { * if (error instanceof OlumiAPIError && error.statusCode === 426) { * console.log('Resume not available - starting new stream'); * } * } * ``` */ export declare function resumeDraftGraph(config: SseStreamConfig, options: ResumeOptions): Promise; /** * Resume an interrupted draft-graph stream in live mode (v1.9.0) * * Replays buffered events AND continues streaming new events until completion. * * **Live Resume Behavior:** * 1. Server replays all buffered events since the token sequence * 2. Server continues polling for new events and streaming them * 3. Connection stays open until stream completes, errors, or times out * * **Fallback:** * - If server doesn't support live mode (SSE_RESUME_LIVE_ENABLED=false), falls back to replay-only * - Check `result.completed` to know if reconnection to main stream is needed * * @param config - SSE stream configuration * @param options - Resume options (token, signal, timeout) * @returns Async iterable of SSE events (replayed + new) * * @example * ```typescript * const events = resumeDraftGraphLive( * { baseUrl, apiKey }, * { token: savedToken, signal: controller.signal } * ); * * for await (const event of events) { * if (event.type === 'stage' && event.data.stage === 'COMPLETE') { * console.log('Stream completed via live resume'); * } * } * ``` */ export declare function resumeDraftGraphLive(config: SseStreamConfig, options: ResumeOptions): AsyncIterable; /** * Configuration for auto-reconnect streaming (v1.9.0) */ export interface AutoReconnectConfig extends SseStreamConfig { /** * Maximum number of reconnection attempts (default: 3) */ maxRetries?: number; /** * Whether to prefer live resume mode when reconnecting (default: true) * Falls back to replay-only if live mode unavailable */ preferLiveResume?: boolean; streamFactory?: (config: SseStreamConfig, request: DraftGraphRequest, options?: RequestOptions) => AsyncIterable; } /** * Stream draft-graph with automatic reconnection on disconnection (v1.9.0) * * Provides resilient streaming with automatic recovery: * 1. Starts initial stream and captures resume token * 2. On disconnection, attempts live resume with exponential backoff * 3. Falls back to replay-only resume if live mode unavailable * 4. Reconnects to main stream if needed * * **Exponential Backoff:** * - Attempt 1: 1.5s delay * - Attempt 2: 4s delay * - Attempt 3: 8s delay * - Max 3 retries (configurable) * * **Error Handling:** * - Retries on: network errors, 5xx errors, timeouts * - No retry on: 4xx errors (except 429), user abort * - Cleans up all listeners and connections in finally block * * @param config - Stream configuration with auto-reconnect options * @param request - Draft graph request * @param options - Request options (signal, timeout) * @returns Async iterable of SSE events with automatic recovery * * @example * ```typescript * const config: AutoReconnectConfig = { * baseUrl: "https://olumi-assistants-service.onrender.com", * apiKey: process.env.OLUMI_API_KEY!, * maxRetries: 3, * preferLiveResume: true, * }; * * try { * for await (const event of streamDraftGraphWithAutoReconnect(config, { brief: "test" })) { * if (event.type === 'stage' && event.data.stage === 'COMPLETE') { * console.log('Stream completed:', event.data.payload); * } * } * } catch (error) { * console.error('Stream failed after all retries:', error); * } * ``` */ export declare function streamDraftGraphWithAutoReconnect(config: AutoReconnectConfig, request: DraftGraphRequest, options?: RequestOptions): AsyncIterable;