feat(voice): dynamic voice list with preview#2
Draft
heavygee wants to merge 13 commits into
Draft
Conversation
Single canonical guide at docs/operator/AGENTS.md; merge=ours keeps AGENTS.md deleted when syncing tiann/hapi. Upstream PR branches must still be cut from upstream/main only. Co-authored-by: Cursor <cursoragent@cursor.com>
Adds a Voice dropdown in the Voice Assistant settings section, mirroring the existing language picker pattern. - New `web/src/lib/voices.ts` — curated list of 10 pre-made ElevenLabs voices with name, gender, and short description - `VoiceSessionConfig` gains optional `voiceId` field - `startRealtimeSession` and `VoiceContext.startVoice` read `hapi-voice-id` from localStorage and thread it through to the ElevenLabs `startSession` call via `overrides.tts.voice_id` - `buildVoiceAgentConfig` enables `tts.voice_id` override in `platform_settings` alongside the existing `language` override - Settings page renders the picker with Default + 10 named options; selection persists to localStorage immediately Default path: when no voice is stored the existing `cgSgspJ2msm6clMCkdW9` (Jessica) baked into the agent config is used unchanged. NOTE: branch cut from fork main — re-cut from upstream/main before opening a PR to tiann/hapi. via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
- Add GET /api/voice/voices hub route proxying ElevenLabs /v1/voices (returns empty list gracefully when no API key configured) - Add fetchVoices() to ApiClient and web API layer with VoiceInfo type - Settings voice picker now fetches account voices dynamically on mount, including user's cloned voices (shown with "clone" badge) - Falls back to static built-in voice list if API returns empty - Add play/stop preview button per voice using ElevenLabs preview_url - Fix voice_id → voiceId in ElevenLabs override (SDK camelCase) via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GET /api/voice/voiceshub route that proxies the ElevenLabs/v1/voicesendpoint, exposing all voices available to the configured API key — including user voice clonespreview_urlexistsRefs: tiann#686
Test plan
ELEVENLABS_API_KEYset — picker falls back to static list, preview buttons are visible but disabled with tooltip, and a 400 toast appears on startweb/src/routes/settings/index.test.tsxpasses (21/21)