/**
 * Reconnecting WebSocket primitive shared by the SDK's WS-based realtime
 * helpers (text-stream, session-connect, observer).
 *
 * The platform exposes three workspace-scoped WebSocket surfaces with similar
 * lifecycle requirements:
 *
 *   * Resume on transient drops with exponential backoff + full jitter
 *   * Treat 4001 (client error) and 4403 (auth) close codes as terminal
 *   * Treat 4029 (rate limit / cap) as terminal-but-retryable on a slow timer
 *   * Watchdog the connection: if no message arrives within an idle window,
 *     the upstream is dead even if the TCP socket has not closed; force a
 *     reconnect
 *   * Surface every typed message through ``onMessage`` and every state
 *     transition through ``onStateChange``
 *
 * Before this primitive existed, every consumer (developer-console
 * useStreamSession, useCallObserver, agent-engineering scripts) re-implemented
 * the loop with subtle bugs (different idle thresholds, missing retry budget,
 * no terminal-code handling). This module is the single canonical
 * implementation; resource helpers compose it with their own message parsers
 * and protocol details.
 *
 * @see ReconnectingWebSocket
 * @see EventsResource for the analogous SSE-based helper
 */
/** Lifecycle states reported via {@link ReconnectingWebSocketOptions.onStateChange}. */
export type ReconnectingWebSocketState = 'connecting' | 'open' | 'closing' | 'closed' | 'reconnecting' | 'terminal';
/** Reasons surfaced to {@link ReconnectingWebSocketOptions.onError} on a terminal close. */
export type ReconnectingWebSocketErrorReason = 'auth' | 'rate_limited' | 'client_error' | 'server_error' | 'reconnect_budget_exhausted' | 'aborted' | 'idle_watchdog' | 'open_failed' | 'unknown';
/** Structured terminal error surfaced to consumers. */
export declare class ReconnectingWebSocketError extends Error {
    readonly reason: ReconnectingWebSocketErrorReason;
    readonly closeCode: number | undefined;
    readonly closeReason: string | undefined;
    readonly attempts: number;
    constructor(message: string, reason: ReconnectingWebSocketErrorReason, closeCode: number | undefined, closeReason: string | undefined, attempts: number);
}
/**
 * Constructor for the underlying WebSocket. Defaults to the global
 * ``WebSocket`` (browsers, Bun, Deno, Node 22+ via global) if available.
 *
 * Pass an explicit factory in environments without a global (older Node) or
 * for tests that swap in a mock.
 */
export type WebSocketFactory = (url: string, protocols?: string | string[]) => WebSocket;
/** Options for {@link ReconnectingWebSocket}. */
export interface ReconnectingWebSocketOptions {
    /** Target ws:// or wss:// URL. */
    url: string;
    /**
     * Optional WebSocket subprotocols. The platform's auth scheme passes the
     * bearer token here (``['auth', token]``) so it never appears in the URL.
     */
    protocols?: string | string[];
    /**
     * Initial backoff delay (ms). Doubles with full jitter on each successive
     * failure up to ``maxDelayMs``. Default ``1_000``.
     */
    initialDelayMs?: number;
    /** Cap on the reconnect backoff delay (ms). Default ``30_000``. */
    maxDelayMs?: number;
    /**
     * Maximum number of reconnect attempts before giving up. Default ``10``.
     * Set to ``Infinity`` to retry forever (rely on AbortSignal for shutdown).
     */
    maxReconnects?: number;
    /**
     * Idle watchdog (ms). If no message arrives within this window the
     * connection is considered dead and is force-closed; the reconnect loop
     * then handles the rebuild. Default ``45_000`` (matches the longest
     * platform endpoint heartbeat). Set to ``0`` to disable.
     */
    idleTimeoutMs?: number;
    /**
     * Cancellation signal. Aborting the signal closes the underlying socket
     * and stops the reconnect loop. The ``done`` promise resolves once the
     * teardown completes.
     */
    signal?: AbortSignal;
    /**
     * Optional WebSocket factory. Defaults to ``globalThis.WebSocket`` if
     * available; throws at first connect attempt otherwise.
     */
    webSocketFactory?: WebSocketFactory;
    /**
     * Invoked when the underlying socket transitions states. Mostly useful
     * for surfacing reconnects to the UI (e.g., "Reconnecting…" banner).
     */
    onStateChange?: (state: ReconnectingWebSocketState) => void;
    /**
     * Invoked once per inbound frame. ``MessageEvent.data`` is delivered raw
     * — consumers parse JSON / binary themselves.
     */
    onMessage: (event: MessageEvent) => void;
    /**
     * Invoked just before each reconnect attempt with the 1-based attempt
     * number, the planned delay (ms), and the close code that triggered the
     * reconnect.
     */
    onReconnect?: (info: {
        attempt: number;
        delayMs: number;
        closeCode: number | undefined;
    }) => void;
    /**
     * Invoked exactly once per ``ReconnectingWebSocket`` instance on a
     * terminal failure (consumer-aborted, reconnect budget exhausted, or a
     * close code in the terminal set: 4001 / 4003 / 4403 / 4100 / 1008).
     */
    onError?: (error: ReconnectingWebSocketError) => void;
}
/** Handle returned by {@link createReconnectingWebSocket}. */
export interface ReconnectingWebSocketHandle {
    /**
     * Resolves when the loop has fully stopped (post-abort cleanup complete).
     * Never rejects; consume errors via ``onError``.
     */
    done: Promise<void>;
    /**
     * Send a frame on the currently open socket. Throws if no socket is
     * currently open. Use ``onStateChange`` to gate sends, or buffer in
     * caller code.
     */
    send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
    /**
     * Close the connection and stop reconnecting. Equivalent to aborting the
     * caller-supplied signal. Idempotent.
     */
    close(code?: number, reason?: string): void;
    /** Latest known lifecycle state. */
    readonly state: ReconnectingWebSocketState;
}
/**
 * Build a managed reconnecting WebSocket.
 *
 * The returned handle is the only public surface; the underlying
 * ``WebSocket`` is held privately so consumers cannot bypass the lifecycle
 * machinery (which would defeat the watchdog and reconnect loop).
 *
 * @example
 * ```ts
 * const handle = createReconnectingWebSocket({
 *   url: client.conversations.sessionConnectUrl({ serviceId, entityId }),
 *   protocols: sessionConnectAuthProtocols(apiKey),
 *   onMessage: (e) => console.log('frame', e.data),
 *   onStateChange: (s) => console.log('state', s),
 *   onError: (err) => console.error('terminal:', err.reason, err.closeCode),
 * });
 *
 * handle.send(JSON.stringify({ type: 'user_text', text: 'hi' }));
 * await handle.done;  // resolves after handle.close() or terminal error
 * ```
 */
export declare function createReconnectingWebSocket(options: ReconnectingWebSocketOptions): ReconnectingWebSocketHandle;
//# sourceMappingURL=reconnecting-websocket.d.ts.map