Skip to main content

Documentation Index

Fetch the complete documentation index at: https://lemonslice.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

LiveKit Agents provides a realtime framework for voice, video, and multimodal applications. Our open-source integration lets you add a LemonSlice avatar to your existing agent stack.
Jump to the example code section for ready-to-use starter repos.

Prerequisites

  1. LemonSlice avatar configuration (either a base image URL or a LemonSlice avatar ID)
    • Agent base image — a publicly accessible image URL of your avatar, focused on the face. The image should be 368 × 560 pixels. LemonSlice will automatically center-crop your image to the target aspect ratio if the dimensions do not match the expected values. Best results are achieved with anthropomorphic images where the face and mouth are clearly identifiable.
    • LemonSlice Agent ID
      Selected voices and personalities for a LemonSlice agent will be ignored when using the LiveKit plugin.
  2. LiveKit Agents app

How to use

1

Install the plugin

  1. Within your LiveKit Agents app, install the plugin:
# When using PIP
pip install "livekit-agents[lemonslice]"

# When using UV
uv add "livekit-agents[lemonslice]"
2

Authenticate

  1. Create a LemonSlice API key
  2. In your LiveKit Agents app, set LEMONSLICE_API_KEY in your .env file
3

Add AvatarSession to AgentSession

In your LiveKit Agents app, create a lemonslice.AvatarSession alongside your AgentSession:
from livekit import agents
from livekit.agents import AgentSession, RoomOutputOptions
from livekit.plugins import lemonslice

async def entrypoint(ctx: agents.JobContext):
    await ctx.connect()

    session = AgentSession(
        # Add STT, LLM, TTS, and other components here
    )

    avatar = lemonslice.AvatarSession(
        # Publicly accessible image URL for the avatar
        agent_image_url="...",
        # Prompt to guide the avatar's demeanor
        agent_prompt="a person talking"
    )

    # Start the avatar and wait for it to join
    session_id = await avatar.start(session, room=ctx.room)

    # Start your agent session with the user
    await session.start(
        # ... room, agent, room_options, etc....
    )
Parameters for lemonslice.AvatarSession. Either agent_image_url or agent_id is required.
ParameterDescription
agent_image_urlA URL to an agent image to use.
agent_idThe ID of the LemonSlice agent.
agent_prompt(Optional) A 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 demeanor (for example, “feel excited” or “look sad”) rather than precise or deterministic actions.
agent_idle_prompt(Optional) A high-level system prompt that influences the avatar’s movements, expressions, and emotional demeanor during the idle state.
idle_timeout(Optional) Idle timeout in seconds. Defaults to 60. If a negative number is provided, the session will have no idle timeout.
response_done_timeout(Optional) Time in seconds to wait without receiving new audio bytes before marking the response as complete. Some TTS models do not send an end response event, or do not send it in a timely manner, after transmitting all audio bytes. This parameter enables detection of response completion when such events are missing or delayed.
simulcast(Optional) Enable WebRTC simulcast, which publishes multiple resolutions of the avatar video so subscribers receive the best quality their bandwidth allows. LiveKit rooms only.
When using the Gemini Live S2S model for realtime interactions, set response_done_timeout=0.8 to handle end of responses correctly.If you encounter stutters or glitches with any other TTS, please contact support@lemonslice.com.
4

Hook into Events

Listen to LemonSlice RPC events over the LiveKit data channel to better manage the avatar lifecycle:
LEMONSLICE_RPC_TOPIC = "lemonslice"
AVATAR_READY_MSG_TYPE = "bot_ready"

def on_data_received(packet: rtc.DataPacket) -> None:
    if packet.topic != LEMONSLICE_RPC_TOPIC:
        return

    try:
        payload = json.loads(packet.data.decode("utf-8"))
    except (UnicodeDecodeError, json.JSONDecodeError):
        logger.warning("Unable to decode LemonSlice RPC JSON", exc_info=True)
        return

    if (
        not isinstance(payload, dict)
        or payload.get("type") != AVATAR_READY_MSG_TYPE
    ):
        return

    session_id = payload.get("session_id")
    logger.info(f"Avatar has joined and is ready! session_id = {session_id}")

room.on("data_received", on_data_received)
LemonSlice Events
Event TypeDescription
bot_readyFired when the LemonSlice agent has successfully joined the room and is ready to send and receive audio and video.
idle_timeoutEmitted when the agent stops due to inactivity. The idle timeout threshold is defined by the agent’s configuration.
errorA pipeline-related error occurred. Includes error and fatal fields.
video_generation_errorA failure occurred while generating a video segment.
metricReturned after every avatar response with performance metrics. Includes time_to_first_push (time from receiving the first audio byte to pushing the first generated video frame). If LiveKit/TTS failed to deliver audio in real time, tts_audio_delay will be set to true.
These events are available to both your backend agent and frontend client, allowing you to coordinate avatar state across your entire application.
5

Preview

Preview the avatar in the Agents Playground or refer to one of our end-to-end examples for sample frontend code.
6

Shutdown the LiveKit room

Gracefully shut down the LiveKit room, LiveKit agent, and/or LemonSlice avatar session:
  1. Call ctx.room.disconnect() to close the LiveKit room connection which will end the LemonSlice avatar session.
  2. Call ctx.shutdown() to stop the Agent’s JobContext and the LemonSlice avatar session if you don’t want to shutdown the LiveKit room.
  3. Call the session control endpoint with the terminate event to shutdown only the LemonSlice avatar without shutting down the LiveKit room or agent.
where ctx is LiveKit’s agents.JobContext defined by the function annotated with @server.rtc_session()
PYTHON
@server.rtc_session()
async def my_agent(ctx: agents.JobContext):
  ...
If the LemonSlice session is not shut down, the LemonSlice session will remain active until the configured idle timeout is reached or the 1-hour maximum session duration expires.

Example Code

RepoWhat’s included
02-livekit-playground-demoStarter code to launch a LiveKit agent with the LemonSlice avatar plugin. Run your agent locally and connect in the LiveKit playground for rapid prototyping
03-livekit-app-pythonFullstack web app using the LiveKit Python SDK. Includes LiveKit Agent + LemonSlice code, front-end UI, and backend token server.
04-livekit-app-nodejsFullstack web app using the LiveKit Node.js SDK. Includes LiveKit Agent + LemonSlice code, front-end UI, and backend token server.