livekit-plugins-chatfx 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ .pytest_cache/
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.5
2
+ Name: livekit-plugins-chatfx
3
+ Version: 0.1.0
4
+ Summary: ChatFX Avatar for LiveKit Agents: a real-time talking face for your voice agent
5
+ Project-URL: Homepage, https://chatfx.com/avatar/
6
+ Project-URL: Documentation, https://chatfx.com/support/avatar-connect/
7
+ Author-email: "ChatRep, Inc." <service@chatfx.com>
8
+ License-Expression: Apache-2.0
9
+ Keywords: agents,avatar,chatfx,livekit,realtime,voice
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Multimedia :: Video
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: aiohttp>=3.9
16
+ Requires-Dist: livekit-agents>=1.2
17
+ Requires-Dist: pillow>=10.1
18
+ Description-Content-Type: text/markdown
19
+
20
+ # ChatFX Avatar for LiveKit Agents
21
+
22
+ A real-time talking face for your LiveKit voice agent. The avatar joins your agent's LiveKit Cloud room as one more
23
+ participant, takes your agent's voice and speaks it with its lips in time, shown as your agent. You keep your own
24
+ listening, AI and voice; ChatFX adds the face, billed by the minute.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install livekit-plugins-chatfx
30
+ ```
31
+
32
+ Requires Python 3.10+ and `livekit-agents` 1.2 or newer.
33
+
34
+ ## Add your key
35
+
36
+ Create a key under **API keys** at [avatar.chatfx.com](https://avatar.chatfx.com). Then add it to your voice agent's secrets
37
+ at LiveKit, named exactly `CHATFX_AVATAR_API_KEY`. In your agent's folder:
38
+
39
+ ```bash
40
+ lk agent update-secrets --secrets "CHATFX_AVATAR_API_KEY=cfx_..."
41
+ ```
42
+
43
+ Running your agent on your own server instead? Add the key to that server's environment variables, with the same name.
44
+
45
+ Your agent also needs `LIVEKIT_URL`, `LIVEKIT_API_KEY` and `LIVEKIT_API_SECRET`, which it already has. They never leave your
46
+ server.
47
+
48
+ ## Use it
49
+
50
+ In your agent's entrypoint, after you make the `AgentSession` and before `session.start()`:
51
+
52
+ ```python
53
+ from livekit.plugins import chatfx
54
+
55
+ avatar = chatfx.AvatarSession(avatar_id="chatfx-lois") # copy the id from the Avatars page
56
+ await avatar.start(session, room=ctx.room)
57
+
58
+ await session.start(agent=MyAgent(), room=ctx.room)
59
+ ```
60
+
61
+ That's all the code. When the job ends, the session ends too, so billing stops. To end it earlier, call
62
+ `await avatar.aclose()`.
63
+
64
+ ## What it does for you
65
+
66
+ - **Shows a waiting picture, with nothing to add to your page.** The moment a call starts, your agent shows the avatar's picture
67
+ as its own video, with "Video starting..." on it, and the live face takes over when it's ready. Any page that shows the
68
+ agent's video gets this.
69
+ - **Greets with the face.** `start()` waits up to 10 seconds for the face, so your agent's first words come with it.
70
+ - **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.
71
+ - **Never depends on the face.** If the face can't come, or leaves mid-call, your agent carries on by voice.
72
+ - **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.
73
+ - **Stops forgotten calls**, so they don't use your minutes: after 2 minutes with nobody talking, 2 minutes after the visitor
74
+ leaves (long enough for a page reload), or at 1 hour.
75
+ - **Can't go deaf.** If the face's "finished talking" message is late, the plugin ends the reply once the sound has run out,
76
+ so your agent hears the next question.
77
+
78
+ ## Options
79
+
80
+ ```python
81
+ chatfx.AvatarSession(
82
+ avatar_id="chatfx-lois",
83
+ api_key=None, # defaults to CHATFX_AVATAR_API_KEY
84
+ api_url=None, # defaults to https://api.chatfx.com
85
+ avatar_participant_identity="chatfx-avatar",
86
+ avatar_participant_name="ChatFX",
87
+ face_first_seconds=10.0, # how long start() waits for the face
88
+ start_timeout=300.0, # how long to keep trying while a GPU wakes
89
+ quiet_seconds=120.0, # end the call after this long with nobody talking (None: never)
90
+ visitor_gone_seconds=120.0, # end the call this long after the last visitor leaves (None: never)
91
+ longest_call_seconds=3600.0, # end the call at this length (None: never)
92
+ end_call_when_idle=True, # False: only the avatar leaves, and your agent carries on by voice
93
+ waiting_picture=True, # show the avatar's picture until the live face is ready
94
+ waiting_text="Video starting...", # the words on it, in your language (None: no words)
95
+ )
96
+ ```
97
+
98
+ `avatar.start()` also takes `livekit_url`, `livekit_api_key` and `livekit_api_secret` if you'd rather not use the settings.
99
+
100
+ We recommend `"interruption": {"min_words": 1}` in your session's turn handling. The avatar's sound can't pause and carry on,
101
+ so a false alarm would otherwise cut a reply off for good.
102
+
103
+ ## Optional: make the face appear sooner
104
+
105
+ 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
106
+ 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
107
+ in its environment variables too. Never put the key in a web page.
108
+
109
+ ```python
110
+ await chatfx.warm()
111
+ ```
112
+
113
+ Or without Python:
114
+
115
+ ```bash
116
+ curl -X POST https://api.chatfx.com/v1/warm -H "Authorization: Bearer $CHATFX_AVATAR_API_KEY"
117
+ ```
118
+
119
+ ## If you build your own call screen
120
+
121
+ Your agent's participant attribute `chatfx-face` says where the face is: `waking`, `voice`, `on` or `off`. In the agent,
122
+ `avatar.face_status` says the same. You don't need either to get the waiting picture.
123
+
124
+ ## When there's no face
125
+
126
+ A refusal doesn't stop the call. The log says why, and `avatar.failure` is a `chatfx.ChatFXException` with the API's `code`
127
+ (for example `invalid_api_key`, `avatar_not_found`, `premium_avatar`, `out_of_minutes`) and a plain message. A missing key or
128
+ missing LiveKit setting raises right away, so you find it while setting up.
129
+
130
+ ## Docs
131
+
132
+ [Connecting your agent](https://chatfx.com/support/avatar-connect/) · [Building avatars](https://chatfx.com/support/avatar-builder/) · [Minutes and plans](https://chatfx.com/support/avatar-billing/)
@@ -0,0 +1,113 @@
1
+ # ChatFX Avatar for LiveKit Agents
2
+
3
+ A real-time talking face for your LiveKit voice agent. The avatar joins your agent's LiveKit Cloud room as one more
4
+ participant, takes your agent's voice and speaks it with its lips in time, shown as your agent. You keep your own
5
+ listening, AI and voice; ChatFX adds the face, billed by the minute.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install livekit-plugins-chatfx
11
+ ```
12
+
13
+ Requires Python 3.10+ and `livekit-agents` 1.2 or newer.
14
+
15
+ ## Add your key
16
+
17
+ Create a key under **API keys** at [avatar.chatfx.com](https://avatar.chatfx.com). Then add it to your voice agent's secrets
18
+ at LiveKit, named exactly `CHATFX_AVATAR_API_KEY`. In your agent's folder:
19
+
20
+ ```bash
21
+ lk agent update-secrets --secrets "CHATFX_AVATAR_API_KEY=cfx_..."
22
+ ```
23
+
24
+ Running your agent on your own server instead? Add the key to that server's environment variables, with the same name.
25
+
26
+ Your agent also needs `LIVEKIT_URL`, `LIVEKIT_API_KEY` and `LIVEKIT_API_SECRET`, which it already has. They never leave your
27
+ server.
28
+
29
+ ## Use it
30
+
31
+ In your agent's entrypoint, after you make the `AgentSession` and before `session.start()`:
32
+
33
+ ```python
34
+ from livekit.plugins import chatfx
35
+
36
+ avatar = chatfx.AvatarSession(avatar_id="chatfx-lois") # copy the id from the Avatars page
37
+ await avatar.start(session, room=ctx.room)
38
+
39
+ await session.start(agent=MyAgent(), room=ctx.room)
40
+ ```
41
+
42
+ That's all the code. When the job ends, the session ends too, so billing stops. To end it earlier, call
43
+ `await avatar.aclose()`.
44
+
45
+ ## What it does for you
46
+
47
+ - **Shows a waiting picture, with nothing to add to your page.** The moment a call starts, your agent shows the avatar's picture
48
+ as its own video, with "Video starting..." on it, and the live face takes over when it's ready. Any page that shows the
49
+ agent's video gets this.
50
+ - **Greets with the face.** `start()` waits up to 10 seconds for the face, so your agent's first words come with it.
51
+ - **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.
52
+ - **Never depends on the face.** If the face can't come, or leaves mid-call, your agent carries on by voice.
53
+ - **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.
54
+ - **Stops forgotten calls**, so they don't use your minutes: after 2 minutes with nobody talking, 2 minutes after the visitor
55
+ leaves (long enough for a page reload), or at 1 hour.
56
+ - **Can't go deaf.** If the face's "finished talking" message is late, the plugin ends the reply once the sound has run out,
57
+ so your agent hears the next question.
58
+
59
+ ## Options
60
+
61
+ ```python
62
+ chatfx.AvatarSession(
63
+ avatar_id="chatfx-lois",
64
+ api_key=None, # defaults to CHATFX_AVATAR_API_KEY
65
+ api_url=None, # defaults to https://api.chatfx.com
66
+ avatar_participant_identity="chatfx-avatar",
67
+ avatar_participant_name="ChatFX",
68
+ face_first_seconds=10.0, # how long start() waits for the face
69
+ start_timeout=300.0, # how long to keep trying while a GPU wakes
70
+ quiet_seconds=120.0, # end the call after this long with nobody talking (None: never)
71
+ visitor_gone_seconds=120.0, # end the call this long after the last visitor leaves (None: never)
72
+ longest_call_seconds=3600.0, # end the call at this length (None: never)
73
+ end_call_when_idle=True, # False: only the avatar leaves, and your agent carries on by voice
74
+ waiting_picture=True, # show the avatar's picture until the live face is ready
75
+ waiting_text="Video starting...", # the words on it, in your language (None: no words)
76
+ )
77
+ ```
78
+
79
+ `avatar.start()` also takes `livekit_url`, `livekit_api_key` and `livekit_api_secret` if you'd rather not use the settings.
80
+
81
+ We recommend `"interruption": {"min_words": 1}` in your session's turn handling. The avatar's sound can't pause and carry on,
82
+ so a false alarm would otherwise cut a reply off for good.
83
+
84
+ ## Optional: make the face appear sooner
85
+
86
+ 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
87
+ 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
88
+ in its environment variables too. Never put the key in a web page.
89
+
90
+ ```python
91
+ await chatfx.warm()
92
+ ```
93
+
94
+ Or without Python:
95
+
96
+ ```bash
97
+ curl -X POST https://api.chatfx.com/v1/warm -H "Authorization: Bearer $CHATFX_AVATAR_API_KEY"
98
+ ```
99
+
100
+ ## If you build your own call screen
101
+
102
+ Your agent's participant attribute `chatfx-face` says where the face is: `waking`, `voice`, `on` or `off`. In the agent,
103
+ `avatar.face_status` says the same. You don't need either to get the waiting picture.
104
+
105
+ ## When there's no face
106
+
107
+ A refusal doesn't stop the call. The log says why, and `avatar.failure` is a `chatfx.ChatFXException` with the API's `code`
108
+ (for example `invalid_api_key`, `avatar_not_found`, `premium_avatar`, `out_of_minutes`) and a plain message. A missing key or
109
+ missing LiveKit setting raises right away, so you find it while setting up.
110
+
111
+ ## Docs
112
+
113
+ [Connecting your agent](https://chatfx.com/support/avatar-connect/) · [Building avatars](https://chatfx.com/support/avatar-builder/) · [Minutes and plans](https://chatfx.com/support/avatar-billing/)
@@ -0,0 +1,37 @@
1
+ """ChatFX Avatar for LiveKit Agents.
2
+
3
+ A real-time talking face for your voice agent. The avatar joins your agent's LiveKit room as one more participant, takes
4
+ your agent's voice and speaks it with its lips in time, shown as your agent.
5
+
6
+ from livekit.plugins import chatfx
7
+
8
+ avatar = chatfx.AvatarSession(avatar_id="chatfx-lois") # your key in CHATFX_AVATAR_API_KEY
9
+ await avatar.start(session, room=ctx.room)
10
+
11
+ Docs: https://chatfx.com/support/avatar-connect/
12
+ """
13
+
14
+ from livekit.agents import Plugin
15
+
16
+ from .avatar import AvatarSession, ChatFXException, warm
17
+ from .log import logger
18
+ from .version import __version__
19
+
20
+ __all__ = ["AvatarSession", "ChatFXException", "warm", "__version__"]
21
+
22
+
23
+ class ChatFXPlugin(Plugin):
24
+ def __init__(self) -> None:
25
+ super().__init__(__name__, __version__, __package__, logger)
26
+
27
+
28
+ Plugin.register_plugin(ChatFXPlugin())
29
+
30
+ # Cleanup docs of unexported modules
31
+ _module = dir()
32
+ NOT_IN_ALL = [m for m in _module if m not in __all__]
33
+
34
+ __pdoc__ = {}
35
+
36
+ for n in NOT_IN_ALL:
37
+ __pdoc__[n] = False