Provider live
What it is. Which TTS engine synthesizes speech: ElevenLabs, FreyaTTS (self-hosted), Cartesia, OpenAI, or a custom OpenAI-compatible endpoint. This is the first branch in the whole TTS build.
Runtime. base_service.py:833 reads and lowercases the value, then branches at :864,873,885,897,909. When settings.server.is_on_premise is true (base_service.py:864), it always builds FreyaTTSService — the dashboard provider field is ignored on-prem.
- When to change: cloud demos may use ElevenLabs/Cartesia for voice variety; regulated on-prem deployments are pinned to FreyaTTS by environment, not by this field.
Symptom it fixes: "the voice sounds robotic / wrong accent" — usually a provider+voice mismatch, often a test agent silently falling back to ElevenLabs because ENVIRONMENT wasn't set to on-premise.
Model live
What it is. The specific model within the provider (e.g. ElevenLabs eleven_flash_v2_5, Cartesia sonic-2).
Runtime. For the Freya path the model name is effectively hardcoded to freya-tts (base_service.py:911); for custom providers it is passed through as free text.
- When to change: switching to a lower-latency model (e.g. ElevenLabs flash) for latency-sensitive deployments. See Part 10's latency playbook.
Symptom it fixes: "responses are slow" can be partly a heavyweight TTS model; flash/turbo variants shave hundreds of ms.
Voice (picker vs custom voice ID) live
What it is. The actual voice. Either pick from the provider's gallery or paste a custom voice ID. This is the only TTS field marked required.
Runtime. base_service.py:838,868,901. The cloud Freya branch maps specific "magic" UUIDs to either FreyaTTSService(voice="leyla") or named ElevenLabs voices (voice map at base_service.py:922-978); unknown IDs fall back to a default ElevenLabs voice. On-prem (:864) builds FreyaTTSService(voice=voiceId or TTS_VOICE_ID), so the UUID mapping is bypassed entirely and your voiceId is taken as a literal Freya voice name.
- When to change: brand voice selection. For Turkish deployments the in-house voices are Leyla / Zeynep / Alev / Ali / Alper / Mustafa.
Symptom it fixes: "we want a female/male voice" / "this isn't the voice we approved" — set voiceId to the agreed voice.
Try it — voice picker resolution
Pick a voice and see how the runtime resolves it. The same selection resolves differently depending on whether the agent is running cloud or on-prem — that nuance is what trips up test agents.
Reminder: on-prem forces FreyaTTSService regardless of provider/voiceId (base_service.py:864) — the ElevenLabs fallback can only ever happen on the cloud branch (:909).
voiceId UUID that maps to a named voice in base_service.py:922-978 and what each one resolves to (FreyaTTS leyla vs which ElevenLabs voice), then tell me what an unrecognized UUID falls back to."Language live
What it is. The spoken language for TTS, or multi for multilingual.
multi
default validator: multi · seeded base config: en
Runtime. base_service.py:834-835,860. Drives whether a LanguageTextFilter is added (it is skipped when multi). FreyaTTS disallows multi (enforced in the UI, tts-config-panel.tsx:842). Note the default mismatch: the validator defaults to multi while the seeded base config uses en (see Part 10).
- When to change: single-language deployments (almost all Turkish bank deployments) should set
trexplicitly — both for the language filter and because it unlocks the Turkish number-normalization toggles (Part 4), which are gated onlanguage === tr.
Symptom it fixes: "it reads phone numbers as one giant number" — you can't even enable the TC/phone normalizers until language is tr.
Try it — language gate preview
Language is more than a voice setting: it gates two downstream behaviors. Switch the code and watch what unlocks or breaks.
Custom base URL & API key live
What it is. For provider = custom, the OpenAI-compatible TTS endpoint and its key.
Runtime. Routed through the OpenAI-TTS path (base_service.py:897, OpenAITTSService); the key is resolved via the encrypted _get_api_key helper.
- When to change: bringing your own TTS (rare). Most deployments use a built-in provider or env-driven FreyaTTS (
BASE_SPEECH_URL).
Symptom it fixes: niche; usually a partner who insists on their own voice stack.
Advanced provider settings tuning
{speed:1, stability:0.5, similarity_boost:0.75} (ElevenLabs InputParams at base_service.py:938-940). Raise speed slightly for impatient callers; raise stability if the voice wavers.
Try it — on-prem override explainer
This is the single most important rule in Part 2: the runtime provider branch is decided by ENVIRONMENT / is_on_premise, not the dashboard. Toggle it and see what the dashboard fields actually do.
base_service.py, trace create_tts_service from the provider read at :833 through the is_on_premise check at :864 and the cloud-freya fallback at :909, and tell me exactly when a dashboard voiceId gets ignored."Checkpoint
A test agent keeps speaking in an ElevenLabs voice even though you set FreyaTTS Leyla. Why?
Because the runtime provider branch is decided by ENVIRONMENT / is_on_premise, not the dashboard field (base_service.py:864). If the agent isn't running with ENVIRONMENT=on-premise, the cloud branch runs and an unrecognized voiceId falls back to ElevenLabs (base_service.py:909 onward). Fix the env, not the dashboard.