feat(voice): dynamic settings voice picker with safe fallback + preview#690
feat(voice): dynamic settings voice picker with safe fallback + preview#690heavygee wants to merge 3 commits into
Conversation
c3d8e89 to
3b07716
Compare
There was a problem hiding this comment.
Findings
- [Major] Selected voice is ignored when
ELEVENLABS_AGENT_IDis configured —voiceIdreaches the token route, butprocess.env.ELEVENLABS_AGENT_IDwins before the per-voice auto-create path runs, and the client no longer sends a runtime TTS override. Any install with a configured default agent will keep using that agent's voice for non-default picker selections. Evidencehub/src/web/routes/voice.ts:185. - [Minor] Preview audio can keep playing after leaving Settings — the new
Audioinstance is stored in a ref, but nothing pauses it on unmount, so navigating away while a preview is playing leaves audio running with no visible stop control. Evidenceweb/src/routes/settings/index.tsx:440.
Summary
- Review mode: initial
- The PR needs changes for the configured-agent voice selection path. Residual risk: I could not execute local automation in this runner because
bunis not installed.
Testing
- Not run (automation;
bun: command not found)
HAPI Bot
| let agentId = customAgentId || process.env.ELEVENLABS_AGENT_ID | ||
| const voiceAgentMap = parseVoiceAgentMap() | ||
| const mappedAgentId = voiceId ? voiceAgentMap[voiceId] : undefined | ||
| let agentId = customAgentId || mappedAgentId || process.env.ELEVENLABS_AGENT_ID |
There was a problem hiding this comment.
[MAJOR] This makes the picker ineffective for the common configured-agent setup. When ELEVENLABS_AGENT_ID is set, agentId is resolved here even if voiceId is present, so the request never reaches getOrCreateAgentIdForVoice(...). Since RealtimeVoiceSession only passes the voice to the token endpoint and does not include a TTS override in startSession, non-default voice selections will keep using the configured agent's existing voice.
Suggested fix:
const voiceAgentMap = parseVoiceAgentMap()
const mappedAgentId = voiceId ? voiceAgentMap[voiceId] : undefined
const defaultAgentId = process.env.ELEVENLABS_AGENT_ID
let agentId = customAgentId || mappedAgentId || (!voiceId ? defaultAgentId : undefined)
if (!agentId) {
agentId = await getOrCreateAgentIdForVoice(apiKey, voiceId) ?? undefined
if (!agentId) {
return c.json({
allowed: false,
error: 'Failed to create ElevenLabs agent automatically'
}, 500)
}
}| } | ||
|
|
||
| currentAudioRef.current?.pause() | ||
| const audio = new Audio(previewUrl) |
There was a problem hiding this comment.
[MINOR] A playing preview is not stopped when the Settings page unmounts. currentAudioRef owns the Audio object, but there is no cleanup effect, so users can navigate away from Settings and the preview keeps playing without the stop button still being available.
Suggested fix:
useEffect(() => {
return () => {
currentAudioRef.current?.pause()
currentAudioRef.current = null
}
}, [])There was a problem hiding this comment.
Findings
- No high-confidence issues found.
Summary
- Review mode: follow-up after new commits
- Full latest diff reviewed. The prior bot findings appear addressed: selected
voiceIdnow resolves a voice-specific agent before falling back toELEVENLABS_AGENT_ID, and Settings preview audio is paused on unmount. - Residual risk: local automation was not run because
bunis not installed in this runner.
Testing
- Not run (automation;
bunnot found)
HAPI Bot
|
Linking related upstream Discussion for roadmap context: #691 |
Summary
GET /api/voice/voicespreview_urlis availableclonebadgeRefs #686
Test plan
cd web && bun run test src/routes/settings/index.test.tsx src/lib/voices.test.tscd hub && bun test src/web/routes/voice.test.ts