Skip to content

Text-to-speech

You bind a voice to an agent. AI Chat can then speak that agent’s assistant replies. There is no per-user provider override and no hidden default voice: if the agent has no voice, speak controls stay hidden and auto-read does nothing.

You enable portals from Administration → Voice (/admin/ai/tts). A portal is configured when it is available:

Portal How it runs When it is configured
Local browser Web Speech generated in the browser (speechSynthesis) Chrome, Edge, and Safari (not Firefox)
Fontana Voice Air-gapped Fontana Voice on the host bridge platform.tts is enabled in fontana.yaml
OpenAI OpenAI TTS (gpt-4o-mini-tts) OPENAI_API_KEY is set in Administration → API Keys
ElevenLabs Account library, Voice Design, and Instant Voice Clone ELEVENLABS_API_KEY is set in Administration → API Keys

There is no automatic failover between portals. If the bound voice fails, Flow shows an error and you fix the portal or pick another voice.

On Administration → Voice you pick a portal from the list. The welcome pane stays until you select one. For the selected portal you:

  1. Confirm availability (browser support, Fontana Voice on the host, or a BYOK key).
  2. Save OpenAI and ElevenLabs keys on the portal detail, or from API Keys.
  3. Use Test (requires platform:write) to play a short sample.

Admin does not pick a workspace default voice. You choose the voice on each agent.

On the agent Model settings card, Voice is optional. The two-step selector lists portals, then voices for that portal. Step 2 includes search, a language picker, a compact gender filter, a short description, and a play control that shows a spinner while the sample loads. Flow waits for portal configuration before showing the selector, so loading never appears as an unconfigured portal. For ElevenLabs you can pick a library voice, generate a Voice Design preview from a prompt, or Instant Voice Clone from uploaded audio. Professional Voice Clone is out of scope.

The stored id is provider::voiceKey (the same class as languageModel). Clear removes the voice.

On the Voice label, Snippets lets the agent generate MP3 clips in this voice. The tool receives only the text to speak. Flow uses the agent’s Voice settings and keeps API keys in Vault. Local browser voices cannot produce a server clip, so the switch stays off until you assign Fontana Voice, OpenAI, or ElevenLabs. Clearing the voice or switching to Local browser removes the tool. Picking a cloud voice does not turn Snippets on by itself.

On assistant replies, a speak control sits beside the ... menu on every AI Chat v2 surface, including nested child threads. Click once to play; click again to stop. User messages have no speak control.

The bottom-controls cog turns auto-read on or off for you (default off). When auto-read is on and the agent on the open thread has a voice, Flow speaks completed sentences as that thread’s reply streams, then flushes any open tail when the run finishes. Other chats that keep running in the background stay silent until you open them. Intentional stop does not show a failure toast; real speak errors fail closed with an error toast.

You can dictate into the AI Chat composer and the header agent omnibar. Click the microphone, speak, then pause. Flow appends the transcript to the prompt and you send it yourself. The control is hidden when the browser does not support speech recognition.

Kokoro runs as a shared fontana-gateway singleton (default on). To skip it on a RAM-constrained host, set in fontana.yaml:

platform:
tts:
disabled: true

Then run fontana apply. Speech traffic uses the platform host bridge (/v1/audio/speech). Post-apply and fontana status record the kokoro Deployment when it exists. See Fontana CLI for the platform.* disable table.

  • BYOK - OpenAI and ElevenLabs speech use the same API Keys vault as other BYOK providers
  • Gateways - LLM gateways are separate from Voice portals
  • Fontana CLI - platform.tts.disabled for light installs