import { AgentInference } from '@livekit/protocol';
import type { AudioFrame } from '@livekit/rtc-node';
import { APIError } from '../../_exceptions.js';
import type { InferenceExecutor } from '../../ipc/inference_executor.js';
import { type StreamChannel } from '../../stream/stream_channel.js';
import { type APIConnectOptions } from '../../types.js';
import { type BaseStreamingTurnDetectorOptions, type BaseStreamingTurnDetectorStream, type FlushSentinel, type StreamingTurnDetectionTransport } from './base.js';
import type { TurnDetector } from './detector.js';
type ClientMsg = InstanceType<typeof AgentInference.ClientMessage>;
type ServerMsg = InstanceType<typeof AgentInference.ServerMessage>;
export interface CloudTransportOptions {
    baseUrl: string;
    apiKey: string;
    apiSecret: string;
    connOptions: APIConnectOptions;
}
/**
 * Minimal WebSocket shape both the real `ws` socket and test fakes satisfy.
 * The cloud transport only needs send/close/readyState + the three events.
 */
export interface CloudWebSocket {
    send(data: Uint8Array): void;
    close(): void;
    readonly readyState: number;
    on(event: 'message', cb: (data: Buffer | ArrayBuffer | Buffer[]) => void): void;
    on(event: 'close', cb: () => void): void;
    on(event: 'error', cb: (err: Error) => void): void;
}
/**
 * Append-only ring buffer of 16-bit PCM samples used by the local transport
 * to keep the last ~1.2 s of audio available for per-window prediction.
 */
declare class PcmRingBuffer {
    readonly capacity: number;
    private buf;
    private writeIdx;
    private filled;
    constructor(capacity: number);
    pushFrame(frame: AudioFrame): void;
    /** Returns a contiguous Int16Array snapshot of the last `filled` samples. */
    read(): Int16Array;
    /** Drop the oldest `n` samples. */
    shift(n: number): void;
    get length(): number;
}
/**
 * Transport for the local `turn-detector-v1-mini` model.
 *
 * The native model runs in the shared `InferenceProcExecutor` (one load per
 * host, ~138 MB) rather than in every job worker. Audio is buffered locally
 * in the job process (no per-frame IPC); on each inference window the last
 * ~1.2 s is snapshotted, base64-encoded, and sent over IPC to the runner
 * (`inference/eot/runner.ts`) via `executor.doInference(...)`.
 *
 * When no executor is available (binding couldn't load on this platform),
 * predictions resolve to a positive default (1.0) so the session still
 * commits turns after `minDelay` — same as the existing local-failure path.
 */
export declare class LocalTransport implements StreamingTurnDetectionTransport {
    protected _opts: BaseStreamingTurnDetectorOptions;
    protected _executor: InferenceExecutor | undefined;
    protected _buf: PcmRingBuffer;
    protected _streamRef: WeakRef<BaseStreamingTurnDetectorStream> | undefined;
    protected _tasks: Set<Promise<void>>;
    protected _warnedNoExecutor: boolean;
    protected _logger: import("pino").Logger;
    constructor(opts: {
        opts: BaseStreamingTurnDetectorOptions;
        executor: InferenceExecutor | undefined;
    });
    attach(stream: BaseStreamingTurnDetectorStream): void;
    runInference(requestId: string): void;
    protected _predict(requestId: string, pcmSnapshot: Int16Array): Promise<void>;
    pushFrame(frame: AudioFrame): Promise<void>;
    flush(_sentinel: FlushSentinel): Promise<void>;
    detach(): void;
    run(): Promise<void>;
}
/**
 * WebSocket transport for the `turn-detector-v1` (cloud) model.
 *
 * Maintains one inference session against the LiveKit Agent Gateway:
 * connect → `SessionCreate` → three concurrent tasks (drain audio, send,
 * receive) → protobuf encode/decode → `stream._resolvePrediction(...)` +
 * `EOTInferenceMetrics` on the detector.
 *
 * All outbound messages flow through a single FIFO send channel so control
 * hooks fired synchronously between two awaited audio frames (e.g.
 * `inferenceStart` then `inputAudio`) reach the wire in call order.
 */
export declare class CloudTransport implements StreamingTurnDetectionTransport {
    protected _detectorRef: WeakRef<TurnDetector>;
    protected _opts: BaseStreamingTurnDetectorOptions;
    protected _cloudOpts: CloudTransportOptions;
    protected _connOptions: APIConnectOptions;
    protected _streamRef: WeakRef<BaseStreamingTurnDetectorStream> | undefined;
    protected _ws: CloudWebSocket | undefined;
    protected _numRetries: number;
    protected _connectCalls: number;
    /** Outbound FIFO for the active connection; recreated per `_runOnce`. */
    protected _sendChannel: StreamChannel<ClientMsg> | undefined;
    /** Set by `detach()`; stops the retry loop and suppresses the
     * connection-closed throw so a teardown can't trigger a reconnect. */
    protected _detached: boolean;
    /** Aborted by `detach()` to release the audio-drain reader lock so a
     * swapped-in transport can re-acquire the shared audio stream. */
    protected _runAbort: AbortController | undefined;
    protected _logger: import("pino").Logger;
    /** Optional connect override for tests; defaults to a real WS handshake. */
    private _connectImpl;
    constructor(args: {
        detector: TurnDetector;
        opts: BaseStreamingTurnDetectorOptions;
        cloudOpts: CloudTransportOptions;
        /** @internal test seam — supply a fake WebSocket factory. */
        connect?: (transport: CloudTransport) => Promise<CloudWebSocket>;
    });
    /** @internal Test-visible: number of connect attempts. */
    get connectCalls(): number;
    /** @internal Test-visible: retry counter (resets to 0 after a connect). */
    get numRetries(): number;
    attach(stream: BaseStreamingTurnDetectorStream): void;
    /** @internal Test-visible: true once the WS handshake is open. Not part of
     * the transport interface — the stream FSM does not gate on this. */
    transportReady(): boolean;
    runInference(requestId: string): void;
    pushFrame(frame: AudioFrame): Promise<void>;
    flush(_sentinel: FlushSentinel): Promise<void>;
    detach(): void;
    private _enqueue;
    private _defaultConnect;
    private _warnTransportLatency;
    protected _processServerMessage(msg: ServerMsg): void;
    run(): Promise<void>;
    protected _runOnce(): Promise<void>;
}
export type { StreamingTurnDetectionTransport };
export type { APIError };
//# sourceMappingURL=transports.d.ts.map