# LiveKit voice and streaming

CLAWD Mail uses LiveKit Cloud for the custom `/voice` conversation interface and `/stream/livekit` media rooms. Both pages require the same signed-in account, onboarding, and terms checks as the rest of the app. The existing `/stream` broadcasts remain available.

## Server configuration

Set these variables on the web backend. For local development, use the ignored, owner-readable `backend/.env.livekit.local` file.

```dotenv
LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=your-server-key
LIVEKIT_API_SECRET=your-server-secret
LIVEKIT_AGENT_ID=A_J68u6xieNdcS
LIVEKIT_AGENT_NAME=your-agent-dispatch-name
```

An `A_` resource ID is distinct from the dispatch name configured in the agent worker. Verify the project and name with `lk agent list --id A_J68u6xieNdcS` and `lk agent status --id A_J68u6xieNdcS`, using credentials through environment variables. An absent deployment must be deployed in the correct project before voice conversations can start. Never substitute the resource ID for its dispatch name.

The browser receives a short-lived token limited to a server-selected room and participant. It never receives the API key or secret. A viewer token cannot publish media or data. Session shutdown is limited to its owner; logout, account revocation, expiry, and server shutdown also clean up owned sessions.

## Voice, expressions, and chat

Start a conversation explicitly, then enable the microphone. Camera and screen sharing are separate actions. Ending or leaving the page stops local capture and disconnects the session. If browser autoplay is blocked, the page offers an explicit audio playback control.

The custom CLAWD visualizer responds to real audio levels and the agent's `lk.agent.state` attribute. Expression colors read `lk.expression` metadata on `lk.transcription` streams. Without an expressive TTS provider, the visualizer stays neutral. Expression metadata is presentation only; it does not trigger an action or imply an inferred user emotion.

Typed messages use the `lk.chat` topic. Speech captions use `lk.transcription`; partial updates replace the same segment instead of adding duplicate messages. The transcript is held in the current browser session. Incoming text renders as text, without HTML interpretation.

Agent avatar video is a standard remote video track. The UI renders it when the deployed agent publishes one, including a separate avatar participant publishing on the agent's behalf. A local mascot visualization does not prove that an avatar provider is configured. Avatar generation and expressive TTS require those features in the deployed worker; LiveKit Agent Builder currently has provider and modality limitations.

## Media rooms

Start a stream, enable the devices you want to publish, and copy its unlisted room link. Another signed-in, approved member can explicitly watch with devices off. A viewer cannot stop the owner's broadcast. Ending the stream removes the provider room and disconnects its viewers.

Microphone capture uses standard WebRTC echo cancellation and noise suppression. Camera, screen sharing, and browser tab audio depend on browser capabilities and permission. No microphone or camera permission is requested merely by opening a page.

## Related LiveKit documentation

- [Production token endpoints](https://docs.livekit.io/frontends/build/authentication/endpoint/)
- [Agent dispatch](https://docs.livekit.io/agents/server/agent-dispatch/)
- [Text and transcriptions](https://docs.livekit.io/agents/multimodality/text/)
- [Expressive speech](https://docs.livekit.io/agents/models/tts/expressive/)
- [Avatar workers](https://docs.livekit.io/agents/models/avatar/)
- [Media tracks](https://docs.livekit.io/transport/media/subscribe/)
- [Screen sharing](https://docs.livekit.io/transport/media/screenshare/)

The supplied export, ingress, VM, Redis, and SIP references describe separate infrastructure capabilities. This integration uses the supplied LiveKit Cloud project. Recording, RTMP destinations, encoder ingress, and telephony require their own configured destinations or trunks and explicit product controls; opening or starting a conversation does not record it or call a telephone number.
