import { a as TranscriberSessionOptions, c as VoiceAudioFormat, d as VoicePipelineMetrics, f as VoiceRole, h as VoiceTransport, i as TranscriberSession, l as VoiceAudioInput, m as VoiceStatus, n as TTSProvider, o as TranscriptMessage, p as VoiceServerMessage, r as Transcriber, s as VOICE_PROTOCOL_VERSION, t as StreamingTTSProvider, u as VoiceClientMessage } from "./types-BT8XX-6F.js"; import { Agent, Connection } from "agents"; //#region src/text-stream.d.ts /** * Utilities for normalising various text-producing sources into a uniform * `AsyncGenerator`. This lets `onTurn()` return any of: * * - A plain `string` * - An `AsyncIterable` (deprecated for AI SDK `textStream`) * - An `AsyncIterable` of AI SDK `fullStream` parts * - A `ReadableStream` (e.g. a raw `fetch` response body * containing newline-delimited JSON / SSE) * - A `ReadableStream` * * The generator yields individual text chunks as they become available. */ /** Union of every source type that {@link iterateText} accepts. */ type TextSource = string | TextReadableStream | AsyncIterable; type TextReadableStreamReader = { read(): Promise>; }; interface TextReadableStream { getReader(): TextReadableStreamReader; } /** * Turn any {@link TextSource} into a lazy async generator of string chunks. * * - `string` → yields the string once (if non-empty). * - `ReadableStream` → yields each chunk directly. * - `ReadableStream` → decodes and parses as newline-delimited * JSON (NDJSON) / SSE (`data: …` lines), extracting text from common AI * response formats. * - `AsyncIterable` → re-yields each chunk. */ declare function iterateText(source: TextSource): AsyncGenerator; //#endregion //#region src/sentence-chunker.d.ts /** * Sentence chunker — accumulates streaming text and yields complete sentences. * * Isolated and testable: no dependencies on the voice pipeline, Agent, or AI APIs. * Feed it tokens via `add()`, get back sentences via the return value. * Call `flush()` at end-of-stream to get any remaining text. * * Current implementation: splits on sentence-ending punctuation (. ! ?) followed * by a space or end-of-input. This is intentionally simple — optimize later with * better heuristics (abbreviations, decimal numbers, quoted speech, etc.). */ declare class SentenceChunker { #private; /** * Add a chunk of text (e.g. a streamed LLM token). * Returns an array of complete sentences extracted from the buffer. * May return 0, 1, or multiple sentences depending on the input. */ add(text: string): string[]; /** * Flush any remaining text in the buffer as a final sentence. * Call this when the LLM stream ends. * Returns the remaining text (trimmed), or an empty array if nothing is left. */ flush(): string[]; /** * Reset the chunker, discarding any buffered text. */ reset(): void; } //#endregion //#region src/voice-input.d.ts type Constructor$1 = new (...args: any[]) => T; type AgentLike$1 = Constructor$1, "keepAlive">>; /** Public surface of the voice input mixin, used as an explicit return type to satisfy TS6 declaration emit. */ interface VoiceInputMixinMembers { transcriber?: Transcriber; onTranscript(text: string, connection: Connection): void | Promise; createTranscriber(connection: Connection): Transcriber | null; beforeCallStart(connection: Connection): boolean | Promise; onCallStart(connection: Connection): void | Promise; onCallEnd(connection: Connection): void | Promise; onInterrupt(connection: Connection): void | Promise; afterTranscribe( transcript: string, connection: Connection ): string | null | Promise; } type VoiceInputMixinReturn = TBase & (new (...args: any[]) => VoiceInputMixinMembers); /** * Voice-to-text input mixin. Adds STT-only voice input to an Agent class. * * Subclasses must set a `transcriber` property (or override `createTranscriber`). * No TTS provider is needed. Override `onTranscript` to handle each * transcribed utterance. * * @param Base - The Agent class to extend (e.g. `Agent`). * @param voiceInputOptions - Optional pipeline configuration. * * @example * ```typescript * import { Agent } from "agents"; * import { withVoiceInput, WorkersAINova3STT } from "@cloudflare/voice"; * * const InputAgent = withVoiceInput(Agent); * * class MyAgent extends InputAgent { * transcriber = new WorkersAINova3STT(this.env.AI); * * onTranscript(text, connection) { * console.log("User said:", text); * } * } * ``` */ declare function withVoiceInput( Base: TBase ): VoiceInputMixinReturn; //#endregion //#region src/sfu-utils.d.ts /** * Pure utility functions for the Cloudflare Realtime SFU integration. * * Extracted from sfu.ts for testability. These handle: * - Protobuf varint encoding/decoding * - SFU WebSocket adapter protobuf packet encoding/decoding * - Audio format conversion (48kHz stereo ↔ 16kHz mono) */ declare function decodeVarint( buf: Uint8Array, offset: number ): { value: number; bytesRead: number; }; declare function encodeVarint(value: number): Uint8Array; /** Extract the PCM payload from a protobuf Packet message. */ declare function extractPayloadFromProtobuf( data: ArrayBuffer ): Uint8Array | null; /** Encode PCM payload into a protobuf Packet message (for ingest/buffer mode — just payload). */ declare function encodePayloadToProtobuf(payload: Uint8Array): ArrayBuffer; /** Downsample 48kHz stereo interleaved PCM to 16kHz mono PCM (both 16-bit LE). */ declare function downsample48kStereoTo16kMono( stereo48k: Uint8Array ): ArrayBuffer; /** Upsample 16kHz mono PCM to 48kHz stereo interleaved PCM (both 16-bit LE). */ declare function upsample16kMonoTo48kStereo(mono16k: ArrayBuffer): Uint8Array; interface SFUConfig { appId: string; apiToken: string; } declare function sfuFetch( config: SFUConfig, path: string, body: unknown ): Promise; declare function createSFUSession(config: SFUConfig): Promise<{ sessionId: string; }>; declare function addSFUTracks( config: SFUConfig, sessionId: string, body: unknown ): Promise; declare function renegotiateSFUSession( config: SFUConfig, sessionId: string, sdp: string ): Promise; declare function createSFUWebSocketAdapter( config: SFUConfig, tracks: unknown[] ): Promise; //#endregion //#region src/workers-ai-providers.d.ts /** Loose type for the Workers AI binding — avoids hard dependency on @cloudflare/workers-types. */ interface AiLike { run( model: string, input: Record, options?: Record ): Promise; } interface WorkersAITTSOptions { /** TTS model name. @default "@cf/deepgram/aura-1" */ model?: string; /** TTS speaker voice. @default "asteria" */ speaker?: string; } /** * Workers AI text-to-speech provider. * * @example * ```ts * class MyAgent extends VoiceAgent { * tts = new WorkersAITTS(this.env.AI); * } * ``` */ declare class WorkersAITTS implements TTSProvider { #private; constructor(ai: AiLike, options?: WorkersAITTSOptions); synthesize(text: string, signal?: AbortSignal): Promise; } interface WorkersAIFluxSTTOptions { /** End-of-turn confidence threshold (0.5-0.9). @default 0.7 */ eotThreshold?: number; /** * Eager end-of-turn threshold (0.3-0.9). When set, enables * EagerEndOfTurn and TurnResumed events for speculative processing. */ eagerEotThreshold?: number; /** EOT timeout in milliseconds. @default 5000 */ eotTimeoutMs?: number; /** Keyterms to boost recognition of specialized terminology. */ keyterms?: string[]; /** Sample rate in Hz. @default 16000 */ sampleRate?: number; } /** * Workers AI continuous speech-to-text provider using the Flux model. * * Flux is a conversational STT model with built-in end-of-turn detection. * A single session is created per call and receives all audio continuously. * The model detects speech boundaries and fires `onUtterance` when a * turn is complete — no client-side silence detection needed for STT. * * Recommended for `withVoice` (conversational voice agents). * * @example * ```ts * import { Agent } from "agents"; * import { withVoice, WorkersAIFluxSTT, WorkersAITTS } from "@cloudflare/voice"; * * const VoiceAgent = withVoice(Agent); * * class MyAgent extends VoiceAgent { * transcriber = new WorkersAIFluxSTT(this.env.AI); * tts = new WorkersAITTS(this.env.AI); * * async onTurn(transcript, context) { ... } * } * ``` */ declare class WorkersAIFluxSTT implements Transcriber { #private; constructor(ai: AiLike, options?: WorkersAIFluxSTTOptions); createSession(options?: TranscriberSessionOptions): TranscriberSession; } interface WorkersAINova3STTOptions { /** Language code. @default "en" */ language?: string; /** Endpointing silence duration in ms. @default 300 */ endpointingMs?: number; /** Utterance end detection timeout in ms. @default 1000 */ utteranceEndMs?: number; /** Enable smart formatting (numbers, dates, etc.). @default true */ smartFormat?: boolean; /** Enable punctuation. @default true */ punctuate?: boolean; /** Keyterms to boost recognition of specialized terminology. */ keyterms?: string[]; /** Sample rate in Hz. @default 16000 */ sampleRate?: number; } /** * Workers AI continuous speech-to-text provider using Nova 3. * * Nova 3 is a high-accuracy STT model with streaming WebSocket support. * A single session is created per call and receives all audio continuously. * Server-side VAD events and endpointing handle speech boundary detection. * * Recommended for `withVoiceInput` (dictation / voice input UIs). * * @example * ```ts * import { Agent } from "agents"; * import { withVoiceInput, WorkersAINova3STT } from "@cloudflare/voice"; * * const InputAgent = withVoiceInput(Agent); * * class MyAgent extends InputAgent { * transcriber = new WorkersAINova3STT(this.env.AI); * * onTranscript(text, connection) { ... } * } * ``` */ declare class WorkersAINova3STT implements Transcriber { #private; constructor(ai: AiLike, options?: WorkersAINova3STTOptions); createSession(options?: TranscriberSessionOptions): TranscriberSession; } //#endregion //#region src/voice.d.ts /** Context passed to the `onTurn()` hook. */ interface VoiceTurnContext { connection: Connection; messages: Array<{ role: VoiceRole; content: string; }>; signal: AbortSignal; } /** Configuration options for the voice mixin. Passed to `withVoice()`. */ interface VoiceAgentOptions { /** Max conversation history messages loaded for context. @default 20 */ historyLimit?: number; /** Audio format used for binary audio payloads sent to the client. @default "mp3" */ audioFormat?: VoiceAudioFormat; /** * Sample rate (Hz) of raw PCM audio payloads sent to the client. * Declared in the `audio_config` message so the client can play `pcm16` * at the provider's native rate (e.g. 24000 for Gemini TTS). * Encoded formats (mp3/wav/opus) carry their own rate and ignore this. * @default 16000 */ sampleRate?: number; /** Max conversation messages to keep in SQLite. Oldest are pruned. @default 1000 */ maxMessageCount?: number; } type Constructor = new (...args: any[]) => T; type AgentLike = Constructor< Pick, "sql" | "getConnections" | "keepAlive"> >; /** Public surface of the voice mixin, used as an explicit return type to satisfy TS6 declaration emit. */ interface VoiceAgentMixinMembers { transcriber?: Transcriber; tts?: (TTSProvider & Partial) | undefined; onTurn(transcript: string, context: VoiceTurnContext): Promise; createTranscriber(connection: Connection): Transcriber | null; beforeCallStart(connection: Connection): boolean | Promise; onCallStart(connection: Connection): void | Promise; onCallEnd(connection: Connection): void | Promise; onInterrupt(connection: Connection): void | Promise; afterTranscribe( transcript: string, connection: Connection ): string | null | Promise; beforeSynthesize( text: string, connection: Connection ): string | null | Promise; afterSynthesize( audio: ArrayBuffer | null, text: string, connection: Connection ): ArrayBuffer | null | Promise; saveMessage(role: "user" | "assistant", text: string): void; getConversationHistory(limit?: number): Array<{ role: VoiceRole; content: string; }>; forceEndCall(connection: Connection): void; speak(connection: Connection, text: string): Promise; speakAll(text: string): Promise; } type VoiceAgentMixinReturn = TBase & (new (...args: any[]) => VoiceAgentMixinMembers); /** * Voice pipeline mixin. Adds the full voice pipeline to an Agent class. * * Subclasses must set a `transcriber` property (or override `createTranscriber`) * and a `tts` provider property. The transcriber session is per-call — created * at start_call and closed at end_call. The model handles turn detection. * * @param Base - The Agent class to extend (e.g. `Agent`). * @param voiceOptions - Optional pipeline configuration. * * @example * ```typescript * import { Agent } from "agents"; * import { withVoice, WorkersAIFluxSTT, WorkersAITTS } from "@cloudflare/voice"; * * const VoiceAgent = withVoice(Agent); * * class MyAgent extends VoiceAgent { * transcriber = new WorkersAIFluxSTT(this.env.AI); * tts = new WorkersAITTS(this.env.AI); * * async onTurn(transcript, context) { * return "Hello! I heard you say: " + transcript; * } * } * ``` */ declare function withVoice( Base: TBase, voiceOptions?: VoiceAgentOptions ): VoiceAgentMixinReturn; //#endregion export { type SFUConfig, SentenceChunker, type StreamingTTSProvider, type TTSProvider, type TextSource, type Transcriber, type TranscriberSession, type TranscriberSessionOptions, type TranscriptMessage, VOICE_PROTOCOL_VERSION, VoiceAgentMixinMembers, VoiceAgentOptions, type VoiceAudioFormat, type VoiceAudioInput, type VoiceClientMessage, type VoicePipelineMetrics, type VoiceRole, type VoiceServerMessage, type VoiceStatus, type VoiceTransport, VoiceTurnContext, WorkersAIFluxSTT, type WorkersAIFluxSTTOptions, WorkersAINova3STT, type WorkersAINova3STTOptions, WorkersAITTS, type WorkersAITTSOptions, addSFUTracks, createSFUSession, createSFUWebSocketAdapter, decodeVarint, downsample48kStereoTo16kMono, encodePayloadToProtobuf, encodeVarint, extractPayloadFromProtobuf, iterateText, renegotiateSFUSession, sfuFetch, upsample16kMonoTo48kStereo, withVoice, withVoiceInput }; //# sourceMappingURL=voice.d.ts.map