docs(lobe-chat): TTS works with zero client-side settings now
infra-ops aliased tts-1, tts-1-hd and gpt-4o-mini-tts onto ext-tts's upstream and extended the lobe-chat-esh key allow-list 20 -> 23 models, so the manual "set the TTS model to ext-tts, per browser" step this file described a few hours ago is obsolete. Lobe's stock three-field payload now returns 200 audio/mpeg — verified from the host with this stack's own .env. Adds the coupling that the fix introduces: the three new names are independent LiteLLM DB rows carrying their own copy of the upstream URL, so a future repoint of ext-tts must move all four or stock clients land on a dead engine without any error on the gateway side. Comment/doc only — no functional change, no redeploy.
This commit is contained in:
+18
-10
@@ -50,12 +50,16 @@ model are a **one-time UI setup per browser**, not a maintenance surface. That i
|
||||
> 1. **"An unknown `model` routes to the gateway default" — false on this path.**
|
||||
> True direct-to-`:8198`, which accepts-and-ignores `model`. But requests go
|
||||
> through **LiteLLM**, which resolves the model name *first*. Lobe's default is
|
||||
> `tts-1`, and `POST $OPENAI_PROXY_URL/audio/speech {"model":"tts-1",...}` returns
|
||||
> **403 `key not allowed to access model`** (the scoped key's allow-list holds
|
||||
> `ext-tts` alone; on an unscoped key it is a 400 `Invalid model name`). The same
|
||||
> call with `"model":"ext-tts"` returns 200 + audio. **So TTS was dead on arrival
|
||||
> from deploy until the model field was set** — the endpoint being wired is
|
||||
> necessary, not sufficient.
|
||||
> `tts-1`, and `POST $OPENAI_PROXY_URL/audio/speech {"model":"tts-1",...}` returned
|
||||
> **403 `key not allowed to access model`** (the scoped key's allow-list held
|
||||
> `ext-tts` alone; on an unscoped key it is a 400 `Invalid model name`). **So TTS
|
||||
> was dead on arrival from deploy until 2026-08-17** — the endpoint being wired is
|
||||
> necessary, not sufficient. **Fixed the same day**: infra-ops aliased `tts-1`,
|
||||
> `tts-1-hd` and `gpt-4o-mini-tts` to ext-tts's upstream and extended the
|
||||
> `lobe-chat-esh` key allow-list 20 → 23 models, so the stock payload now works
|
||||
> with **zero client-side settings** (verified from this host with this `.env`:
|
||||
> 200, `audio/mpeg`, real MP3). Setting the UI model field to `ext-tts` remains
|
||||
> valid and harmless.
|
||||
> 2. **"`response_format: mp3` … set it in the UI" — not possible.** Lobe's OpenAI
|
||||
> TTS client sends exactly three fields (server bundle `chunks/29685.js`):
|
||||
> `{ input, model: options?.model || 'tts-1', voice }`. `response_format` is never
|
||||
@@ -65,10 +69,14 @@ model are a **one-time UI setup per browser**, not a maintenance surface. That i
|
||||
> regardless of the bytes. Chrome sniffs and plays it. Fixing the size is
|
||||
> tts-dev's side of the fence, not a setting here.
|
||||
>
|
||||
> **To make TTS work in a browser today:** Settings → TTS → *OpenAI TTS model* →
|
||||
> `ext-tts`. Per browser, because the settings store is client-side. Removing that
|
||||
> manual step means aliasing `tts-1` → `ext-tts` in LiteLLM **and** adding it to the
|
||||
> `lobe-chat-esh` key's allow-list — both master-key operations (infra-ops).
|
||||
> **Nothing to do in the browser any more.** The alias + allow-list pair above
|
||||
> removed the manual step entirely; a fresh browser, a phone, or any stock OpenAI
|
||||
> client works out of the box.
|
||||
>
|
||||
> ⚠️ **Coupling worth knowing:** `tts-1`, `tts-1-hd` and `gpt-4o-mini-tts` are
|
||||
> independent LiteLLM DB rows pointing at ext-tts's upstream, not references to
|
||||
> `ext-tts`. If that upstream ever repoints, all four move together or stock
|
||||
> clients quietly land on a dead engine.
|
||||
|
||||
Trade recorded for the record: Open WebUI has dedicated `AUDIO_TTS_*` env vars (fully
|
||||
scriptable) at 1,825 MB; Lobe is endpoint-env + UI-cosmetic at 143 MB. Operator chose
|
||||
|
||||
@@ -35,12 +35,15 @@
|
||||
# ALIASED, not rejected (echo/alloy/onyx/ash->donut, nova->miranda,
|
||||
# shimmer/coral->emmie, fable/sage->glados), so a UI mis-click is NOT the
|
||||
# hazard I first recorded. Only `ballad` and `verse` 404 -- both aliased since.
|
||||
# ⚠️ REQUIRED UI STEP (tts-dev 2026-08-17): Settings -> TTS -> OpenAI TTS model
|
||||
# -> `ext-tts`. There is no env var for it. Lobe's default is `tts-1`, and while
|
||||
# :8198 ignores `model`, LITELLM IN FRONT OF IT DOES NOT -- it resolves the name
|
||||
# first, so `tts-1` returns 403 (`key not allowed to access model`; 400 on an
|
||||
# unscoped key) and TTS does nothing. Verified from this host with this .env.
|
||||
# Per browser -- the TTS settings store is client-side.
|
||||
# MODEL NAME -- no longer a manual step (2026-08-17). Lobe defaults to `tts-1`,
|
||||
# and while :8198 ignores `model`, LITELLM IN FRONT OF IT DOES NOT -- it resolves
|
||||
# the name first, so `tts-1` used to 403 (`key not allowed to access model`) and
|
||||
# TTS did nothing from deploy until it was found. infra-ops then aliased `tts-1`,
|
||||
# `tts-1-hd` and `gpt-4o-mini-tts` to ext-tts's upstream AND added them to the
|
||||
# `lobe-chat-esh` key allow-list, so the stock payload works with ZERO settings.
|
||||
# Verified from this host with this .env: {"input":...,"model":"tts-1",
|
||||
# "voice":"alloy"} -> 200 audio/mpeg. Setting the UI field to `ext-tts` also
|
||||
# works and does no harm.
|
||||
# SIZE: Lobe sends only {input, model, voice} -- no `response_format`, no
|
||||
# `speed`, and no UI field for either -- so you get the gateway's default (WAV,
|
||||
# ~23.5 MB for a 245 s turn), relabelled `audio/mpeg` by LiteLLM. Not fixable
|
||||
|
||||
Reference in New Issue
Block a user