Skip to main content

livekit-plugins-facemode

FaceMode avatar output for LiveKit Agents Python applications.

Install

pip install livekit-plugins-facemode

From this repository:

pip install .

Requires Python 3.13 or later, LiveKit 1.x, and LiveKit Agents 1.7 or later.

Usage

The host application supplies a server-side LiveKit room object. The room token must grant the FaceMode worker permission to join, publish, and subscribe in the customer room. Keep the token on the server and never log it or expose it to a browser client.

import os

from livekit.agents import Agent, AgentSession, room_io
from livekit_plugins_facemode import AvatarSession

avatar = AvatarSession(
    api_key=os.environ["FACEMODE_API_KEY"],
    avatar_id=os.environ.get("FACEMODE_AVATAR_ID", ""),
)

await ctx.connect()
await avatar.start(
    agent_session,
    ctx.room,
    room={
        "type": "livekit",
        "url": os.environ["LIVEKIT_URL"],
        "token": os.environ["LIVEKIT_TOKEN"],
    },
)
await agent_session.start(
    agent=Agent(instructions="You are a helpful assistant."),
    room=ctx.room,
    room_options=room_io.RoomOptions(audio_output=False),
)
await avatar.wait_for_join()

AvatarSession.start() creates a FaceMode session with the room object. The create response normally returns ready: true with the ingestion url and a one-time wsToken (about 15 minute expiry), so no polling happens in the common path. If worker assignment is still pending, the plugin polls the session endpoint with bounded backoff for up to 240 seconds and stops immediately on FAILED/ENDED worker states. The initial response's room credentials remain in memory and are not expected in the polling response.

The ingestion WebSocket handshake uses the Sec-WebSocket-Protocol subprotocol facemode.<wsToken> with a 240 second open timeout. When the backend returns optional ingestion.headers, the plugin forwards them during the handshake. It disables compression and native WebSocket keepalives in favor of the canonical application ping/pong messages after negotiation.

Pass input_provider (one of deepgram, gemini, gnani, elevenlabs, openai, cartesia, sarvam, custom) to AvatarSession when the session should pin a specific upstream input provider; it is omitted from the request otherwise.

If the WebSocket transport drops after the protocol has started, the plugin auto-reconnects in the background: it POSTs the session reconnect endpoint for a fresh one-time wsToken (a consumed token is never reused), opens a new socket with facemode.<newToken>, re-sends the canonical start message, and waits for started before resuming. Outgoing control seq numbers stay monotonic across the reconnect and buffered audio is not replayed. Reconnect is bounded to 2 attempts with backoff and is single-flight; exhaustion surfaces a typed FaceModeNotReadyError/FaceModeAPIError. Intentional stop(), a canonical ended, fatal protocol errors, and drops before the first negotiation do not reconnect.

Every TTS frame is sent as canonical PCM audio. The plugin locks sample rate and channel count at protocol negotiation and rejects a format change or unaligned 16-bit PCM afterward. cancel_utterance is sent when LiveKit interrupts the audio output. Graceful close sends end_session and waits briefly for canonical ended; ended is a protocol acknowledgement, not backend cleanup confirmation.

Token grants

The room.token value must allow the worker to join the customer room and publish its avatar audio/video tracks. If the token uses a fixed participant identity, use avatar_participant_identity and make the room policy allow that identity. The worker does not create or replace the customer LiveKit room.

API URL

The default API URL is https://api.facemode.io/api. Set api_url for a self-hosted or local backend.

License

Apache-2.0 - see LICENSE. Part of the facemode-integrations monorepo.

Metadata

Release files for livekit-plugins-facemode 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for livekit-plugins-facemode 0.2.0
File Size Uploaded
livekit_plugins_facemode-0.2.0.tar.gz 24.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for livekit-plugins-facemode 0.2.0
File Interpreter ABI Platform
livekit_plugins_facemode-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 43.9 kB

Release files / livekit_plugins_facemode-0.2.0.tar.gz

Download URL livekit_plugins_facemode-0.2.0.tar.gz
Size 24.9 kB
Tags Source
SHA-256 checksum
How to use checksums
82c8b179e8b3f9ab95cf93f5c289a6405c37072eaafc4041f48260b44c1b86e5
BLAKE2b-256 checksum
How to use checksums
2e4dd9e708b2b8adc0d10da4d9f3d60a9c6bc6b6f6d8b1119b1bf04c2729207f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / livekit_plugins_facemode-0.2.0-py3-none-any.whl

Download URL livekit_plugins_facemode-0.2.0-py3-none-any.whl
Size 19.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bb969ed09187b3016d53adfcf1b91685391fb504e4369f358fef5cec8aef207e
BLAKE2b-256 checksum
How to use checksums
239c91358a1ae5b7e7bd5cd6d99cd036de715b9d36bf9e5b3d99277c0ff30b00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page