I am implementing the warm call transfer but getti...
# ask-ai
g
I am implementing the warm call transfer but getting this issue The error indicates move_participant isn't implemented on the LiveKit server. Checking the warm transfer implementation and available alternatives: The error is that move_participant isn't implemented on the LiveKit server. WarmTransferTask uses this to merge calls, but the server doesn't support it. Checking the implementation and suggesting a fix: WarmTransferTask uses move_participant, which isn't supported by the LiveKit server. Catching this error and falling back to a simpler transfer method that adds the human agent to the same room: Updating the transfer_to_human method to catch the TwirpError and fall back to a simpler transfer that adds the human agent to the same room:
t
Thanks for reaching out, ashutosh. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I looked into the error you reported about
move_participant
. You’re seeing that error because
move_participant
is only available on LiveKit Cloud and is not supported on self‑hosted LiveKit Server. That’s why WarmTransferTask’s call to
move_participant
fails in your environment. What you can do instead • Use a same‑room warm transfer (co‑location): invite/add the human agent into the same room as the caller and AI agent, then hand off conversation state via metadata or client logic. This avoids
move_participant
entirely and works on all LiveKit deployments. • Promote the agent’s role or update participant metadata to indicate the transfer state so clients know who should speak/listen. • If you’re using SIP, create the SIP participant into the same room and preserve caller ID using
sip_number
in
CreateSIPParticipantRequest
. If you want, I can: • Provide a short code snippet to catch the Twirp error and perform the fallback (add agent to the room). • Show an example flow for signaling transfer state with participant metadata or TrackPublication events. Quick question to confirm next steps: are you running LiveKit Cloud or a self‑hosted LiveKit Server? Sources: Managing participants | LiveKit docs | Preserving Caller ID During SIP Transfers in LiveKit Agents
g
Provide a code snipit also the flow
t
Thanks — I’m responding to your request for a code snippet that catches the
move_participant
error and falls back to adding the human agent to the same room, plus a clear transfer flow. Flow (fallback same-room warm transfer) 1. AI and caller are in Room A. 2. AI decides to escalate and notifies the caller: “I will add a human agent.” 3. AI attempts to call
move_participant
(if code tries it). If that fails (not supported), catch the error. 4. Fallback: create or invite the human agent into Room A (e.g., via SIP outbound call or creating a participant for the agent). 5. Wait for human agent to join; update participant metadata/roles to indicate transfer status. 6. Once human is connected, AI either mutes/stops its media or leaves the room (depending on desired UX). 7. Use metadata or TrackPublication events so clients switch focus to the human agent. Minimal Python example (async) — catch TwirpError and fall back to SIP invite into the same room
Copy code
from livekit import api  # replace with your LiveKit API client import
from livekit import twirp_errors  # placeholder for Twirp error types
import os

async def transfer_to_human(job_ctx, session):
    room_name = job_ctx.room.name

    # Optional: try move_participant if your environment might be LiveKit Cloud
    try:
        await job_ctx.api.move_participant(
            api.MoveParticipantRequest(
                room_name=room_name,
                participant_identity=job_ctx.participant.identity,
                target_room="support-room",
            )
        )
        await session.generate_reply(instructions="Transferring you to a support room...")
        return
    except twirp_errors.TwirpError as e:
        # move_participant not implemented on self-hosted servers
        # fall back to same-room transfer
        # (You can narrow by checking e.code or message if needed)
        pass

    # Fallback: create SIP participant (call human into same room)
    try:
        await job_ctx.api.sip.create_sip_participant(
            api.CreateSIPParticipantRequest(
                room_name=room_name,
                sip_trunk_id=os.getenv("HUMAN_SIP_TRUNK_ID"),
                sip_call_to=os.getenv("HUMAN_PHONE_NUMBER"),
                participant_identity="human-support-agent",
                wait_until_answered=True,  # block until human answers (optional)
            )
        )
        await session.generate_reply(instructions="A human agent is joining now.")
    except Exception:
        await session.generate_reply(
            instructions="I couldn't connect a human agent right now. Please hold while I try again or transfer you another way."
        )
Notes and suggestions • Use participant metadata or a
role
field to signal to clients which participant is the human agent and when transfer is complete. • For SIP, set
sip_number
or appropriate fields to preserve caller ID as needed. • If you want the AI to gracefully exit after the human joins, have the AI stop publishing tracks or call a participant update/delete API. If you’d like, I can: • Provide a JavaScript/TypeScript equivalent snippet. • Show example metadata payloads and client-side logic for switching UI to the human agent. Which would you prefer? Sources: Managing participants | LiveKit docs | Agents telephony integration | LiveKit docs | Outbound Calling Script | LiveKit docs