livekit-plugins-boson-avatar 1.8.5__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,180 @@
1
+ **/.vscode
2
+ **/.DS_Store
3
+ .env
4
+
5
+ # Byte-compiled / optimized / DLL files
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+
10
+ # C extensions
11
+ *.so
12
+
13
+ # Distribution / packaging
14
+ .Python
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+
33
+ # PyInstaller
34
+ # Usually these files are written by a python script from a template
35
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
36
+ *.manifest
37
+ *.spec
38
+
39
+ # Installer logs
40
+ pip-log.txt
41
+ pip-delete-this-directory.txt
42
+
43
+ # Unit test / coverage reports
44
+ htmlcov/
45
+ .tox/
46
+ .nox/
47
+ .coverage
48
+ .coverage.*
49
+ .cache
50
+ nosetests.xml
51
+ coverage.xml
52
+ *.cover
53
+ *.py,cover
54
+ .hypothesis/
55
+ .pytest_cache/
56
+ cover/
57
+
58
+ # Translations
59
+ *.mo
60
+ *.pot
61
+
62
+ # Django stuff:
63
+ *.log
64
+ local_settings.py
65
+ db.sqlite3
66
+ db.sqlite3-journal
67
+
68
+ # Flask stuff:
69
+ instance/
70
+ .webassets-cache
71
+
72
+ # Scrapy stuff:
73
+ .scrapy
74
+
75
+ # Sphinx documentation
76
+ docs/_build/
77
+
78
+ # PyBuilder
79
+ .pybuilder/
80
+ target/
81
+
82
+ # Jupyter Notebook
83
+ .ipynb_checkpoints
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ # For a library or package, you might want to ignore these files since the code is
91
+ # intended to run in multiple environments; otherwise, check them in:
92
+ # .python-version
93
+
94
+ # pipenv
95
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
97
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
98
+ # install all needed dependencies.
99
+ #Pipfile.lock
100
+
101
+ # poetry
102
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
103
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
104
+ # commonly ignored for libraries.
105
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
106
+ #poetry.lock
107
+
108
+ # pdm
109
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
110
+ #pdm.lock
111
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
112
+ # in version control.
113
+ # https://pdm.fming.dev/#use-with-ide
114
+ .pdm.toml
115
+
116
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
117
+ __pypackages__/
118
+
119
+ # Celery stuff
120
+ celerybeat-schedule
121
+ celerybeat.pid
122
+
123
+ # SageMath parsed files
124
+ *.sage.py
125
+
126
+ # Environments
127
+ .env
128
+ .venv
129
+ env/
130
+ venv/
131
+ ENV/
132
+ env.bak/
133
+ venv.bak/
134
+
135
+ # Spyder project settings
136
+ .spyderproject
137
+ .spyproject
138
+
139
+ # Rope project settings
140
+ .ropeproject
141
+
142
+ # mkdocs documentation
143
+ /site
144
+
145
+ # mypy
146
+ .mypy_cache/
147
+ .dmypy.json
148
+ dmypy.json
149
+
150
+ # trunk
151
+ .trunk/
152
+
153
+ # Pyre type checker
154
+ .pyre/
155
+
156
+ # pytype static type analyzer
157
+ .pytype/
158
+
159
+ # Cython debug symbols
160
+ cython_debug/
161
+
162
+ # PyCharm
163
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
164
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
165
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
166
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
167
+ .idea/
168
+
169
+ node_modules
170
+
171
+ credentials.json
172
+ pyrightconfig.json
173
+ docs/
174
+
175
+ # Database files
176
+ *.db
177
+
178
+
179
+ # Examples for development
180
+ examples/dev/*
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.5
2
+ Name: livekit-plugins-boson-avatar
3
+ Version: 1.8.5
4
+ Summary: Agent Framework plugin for Boson Higgs Audio-Driven Avatar
5
+ Project-URL: Documentation, https://docs.livekit.io
6
+ Project-URL: Website, https://livekit.io/
7
+ Project-URL: Source, https://github.com/livekit/agents
8
+ Author-email: LiveKit <support@livekit.io>
9
+ License-Expression: Apache-2.0
10
+ Keywords: agents,avatar,livekit,realtime,webrtc
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Topic :: Multimedia :: Sound/Audio
17
+ Classifier: Topic :: Multimedia :: Video
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10.0
20
+ Requires-Dist: aiohttp>=3.10
21
+ Requires-Dist: livekit-agents>=1.8.5
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Boson Higgs Avatar plugin for LiveKit Agents
25
+
26
+ Use Boson's Higgs Audio-Driven Avatar as the video output for a LiveKit voice
27
+ agent. This is an Avatar plugin: it composes with your existing voice/LLM
28
+ plugin and does not replace or fork it.
29
+
30
+ The plugin has no dependency on Boson Voice, Boson Audio, or a particular TTS
31
+ provider. Its input is the standard audio output of a LiveKit `AgentSession`,
32
+ so it works with any TTS plugin, realtime model, or custom source that produces
33
+ LiveKit audio frames. Only Avatar rendering and Avatar session lifecycle are
34
+ Boson-specific.
35
+
36
+ ## Installation
37
+
38
+ ```shell
39
+ pip install livekit-plugins-boson-avatar
40
+ ```
41
+
42
+ Set the credentials used by your LiveKit Agent Worker:
43
+
44
+ ```shell
45
+ export BOSON_API_KEY="..."
46
+ export BOSON_AVATAR_API_URL="https://your-avatar-session-service.example/v1"
47
+ export LIVEKIT_URL="wss://..."
48
+ export LIVEKIT_API_KEY="..."
49
+ export LIVEKIT_API_SECRET="..."
50
+ ```
51
+
52
+ The plugin deliberately has no hard-coded provider endpoint. Your application
53
+ or deployment environment supplies the base URL exposed by its Boson Avatar
54
+ deployment/operator. The plugin appends `POST /sessions` when starting an
55
+ Avatar and `DELETE /sessions/{id}` during cleanup, so do not include
56
+ `/sessions` itself in `BOSON_AVATAR_API_URL`.
57
+
58
+ Load the project-scoped Avatar catalog on your application server and use it
59
+ to populate the face picker. The returned `avatar_id` is passed unchanged to
60
+ `AvatarSession`; browser users never need to type or remember it:
61
+
62
+ ```python
63
+ from livekit.plugins import boson_avatar
64
+
65
+
66
+ async def avatar_options():
67
+ # Returns [AvatarInfo(avatar_id="...", name="...")]
68
+ return await boson_avatar.list_avatars()
69
+ ```
70
+
71
+ This calls `GET {BOSON_AVATAR_API_URL}/avatars` with `BOSON_API_KEY`. Keep the
72
+ key server-side and cache the result according to your application's needs.
73
+
74
+ ## Usage
75
+
76
+ Create the voice `AgentSession` with the audio provider of your choice, then
77
+ start the Avatar before starting the agent session:
78
+
79
+ ```python
80
+ from livekit.agents import Agent, AgentSession, JobContext, inference
81
+ from livekit.plugins import boson_avatar
82
+
83
+
84
+ async def entrypoint(ctx: JobContext) -> None:
85
+ await ctx.connect()
86
+
87
+ session = AgentSession(
88
+ stt=inference.STT("deepgram/nova-3"),
89
+ llm=inference.LLM("openai/gpt-4.1-mini"),
90
+ tts=inference.TTS("cartesia/sonic-3"),
91
+ )
92
+ avatar = boson_avatar.AvatarSession(
93
+ avatar_id="your-avatar-id",
94
+ )
95
+
96
+ await avatar.start(session, room=ctx.room)
97
+ await session.start(
98
+ agent=Agent(instructions="You are a helpful assistant."),
99
+ room=ctx.room,
100
+ )
101
+ ```
102
+
103
+ `BOSON_AVATAR_ID` can supply `avatar_id` instead. `AvatarSession` also accepts
104
+ optional `width`, `height`, `max_duration_seconds`,
105
+ `avatar_participant_identity`, `idempotency_key`, and `APIConnectOptions`.
106
+ `max_duration_seconds` must be an integer from 1 through 14400.
107
+
108
+ Inside a LiveKit Agent job, provider-session creation automatically derives a
109
+ stable UUID idempotency key from the LiveKit job ID and Avatar session binding.
110
+ If LiveKit redelivers that job after a worker crash, the plugin recovers the
111
+ existing provider session instead of allocating another one. The standard
112
+ model is one Avatar lifecycle per LiveKit job. If one job intentionally starts
113
+ another Avatar after closing the first, pass a new explicit UUID
114
+ `idempotency_key` for that lifecycle.
115
+
116
+ The `avatar_id` is the value returned by `list_avatars()` behind the Avatar
117
+ selected in your application; end users do not need to type or remember it.
118
+
119
+ The plugin handles the provider API call, LiveKit participant token, PCM data
120
+ stream routing, interruption buffer clears, and provider-session cleanup. A
121
+ developer does not need to call Boson's Avatar REST API or combine voice and
122
+ Avatar responses in an application server. The application server only needs
123
+ its normal responsibility: create a LiveKit room and dispatch the Agent Worker.
124
+
125
+ When started inside a LiveKit job, cleanup is registered automatically. When
126
+ using the plugin in a standalone script or test, open LiveKit's HTTP context and
127
+ close the Avatar explicitly:
128
+
129
+ ```python
130
+ from livekit.agents import utils
131
+
132
+
133
+ async with utils.http_context.open():
134
+ await avatar.start(session, room)
135
+ try:
136
+ # Run the standalone session.
137
+ ...
138
+ finally:
139
+ await avatar.aclose()
140
+ ```
@@ -0,0 +1,117 @@
1
+ # Boson Higgs Avatar plugin for LiveKit Agents
2
+
3
+ Use Boson's Higgs Audio-Driven Avatar as the video output for a LiveKit voice
4
+ agent. This is an Avatar plugin: it composes with your existing voice/LLM
5
+ plugin and does not replace or fork it.
6
+
7
+ The plugin has no dependency on Boson Voice, Boson Audio, or a particular TTS
8
+ provider. Its input is the standard audio output of a LiveKit `AgentSession`,
9
+ so it works with any TTS plugin, realtime model, or custom source that produces
10
+ LiveKit audio frames. Only Avatar rendering and Avatar session lifecycle are
11
+ Boson-specific.
12
+
13
+ ## Installation
14
+
15
+ ```shell
16
+ pip install livekit-plugins-boson-avatar
17
+ ```
18
+
19
+ Set the credentials used by your LiveKit Agent Worker:
20
+
21
+ ```shell
22
+ export BOSON_API_KEY="..."
23
+ export BOSON_AVATAR_API_URL="https://your-avatar-session-service.example/v1"
24
+ export LIVEKIT_URL="wss://..."
25
+ export LIVEKIT_API_KEY="..."
26
+ export LIVEKIT_API_SECRET="..."
27
+ ```
28
+
29
+ The plugin deliberately has no hard-coded provider endpoint. Your application
30
+ or deployment environment supplies the base URL exposed by its Boson Avatar
31
+ deployment/operator. The plugin appends `POST /sessions` when starting an
32
+ Avatar and `DELETE /sessions/{id}` during cleanup, so do not include
33
+ `/sessions` itself in `BOSON_AVATAR_API_URL`.
34
+
35
+ Load the project-scoped Avatar catalog on your application server and use it
36
+ to populate the face picker. The returned `avatar_id` is passed unchanged to
37
+ `AvatarSession`; browser users never need to type or remember it:
38
+
39
+ ```python
40
+ from livekit.plugins import boson_avatar
41
+
42
+
43
+ async def avatar_options():
44
+ # Returns [AvatarInfo(avatar_id="...", name="...")]
45
+ return await boson_avatar.list_avatars()
46
+ ```
47
+
48
+ This calls `GET {BOSON_AVATAR_API_URL}/avatars` with `BOSON_API_KEY`. Keep the
49
+ key server-side and cache the result according to your application's needs.
50
+
51
+ ## Usage
52
+
53
+ Create the voice `AgentSession` with the audio provider of your choice, then
54
+ start the Avatar before starting the agent session:
55
+
56
+ ```python
57
+ from livekit.agents import Agent, AgentSession, JobContext, inference
58
+ from livekit.plugins import boson_avatar
59
+
60
+
61
+ async def entrypoint(ctx: JobContext) -> None:
62
+ await ctx.connect()
63
+
64
+ session = AgentSession(
65
+ stt=inference.STT("deepgram/nova-3"),
66
+ llm=inference.LLM("openai/gpt-4.1-mini"),
67
+ tts=inference.TTS("cartesia/sonic-3"),
68
+ )
69
+ avatar = boson_avatar.AvatarSession(
70
+ avatar_id="your-avatar-id",
71
+ )
72
+
73
+ await avatar.start(session, room=ctx.room)
74
+ await session.start(
75
+ agent=Agent(instructions="You are a helpful assistant."),
76
+ room=ctx.room,
77
+ )
78
+ ```
79
+
80
+ `BOSON_AVATAR_ID` can supply `avatar_id` instead. `AvatarSession` also accepts
81
+ optional `width`, `height`, `max_duration_seconds`,
82
+ `avatar_participant_identity`, `idempotency_key`, and `APIConnectOptions`.
83
+ `max_duration_seconds` must be an integer from 1 through 14400.
84
+
85
+ Inside a LiveKit Agent job, provider-session creation automatically derives a
86
+ stable UUID idempotency key from the LiveKit job ID and Avatar session binding.
87
+ If LiveKit redelivers that job after a worker crash, the plugin recovers the
88
+ existing provider session instead of allocating another one. The standard
89
+ model is one Avatar lifecycle per LiveKit job. If one job intentionally starts
90
+ another Avatar after closing the first, pass a new explicit UUID
91
+ `idempotency_key` for that lifecycle.
92
+
93
+ The `avatar_id` is the value returned by `list_avatars()` behind the Avatar
94
+ selected in your application; end users do not need to type or remember it.
95
+
96
+ The plugin handles the provider API call, LiveKit participant token, PCM data
97
+ stream routing, interruption buffer clears, and provider-session cleanup. A
98
+ developer does not need to call Boson's Avatar REST API or combine voice and
99
+ Avatar responses in an application server. The application server only needs
100
+ its normal responsibility: create a LiveKit room and dispatch the Agent Worker.
101
+
102
+ When started inside a LiveKit job, cleanup is registered automatically. When
103
+ using the plugin in a standalone script or test, open LiveKit's HTTP context and
104
+ close the Avatar explicitly:
105
+
106
+ ```python
107
+ from livekit.agents import utils
108
+
109
+
110
+ async with utils.http_context.open():
111
+ await avatar.start(session, room)
112
+ try:
113
+ # Run the standalone session.
114
+ ...
115
+ finally:
116
+ await avatar.aclose()
117
+ ```
@@ -0,0 +1,39 @@
1
+ # Copyright 2026 LiveKit, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Boson Higgs Audio-Driven Avatar plugin for LiveKit Agents."""
16
+
17
+ from livekit.agents import Plugin
18
+
19
+ from .api import AvatarInfo, list_avatars
20
+ from .avatar import AvatarSession
21
+ from .errors import BosonAvatarException
22
+ from .log import logger
23
+ from .version import __version__
24
+
25
+ __all__ = [
26
+ "AvatarInfo",
27
+ "AvatarSession",
28
+ "BosonAvatarException",
29
+ "__version__",
30
+ "list_avatars",
31
+ ]
32
+
33
+
34
+ class BosonAvatarPlugin(Plugin):
35
+ def __init__(self) -> None:
36
+ super().__init__(__name__, __version__, __package__, logger)
37
+
38
+
39
+ Plugin.register_plugin(BosonAvatarPlugin())