ChatFX Avatar for LiveKit Agents
A real-time talking face for your LiveKit voice agent. The avatar joins your agent's LiveKit Cloud room as one more participant, takes your agent's voice and speaks it with its lips in time, shown as your agent. You keep your own listening, AI and voice; ChatFX adds the face, billed by the minute.
Install
pip install livekit-plugins-chatfx
Requires Python 3.10+ and livekit-agents 1.2 or newer.
Add your key
Create a key under API keys at avatar.chatfx.com. Then add it to your voice agent's secrets
at LiveKit, named exactly CHATFX_AVATAR_API_KEY. In your agent's folder:
lk agent update-secrets --secrets "CHATFX_AVATAR_API_KEY=cfx_..."
Running your agent on your own server instead? Add the key to that server's environment variables, with the same name.
Your agent also needs LIVEKIT_URL, LIVEKIT_API_KEY and LIVEKIT_API_SECRET, which it already has. They never leave your
server.
Use it
In your agent's entrypoint, after you make the AgentSession and before session.start():
from livekit.plugins import chatfx
avatar = chatfx.AvatarSession(avatar_id="chatfx-lois") # copy the id from the Avatars page
await avatar.start(session, room=ctx.room)
await session.start(agent=MyAgent(), room=ctx.room)
That's all the code. When the job ends, the session ends too, so billing stops. To end it earlier, call
await avatar.aclose().
What it does for you
- Shows a waiting picture, with nothing to add to your page. The moment a call starts, your agent shows the avatar's picture as its own video, with "Video starting..." on it, and the live face takes over when it's ready. Any page that shows the agent's video gets this.
- Greets with the face.
start()waits up to 10 seconds for the face, so your agent's first words come with it. - Starts by voice, over the picture, if the face is late. The voice moves to the face between replies, so a sentence is never split.
- Never depends on the face. If the face can't come, or leaves mid-call, your agent carries on by voice.
- Keeps trying while a GPU wakes or is busy, for up to 5 minutes, and stops at once on a refusal more tries won't fix.
- Stops forgotten calls, so they don't use your minutes: after 2 minutes with nobody talking, 2 minutes after the visitor leaves (long enough for a page reload), or at 1 hour.
- Can't go deaf. If the face's "finished talking" message is late, the plugin ends the reply once the sound has run out, so your agent hears the next question.
Options
chatfx.AvatarSession(
avatar_id="chatfx-lois",
api_key=None, # defaults to CHATFX_AVATAR_API_KEY
api_url=None, # defaults to https://api.chatfx.com
avatar_participant_identity="chatfx-avatar",
avatar_participant_name="ChatFX",
face_first_seconds=10.0, # how long start() waits for the face
start_timeout=300.0, # how long to keep trying while a GPU wakes
quiet_seconds=120.0, # end the call after this long with nobody talking (None: never)
visitor_gone_seconds=120.0, # end the call this long after the last visitor leaves (None: never)
longest_call_seconds=3600.0, # end the call at this length (None: never)
end_call_when_idle=True, # False: only the avatar leaves, and your agent carries on by voice
waiting_picture=True, # show the avatar's picture until the live face is ready
waiting_text="Video starting...", # the words on it, in your language (None: no words)
)
avatar.start() also takes livekit_url, livekit_api_key and livekit_api_secret if you'd rather not use the settings.
We recommend "interruption": {"min_words": 1} in your session's turn handling. The avatar's sound can't pause and carry on,
so a false alarm would otherwise cut a reply off for good.
Optional: make the face appear sooner
The plugin starts waking the GPU as soon as a call begins, which takes about 11 seconds. To start even earlier, call warm() from your website's server when a visitor
is about to start a call, and again every 20 seconds while they get ready. It's free. Your website's server then needs the key
in its environment variables too. Never put the key in a web page.
await chatfx.warm()
Or without Python:
curl -X POST https://api.chatfx.com/v1/warm -H "Authorization: Bearer $CHATFX_AVATAR_API_KEY"
If you build your own call screen
Your agent's participant attribute chatfx-face says where the face is: waking, voice, on or off. In the agent,
avatar.face_status says the same. You don't need either to get the waiting picture.
When there's no face
A refusal doesn't stop the call. The log says why, and avatar.failure is a chatfx.ChatFXException with the API's code
(for example invalid_api_key, avatar_not_found, premium_avatar, out_of_minutes) and a plain message. A missing key or
missing LiveKit setting raises right away, so you find it while setting up.
Docs
Connecting your agent · Building avatars · Minutes and plans
Metadata
Release files for livekit-plugins-chatfx 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| livekit_plugins_chatfx-0.1.0.tar.gz | 16.5 kB | Without provenance | Details for livekit_plugins_chatfx-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| livekit_plugins_chatfx-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for livekit_plugins_chatfx-0.1.0-py3-none-any.whl |
Total release size: 29.9 kB
Release files / livekit_plugins_chatfx-0.1.0.tar.gz
| Download URL | livekit_plugins_chatfx-0.1.0.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fe5fdf52e988c866de1c9bd6784251ac0463c95e16e633f06d6840792fa54a76
|
|
BLAKE2b-256 checksum How to use checksums |
6de63f71dc66dbcd576ffcf4ce6e21eca3092e3dd7eaca3f3a08062bee2f5f25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / livekit_plugins_chatfx-0.1.0-py3-none-any.whl
| Download URL | livekit_plugins_chatfx-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f261a34e9e00e7877f6abbaa2360d0a3d1fb03967e196bf12195b65e2fa34ba5
|
|
BLAKE2b-256 checksum How to use checksums |
0e8540ceda966c3b72878e3c7e92e57552039fe23a8a15dc790329ef0a0cee3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Security for livekit-plugins-chatfx 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.