Voice¶
Realtime voice in Chat lets you talk to an agent out loud — your microphone streams to the provider, the agent answers with audio, and the full transcript lands in your chat session.
Quick start¶
-
Add to
~/.soulacy/config.yaml: -
Restart the gateway (Config page → Restart Gateway, or restart the service).
- Open Chat, click the 🎤 button, and allow microphone access when the browser asks.
- Talk. Click ⏹ 🎤 to end the session.
Requirements¶
voice.provider: openaiin config — without it the voice button is disabled.- An OpenAI API key in
llm.providers.openai.api_keyor theOPENAI_API_KEYenvironment variable. - A browser context where
getUserMediaworks: localhost or HTTPS. The default local deployment (http://localhost:18789) qualifies; remote deployments need TLS.
Check availability without the GUI:
curl http://localhost:18789/api/v1/voice/status \
-H "Authorization: Bearer $SOULACY_API_KEY"
# → {"available": true, "provider": "openai", "model": "gpt-realtime-mini"}
How a session works¶
Clicking 🎤 walks through these steps:
- The gateway mints a short-lived ephemeral client key (
POST /api/v1/voice/ephemeral). Your real API key never reaches the browser. - The browser asks for microphone permission and opens a WebRTC connection directly to the provider — audio never transits the Soulacy gateway, so there is no added latency.
- The button shows ⏳ while connecting, then pulses red while live. A system line ("🎤 voice session started") marks the start in the chat.
- Speak naturally — the provider's server-side voice activity detection handles turn-taking and barge-in.
- Click the button again (⏹) to stop; the mic is released and "🎤 voice session ended" is appended.
Transcripts attach to the session¶
As you talk, transcripts render live in the chat:
- your completed utterances appear as user messages,
- the assistant's spoken reply streams in as a growing assistant bubble, finalized when the turn ends.
They are part of the same chat session as your typed messages — text only, no audio blobs are stored.
Usage chip¶
Once the session has consumed tokens, a usage chip appears in the header:
That is the running input/output token total for realtime voice in this session (hover it to see the model).
When voice is not configured¶
The feature degrades gracefully:
- No
voice.providerset → the 🎤 button is disabled; its tooltip explains what to configure ("no realtime voice provider configured — set voice.provider and an OpenAI API key in config.yaml"). - Provider set but no API key →
/api/v1/voice/statusreports unavailable with the reason, and the button stays disabled. - A failed session shows ⚠ 🎤; click it once to reset to idle and try again.
Everything else in Chat keeps working normally — voice is purely additive.
Note
Voice minutes are billed by the provider per audio token and cost noticeably more than text chat. The usage chip exists so you always see what a session consumed.
Tip
If the browser never asks for the microphone, check the site permission settings — a previously denied mic permission silently fails the session with ⚠ 🎤.