// TTS provider registry — voices/languages are the keys the Python backend reads from config export const TTS_PROVIDERS = { sarvam: { label: 'Sarvam', voices: [ { value: 'simran', label: 'Simran (F)' }, { value: 'meera', label: 'Meera (F)' }, { value: 'anushka', label: 'Anushka (F)' }, { value: 'pavithra', label: 'Pavithra (F)' }, { value: 'priya', label: 'Priya (F)' }, { value: 'maitreyi', label: 'Maitreyi (F)' }, { value: 'arya', label: 'Arya (F)' }, { value: 'amol', label: 'Amol (M)' }, { value: 'advait', label: 'Advait (M)' }, ], languages: [ { value: 'en-IN', label: 'English (India)' }, { value: 'hi-IN', label: 'Hindi' }, { value: 'ta-IN', label: 'Tamil' }, { value: 'te-IN', label: 'Telugu' }, { value: 'kn-IN', label: 'Kannada' }, { value: 'ml-IN', label: 'Malayalam' }, { value: 'mr-IN', label: 'Marathi' }, { value: 'bn-IN', label: 'Bengali' }, { value: 'gu-IN', label: 'Gujarati' }, ], defaults: { voice: 'simran', language: 'en-IN' }, buildId: ({ voice, language }) => ({ service: 'sarvam', voice, language }), }, deepgram: { label: 'Deepgram', voices: [ { value: 'aura-2-thalia-en', label: 'Thalia (F)' }, { value: 'aura-2-luna-en', label: 'Luna (F)' }, { value: 'aura-2-stella-en', label: 'Stella (F)' }, { value: 'aura-2-asteria-en', label: 'Asteria (F)' }, { value: 'aura-2-orion-en', label: 'Orion (M)' }, { value: 'aura-2-atlas-en', label: 'Atlas (M)' }, { value: 'aura-2-helios-en', label: 'Helios (M)' }, ], defaults: { voice: 'aura-2-thalia-en' }, buildId: ({ voice }) => ({ service: 'deepgram', 'model-name': voice }), }, resembleai: { label: 'ResembleAI', voices: [ { value: 'c99f388c', label: 'Default Voice' }, ], defaults: { voice: 'c99f388c' }, buildId: ({ voice }) => ({ service: 'resembleai', voice }), }, google: { label: 'Google TTS', voices: [ { value: 'en-IN-Wavenet-A', label: 'Wavenet-A (F, IN)' }, { value: 'en-IN-Wavenet-B', label: 'Wavenet-B (M, IN)' }, { value: 'en-IN-Wavenet-C', label: 'Wavenet-C (M, IN)' }, { value: 'en-IN-Wavenet-D', label: 'Wavenet-D (F, IN)' }, { value: 'en-US-Neural2-F', label: 'Neural2-F (F, US)' }, { value: 'en-US-Neural2-D', label: 'Neural2-D (M, US)' }, ], defaults: { voice: 'en-IN-Wavenet-A' }, buildId: ({ voice }) => ({ service: 'google', 'voice-name': voice }), }, } // STT provider registry export const STT_PROVIDERS = { 'deepgram-streaming': { label: 'Deepgram (Streaming)', models: [ { value: 'nova-3', label: 'Nova 3' }, { value: 'nova-2', label: 'Nova 2' }, ], languages: [ { value: 'en-IN', label: 'English (India)' }, { value: 'en-US', label: 'English (US)' }, { value: 'multi', label: 'Multilingual' }, { value: 'hi', label: 'Hindi' }, ], defaults: { model: 'nova-3', language: 'en-IN' }, buildId: ({ model, language }) => ({ service: 'deepgram-streaming', 'model-name': model, language }), }, deepgram: { label: 'Deepgram (Batch)', models: [ { value: 'nova-3', label: 'Nova 3' }, { value: 'nova-2', label: 'Nova 2' }, ], languages: [ { value: 'en-IN', label: 'English (India)' }, { value: 'en-US', label: 'English (US)' }, { value: 'multi', label: 'Multilingual' }, ], defaults: { model: 'nova-3', language: 'en-IN' }, buildId: ({ model, language }) => ({ service: 'deepgram', 'model-name': model, language }), }, sarvam: { label: 'Sarvam (Saarika)', languages: [ { value: 'en-IN', label: 'English (India)' }, { value: 'hi-IN', label: 'Hindi' }, { value: 'ta-IN', label: 'Tamil' }, { value: 'te-IN', label: 'Telugu' }, ], defaults: { language: 'en-IN' }, buildId: ({ language }) => ({ service: 'sarvam', language }), }, soniox: { label: 'Soniox', multiLanguage: true, languages: [ { value: 'af', label: 'Afrikaans' }, { value: 'sq', label: 'Albanian' }, { value: 'ar', label: 'Arabic' }, { value: 'az', label: 'Azerbaijani' }, { value: 'eu', label: 'Basque' }, { value: 'be', label: 'Belarusian' }, { value: 'bn', label: 'Bengali' }, { value: 'bs', label: 'Bosnian' }, { value: 'bg', label: 'Bulgarian' }, { value: 'ca', label: 'Catalan' }, { value: 'zh', label: 'Chinese' }, { value: 'hr', label: 'Croatian' }, { value: 'cs', label: 'Czech' }, { value: 'da', label: 'Danish' }, { value: 'nl', label: 'Dutch' }, { value: 'en', label: 'English' }, { value: 'et', label: 'Estonian' }, { value: 'fi', label: 'Finnish' }, { value: 'fr', label: 'French' }, { value: 'gl', label: 'Galician' }, { value: 'de', label: 'German' }, { value: 'el', label: 'Greek' }, { value: 'gu', label: 'Gujarati' }, { value: 'he', label: 'Hebrew' }, { value: 'hi', label: 'Hindi' }, { value: 'hu', label: 'Hungarian' }, { value: 'id', label: 'Indonesian' }, { value: 'it', label: 'Italian' }, { value: 'ja', label: 'Japanese' }, { value: 'kn', label: 'Kannada' }, { value: 'kk', label: 'Kazakh' }, { value: 'ko', label: 'Korean' }, { value: 'lv', label: 'Latvian' }, { value: 'lt', label: 'Lithuanian' }, { value: 'mk', label: 'Macedonian' }, { value: 'ms', label: 'Malay' }, { value: 'ml', label: 'Malayalam' }, { value: 'mr', label: 'Marathi' }, { value: 'no', label: 'Norwegian' }, { value: 'fa', label: 'Persian' }, { value: 'pl', label: 'Polish' }, { value: 'pt', label: 'Portuguese' }, { value: 'pa', label: 'Punjabi' }, { value: 'ro', label: 'Romanian' }, { value: 'ru', label: 'Russian' }, { value: 'sr', label: 'Serbian' }, { value: 'sk', label: 'Slovak' }, { value: 'sl', label: 'Slovenian' }, { value: 'es', label: 'Spanish' }, { value: 'sw', label: 'Swahili' }, { value: 'sv', label: 'Swedish' }, { value: 'tl', label: 'Tagalog' }, { value: 'ta', label: 'Tamil' }, { value: 'te', label: 'Telugu' }, { value: 'th', label: 'Thai' }, { value: 'tr', label: 'Turkish' }, { value: 'uk', label: 'Ukrainian' }, { value: 'ur', label: 'Urdu' }, { value: 'vi', label: 'Vietnamese' }, { value: 'cy', label: 'Welsh' }, ], defaults: { languages: ['hi', 'en'] }, buildId: ({ languages }) => ({ service: 'soniox', language: languages }), }, } export const VOICE_SETTING_DEFAULTS = { ttsProvider: 'sarvam', ttsVoice: 'simran', ttsLanguage: 'en-IN', sttProvider: 'deepgram-streaming', sttModel: 'nova-3', sttLanguage: 'en-IN', sttLanguages: ['hi', 'en'], // for multi-language providers (soniox) grainVoice: false, grainLevel: 0.025, preFire: true, preFireMin: 50, preFireMax: 5000, preFireCurrent: 100, inactivity: true, inactivityTimePeriod: 1000, inactivityMaxTimes: 3, inactivityMessage: "Are you still there? No rush — take your time and answer whenever you're ready.", inactivityInterruptionType: 'full', } // Converts the flat settings object into the customs keys the backend expects export function buildVoiceCustoms(settings) { const s = { ...VOICE_SETTING_DEFAULTS, ...settings } const ttsDef = TTS_PROVIDERS[s.ttsProvider]?.defaults ?? {} const sttDef = STT_PROVIDERS[s.sttProvider]?.defaults ?? {} const sttProv = STT_PROVIDERS[s.sttProvider] const ttsParams = { voice: s.ttsVoice ?? ttsDef.voice, language: s.ttsLanguage ?? ttsDef.language, model: ttsDef.model, } const sttParams = sttProv?.multiLanguage ? { languages: s.sttLanguages?.length ? s.sttLanguages : (sttDef.languages ?? ['en']) } : { model: s.sttModel ?? sttDef.model, language: s.sttLanguage ?? sttDef.language } return { tts_id: TTS_PROVIDERS[s.ttsProvider]?.buildId(ttsParams) ?? { service: s.ttsProvider }, stt_id: sttProv?.buildId(sttParams) ?? { service: s.sttProvider }, 'grain-voice': s.grainVoice, 'grain-level': s.grainVoice ? s.grainLevel : 0, 'pre-fire': s.preFire, 'pre-fire-config': s.preFire ? { min: s.preFireMin, max: s.preFireMax, current: s.preFireCurrent } : {}, inactivity: s.inactivity, 'inactivity-metadata': s.inactivity ? { 'time-period': s.inactivityTimePeriod, 'max-times': s.inactivityMaxTimes, 'inactivity-type': 'static', message: s.inactivityMessage, 'interruption-type': s.inactivityInterruptionType, 'interruption-metadata': {}, } : {}, } }