/** * Server-side TTS synthesis for chat read-aloud (POST/GET /api/tts). * * Validates and bounds request text, synthesizes it either whole or * sentence-by-sentence for fast time-to-first-audio, and reports engine * readiness. The Kokoro engine is a process-wide singleton so there is * exactly one sidecar. */ import { createKokoroTts } from "./kokoro.js"; import type { Tts } from "./protocol.js"; type KokoroOpts = Parameters[0]; /** The shared Kokoro engine (lazily constructed with the live config). */ export declare function getTalkTts(opts?: KokoroOpts): Tts; /** Test seam: swap the singleton for a mock. */ export declare function __setTalkTtsForTest(tts: Tts | null): void; /** * Max characters accepted by POST /api/tts in a single read-aloud call. Bounds * the sidecar's synth time and the WAV response size (≈ a few minutes of audio). */ export declare const TTS_MAX_CHARS = 8000; /** * Validate + bound the `text` field of a POST /api/tts request. Trims, rejects * non-strings and empties, and caps over-long input at the last sentence/space * boundary before the limit so a word is never cut mid-token. Pure — unit-tested. */ export declare function validateTtsText(raw: unknown, maxChars?: number): { ok: true; text: string; } | { ok: false; error: string; }; /** * Standalone one-shot synthesis for POST /api/tts: returns a single WAV buffer * for the whole text. Reuses the shared Kokoro engine; rejects when unavailable. */ export declare function synthesizeText(text: string, opts?: KokoroOpts): Promise; /** TTS engine readiness for GET /api/tts — no synth, no sidecar spawn. */ export declare function ttsStatus(opts?: KokoroOpts): { available: boolean; voice: string; }; /** * Split already-markdown-stripped prose into sentence-sized chunks for streamed * read-aloud. Splits on sentence terminators (followed by whitespace) AND on * newlines (list items / paragraphs), collapsing inner whitespace and dropping * empties. Pure — unit-tested. Text with no terminator stays one chunk. */ export declare function splitTtsSentences(text: string): string[]; /** * Synthesize `text` sentence-by-sentence, invoking `onFrame` with each sentence's * WAV as soon as it's ready — so the client can PLAY sentence 1 while 2..N are * still synthesizing (time-to-first-audio ≈ one sentence, not the whole message). * * Kokoro is one-request-at-a-time, so synthesis is naturally sequential; that's * fine since playback is sequential too. `isCancelled` is checked before and * after each synth so a paused/aborted client stops further synthesis promptly * (we don't keep synthesizing a message nobody is listening to). Resolves with * the number of frames emitted. */ export declare function streamTtsSentences(text: string, opts: KokoroOpts | undefined, onFrame: (wav: Buffer) => void, isCancelled: () => boolean): Promise; export {}; //# sourceMappingURL=tts-stream.d.ts.map