From 18832146632be26538e768106ca389008a5205e2 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Sat, 1 Aug 2026 18:38:14 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20Donut=20voiced-interview=20slice-2=20?= =?UTF-8?q?=E2=80=94=20auto-TTS=20via=20the=20Zonos=20gateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds affect-modulated voice to the web console: the completed assistant response is spoken on SSE `done`, emotion-modulated by the live PAD the persona pane already shows (DEC-7 — voice as affect OBSERVABILITY, not chat-app TTS). - src/ratatoskr/tts.py (new): Zonos-gateway client + PAD→emotion-dial mapping. tts_synthesize POSTs {input, voice, response_format:"wav", **dials}; wav-only (DEC-3 — mp3/opus silently return mislabeled PCM). pad_to_dials is total (None/NaN/out-of-range → valid dials, never raises). TtsUnavailable on any gateway failure; the single swap seam if we ever move off Zonos. - web/server.py: POST /api/tts proxy (DEC-4/INV-TTS-1 — the gateway host never reaches the browser). Per-character voice map (DEC-8: ratatoskr:donut→donut), serialize lock (DEC-5 — shared 3090), 503 degrade (INV-TTS-4). - web/static/index.html: 🔊 toggle (opt-in, localStorage, default off, INV-TTS-2), speak-on-done, AbortController cancel-on-new-turn (INV-TTS-3), hidden