diff --git a/docs/contracts/donut_voiced_interview.contract.md b/docs/contracts/donut_voiced_interview.contract.md index 00220b0..24030cc 100644 --- a/docs/contracts/donut_voiced_interview.contract.md +++ b/docs/contracts/donut_voiced_interview.contract.md @@ -62,12 +62,18 @@ each independently shippable. Slice order is chosen for fastest visible result. swappable `ext-tts` LiteLLM alias. Rationale: the emotion dials (the whole point — affect-driven voice) don't pass through `ext-tts`. Accept the Zonos coupling; the `tts.py` client is the single swap seam if we ever move. -- **DEC-2 — full-synth latency accepted (no true streaming).** The gateway - buffers to a complete clip (~1.8s/sentence, scales). "Speak on done" gives the - whole clip after a short delay. True first-audio-early is a future gateway - enhancement (infra-ops to expose the native PCM stream); not in v1. -- **DEC-3 — wav only.** `response_format:"wav"` (16-bit RIFF). `mp3`/`opus` are - accepted but silently return mislabeled PCM — never request them. +- **DEC-2 — STREAMING, play-as-it-arrives (amended 2026-08-02, operator-directed).** + The gateway ALREADY streams: `POST /v1/audio/speech` relays a chunked int16 WAV + (transfer-encoding: chunked, placeholder 0xFFFFFFFF RIFF/data sizes) as it synthesizes + — TTFB ~0.44s vs ~7s total (infra-ops verified). So ratatoskr PROXIES THE CHUNKS + STRAIGHT THROUGH (`tts_stream`, `GET /api/tts`) and the browser plays a progressive + `