Falls back to global voice if unset: effectiveVoice = modelVoice ?? globalVoice
Dropdown shows "Use default voice" when unset
Voice options populated from admin TTS engine settings
2. Fix TTS Dropdown UX Bug
Fixes OpenAI TTS dropdowns that appeared empty due to datalist filtering behavior
Replaces input + datalist with proper select elements for OpenAI TTS engine
Improves accessibility with native select keyboard support
3. Add TTS Connection Test Feature
"Test Connection" button in admin settings validates configuration
Auto-populates dropdowns with actual server options via /v1/models and /v1/audio/voices
Smart URL normalization and clear error messages with Kokoro/OpenAI-specific guidance
Success: "Found X models and Y voices. Please select your preferences."
API Changes
Stores single tts_voice_id on ModelMeta (no DB migration required)
Falls back to existing global voice configuration
Technical Implementation
Added tts_voice_id: Optional[str] to ModelMeta with future-compatibility comment
Created TTSVoiceSelector.svelte component that adapts to admin TTS engine
Enhanced connection test with timeout handling and specific backend guidance
Unit test coverage for voice resolution fallback logic
Usage
Per-model voices: Edit model → TTS Configuration → Select voice → Save Connection test: Admin Settings → Audio → Enter API URL → Click "Test" → Select preferences
Scope
In scope: Model-level voice assignment, dropdown fixes, admin productivity
Out of scope: User-level overrides, nested TTS config, multi-backend routing
Checklist
I have performed a self-review of my code
I have commented my code, particularly in hard-to-understand areas
I have made corresponding changes to the documentation
My changes generate no new warnings
I have added tests that prove my fix is effective or that my feature works
New and existing unit tests pass locally with my changes
Any dependent changes have been merged and published in downstream modules
CLA Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/16708
**Author:** [@FSSCoding](https://github.com/FSSCoding)
**Created:** 8/18/2025
**Status:** ❌ Closed
**Base:** `main` ← **Head:** `feature/per-model-voice-assignment`
---
### 📝 Commits (2)
- [`9bfa3a4`](https://github.com/open-webui/open-webui/commit/9bfa3a466283420f26560792fb2058be16272bd1) Implement strategic improvements based on feedback
- [`97034bb`](https://github.com/open-webui/open-webui/commit/97034bbc6155a067d0f0b91f36d53b2969deb06b) fix: remove duplicate test_tts_voice_resolution function
### 📊 Changes
**6 files changed** (+328 additions, -21 deletions)
<details>
<summary>View changed files</summary>
📝 `backend/open_webui/models/models.py` (+7 -0)
📝 `backend/open_webui/test/apps/webui/routers/test_models.py` (+18 -0)
📝 `src/lib/components/admin/Settings/Audio.svelte` (+157 -16)
📝 `src/lib/components/chat/Messages/ResponseMessage.svelte` (+28 -5)
📝 `src/lib/components/workspace/Models/ModelEditor.svelte` (+20 -0)
➕ `src/lib/components/workspace/Models/TTSVoiceSelector.svelte` (+98 -0)
</details>
### 📄 Description
**Closes:** #3347, #3097, #8354
## Summary
Complete TTS workflow improvements addressing multiple user-reported issues: per-model voice assignment, dropdown UX bugs, and admin connection testing.
## Features Included
### 1. Per-Model TTS Voice Assignment
- Adds optional voice selector in model editor
- Falls back to global voice if unset: `effectiveVoice = modelVoice ?? globalVoice`
- Dropdown shows "Use default voice" when unset
- Voice options populated from admin TTS engine settings
### 2. Fix TTS Dropdown UX Bug
- Fixes OpenAI TTS dropdowns that appeared empty due to datalist filtering behavior
- Replaces `input` + `datalist` with proper `select` elements for OpenAI TTS engine
- Improves accessibility with native select keyboard support
### 3. Add TTS Connection Test Feature
- "Test Connection" button in admin settings validates configuration
- Auto-populates dropdowns with actual server options via `/v1/models` and `/v1/audio/voices`
- Smart URL normalization and clear error messages with Kokoro/OpenAI-specific guidance
- Success: "Found X models and Y voices. Please select your preferences."
## API Changes
- Stores single `tts_voice_id` on ModelMeta (no DB migration required)
- Falls back to existing global voice configuration
## Technical Implementation
- Added `tts_voice_id: Optional[str]` to ModelMeta with future-compatibility comment
- Created `TTSVoiceSelector.svelte` component that adapts to admin TTS engine
- Enhanced connection test with timeout handling and specific backend guidance
- Unit test coverage for voice resolution fallback logic
## Usage
**Per-model voices:** Edit model → TTS Configuration → Select voice → Save
**Connection test:** Admin Settings → Audio → Enter API URL → Click "Test" → Select preferences
## Scope
- **In scope:** Model-level voice assignment, dropdown fixes, admin productivity
- **Out of scope:** User-level overrides, nested TTS config, multi-backend routing
## Checklist
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream modules
## CLA Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/16708
Author: @FSSCoding
Created: 8/18/2025
Status: ❌ Closed
Base:
main← Head:feature/per-model-voice-assignment📝 Commits (2)
9bfa3a4Implement strategic improvements based on feedback97034bbfix: remove duplicate test_tts_voice_resolution function📊 Changes
6 files changed (+328 additions, -21 deletions)
View changed files
📝
backend/open_webui/models/models.py(+7 -0)📝
backend/open_webui/test/apps/webui/routers/test_models.py(+18 -0)📝
src/lib/components/admin/Settings/Audio.svelte(+157 -16)📝
src/lib/components/chat/Messages/ResponseMessage.svelte(+28 -5)📝
src/lib/components/workspace/Models/ModelEditor.svelte(+20 -0)➕
src/lib/components/workspace/Models/TTSVoiceSelector.svelte(+98 -0)📄 Description
Closes: #3347, #3097, #8354
Summary
Complete TTS workflow improvements addressing multiple user-reported issues: per-model voice assignment, dropdown UX bugs, and admin connection testing.
Features Included
1. Per-Model TTS Voice Assignment
effectiveVoice = modelVoice ?? globalVoice2. Fix TTS Dropdown UX Bug
input+datalistwith properselectelements for OpenAI TTS engine3. Add TTS Connection Test Feature
/v1/modelsand/v1/audio/voicesAPI Changes
tts_voice_idon ModelMeta (no DB migration required)Technical Implementation
tts_voice_id: Optional[str]to ModelMeta with future-compatibility commentTTSVoiceSelector.sveltecomponent that adapts to admin TTS engineUsage
Per-model voices: Edit model → TTS Configuration → Select voice → Save
Connection test: Admin Settings → Audio → Enter API URL → Click "Test" → Select preferences
Scope
Checklist
CLA Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.