nika:tts_generate is the image pipeline’s sibling for audio: one file
lands under a permit-gated output_dir:, sha256-named, manifest beside it,
and audio bytes never ride workflow outputs — tasks pass a path and a
hash, not megabytes of base64.
The four providers
Keys and the local URL are engine config, never workflow args:
OPENAI_API_KEY / ELEVENLABS_API_KEY (or NIKA_-prefixed),
NIKA_TTS_LOCAL_URL (+ optional NIKA_TTS_LOCAL_API_KEY). nika doctor
prints a tts line naming what’s wired.
Quickstart
Honesty rules
- The extension follows the bytes. WAV
RIFF…WAVEand MP3 headers are sniffed; a mislabel is aformat_mismatch:warning, a non-audio payload is a hard error — never a corrupt file on disk. - Duration is exact or absent. WAV
duration_msis pure header math; MP3 duration is honestlynullrather than a frame-walking guess. text:caps at 4096 chars (the strictest wire’s limit, held portably) — fan longer scripts out withfor_eachover paragraphs.- Content credentials are detected, not verified: audio C2PA carriage
(RIFF
C2PA· MP3 GEOB) is surfaced ascontent_credentialsin output and manifest, the same contract as images. - Watermarking is declared, never byte-verified. The manifest’s
watermark_declaredis a catalog fact:elevenlabs→"synthid (provider-declared · not byte-verified)", every other provider →null— no such declaration, honestly absent.
Cookbook (proven against live APIs)
An LLM writes the script, another model speaks it — one run:Local CPU synthesis gets a 300s default timeout (
timeout_ms: up to
600000); clouds default to 120s. Sub-second values are refused — under 1s
is a typo’d unit.