From 30e3d36b1ecbe961d30cc5750d1837ad2b0b1f40 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 18 Oct 2026 20:15:28 -0700 Subject: [PATCH 1/2] docs(openwebui): the TTS voice rejector is in-browser Kokoro, not frank-tts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `Voice "narrator1" not found. Should be one of: af_heart, …, bm_fable` toast is OpenWebUI 0.11.4's bundled Kokoro.js validator: the enum is Kokoro's fixed 29-voice pack, not frank-tts's registry. Frank-tts answers 200 audio/mpeg for the exact OpenWebUI body from inside the container, and the failing click leaves no `audio/speech` line in the container log — that contrast is the instrument. Admin config DB is correct (engine=openai, base URL :7772/v1, model frank-tts, voice narrator1); no container env and no user row carries an audio override, so the `browser-kokoro` choice is per-browser storage. Fix: Settings → Audio → TTS Engine → Default. --- serverAppConfigs-docs/Dankclaw/OpenWebUI.md | 36 +++++++++++++++++++++ serverAppConfigs-docs/log.md | 33 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md index 521e44d..3d14340 100644 --- a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md +++ b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md @@ -292,6 +292,42 @@ carries base64 image data or a URL. Failure modes: connection refused ⇒ OpenWebUI or ComfyUI is down; timeouts on large sizes ⇒ check ComfyUI resources; 401 ⇒ the token is bad. +## Text-to-speech (frank-tts) + +TTS is the fleet's one OpenAI-compatible speech endpoint — +`http://host.containers.internal:7772/v1` (`audio.tts.openai.api_base_url` +in the config DB, 2026-10-18), model `frank-tts`, voice `narrator1`. That +port is the rootless quadlet `frank-tts` (this repo: +`dankclaw/voiceservice/quadlet/frank-tts.container`, +`scripts/frank-tts.env`), and its shim resolves `voice=` against +`/home/dank/voices//reference.wav` — a name without a reference is a +400 listing the voices that exist, never a silent fallback. + +**The 29-voice `af_* … bm_fable` list is NOT frank-tts.** That enum belongs +to **Kokoro.js running in the browser**: the deployed front end (0.11.4) +ships an in-page Kokoro implementation (chunk carrying a frozen voice table +`{af_heart:{name:"Heart",…}}` and `_validate_voice`, model +`onnx-community/Kokoro-82M-v1.0-ONNX`, plus a personal *Kokoro.js dtype* +setting). Its engine select takes `""` (Default) or `browser-kokoro`; when +`browser-kokoro` is chosen the page synthesizes locally and rejects any +voice outside its fixed pack — so `narrator1` fails with +`Voice: "narrator1" not found. Should be one of: af_heart, …` **without a +single request reaching the server**. Personal audio settings are per +browser: no `user.settings` row and no container env carries an audio +override, yet the toast still appears ⇒ the choice lives in that browser's +own storage. Fix in the UI: Settings → Audio → TTS Engine → **Default**, +which hands synthesis to the admin config (frank-tts); picking `af_heart` +instead keeps Kokoro, and Kokoro cannot clone — fixed pack only. + +Verified 2026-10-18 from inside the container with the exact OpenWebUI body +(`{"model":"frank-tts","input":…,"voice":"narrator1", +"response_format":"mp3","speed":1.0}`) → **200, `audio/mpeg`, 7,629 B**, +while `podman logs open-webui` recorded **zero** `audio/speech` requests for +the failing click — that contrast is the instrument: a server-path failure +leaves a log line and a frank-tts error, a `browser-kokoro` failure leaves +neither. + + ## Retired instances - The compose `open-webui` service (port 3000) was never run: 3000 is Gitea's HTTP port, so it could not bind. diff --git a/serverAppConfigs-docs/log.md b/serverAppConfigs-docs/log.md index b397e67..2366a5d 100644 --- a/serverAppConfigs-docs/log.md +++ b/serverAppConfigs-docs/log.md @@ -2311,3 +2311,36 @@ every restart since the cutover. Kokoro-enum-only — so "the agent talks in my voice" needs that provider row or a `pi.registerProvider` extension, decided in phase 2. + +## 2026-10-18 — OpenWebUI "voice narrator1 not found": the rejector is in the browser + +- Frank's toast — `Error: Voice "narrator1" not found. Should be one of: + af_heart, …, bm_fable` — looked like frank-tts refusing the name. It is + not: that 29-name enum is the voice pack of **Kokoro.js running in the + page**, and OpenWebUI 0.11.4 ships that implementation in its own front + end (frozen table `{af_heart:{name:"Heart",…}}`, `_validate_voice`, model + `onnx-community/Kokoro-82M-v1.0-ONNX`, a personal *Kokoro.js dtype* + setting, engine values `""`/`browser-kokoro`). +- Instruments that separated the two paths, in order: the admin config DB is + correct (`audio.tts.engine=openai`, + `audio.tts.openai.api_base_url=http://host.containers.internal:7772/v1`, + `model=frank-tts`, `voice=narrator1`, `split_on=punctuation`); from inside + the container the exact OpenWebUI body + (`{"model":"frank-tts","input":…,"voice":"narrator1","response_format":"mp3","speed":1.0}`) + returns **200 `audio/mpeg` 7,629 B**; and `podman logs open-webui` holds + **zero** `audio/speech` requests for the failing click. A server-path + failure leaves a log line and a frank-tts error — a `browser-kokoro` + failure leaves neither. No container env carries an `AUDIO_*`/`TTS` + variable and no `user.settings` row (all four users) carries an audio + override, so the engine choice is per-browser storage, not fleet state. +- Fix is a UI click, not a deploy: Settings → Audio → TTS Engine → + **Default** hands synthesis back to frank-tts and the cloned voices; + choosing `af_heart` keeps in-browser Kokoro, which cannot clone (fixed + pack). Recorded on [[OpenWebUI]] under *Text-to-speech (frank-tts)*; + suite green 384/384 (wall 65.9 s). +- Also in the window: **PR #22 merged** (`0c7fe8b`, `dank/command-center`) so + `agent/extensions/dankvoice.ts` landed on the auto-load path — proven in a + plain `omp` session with no flags: `/say merged build check` → 1.20 s WAV + to the player, temp dir cleaned; the audible pass through the default + `pw-play` detection confirmed by Frank. Sessions open before the merge need + a restart to pick the command up. From 9a17b93e8ab8e0568bde39f8acaa3ca8775d3048 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 18 Oct 2026 20:17:19 -0700 Subject: [PATCH 2/2] docs(frank-tts): crosslink the browser-Kokoro rejector both ways MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A consumer that lists the 29-name af_*/am_*/bf_*/bm_* pack and refuses narrator1 without a request reaching the façade is synthesizing in the browser. Frank TTS's troubleshooting table gains that symptom; OpenWebUI's See Also gains the service page. --- serverAppConfigs-docs/Dankclaw/Frank TTS.md | 1 + serverAppConfigs-docs/Dankclaw/OpenWebUI.md | 1 + 2 files changed, 2 insertions(+) diff --git a/serverAppConfigs-docs/Dankclaw/Frank TTS.md b/serverAppConfigs-docs/Dankclaw/Frank TTS.md index 83416e8..aa65bb6 100644 --- a/serverAppConfigs-docs/Dankclaw/Frank TTS.md +++ b/serverAppConfigs-docs/Dankclaw/Frank TTS.md @@ -201,3 +201,4 @@ harness bundle and measured the day of the flip: | Endpoint answers, synthesis fails | the engine: `podman healthcheck run frank-tts-engine`, then `systemctl --user status frank-tts-engine.service` | | First request of the day is ~0.6 s slower than the rest — or every name returns 400 | the warm pass did not run; it carries `-`, so it cannot fail the unit. `journalctl --user -u frank-tts-engine` for the warmer's lines, then `podman exec frank-tts-engine /app/warm-voices.sh` — the registry is memory-only (law 1 of [[Frank TTS Engine]]) | | The unit never appears after a deploy | the generator dropped it: `frank-tts-engine.network` is missing from `~/.config/containers/systemd/` | +| A consumer rejects `narrator1` by listing 29 names (`af_heart … bm_fable`) and no request ever reaches this endpoint | that consumer is synthesizing **in the browser** with Kokoro.js, whose voice pack is fixed — OpenWebUI 0.11.4 ships it as the `browser-kokoro` TTS engine; see [[OpenWebUI]] | diff --git a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md index 3d14340..386e4f5 100644 --- a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md +++ b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md @@ -385,6 +385,7 @@ neither. ## See Also - [[Dankclaw Stack]] +- [[Frank TTS]] — the speech endpoint behind *Text-to-speech (frank-tts)* - [[Hermes]] — the agent OpenWebUI can talk to - [[SearXNG]] — the search engine on this host - [LLM knowledge base](../LLM/index.md) — the vLLM and llama.cpp endpoints