Overview
LemonSlice provides realtime avatars in any style, from lifelike humans to cartoon mascots and animals. You can use the open source LemonSlice integration for LiveKit Agents to seamlessly add virtual avatars to your voice AI app.
Installation
uv add "livekit-agents[lemonslice]~=1.8"
pnpm add @livekit/agents-plugin-lemonslice
Authentication
The LemonSlice plugin requires a LemonSlice API key .
Set LEMONSLICE_API_KEY in your .env file.
Avatar setup
The LemonSlice plugin requires one of three sources to start an avatar session: an image URL set by agent_image_url, an image passed directly as agent_image, or an agent ID set by agent_id. Only one of these parameters can be configured.
Agent image URL
The LemonSlice plugin accepts a source image URL from which to generate the avatar. The avatars render as 368x560 pixel videos. LemonSlice will automatically center-crop your image to the target aspect ratio if the dimensions do not match the expected values. LemonSlice supports a wide range of faces, from humanoid to animal, and styles from photorealistic to animated. Best results are achieved with anthropomorphic images where the face and mouth are clearly identifiable. The image URL must be publicly accessible and return an image/* content type.
Agent image
To use an image you generate or already have on hand, pass it as agent_image instead of hosting it at a URL. The plugin uploads the image to LemonSlice directly. The same image guidance as Agent image URL applies: best results come from anthropomorphic images with a clearly identifiable face and mouth.
In Python, pass a PIL Image. Pillow ships with the plugin, so you don't need to install it separately.
In Node.js, pass either a path to a local file or a Buffer of raw image bytes. The plugin supports PNG, JPEG, and WebP. Given a path, the plugin reads the file and infers the type from the extension. Given a Buffer, the plugin assumes PNG, so set agentImageMimeType when the bytes are JPEG or WebP.
from pathlib import Pathfrom PIL import Imageavatar = lemonslice.AvatarSession(agent_image=Image.open(Path(__file__).parent / "avatar.jpg"),agent_prompt="Be expressive in your movements and use your hands while talking.",)
import { dirname, join } from 'node:path';import { fileURLToPath } from 'node:url';import * as lemonslice from '@livekit/agents-plugin-lemonslice';const avatar = new lemonslice.AvatarSession({agentImage: join(dirname(fileURLToPath(import.meta.url)), 'avatar.jpg'),agentPrompt: 'Be expressive in your movements and use your hands while talking.',});
Agent ID
To use an existing LemonSlice agent as your avatar, set the agent_id in AvatarSession. You can find the agent ID in the LemonSlice agent dashboard . You can also create new LemonSlice agents through the agent creation flow by specifying an image.
LiveKit TTS settings will supersede selected voices and personalities configured for the LemonSlice agent.
Usage
Use the plugin in an AgentSession. For example, you can use this avatar in the Voice AI quickstart.
from livekit import agentsfrom livekit.agents import AgentServer, AgentSessionfrom livekit.plugins import lemonsliceserver = AgentServer()@server.rtc_session(agent_name="my-agent")async def my_agent(ctx: agents.JobContext):session = AgentSession(# ... stt, llm, tts, etc.)avatar = lemonslice.AvatarSession(# Publicly accessible image URL for the avataragent_image_url="...",# Prompt to guide the avatar's movementsagent_prompt="Be expressive in your movements and use your hands while talking.")# Start the avatar and wait for it to joinawait avatar.start(session, room=ctx.room)# Start your agent session with the userawait session.start(# ... room, agent, room_options, etc....)
import { voice } from '@livekit/agents';import * as lemonslice from '@livekit/agents-plugin-lemonslice';const session = new voice.AgentSession({// Add STT, LLM, TTS, and other components here});const avatar = new lemonslice.AvatarSession({agentImageUrl: 'publicly-accessible-image-url',apiKey: 'your-lemonslice-api-key', // or set LEMONSLICE_API_KEY env var});// Start the avatar and wait for it to joinawait avatar.start(session, room);// Start your agent session with the userawait session.start(// ... room, agent, room_options, etc.);
Preview the avatar in the Agent Console or a frontend starter app that you build.
Parameters
This section describes some of the available parameters. See the plugin reference for a complete list of all available parameters.
agent_image_urlstringPublicly accessible image url for the avatar. See Agent image URL for details.
agent_imageImageThe avatar's source image, supplied directly rather than by URL. Takes a PIL Image. In Node.js this parameter is called agentImage and takes a local file path or a Buffer. See Agent image setup for details.
agent_image_mime_typestringDefault: image/pngMIME type of the image bytes, one of image/png, image/jpeg, or image/webp. Applies only when agentImage is a Buffer, since a file path infers the type from its extension. In Node.js this parameter is called agentImageMimeType, and Python has no equivalent because agent_image always takes a decoded Image.
agent_idstringThe ID of the LemonSlice agent to use. See Agent ID for details.
agent_promptstringA high-level system prompt that subtly influences the avatar's movements, expressions, and emotional demeanor. This prompt is best used to suggest general affect or behavior (e.g., "feel excited" or "look sad") rather than precise or deterministic actions.
agent_idle_promptstringA high-level system prompt that subtly influences the avatar's movements, expressions, and emotional demeanor while the avatar is idle rather than speaking. Takes the same style of general suggestion as agent_prompt.
idle_timeoutintIdle timeout in seconds. The avatar will leave the session if this timeout is hit. Defaults to 60 seconds. If a negative number is provided, the session will have no idle timeout.
Third-party meeting platforms
Send a LemonSlice avatar into a Zoom, Google Meet, Microsoft Teams, or Webex meeting. The avatar joins through a LemonSlice-managed relay that streams the meeting's mixed audio into your agent's STT and publishes the avatar's audio and video into the call.
avatar = lemonslice.AvatarSession(agent_image_url="...",)# Start the avatar and wait for it to joinawait avatar.start(session, room=ctx.room)# Send the avatar into the meetingawait avatar.join_meeting("https://zoom.us/j/123456789?pwd=abcdef",bot_name="Support Agent",listen_to_meeting_chat=True,)# Start the agent session using meeting audio as inputawait session.start(agent=agent,room=ctx.room,room_options=avatar.room_options(),)
const avatar = new lemonslice.AvatarSession({agentImageUrl: 'publicly-accessible-image-url',});// Start the avatar and wait for it to joinawait avatar.start(session, ctx.room);// Send the avatar into the meetingawait avatar.joinMeeting('https://zoom.us/j/123456789?pwd=abcdef', {botName: 'Support Agent',listenToMeetingChat: true,});// Start the agent session using meeting audio as inputawait session.start({agent,room: ctx.room,...avatar.roomOptions(),});
The avatar leaves the meeting when the avatar session closes. To remove the avatar but keep the session active, call leave_meeting (Python) or leaveMeeting (Node.js).
For meeting URL formats by platform and end-to-end examples, see Send your avatar to a Zoom call in the LemonSlice docs.
Meeting parameters
meeting_urlstringURL of the meeting to join.
bot_namestringDisplay name for the avatar in the meeting. LemonSlice assigns a name if you omit this parameter. The chat relay also uses this name to skip the avatar's own messages, and it expects LemonSlice Avatar by default. Set bot_name unless you disable listen_to_meeting_chat. In Node.js this parameter is called botName.
listen_to_meeting_chatbooleanDefault: TrueRelay meeting chat messages into the agent session as user input. Each message interrupts the agent and triggers a reply. The relay skips messages from bot_name. Set to False to ignore meeting chat. In Node.js this parameter is called listenToMeetingChat.
Additional resources
The following resources provide more information about using LemonSlice with LiveKit Agents.