Video/Voice Calls in Team Chat (LiveKit WebRTC, in development)
Video and voice calls inside a Team Chat channel, powered by LiveKit: start a call from the channel header, ring the other members, and talk peer-to-peer with up to fifty participants, with mute, camera, screen share and virtual backgrounds. Still in development behind a Lab flag, with the cloud functions and the data processing agreement outstanding before it ships.
What it is
Status: In-development (gated behind video-calls unreleased feature). Reveal via Settings -> Lab -> Video Calls, or launch with AMC_SHOW_VIDEO_CALLS=1.
Channel-scoped voice and video calls inside Team Chat, powered by LiveKit (a WebRTC SFU). A call is a Firestore document with a status state machine (ringing -> active -> ended); the renderer manages call state through a Zustand store and connects to LiveKit for peer-to-peer media. Up to 50 participants per call.
Where to find it
The call UI lives inside Team Chat — the call button sits in the channel header, and an incoming call arrives as an overlay. Because the feature is still in development, none of it is visible until you reveal it in Settings -> Lab -> Video Calls.
How it behaves
How it works
- Start a call -- click the call button in the channel header. This creates a Firestore call doc (status
ringing) and obtains a LiveKit token + URL. - Ring -- other channel members see an incoming call overlay. Declining suppresses re-ring for the session. Ring timeout is 30 seconds.
- Join -- accepting transitions the call to
activeand returns a LiveKit token. The LiveKit room connection is renderer-side (no main-process relay). - In-call -- presence heartbeats every 30 seconds; participant count updates from Firestore snapshots.
- End -- sets status to
ended, records duration, posts a system message summarizing the call.
In-call features
- Controls toolbar -- mute (M), camera toggle (V), screen share (S), virtual background (B), end call (Escape). All keyboard-accessible with ARIA labels.
- Virtual backgrounds -- blur (light/medium/heavy) or a custom image (JPEG/PNG/WebP). The track processor is lazy-loaded (not in the critical call-join path). Custom images are stored locally in
{userData}/video-backgrounds/. - Participant grid -- LiveKit-powered grid layout for multiple participants.
What's built vs deployment blockers
Built (renderer-side complete):
- Zustand store with full call state machine (single active call, declined call tracking, connection state)
- UI components: CallButton, InCallView, IncomingCallOverlay, LiveKitCallGrid, CallControls, BackgroundPicker
- IPC schemas and channels:
TEAM_CHAT_CALL_START,TEAM_CHAT_CALL_JOIN,TEAM_CHAT_CALL_END - LiveKit room hook with presence heartbeat
- Virtual background processor with blur and custom image support
- Main-process IPC handlers (wired)
Deployment blockers (must be resolved before shipping):
- Cloud Functions not deployed --
callStart,callJoin,callEndfunctions are referenced inteam-chat-call-relay-client.tsbut are NOT deployed to Firebase. These create/join/end call documents and obtain LiveKit tokens. - LiveKit DPA (Data Processing Agreement) -- pending; required before enabling the feature.
- Server-side call presence cleanup -- stale heartbeat expiry is not yet implemented.
Scope and limits
- Desktop only -- the call UI is a renderer-side feature inside Team Chat.
- One active call at a time -- the store enforces single-call; starting a second ends the first.
- 50-participant cap -- enforced by Zod schema validation on the participants record.
- $0 AI spend -- no Claude tokens used; media is peer-to-peer via LiveKit.
For agents
Architecture (for agents / engineers)
| Piece | Location |
|---|---|
| Zustand store | src/renderer/src/features/team-chat/video-call/call-store.ts |
| IPC client | src/renderer/src/features/team-chat/video-call/call-client.ts |
| Firestore call listener | src/renderer/src/features/team-chat/video-call/use-call-listener.ts |
| LiveKit room + heartbeat | src/renderer/src/features/team-chat/video-call/use-livekit-room.ts |
| Controls toolbar | src/renderer/src/features/team-chat/video-call/CallControls.tsx |
| Background picker | src/renderer/src/features/team-chat/video-call/BackgroundPicker.tsx |
| Background processor | src/renderer/src/features/team-chat/video-call/video-bg-processor.ts |
| Background storage | src/main/services/team-chat/video-backgrounds.ts |
| In-call view | src/renderer/src/features/team-chat/video-call/InCallView.tsx |
| Incoming call overlay | src/renderer/src/features/team-chat/video-call/IncomingCallOverlay.tsx |
| Participant grid | src/renderer/src/features/team-chat/video-call/LiveKitCallGrid.tsx |
| Call button | src/renderer/src/features/team-chat/video-call/CallButton.tsx |
| Zod schemas + constants | src/shared/ipc-schemas/team-chat-calls.ts |
Related
- team-chat.md -- the Team Chat feature that hosts calls
- Contract: team-chat-video-call-contract.md
| Zod schemas + constants | src/shared/ipc-schemas/team-chat-calls.ts |
| Piece | Location |
|---|---|
| Zustand store | src/renderer/src/features/team-chat/video-call/call-store.ts |
| IPC client | src/renderer/src/features/team-chat/video-call/call-client.ts |
| Firestore call listener | src/renderer/src/features/team-chat/video-call/use-call-listener.ts |
| LiveKit room + heartbeat | src/renderer/src/features/team-chat/video-call/use-livekit-room.ts |
| Controls toolbar | src/renderer/src/features/team-chat/video-call/CallControls.tsx |
| Background picker | src/renderer/src/features/team-chat/video-call/BackgroundPicker.tsx |
| Background processor | src/renderer/src/features/team-chat/video-call/video-bg-processor.ts |
| Background storage | src/main/services/team-chat/video-backgrounds.ts |
| In-call view | src/renderer/src/features/team-chat/video-call/InCallView.tsx |
| Incoming call overlay | src/renderer/src/features/team-chat/video-call/IncomingCallOverlay.tsx |
| Participant grid | src/renderer/src/features/team-chat/video-call/LiveKitCallGrid.tsx |
| Call button | src/renderer/src/features/team-chat/video-call/CallButton.tsx |
| Zod schemas + constants | src/shared/ipc-schemas/team-chat-calls.ts |
Last verified 2026-09-23