Voice support contract
Talos provides gateway signaling, media adapter lifecycle management, and optional LiveKit audio publishing, receiving, browser playback, E2EE, and automatic rejoining throughtalos-fluxer/voice. Install livekit-client separately; the core SDK has
no runtime media dependencies. The bundled media integration targets the browser
LiveKit SDK. Node/Bun applications can supply a transport backed by their media
library; Talos does not bundle native WebRTC, FFmpeg, or a Node audio decoder.
Connections and recovery
VoiceConnection owns one transport. A gateway interruption, matching server
leave/move, replacement grant, or terminal media disconnect closes it. Its active
serialization field describes lifecycle; use state for transport connectivity.
Custom adapters without health events cannot provide a media health guarantee.
VoiceSession owns successive connections. Recovery defaults to five total rejoin
attempts over the session’s lifetime, delays starting at 1 second and capped at
30 seconds, and a 30-second wait for gateway readiness per attempt. Each rejoin
also has the join deadline. Successful rejoins do not reset the total budget.
maxAttempts: 0 disables rejoining. Subscribe to retry, connection, state, and
error to observe recovery. The connection getter changes after each rejoin.
A server leave/move or explicit disconnect ends the session permanently; recovery
does not undo a moderation action or move the connection back. A replacement grant
causes cleanup and a fresh join to the configured channel, rather than reusing the
old transport/token/key. Talos does not refresh expiring tokens proactively or
continue an in-progress player, recording, or application-owned published stream
across a new connection. Use the connection event to rebuild these resources.
VoiceSession defaults to selfMute: true; explicitly enable the microphone when
wanted. Operations while recovering reject until a connection is available.
The initial caller signal/deadline stops applying after a successful join, including
for a session. Use disconnect() to stop an established connection or session.
Session disconnect aborts backoff, gateway waits, and pending joins. Cleanup errors
from automatic shutdown or late transports are also reported through the gateway’s
error event. Adapter cleanup must settle for shutdown to finish.
Only one join may be pending per gateway/channel. Applications own established
connections and must close them. Leave commands are best effort. Before a grant
arrives, Talos has no connection ID to leave. Grants have no client attempt ID,
so delayed grants after cancellation cannot be reliably distinguished from a new
attempt for the same channel. Automatic rejoining inherits this protocol limit.
LiveKit setup
This example assumes a readyGatewayClient and a browser/bundler supported by
livekit-client (the integration was typechecked with 2.22.3). The factory must
construct the encrypted room with the same provider and worker it returns. If
allocation fails inside the factory, the factory must dispose its partial resources.
encryption. Encrypted grants will then be rejected.
The setup follows LiveKit’s encryption guide
and Fluxer’s shared-key initialization.
Encryption and codecs are implemented by LiveKit and the runtime. Talos does not
verify other participants’ encryption configuration or add encryption to signaling.
Publishing and queued file playback
player.disconnect() cancels active and queued items and waits
for cleanup. A voice connection closing also closes its player. Transient media
reconnection interrupts the active item; callers decide whether to enqueue it again.
Receiving and recording
Remote participant IDs are LiveKit identities, not necessarily bare Fluxer user IDs. ReadaudioTracks immediately after joining for already-subscribed tracks;
then listen for additions/removals. Omit audioOutput when managing elements or
recording yourself. Local deafening disables the exposed native tracks, including
audio consumed by recordings; it does not unsubscribe network traffic.
MediaRecorder; Talos does not bundle a recorder, PCM frame
processor, or storage policy. Consumers own their manually attached elements,
recorders, and streams and must dispose them on removal or connection close.
Custom adapter responsibilities
connect(grant, { signal, selfMute?, selfDeaf? }) must create a separate transport
for each attempt, configure security and explicit initial media preferences, and
resolve only when ready. Honor cancellation and clean up partial allocations before
rejecting. Talos disconnects transports returned after a cancelled join.
All media methods and health events on VoiceTransport are optional, preserving
signaling-only adapters. Unsupported controls/publishing reject explicitly. Implement
on to expose track, speaker, error, and health events; an emitted terminal
disconnected ends the connection. audioTracks supplies the initial snapshot.
Advertise supportsE2EE: true only if the adapter configures the grant’s encryption
before returning. Keep grants, tokens, keys, and transports out of diagnostics.
VoiceConnection.toJSON() and VoiceSession.toJSON() exclude them.