import { EventEmitter } from './eventEmitter.js'; import { EOUConfig, InterruptConfig } from './config.js'; import type { RealtimeConfig, ContextWindow } from './config.js'; import { PipelineConfig } from './enums.js'; /** Maximum number of recent vision frames retained for {@link Pipeline.getLatestFrames}. */ export declare const VISION_FRAME_BUFFER_MAX = 5; /** Default regex patterns used to filter out "call is being recorded" style transcripts. */ export declare const DEFAULT_STT_FILTER_PATTERNS: string[]; declare class _NoChange { toString(): string; } /** * Sentinel for live component changes: pass it (or omit the key) to leave a * component unchanged. */ export declare const NO_CHANGE: Readonly<_NoChange>; /** Hook names that accept a single handler (latest registration wins). @internal */ export declare const _SINGLE_HOOKS: ReadonlySet; /** Hook names that accept multiple handlers. @internal */ export declare const _MULTI_HOOKS: ReadonlySet; /** Hook names whose presence implicitly enables the corresponding feature. @internal */ export declare const HOOK_NAMES_AUTO_ENABLE: ReadonlySet; /** Map of hook names that are not currently supported, to `[reason, alternative]`. @internal */ export declare const UNSUPPORTED_HOOKS: Record; /** Thrown when a registered pipeline hook is not supported. */ export declare class PipelineHookError extends Error { /** The hook name that failed. */ readonly hookName: string; /** Why the hook is unsupported. */ readonly reason: string; /** A suggested alternative hook, or `null`. */ readonly alternative: string | null; constructor(hookName: string, reason: string, alternative?: string | null); } /** A metrics-hook callback receiving a metrics record for a component. */ export type MetricsHookFn = (metrics: Record) => any; /** * Registry of per-component metrics callbacks. Accessed via {@link Pipeline.metrics}; * register with `metrics.on('stt' | 'llm' | 'tts' | 'eou' | 'realtime', fn)`. */ export declare class PipelineMetricsHooks { private readonly _hooks; /** * Register a metrics callback for a component (`'stt'`, `'llm'`, `'tts'`, `'eou'`, * `'realtime'`). Usable directly (`on(c, fn)`) or as a decorator factory (`on(c)`). */ on(component: string): (fn: MetricsHookFn) => MetricsHookFn; on(component: string, fn: MetricsHookFn): MetricsHookFn; /** Invoke all callbacks registered for `component` with the given metrics. */ trigger(component: string, metrics: Record): Promise; /** Whether any callback is registered for `component`. */ hasHooks(component: string): boolean; } /** A pipeline hook callback. Signature varies by hook. */ export type PipelineHookFn = (...args: any[]) => any; /** Callback invoked when a background worker (STT/TTS/LLM pump) errors. */ export type OnWorkerError = (error: unknown, unexpected: boolean) => void; /** Events emitted by a {@link Pipeline}. */ export type PipelineEvents = { start: any[]; error: any[]; transcript_ready: any[]; content_generated: any[]; synthesis_complete: any[]; recording_started: any[]; recording_stopped: any[]; recording_failed: any[]; }; /** Options for constructing a {@link Pipeline}. Each component is optional. */ export type PipelineOptions = { /** Speech-to-text provider. Defaults to `null`. */ stt?: any; /** Language-model provider. Defaults to `null`. */ llm?: any; /** Text-to-speech provider. Defaults to `null`. */ tts?: any; /** Voice-activity-detection provider. Defaults to `null`. */ vad?: any; /** End-of-turn detector. Defaults to `null`. */ turnDetector?: any; /** Avatar/video provider. Defaults to `null`. */ avatar?: any; /** Audio denoiser. Defaults to `null`. */ denoise?: any; /** End-of-utterance config. Defaults to `EOUConfig()`. */ eouConfig?: EOUConfig | null; /** Interruption-handling config. Defaults to `InterruptConfig()`. */ interruptConfig?: InterruptConfig | null; /** Conversational-graph routing config. Defaults to `null`. */ conversationalGraph?: any; /** Context-window trimming policy. Defaults to `null`. */ contextWindow?: ContextWindow | any; /** Voicemail detector. Defaults to `null`. */ voiceMailDetector?: any; /** DTMF (touch-tone) handler. Defaults to `null`. */ dtmfHandler?: any; /** Realtime speech-to-speech config. Defaults to `null`. */ realtimeConfig?: RealtimeConfig | null; /** Enable the streaming LLM token-rewrite hook. Defaults to `false`. */ llmStreamHookEnabled?: boolean; /** Per-token timeout for the LLM stream hook, in milliseconds. Defaults to `100`. */ llmStreamHookTimeoutMs?: number; /** Grace period in milliseconds before considering playback finished. Defaults to `0`. */ playbackGraceMs?: number; /** Regex patterns to drop from transcripts. Defaults to {@link DEFAULT_STT_FILTER_PATTERNS}. */ sttFilterPatterns?: string[] | null; /** Word replacements applied to transcripts (`{ from: to }`). Defaults to `{}`. */ sttWordSubstitutions?: Record | null; /** Seconds of inactivity before the session times out, or `null` to disable. Defaults to `null`. */ inactivityTimeoutSeconds?: number | null; /** Seconds of caller silence before the agent's `onWakeUp` hook fires, or `null` to disable. Defaults to `null`. */ wakeUp?: number | null; /** Maximum wake-up nudges before the call ends, or `null` for no cap. Defaults to `null`. */ wakeUpMaxAttempts?: number | null; /** * Drop a transcript that consists solely of a filler word ("okay", "yeah", ...) * without an LLM turn. Defaults to `false` (every transcript reaches the model). */ filterFillerWords?: boolean; /** Filler words used when {@link PipelineOptions.filterFillerWords} is on. When unset, the runtime supplies its own defaults. */ fillerWords?: string[] | null; }; /** * Registry of pipeline hooks. Accessed via {@link Pipeline.hooks} or `Pipeline.on(...)`; * lets you observe or transform audio, transcripts, LLM tokens, and lifecycle events. */ export declare class PipelineHooks { private _sttStreamHook; private _ttsStreamHook; private _llmStreamHook; _multiHooks: Record; /** * Register a hook for `event`. Usable directly (`on(event, fn)`) or as a decorator * factory (`on(event)`). Single-handler hooks ({@link _SINGLE_HOOKS}) overwrite; others append. */ on(event: string): (fn: PipelineHookFn) => PipelineHookFn; on(event: string, fn: PipelineHookFn): PipelineHookFn; private _register; /** All multi-handler callbacks registered for `event`. */ getHooks(event: string): PipelineHookFn[]; /** The registered STT stream hook, or `null`. */ get sttStreamHook(): PipelineHookFn | null; /** The registered TTS stream hook, or `null`. */ get ttsStreamHook(): PipelineHookFn | null; /** The registered LLM stream hook, or `null`. */ get llmStreamHook(): PipelineHookFn | null; /** Whether an STT stream hook is registered. */ hasSttStreamHook(): boolean; /** Whether a TTS stream hook is registered. */ hasTtsStreamHook(): boolean; /** Whether an LLM stream hook is registered. */ hasLlmStreamHook(): boolean; /** Whether any observe-only `llm` hooks are registered. */ hasLlmObservationHooks(): boolean; /** Names of all hooks that currently have at least one handler. */ registeredNames(): string[]; /** Remove all registered hooks. */ clearAllHooks(): void; } /** @internal Drives an `llm_stream` async-gen hook, matching one decision per token in order. */ export declare class AsyncGenStreamBridge { private readonly _hook; private readonly _timeoutSeconds; private _inputQueue; private _tokenIdOrder; private _decisionFutures; private _workerTask; private _workerDone; private _closed; constructor(hook: PipelineHookFn, timeoutSeconds?: number); private _ensureWorker; /** Feed one token to the hook; returns `[replacementText, dropped]`. */ process(text: string, tokenId: number): Promise<[string, boolean]>; aclose(): Promise; } /** Drives a custom `stt` stream hook, feeding it audio and forwarding transcripts. @internal */ export declare class CustomSttPump { private readonly _hook; private readonly _sendResultCb; private readonly _onWorkerError; private _inputQueue; private _workerTask; private _workerDone; private _closed; constructor(hook: PipelineHookFn, sendResultCb: (result: any) => any, onWorkerError?: OnWorkerError | null); private _ensureWorker; pushAudio(chunk: any): void; aclose(): Promise; } /** Drives a custom `tts` stream hook, feeding it synthesis requests and forwarding audio. @internal */ export declare class CustomTtsPump { private readonly _hook; private readonly _sendAudioCb; private readonly _onWorkerError; private _inputQueue; private _workerTask; private _workerDone; private _closed; constructor(hook: PipelineHookFn, sendAudioCb: (chunk: any) => any, onWorkerError?: OnWorkerError | null); private _ensureWorker; pushSynthesize(request: any): void; aclose(): Promise; } /** * Manages audio/video input listeners for a {@link Pipeline}. Accessed via * {@link Pipeline.inputStreamManager}. */ export declare class _InputStreamManager { private readonly _pipeline; private _audioListeners; private _videoListeners; constructor(pipeline: Pipeline); /** Add a listener that receives incoming audio frames. Returns the listener. */ addAudioListener(listener: PipelineHookFn): PipelineHookFn; /** Remove a previously added audio listener. */ removeAudioListener(listener: PipelineHookFn): void; /** Add a listener that receives incoming vision frames. Returns the listener. */ addVideoListener(listener: PipelineHookFn): PipelineHookFn; /** Remove a previously added video listener. */ removeVideoListener(listener: PipelineHookFn): void; /** Remove all audio and video listeners. */ cancelTasks(): void; } /** * The runtime's answer to one swap command, delivered as a `runtime_warning` * event on the session's event stream. `promise` resolves once a verdict * arrives (or never, if none does); `resolve()` is idempotent. * @internal */ export type SwapVerdict = { settled: boolean; status: 'ok' | 'fail' | null; message: string; promise: Promise; resolve: () => void; }; /** Options for {@link Pipeline.changeComponent}. Omit a key, or pass {@link NO_CHANGE}, to leave it unchanged. */ export type ChangeComponentOptions = { /** New speech-to-text provider, or {@link NO_CHANGE}. */ stt?: any; /** New language-model provider, or {@link NO_CHANGE}. */ llm?: any; /** New text-to-speech provider, or {@link NO_CHANGE}. */ tts?: any; /** New voice-activity-detection provider, or {@link NO_CHANGE}. */ vad?: any; /** New end-of-turn detector, or {@link NO_CHANGE}. */ turnDetector?: any; /** Present for symmetry with {@link PipelineOptions}; denoise is never hot-swappable. */ denoise?: any; /** When `false`, clear the LLM's conversation history once the swap is confirmed. Defaults to `true`. */ passContext?: boolean; }; /** Options for {@link Pipeline.changePipeline}. Omit a key to leave that part unchanged. */ export type ChangePipelineOptions = { /** New speech-to-text provider (cascade/hybrid_stt target). */ stt?: any; /** New language-model provider; required whenever the shape changes, since it defines the mode. */ llm?: any; /** New text-to-speech provider (cascade/hybrid_tts target). */ tts?: any; /** New voice-activity-detection provider. */ vad?: any; /** New end-of-turn detector. */ turnDetector?: any; /** Retune interruption handling live (cascade pipelines only). */ interruptConfig?: any; /** Retune the conversation context-window budget live. */ contextWindow?: any; /** When `false`, clear the LLM's conversation history once the switch is confirmed. Defaults to `true`. */ passContext?: boolean; }; declare class PipelineImpl extends EventEmitter { /** Speech-to-text provider, or `null`. */ stt: any; /** Language-model provider, or `null`. */ llm: any; /** Text-to-speech provider, or `null`. */ tts: any; /** Voice-activity-detection provider, or `null`. */ vad: any; /** End-of-turn detector, or `null`. */ turnDetector: any; /** Avatar/video provider, or `null`. */ avatar: any; /** Audio denoiser, or `null`. */ denoise: any; /** End-of-utterance config. */ eouConfig: EOUConfig; /** Interruption-handling config. */ interruptConfig: InterruptConfig; /** Context-window trimming policy, or `null`. */ contextWindow: ContextWindow | any; /** Voicemail detector, or `null`. */ voiceMailDetector: any; /** DTMF (touch-tone) handler, or `null`. */ dtmfHandler: any; /** Realtime speech-to-speech config, or `null`. */ realtimeConfig: RealtimeConfig | null; /** Whether the streaming LLM token-rewrite hook is enabled. */ llmStreamHookEnabled: boolean; /** Per-token timeout for the LLM stream hook, in milliseconds. */ llmStreamHookTimeoutMs: number; /** Grace period in milliseconds before playback is considered finished. */ playbackGraceMs: number; /** Regex patterns dropped from transcripts. */ sttFilterPatterns: string[]; /** Word substitutions applied to transcripts. */ sttWordSubstitutions: Record; /** Seconds of inactivity before timeout, or `null`. */ inactivityTimeoutSeconds: number | null; /** Seconds of caller silence before the agent's `onWakeUp` hook fires, or `null`. */ wakeUp: number | null; /** Maximum wake-up nudges before the call ends, or `null`. */ wakeUpMaxAttempts: number | null; /** Whether filler-only transcripts are dropped without an LLM turn. */ filterFillerWords: boolean; /** Filler words used when {@link PipelineImpl.filterFillerWords} is on. */ fillerWords: string[]; /** Hook registry for observing/transforming the pipeline; see {@link PipelineHooks}. */ hooks: PipelineHooks; /** Metrics-hook registry; see {@link PipelineMetricsHooks}. */ metrics: PipelineMetricsHooks; /** The agent bound to this pipeline, or `null`. */ agent: any; /** Conversational-graph adapter, or `null`. */ graphAdapter: any; /** Recent vision frames, capped at {@link VISION_FRAME_BUFFER_MAX}. */ frameBuffer: any[]; /** Background watchers for a late swap verdict; see {@link Pipeline.changeComponent}. @internal */ _swapWatchTasks: Set>; private _inputStreamManagerCache; constructor(opts?: PipelineOptions); /** Derive the {@link PipelineConfig} (mode + active components) from the configured providers. */ get config(): PipelineConfig; /** Bind the agent that runs on this pipeline. */ setAgent(agent: any): void; /** * Register a hook for `event`. Usable directly (`on(event, fn)`) or as a decorator * factory (`on(event)`). Delegates to {@link Pipeline.hooks}. */ on(event: string, callback?: PipelineHookFn): any; /** Snapshot of session metrics (empty in this SDK build). */ getSessionMetricsSnapshot(): Record; /** Infer the target pipeline mode for a live {@link Pipeline.changePipeline}. @internal */ private inferTargetMode; /** Encode the passed target pipeline as `[component, provider, params]` triples. @internal */ private buildReconfigureComponents; /** Assign the switched-to components onto the pipeline's real slots. @internal */ private commitSwitchLocal; /** Revert the whole pipeline shape on a rejected switch, unless it changed again since. @internal */ private settlePipelineSwitch; /** Require an active session to hot-swap against, or throw. @internal */ private requireSwapSession; /** Component kinds swappable in the current pipeline mode. @internal */ private swappableForMode; /** Validate/encode in-place component swaps for {@link Pipeline.changeComponent}. @internal */ private prepareComponentSwaps; /** * Subscribe to the session's `runtime_warning` stream for one swap's verdict. * Returns `[verdict, unsubscribe]`; `verdict` is `null` when the session has no * event stream to confirm against. * @internal */ private listenForSwapVerdict; /** Wait for a late verdict in the background and settle (revert on failure). @internal */ private spawnSwapWatcher; /** Settle immediately when the verdict already arrived, else watch in the background. @internal */ private settleSwap; /** Revert `kind`'s slot on a rejected verdict, unless a newer swap already replaced it. @internal */ private settleComponentSwap; /** `passContext: false`: clear history only once the runtime confirms the swap. @internal */ private clearContextAfterConfirm; /** * Send pre-validated swaps, commit optimistically, and reconcile against the * runtime's per-swap verdict (reverting the local slot on rejection). Returns * the verdict per component kind. @internal */ private applySwaps; /** * Hot-swap components that already exist in the pipeline, in place. Invalid * swaps warn and are skipped; `passContext: false` clears the LLM's history * (only after the runtime confirms the swap succeeded). */ changeComponent(opts?: ChangeComponentOptions): Promise; /** * Replace the whole pipeline mid-session (live mode switch): pass the complete * target pipeline; the mode is inferred from the `llm`/components you pass. */ changePipeline(opts?: ChangePipelineOptions): Promise; /** Speak `text` on the bound agent's session. */ sendMessage(text: string, extras?: Record): Promise; /** Generate a reply to `instructions` on the bound agent's session. */ replyWithContext(instructions: string, extras?: Record): Promise; /** Feed `text` into the bound agent's session as model input. */ processText(text: string): Promise; /** Interrupt the bound agent's current turn. */ interrupt(): void; /** * Return the most recent captured vision frames. * @param numFrames Number of frames to return (most recent). Defaults to `1`. */ getLatestFrames(numFrames?: number): any[]; /** Buffer a vision frame (capped at {@link VISION_FRAME_BUFFER_MAX}) and fire `vision_frame` hooks. */ pushVisionFrame(frame: any): void; /** Fire `audio_delta` hooks for an incoming audio frame. */ pushAudioFrame(frame: any): void; /** Lazily-created manager for audio/video input listeners; see {@link _InputStreamManager}. */ get inputStreamManager(): _InputStreamManager; private _fireHook; } /** * A voice processing pipeline: the STT/LLM/TTS (and optional VAD, turn-detection, * avatar, denoise, realtime) components plus hooks that an {@link Agent} runs on. Its * shape is sent to the Zero Runtime to drive the call. */ export type Pipeline = PipelineImpl; /** Create a {@link Pipeline} from the given component {@link PipelineOptions}. */ export declare const Pipeline: (opts?: PipelineOptions) => Pipeline; export {};