import { StreamingTranscriberParams, AudioData, BeginEvent, TurnEvent, LLMGatewayResponseEvent, SpeakerRevisionEvent, StreamingUpdateConfiguration, WarningEvent, HeartbeatEvent } from "../..";
import type { VadFrame } from "../../types/streaming/dual-channel";
/**
 * Options for `sendAudio`. In dual-channel mode (when `channels` is configured
 * on the transcriber), `channel` is required and must match one of the declared
 * channel names; in single-channel mode it is ignored.
 */
export type SendAudioOptions = {
    channel?: string;
};
export declare class StreamingTranscriber {
    private apiKey?;
    private token?;
    private params;
    private socket?;
    private listeners;
    private sessionTerminatedResolve?;
    private isDualChannel;
    private channelNames?;
    private channelBuffers?;
    private channelSamplesReceived?;
    private channelVadFloatBuffers?;
    private channelVadBufferIdx?;
    private channelVads?;
    private timeline?;
    private flushTimer?;
    private attributionParams?;
    private vadFrameSamples;
    private minChunkSamples;
    private maxChunkSamples;
    private speakerHistory?;
    constructor(params: StreamingTranscriberParams);
    private connectionUrl;
    on(event: "open", listener: (event: BeginEvent) => void): void;
    on(event: "turn", listener: (event: TurnEvent) => void): void;
    on(event: "llmGatewayResponse", listener: (event: LLMGatewayResponseEvent) => void): void;
    on(event: "speakerRevision", listener: (event: SpeakerRevisionEvent) => void): void;
    on(event: "warning", listener: (event: WarningEvent) => void): void;
    on(event: "heartbeat", listener: (event: HeartbeatEvent) => void): void;
    on(event: "vad", listener: (event: VadFrame) => void): void;
    on(event: "error", listener: (error: Error) => void): void;
    on(event: "close", listener: (code: number, reason: string) => void): void;
    /**
     * Open the streaming session.
     *
     * Resolves with the server's `Begin` event once the handshake completes. A
     * single attempt is bounded by `connectTimeout` (default 1000ms); transient
     * failures (timeout, network drop, unexpected close) are retried up to
     * `maxConnectionRetries` times (default 2), waiting `connectionRetryDelay`
     * (default 500ms) between attempts. Permanent failures (auth, insufficient
     * funds, malformed config) are not retried.
     *
     * Unlike previously, a failed connection now rejects this promise rather
     * than only invoking the `error` listener — necessary for the caller (and
     * the retry loop) to observe the failure.
     */
    connect(): Promise<BeginEvent>;
    private connectOnce;
    /** Tear down a half-open socket from a failed connection attempt. */
    private discardPendingSocket;
    /**
     * Returns a WritableStream that pumps PCM chunks into `sendAudio`. Single-channel
     * only — in dual-channel mode use `sendAudio(pcm, { channel })` directly, since
     * `WritableStream` has no place to carry a channel tag.
     */
    stream(): WritableStream<AudioData>;
    /**
     * Send PCM audio.
     *
     * In single-channel mode, `audio` is forwarded directly to the WebSocket and
     * `options` is ignored.
     *
     * In dual-channel mode (when `channels` is configured), `options.channel` is
     * REQUIRED and must match one of the declared channel names. Per-channel PCM is
     * fed into that channel's VAD, accumulated into a per-channel ring buffer, and
     * a scheduled flush (`channelAttribution.flushIntervalMs`, default 50ms) mixes
     * the buffers into mono before sending to the WebSocket.
     */
    sendAudio(audio: AudioData, options?: SendAudioOptions): void;
    private ingestChannelAudio;
    private startFlushTimer;
    private flushMix;
    /**
     * Fill in words whose per-word VAD attribution was `"unknown"` by looking
     * at the dominant non-`"unknown"` channel among ±N neighbors in the same
     * turn. Words with no non-`"unknown"` neighbors stay `"unknown"`. Confident
     * per-word VAD decisions are never modified.
     *
     * Local temporal heuristic — ignores `speaker_label`, so it works even when
     * AAI's diarization re-uses the same label for two physically distinct
     * voices. Each resolved word gets `channelResolved: true` so downstream
     * renderers can distinguish inferred channels from directly-measured ones.
     */
    private resolveUnknownChannelsByWindow;
    /**
     * Fill `"unknown"` words by looking up the speaker's session-wide channel
     * evidence. For each `speaker_label`, sums active VAD frame RMS per channel
     * across every word the speaker has uttered to date. A speaker is
     * "resolvable" if their total evidence clears
     * `speakerHistoryMinRmsEvidence` and their top channel exceeds the
     * runner-up by `speakerHistoryDominanceRatio`.
     *
     * Only touches `"unknown"` words. Confident per-word VAD decisions are
     * never modified. `speaker_label` is never modified.
     */
    private resolveUnknownChannelsBySpeakerHistory;
    /**
     * Update the streaming configuration mid-stream.
     * @param config - The configuration parameters to update
     */
    updateConfiguration(config: Omit<StreamingUpdateConfiguration, "type">): void;
    /**
     * Force the current turn to end immediately.
     */
    forceEndpoint(): void;
    /**
     * Reset the server's inactivity timer. Only needed when the session was
     * created with `inactivityTimeout` and no audio is being sent.
     */
    keepAlive(): void;
    private send;
    close(waitForSessionTermination?: boolean): Promise<void>;
}
