import { type AudioFrame, AudioResampler } from '@livekit/rtc-node';
import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
import type { ReadableStream } from 'node:stream/web';
import type { LanguageCode } from '../language.js';
import type { STTMetrics } from '../metrics/base.js';
import { type APIConnectOptions } from '../types.js';
import type { AudioBuffer } from '../utils.js';
import { AsyncIterableQueue } from '../utils.js';
import type { ConversationItemAddedEvent } from '../voice/events.js';
import type { TimedString } from '../voice/index.js';
/** Indicates start/middle/end of speech */
export declare enum SpeechEventType {
    /**
     * Indicate the start of speech.
     * If the STT doesn't support this event, this will be emitted at the same time
     * as the first INTERIM_TRANSCRIPT.
     */
    START_OF_SPEECH = 0,
    /**
     * Interim transcript, useful for real-time transcription.
     */
    INTERIM_TRANSCRIPT = 1,
    /**
     * Final transcript, emitted when the STT is confident enough that a certain
     * portion of the speech will not change.
     */
    FINAL_TRANSCRIPT = 2,
    /**
     * Indicate the end of speech, emitted when the user stops speaking.
     * The first alternative is a combination of all the previous FINAL_TRANSCRIPT events.
     */
    END_OF_SPEECH = 3,
    /** Usage event, emitted periodically to indicate usage metrics. */
    RECOGNITION_USAGE = 4,
    /**
     * Preflight transcript, emitted before final transcript when STT has high confidence
     * but hasn't fully committed yet. Includes all pre-committed transcripts including
     * final transcript from the previous STT run.
     */
    PREFLIGHT_TRANSCRIPT = 5
}
/** SpeechData contains metadata about this {@link SpeechEvent}. */
export interface SpeechData {
    /** Language code of the speech. */
    language: LanguageCode;
    /** Transcribed text. */
    text: string;
    /** Start time of the speech segment in seconds. */
    startTime: number;
    /** End time of the speech segment in seconds. */
    endTime: number;
    /** Confidence score of the transcription (0-1). */
    confidence: number;
    /** Word-level timing information. */
    words?: TimedString[];
    /** Speaker identifier when the provider supports diarization. */
    speakerId?: string | null;
    /**
     * The source languages spoken by the user.
     *
     * Populated by STT services that support translation, where `language` holds the
     * target language and `sourceLanguages` holds the original spoken language(s),
     * or by multi-language detection services where `language` holds the dominant
     * language and `sourceLanguages` holds all detected languages sorted by prevalence.
     *
     * May contain multiple entries when a single utterance spans multiple source languages.
     */
    sourceLanguages?: LanguageCode[];
    /**
     * The original transcription segments in the source language(s), when translation is active.
     * Each entry corresponds to the same-indexed entry in `sourceLanguages`.
     */
    sourceTexts?: string[];
    /**
     * The target language(s) produced by a translation-capable STT service, one entry per
     * consecutive same-language run, parallel to `targetTexts`.
     *
     * `language` holds the dominant or first target language and `targetLanguages` carries the
     * fine-grained per-run breakdown. Populated when translation is active.
     */
    targetLanguages?: LanguageCode[];
    /**
     * The translated transcription segments in the target language(s).
     * Each entry corresponds to the same-indexed entry in `targetLanguages`.
     */
    targetTexts?: string[];
    /**
     * Optional plugin-specific metadata (e.g. voice profile, provider diagnostics).
     *
     * Plugins may populate this with provider-specific data that doesn't map to standard fields.
     */
    metadata?: Record<string, unknown>;
}
export interface RecognitionUsage {
    /** Duration of the audio that was recognized in seconds. */
    audioDuration: number;
    /** Input audio tokens (for token-based STT billing). */
    inputTokens?: number;
    /** Output text tokens (for token-based STT billing). */
    outputTokens?: number;
}
/** SpeechEvent is a packet of speech-to-text data. */
export interface SpeechEvent {
    type: SpeechEventType;
    alternatives?: [SpeechData, ...SpeechData[]];
    /** Wall-clock time when speech ended, in milliseconds since the Unix epoch. */
    speechEndTime?: number;
    requestId?: string;
    recognitionUsage?: RecognitionUsage;
}
/**
 * Describes the capabilities of the STT provider.
 *
 * @remarks
 * At present, the framework only supports providers that have a streaming endpoint.
 */
export interface STTCapabilities {
    streaming: boolean;
    interimResults: boolean;
    /**
     * Whether this STT supports aligned transcripts with word/chunk timestamps.
     * - 'word': Provider returns word-level timestamps
     * - 'chunk': Provider returns chunk-level timestamps (e.g., sentence/phrase boundaries)
     * - false: Provider does not support aligned transcripts
     */
    alignedTranscript?: 'word' | 'chunk' | false;
    /** Whether this STT supports speaker diarization. */
    diarization?: boolean;
    /** Whether the STT supports keyterm prompting */
    keyterms?: boolean;
    /** Whether the STT can natively consume conversation context (see STT._pushConversationItem) */
    chatContext?: boolean;
}
export interface STTError {
    type: 'stt_error';
    timestamp: number;
    label: string;
    error: Error;
    recoverable: boolean;
}
export type STTCallbacks = {
    ['metrics_collected']: (metrics: STTMetrics) => void;
    ['error']: (error: STTError) => void;
};
declare const STT_base: new () => TypedEmitter<STTCallbacks>;
/**
 * An instance of a speech-to-text adapter.
 *
 * @remarks
 * This class is abstract, and as such cannot be used directly. Instead, use a provider plugin that
 * exports its own child STT class, which inherits this class's methods.
 */
export declare abstract class STT extends STT_base {
    #private;
    abstract label: string;
    constructor(capabilities: STTCapabilities);
    /** Returns this STT's capabilities */
    get capabilities(): STTCapabilities;
    protected updateCapabilities(caps: Partial<STTCapabilities>): void;
    /**
     * Get the model name/identifier for this STT instance.
     *
     * @returns The model name if available, "unknown" otherwise.
     *
     * @remarks
     * Plugins should override this property to provide their model information.
     */
    get model(): string;
    /**
     * Get the provider name for this STT instance.
     *
     * @returns The provider name if available, "unknown" otherwise.
     *
     * @remarks
     * Plugins should override this property to provide their provider information.
     */
    get provider(): string;
    /** Receives an audio buffer and returns transcription in the form of a {@link SpeechEvent} */
    recognize(frame: AudioBuffer, abortSignal?: AbortSignal): Promise<SpeechEvent>;
    protected abstract _recognize(frame: AudioBuffer, abortSignal?: AbortSignal): Promise<SpeechEvent>;
    /**
     * Set the framework-managed keyterms (session config + auto-detection).
     *
     * Internal hook called by the framework, kept separate from the user's own keyterms
     * (constructor / `updateOptions`). Plugins that support keyterms override this to
     * store the session set and apply it merged with the user keyterms.
     *
     * @internal
     */
    _updateSessionKeyterms(_keyterms: string[]): void;
    /**
     * Feed a new conversation turn to the STT to bias recognition (context carryover).
     *
     * Plugins with native context support set `STTCapabilities.chatContext` and override
     * this to forward the item to their provider's carryover field.
     *
     * @internal
     */
    _pushConversationItem(_ev: ConversationItemAddedEvent): void;
    /**
     * Returns a {@link SpeechStream} that can be used to push audio frames and receive
     * transcriptions
     *
     * @param options - Optional configuration including connection options
     */
    abstract stream(options?: {
        connOptions?: APIConnectOptions;
    }): SpeechStream;
    close(): Promise<void>;
}
/**
 * An instance of a speech-to-text stream, as an asynchronous iterable iterator.
 *
 * @example Looping through frames
 * ```ts
 * for await (const event of stream) {
 *   if (event.type === SpeechEventType.FINAL_TRANSCRIPT) {
 *     console.log(event.alternatives[0].text)
 *   }
 * }
 * ```
 *
 * @remarks
 * This class is abstract, and as such cannot be used directly. Instead, use a provider plugin that
 * exports its own child SpeechStream class, which inherits this class's methods.
 */
export declare abstract class SpeechStream implements AsyncIterableIterator<SpeechEvent> {
    #private;
    protected static readonly FLUSH_SENTINEL: unique symbol;
    protected input: AsyncIterableQueue<AudioFrame | typeof SpeechStream.FLUSH_SENTINEL>;
    protected output: AsyncIterableQueue<SpeechEvent>;
    protected queue: AsyncIterableQueue<SpeechEvent>;
    protected neededSampleRate?: number;
    protected resampler?: AudioResampler;
    abstract label: string;
    protected closed: boolean;
    private deferredInputStream;
    private logger;
    private _connOptions;
    private _startTimeOffset;
    private _numRetries;
    protected abortController: AbortController;
    constructor(stt: STT, sampleRate?: number, connectionOptions?: APIConnectOptions);
    /**
     * Runs the STT with retry logic. Errors are emitted via {@link STT} error events
     * and then re-thrown to end the attempt loop; the caller swallows them.
     *
     * @throws {APIError} When the STT request fails with a non-retryable error
     * @throws {APIConnectionError} When all retry attempts are exhausted
     * @internal Not annotated with Throws<> because this is fire-and-forget via startSoon()
     */
    private mainTask;
    private emitError;
    protected pumpInput(): Promise<void>;
    protected monitorMetrics(): Promise<void>;
    protected abstract run(): Promise<void>;
    protected get abortSignal(): AbortSignal;
    /** Whether this stream ended with an unrecoverable error. @internal */
    get _failed(): boolean;
    get startTimeOffset(): number;
    set startTimeOffset(value: number);
    updateInputStream(audioStream: ReadableStream<AudioFrame>): void;
    detachInputStream(): void;
    /** Push an audio frame to the STT */
    pushFrame(frame: AudioFrame): void;
    /** Flush the STT, causing it to process all pending text */
    flush(): void;
    /** Mark the input as ended and forbid additional pushes */
    endInput(): void;
    next(): Promise<IteratorResult<SpeechEvent>>;
    /** Close both the input and output of the STT stream */
    close(): void;
    [Symbol.asyncIterator](): SpeechStream;
}
export {};
//# sourceMappingURL=stt.d.ts.map