feat(voice): dynamic settings voice picker with safe fallback + preview (#690)

* feat(voice): dynamic settings voice picker with safe fallback + preview

* fix(voice): honor picker with configured agent and stop preview on unmount

* fix(voice): apply PR review feedback for agent selection and preview cleanup
This commit is contained in:
HeavyGee
2026-05-27 11:17:01 +08:00
committed by GitHub
parent de5dc97988
commit d5a67b717c
16 changed files with 921 additions and 50 deletions
+19 -1
View File
@@ -538,7 +538,7 @@ export class ApiClient {
})
}
async fetchVoiceToken(options?: { customAgentId?: string; customApiKey?: string }): Promise<{
async fetchVoiceToken(options?: { customAgentId?: string; customApiKey?: string; voiceId?: string }): Promise<{
allowed: boolean
token?: string
agentId?: string
@@ -549,4 +549,22 @@ export class ApiClient {
body: JSON.stringify(options || {})
})
}
async fetchVoices(): Promise<{ voices: Array<{ id: string; name: string; previewUrl: string; category: string }> }> {
return await this.request('/api/voice/voices')
}
async sendVoiceTelemetry(event: {
stage: string
message: string
sessionId?: string
voiceId?: string
language?: string
details?: Record<string, unknown>
}): Promise<void> {
await this.request('/api/voice/telemetry', {
method: 'POST',
body: JSON.stringify(event)
})
}
}
+17
View File
@@ -26,6 +26,7 @@ export interface VoiceTokenResponse {
export interface VoiceTokenRequest {
customAgentId?: string
customApiKey?: string
voiceId?: string
}
/**
@@ -50,6 +51,22 @@ export async function fetchVoiceToken(
}
}
export interface VoiceInfo {
id: string
name: string
previewUrl: string
category: string
}
export async function fetchVoices(api: ApiClient): Promise<VoiceInfo[]> {
try {
const result = await api.fetchVoices()
return result.voices
} catch {
return []
}
}
export interface ElevenLabsAgent {
agent_id: string
name: string