Realtime Voice (gateway relay)
WednesdayAI’s realtime voice surface lets client apps (iOS, Android, macOS, web) stream two-way audio through the Gateway and receive transcripts, tool calls, and close events in real time. The Gateway acts as a relay between the client and a registered voice provider — it handles connection lifecycle, audio framing, and event fan-out.How it works
- Client sends
talk.realtime.session→ Gateway resolves the provider, creates a relay session, returnsrelaySessionId. - Client streams PCM16 audio via
talk.realtime.audioframes. - Gateway bridges audio to the provider’s
RealtimeVoiceBridge. - Provider events (ready, audio, transcript, toolCall, error, close) are pushed back as
talk.realtime.relayWebSocket events. - Client sends
talk.realtime.stopor disconnects; Gateway closes the relay and notifies the provider.
Transport modes
If a client requests a non-relay transport and the provider does not implement
createBrowserSession, the request is rejected with UNAVAILABLE — it never silently falls back to relay.
Session limits
- 30 minutes TTL per session (configurable at compile time;
RELAY_SESSION_TTL_MS). - 2 sessions max per connection.
- 64 sessions max globally across all connections.
- Expired sessions close with reason
"completed". Disconnected-client sessions close with"cancelled".
Configuration
Providers are registered by Gateway plugins viaapi.registerRealtimeVoiceProvider(provider).
Provider-specific configuration is read from talk.providers.<providerId> in openclaw.json.
resolveConfig() and isConfigured() hooks at session
start — the provider validates its own keys. Until a real provider plugin is installed,
talk.realtime.session returns UNAVAILABLE: No realtime voice provider registered.
Gateway methods
Session observability
talk.realtime.status returns all active relay sessions visible to the gateway operator:
Events pushed to the client (talk.realtime.relay)
Barge-in
Sendtalk.realtime.bargeIn with optional hints to interrupt active playback:
audioPlaybackActive: true confirms the assistant is still speaking (useful when the client
cannot provide real playback-mark feedback). force: true bypasses the provider’s echo-guard
heuristics.
Tool calls
When the provider emits atoolCall event, the client executes the tool and sends back:
suppressResponse: true submits the result without asking the provider to generate a new
assistant response — useful when another channel (chat) has already delivered the answer.
Logging
The relay logs undergateway/talk-realtime-relay. Enable debug logging in openclaw.json: