the standard library
nika:tts_generate
Synthesize speech audio (local compat servers · openai gpt-4o-mini-tts · elevenlabs · mock for offline runs) — saves ONE audio file under output_dir and returns path + format + sha256 + duration (+ a provenance manifest); audio bytes never ride outputs. One of 28 builtins in the closed nika: namespace.
the media familyimages, audio, charts: assets, not blobs
- mediafamily4 tools
- 11argsdeclared contract
- 2requiredcheck teaches a miss
- craftedusage filecheck-green below
the contract
11 args · 2 requiredA missing required arg is a nika check finding before anything runs; the vocabulary below comes from the binary itself (nika catalog --tools --json), not from prose.
- provider
stringlocal | openai | elevenlabs | mock (inferred from model: when omitted · local is never inferred)- model
stringprovider model id · defaults: tts-1 (local · LocalAI convention) · gpt-4o-mini-tts · eleven_multilingual_v2 · mock-tts-1- text*
stringthe text to speak · ≤4096 chars (fan long scripts out with for_each)- voice
stringprovider voice · defaults: alloy (openai/local) · Rachel's id (elevenlabs) · sine (mock)- format
stringmp3 | wav | auto (default · provider-native · the saved extension follows the bytes)- speed
number0.25..=4.0 (openai/local · warned-dropped elsewhere)- output_dir*
stringdirectory the audio lands in (created if missing · fs-permit gated)- filename_prefix
stringfilename stem (default: metadata.page_slug, else `speech`)- manifest
booleanwrite the sidecar provenance manifest (default true)- metadata
objectfree-form provenance echoed into output + manifest- timeout_ms
integerper-request cap · default 120000 (local 300000) · max 600000
in a real file
a complete workflownika: v1workflow: id: say-the-verdict description: "one audio file under output_dir — mock provider runs offline"permits: fs: write: ["./audio/**"] exec: false tools: ["nika:log", "nika:tts_generate"]tasks: line: infer: model: ollama/qwen3.5:4b prompt: "One warm sentence announcing a green run. Nothing else." temperature: 0.9 retry: max_attempts: 3 backoff_ms: 500 backoff_max_ms: 4000 speak: with: line: ${{ tasks.line.output }} invoke: tool: "nika:tts_generate" args: provider: mock text: "${{ with.line }}" output_dir: "./audio" on_finally: - invoke: tool: "nika:log" args: { message: "audio pass done — anything staged is under ./audio" }outputs: audio: ${{ tasks.speak.output }}a complete file, nika check green; the drift gate re-validates this copy against the schema on every test run. open it in the playground →
cross-references
ships in skeletons
no skeleton ships it; the crafted file above is the reference.
the check gates
from the blog
the media family
4 toolsimages, audio, charts: assets, not blobs.
- nika:chart
- nika:image_fx
- nika:image_generate
- nika:tts_generate
Machines read the same vocabulary at /tools/catalog.json; the contract lives in spec 06 · stdlib. Install and ask the binary itself: nika catalog --tools. Read the spec →