|
| 1 | +# LiveKit Agents Plugin for SpatialReal Avatar |
| 2 | + |
| 3 | +This plugin provides integration with [SpatialReal](https://www.spatialreal.ai/)'s avatar service for lip-synced avatar rendering in LiveKit voice agents. |
| 4 | + |
| 5 | +## Installation |
| 6 | + |
| 7 | +```bash |
| 8 | +pip install livekit-plugins-spatialreal |
| 9 | +``` |
| 10 | + |
| 11 | +## Configuration |
| 12 | + |
| 13 | +Set the following environment variables: |
| 14 | + |
| 15 | +```bash |
| 16 | +SPATIALREAL_API_KEY=your-api-key |
| 17 | +SPATIALREAL_APP_ID=your-app-id |
| 18 | +SPATIALREAL_AVATAR_ID=your-avatar-id |
| 19 | + |
| 20 | +LIVEKIT_URL= |
| 21 | +LIVEKIT_API_KEY= |
| 22 | +LIVEKIT_API_SECRET= |
| 23 | +``` |
| 24 | + |
| 25 | +## Usage |
| 26 | + |
| 27 | +```python |
| 28 | +from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions |
| 29 | +from livekit.plugins import spatialreal |
| 30 | + |
| 31 | +class VoiceAssistant(Agent): |
| 32 | + def __init__(self): |
| 33 | + super().__init__( |
| 34 | + instructions="You are a helpful voice assistant." |
| 35 | + ) |
| 36 | + |
| 37 | +async def entrypoint(ctx: JobContext): |
| 38 | + await ctx.connect() |
| 39 | + |
| 40 | + # Configure your pipeline components (STT, LLM, TTS) |
| 41 | + session = AgentSession( |
| 42 | + stt=stt, |
| 43 | + llm=llm, |
| 44 | + tts=tts, |
| 45 | + ) |
| 46 | + |
| 47 | + # Initialize and start the avatar session |
| 48 | + avatar = spatialreal.AvatarSession() |
| 49 | + await avatar.start(session, room=ctx.room) |
| 50 | + |
| 51 | + # Start the agent session |
| 52 | + await session.start( |
| 53 | + agent=VoiceAssistant(), |
| 54 | + room=ctx.room, |
| 55 | + ) |
| 56 | + |
| 57 | +if __name__ == "__main__": |
| 58 | + cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint)) |
| 59 | +``` |
| 60 | + |
| 61 | +For production agents, catch `SpatialRealException` so you can decide whether to fail the job or continue without avatar output: |
| 62 | + |
| 63 | +```python |
| 64 | +try: |
| 65 | + await avatar.start(session, room=ctx.room) |
| 66 | +except spatialreal.SpatialRealException as err: |
| 67 | + logger.error("Avatar startup failed: %s", err) |
| 68 | + raise |
| 69 | +``` |
| 70 | + |
| 71 | +## API Reference |
| 72 | + |
| 73 | +### `AvatarSession` |
| 74 | + |
| 75 | +Main class for integrating SpatialReal avatars with LiveKit agents. |
| 76 | + |
| 77 | +#### Constructor Parameters |
| 78 | + |
| 79 | +| Parameter | Type | Description | |
| 80 | +|-----------|------|-------------| |
| 81 | +| `api_key` | `str` | SpatialReal API key (or set `SPATIALREAL_API_KEY`) | |
| 82 | +| `app_id` | `str` | SpatialReal application ID (or set `SPATIALREAL_APP_ID`) | |
| 83 | +| `avatar_id` | `str` | Avatar ID to use (or set `SPATIALREAL_AVATAR_ID`) | |
| 84 | +| `console_endpoint_url` | `str` | Custom console endpoint URL | |
| 85 | +| `ingress_endpoint_url` | `str` | Custom ingress endpoint URL | |
| 86 | +| `avatar_participant_identity` | `str` | LiveKit identity for avatar participant | |
| 87 | +| `idle_timeout_seconds` | `int` | LiveKit egress idle timeout in seconds (`0` uses server defaults) | |
| 88 | +| `sample_rate` | `int \| None` | Optional avatar audio sample rate override | |
| 89 | + |
| 90 | +#### Methods |
| 91 | + |
| 92 | +- `start(agent_session, room, *, livekit_url, livekit_api_key, livekit_api_secret)`: Start the avatar session and hook into the agent's audio output. Raises `SpatialRealException` with actionable context if startup fails. |
| 93 | +- `aclose()`: Clean up avatar session resources. |
| 94 | + |
| 95 | +When starting, the plugin automatically sets `lk.publish_on_behalf` to the |
| 96 | +agent participant identity for avatar worker association in LiveKit frontends. |
| 97 | + |
| 98 | +### `SpatialRealException` |
| 99 | + |
| 100 | +Exception raised for SpatialReal-related errors. |
| 101 | + |
| 102 | +## License |
| 103 | + |
| 104 | +MIT |
0 commit comments