import type { Observable } from 'rxjs'; import type { MediaError } from './errors'; /** * Voice Activity Detection (VAD) tuning. * * SIP sessions use the call-level telephony VAD when available. WS sessions create one * VAD instance for the whole socket session on the first `createAsr()` call and merge * these options with runtime defaults. When no VAD is available, audio is forwarded to * ASR continuously and most VAD observables are empty. */ export interface AsrVadConfig { /** Energy threshold to start speech detection (0.0–1.0). */ positiveThreshold?: number; /** Energy threshold to end speech detection (0.0–1.0). */ negativeThreshold?: number; /** Minimum consecutive speech frames to confirm speech start. */ minSpeechFrames?: number; /** Noise floor energy level. */ energyFloor?: number; /** Smoothing factor for noise floor estimation (0.0–1.0). */ noiseFloorAlpha?: number; /** Frames of PCM (typically 20 ms @ 16 kHz / 640 bytes) to prepend before detected speech start. */ preSpeechFrames?: number; /** Frames of post-speech PCM to still forward to ASR after VAD speech end. */ postSpeechFrames?: number; } /** * Smart turn-taking — controls when the runtime finalizes an utterance (end-of-turn) while * streaming audio to ASR. Reduces cutting off the user mid-sentence when enabled. * * On WS sessions these values are passed to the telephony VAD/SmartTurn service. * On SIP sessions, `enabled: true` also ensures the ASR connector has an * `utterance_end_ms` value (defaulting to `1000`) when the resolved connector config * did not already provide one. */ export interface AsrSmartTurnConfig { /** When `true`, turn-taking heuristics are applied (defaults vary by host). */ enabled?: boolean; /** Frames of speech that must be seen before a "turn" can start. */ triggerFrames?: number; /** Frames to wait before retrying after a short pause inside an utterance. */ retryFrames?: number; /** Max silence frames before force-finalizing the current turn. */ maxSilenceFrames?: number; /** Milliseconds to wait for confirmation after a candidate end-of-turn. */ confirmMs?: number; /** Hard cap: finalize after this many milliseconds of silence regardless of other rules. */ silenceTimeoutMs?: number; } /** * Arguments for {@link import('./media-channel').MediaChannel.createAsr}. * * ### Voctiv platform + logic-executor `key_storage` * * When Voctiv platform compatibility is on and the connector loaded credentials from PostgreSQL, the session's * `authentication_data` includes **`legacyAsrKeysByName`**: a map from **`key_storage.name`** * (string) to flat connector parameters (`api_key`, `base_url`, …) for **this dialog's agent * and company**. You do **not** pass agent UUID in the script — the dialog already belongs to an agent. * * - **`name`**: pick which row from that map to use (same value as in LE admin for the key). * - If omitted, the channel default **`defaultAsrName`** (from Omni / route) is used. * - If neither is set, credentials fall back to the usual **`authentication_data.asr.<engine>`** * blob for the resolved vendor (main/reserved keys on the agent). * * You may also set the same selector as **`data.name`**. The runtime treats it as * the storage-row selector and strips it before sending connector params to the ASR vendor. * * ### Vendor * * **`vendor`** is resolved via ScriptEngine vendor aliases (`"yandex"`, `"deepgram"`, `"neuro_v3"`, …). If you set * **`name`** but omit **`vendor`**, the runtime may infer vendor from the key row's **`platform`** * in the catalog. */ export interface AsrConfig { /** * ASR vendor / engine hint, e.g. `"yandex"`, `"deepgram"`, `"google"`, * `"azure"`, `"voctiv"`, or `"neuro_v3"`. */ vendor?: string; /** * logic-executor **`key_storage.name`** for this dialog's agent + company. Selects credentials * from **`authentication_data.legacyAsrKeysByName[name]`** when Voctiv platform PostgreSQL key auth is enabled. * Overrides channel **`defaultAsrName`**. */ name?: string; /** Recognition language (BCP-47), e.g. `"ru-RU"`. Passed through to the connector as `language`. */ language?: string; /** * Vendor-specific connection parameters (URLs, timeouts, model ids, nested JSON, …). * Merged last over channel defaults and catalog credentials so the script can override * per call. Primitives are stringified; objects and arrays are JSON-serialized. * * Do not rely on **`name`** here for third-party "model name" fields — the runtime consumes * it as the storage row selector and removes it before vendor config is built. */ data?: Record; /** Optional VAD tuning for this session (see host implementation). */ vad?: AsrVadConfig; /** Optional smart-turn tuning for this session. */ smartTurn?: AsrSmartTurnConfig; } /** * Live speech recognition session returned by {@link import('./media-channel').MediaChannel.createAsr}. * * Call **`createAsr` early** to warm the ASR TCP/WebSocket (SSL handshake once per * dialog + vendor + credentials). A second `createAsr` with the same resolved config * reuses that channel instead of opening another socket. Call **`destroy()`** when done * (e.g. on `channel.events.terminated$`) to release the connector. * * Subscribe to **`partial$`** / **`result$`** for transcripts; wire **`speechStart$`** / * **`speechEnd$`** / **`interrupt$`** for barge-in and UI. * * If connector creation fails, SIP/WS return a degraded handle: VAD observables still * mirror the channel where possible, but `partial$` and `result$` do not emit real STT. */ export interface AsrHandle { /** Opaque id (passed to `channel.textInput` helpers in automated tests). */ readonly id: string; /** * Emits one string per finalized utterance (end-of-turn). Empty strings may occur; * filter in application code if needed. */ readonly result$: Observable; /** * Streaming partial hypotheses. **`isFinal: true`** marks the last partial before a finalize * or end-of-turn aligned with **`result$`**. */ readonly partial$: Observable<{ text: string; isFinal: boolean; }>; /** Fires when VAD detects speech start (user started talking). */ readonly speechStart$: Observable; /** Fires when VAD detects speech end (user stopped). */ readonly speechEnd$: Observable; /** Fires on barge-in / interrupt signals from the ASR stack (host-specific). */ readonly interrupt$: Observable; /** Normalized voice-activity probability 0–1 when the host exposes it; else may be inert. */ readonly vadProbability$: Observable; /** * Runtime errors from the ASR provider (gRPC disconnect, auth failures, quota exceeded, etc.). * * A degraded handle (returned when connector creation itself failed) has an inert `error$` * that never emits — the creation failure is reported on {@link import('./media-channel').ChannelEvents.error$} instead. * * ```ts * const asr = await channel.createAsr({ name: 'yandex-asr-test' }); * asr.error$.subscribe(err => console.log('ASR error:', err.message)); * ``` */ readonly error$: Observable; /** Pause forwarding new audio frames to the recognizer; skipped audio is not replayed. */ pause(): void; /** Resume after {@link pause}. */ resume(): void; /** Force end of current utterance and flush **`result$`** as soon as possible. */ finalize(): void; /** Tear down streams, connector, and subscriptions. Idempotent-safe on well-behaved hosts. */ destroy(): void; } //# sourceMappingURL=asr-handle.d.ts.map