UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

74 lines (73 loc) • 2.98 kB
/** * OpenAI Text-to-Speech Handler * * Implementation of TTS using OpenAI's TTS API. * * @module voice/providers/OpenAITTS */ import type { TTSChunk, TTSHandler, TTSOptions, TTSResult, TTSVoice } from "../../types/index.js"; export declare class OpenAITTS implements TTSHandler { private readonly apiKey; private readonly baseUrl; /** * Maximum text length (4096 characters) */ readonly maxTextLength = 4096; /** * Available voices */ private static readonly VOICES; constructor(apiKey?: string); isConfigured(): boolean; getVoices(languageCode?: string): Promise<TTSVoice[]>; private requireApiKey; private prepareRequest; /** * Issue the speech request and reject non-2xx responses. * * `onHeaders` runs as soon as the request settles, before the response body * is touched at all. The buffered path clears its request timeout there, * which is where it has always been cleared: the 30-second bound covers * getting a response, not downloading one. The native path passes no * callback, keeping its own timeout armed across the body reads it owns. */ private createSpeechResponse; private synthesisError; synthesize(text: string, options?: TTSOptions): Promise<TTSResult>; /** * Stream one segment's audio as the response body arrives. * * Returns `undefined` for any format without direct wire proof of * incremental delivery, which selects the buffered `synthesize()` path. * * Every non-empty body read is yielded as soon as it is available and * carries `isFinal: false`: assigning finality here would require a * one-read lookahead, delaying every fragment by a full body read, and * `TTSProcessor` recomputes finality globally anyway. */ synthesizeStream(text: string, options?: TTSOptions): AsyncIterable<TTSChunk> | undefined; /** * Map TTSAudioFormat to OpenAI response_format. * * OpenAI's /audio/speech accepts mp3, opus, aac, flac, wav and pcm. This map * previously stopped at mp3/wav/ogg/opus/pcm16, so `flac` — a valid * TTSAudioFormat *and* a real OpenAI response_format — was treated as * unsupported and silently downgraded to mp3 (#479). A caller who asked for * lossless got lossy, and the only signal was a warn-level log. * * Formats OpenAI genuinely cannot produce still coerce to mp3 with a warning. */ private mapFormat; /** * Get sample rate for format */ private getSampleRate; /** * Map the OpenAI `response_format` string back to the canonical * `TTSAudioFormat` so `TTSResult.format` reflects what the API actually * returned (mapFormat() coerces unsupported requests to "mp3"). Note: * OpenAI returns Ogg-Opus for both "ogg" and "opus" requests — both * surface as "opus" since the bytes are an .ogg/Opus container. */ private effectiveFormat; }