Skip to main content
LemonSlice provides real-time interactive AI avatars with synchronized lip-sync. Add a self-managed video avatar to your agent that speaks with natural movements and expressions.
Vision Agents requires a Stream account for real-time transport. Most providers offer free tiers to get started.

Installation

uv add "vision-agents[lemonslice]"

Quick start

from vision_agents.core import Agent, User
from vision_agents.plugins import cartesia, deepgram, getstream, gemini, lemonslice

agent = Agent(
    edge=getstream.Edge(),
    agent_user=User(name="Assistant", id="agent"),
    instructions="You're a friendly AI assistant.",
    llm=gemini.LLM(),
    tts=cartesia.TTS(),
    stt=deepgram.STT(),
    processors=[
        lemonslice.LemonSliceAvatarPublisher(
            agent_id="your-avatar-id",
        )
    ],
)
Set the following environment variables:
  • LEMONSLICE_API_KEY - Your LemonSlice API key
  • LIVEKIT_URL - Your LiveKit server URL (e.g., wss://your-server.livekit.cloud)
  • LIVEKIT_API_KEY - Your LiveKit API key
  • LIVEKIT_API_SECRET - Your LiveKit API secret

Parameters

NameTypeDefaultDescription
agent_idstrNoneLemonSlice agent ID (from dashboard)
agent_image_urlstrNoneCustom avatar image URL (368x560px) - alternative to agent_id
agent_promptstrNonePrompt to influence avatar expressions and movements
idle_timeoutintNoneSeconds before an idle session is closed
api_keystrNoneAPI key (defaults to LEMONSLICE_API_KEY env var)
livekit_urlstrNoneLiveKit server URL (defaults to LIVEKIT_URL env var)
livekit_api_keystrNoneLiveKit API key (defaults to LIVEKIT_API_KEY env var)
livekit_api_secretstrNoneLiveKit API secret (defaults to LIVEKIT_API_SECRET env var)
widthint1920Output video width in pixels
heightint1080Output video height in pixels

How it works

The avatar works differently depending on your LLM type: With standard LLMs
  1. LLM generates text → TTS converts to audio → Audio sent to LemonSlice → LemonSlice generates synchronized avatar video and audio
With Realtime LLMs
  1. Realtime LLM generates audio → Audio sent to LemonSlice → LemonSlice generates video only (audio from LLM)
# With Gemini Realtime
agent = Agent(
    llm=gemini.Realtime(),
    processors=[lemonslice.LemonSliceAvatarPublisher(agent_id="your-avatar-id")],
)

Custom avatar image

Instead of using a pre-configured agent ID, you can provide a custom avatar image:
lemonslice.LemonSliceAvatarPublisher(
    agent_image_url="https://example.com/avatar.png",  # 368x560px recommended
    agent_prompt="A friendly customer service representative",
)

Next steps