Skip to content

LiveKit Agents

Use Runway Characters with LiveKit Agents to build fully custom conversational experiences where you control the entire pipeline. Your agent handles speech-to-text, language model, and text-to-speech. Runway provides the visual layer: audio in, avatar video out.

You’ll need:

  1. Install the plugin

    Terminal window
    pip install livekit-plugins-runway

    Set the following in your .env file:

    Terminal window
    RUNWAYML_API_SECRET=...
    LIVEKIT_URL=...
    LIVEKIT_API_KEY=...
    LIVEKIT_API_SECRET=...
    GOOGLE_API_KEY=...
  2. Add AvatarSession to your agent

    agent_worker.py
    from dotenv import load_dotenv
    from livekit.agents import Agent, AgentServer, AgentSession, JobContext, cli
    from livekit.plugins import google, runway
    load_dotenv()
    server = AgentServer()
    @server.rtc_session()
    async def entrypoint(ctx: JobContext):
    session = AgentSession(
    llm=google.realtime.RealtimeModel(voice="kore"),
    )
    avatar = runway.AvatarSession(
    preset_id="cat-character",
    )
    await avatar.start(session, room=ctx.room)
    await session.start(
    agent=Agent(instructions="Talk to me!"),
    room=ctx.room,
    )
    session.generate_reply(instructions="Say hello to the user.")
    if __name__ == "__main__":
    cli.run_app(server)

    Use avatar_id / avatarId instead of preset_id / presetId to use a custom Character from the Developer Portal.

    See the LiveKit Runway plugin guide for the full list of AvatarSession parameters.

  3. Test it

    Open the LiveKit Agents Playground to preview your agent without building a frontend. Start a conversation and verify the avatar video track appears alongside your agent’s audio.

Runway bills realtime Character sessions while the Runway avatar worker is active. The plugin cancels the Runway realtime session during normal LiveKit job shutdown, so make sure your agent shutdown path runs when the user leaves, your agent disconnects, or your app ends the conversation.

Set max_duration / maxDuration (seconds) in the AvatarSession constructor to cap session length. If the job is force-killed before cleanup runs, the Runway session can continue until this limit.

AvatarSession.start() can fail before the Character joins the LiveKit room, for example if the Runway project has insufficient credits or the session request is invalid. Catch startup errors in your agent and send an application-level message to your frontend so the user does not wait indefinitely for the avatar video track.

try:
await avatar.start(session, room=ctx.room)
except Exception as exc:
print(f"failed to start Runway avatar: {exc}")
raise