rapid-honey-43838
03/07/2026, 11:48 PMtall-airline-16756
03/07/2026, 11:49 PMtall-airline-16756
03/07/2026, 11:49 PMsession.say() or session.generate_reply() and then await the returned SpeechHandle’s playout completion (use wait_for_playout() / waitForPlayout()) before calling the SIP transfer. That guarantees the audio finishes before the call is connected to the agent.
Why this works
• session.say() / session.generate_reply() return a SpeechHandle. Calling await handle.wait_for_playout() ensures the spoken audio is delivered completely to the participant. If you don’t await it, the transfer will run immediately and cut off playback.
Examples
1) Python
handle = session.generate_reply(instructions="Please hold while I connect you to an agent.")
await handle.wait_for_playout() # wait until playback finishes
await job_ctx.api.sip.transfer_sip_participant(
api.TransferSIPParticipantRequest(
room_name=job_ctx.room.name,
participant_identity=caller_identity,
transfer_to=f"tel:{human_agent_number}",
)
)
2) Node.js / TypeScript
const handle = session.generateReply({ instructions: 'Please hold while I connect you to an agent.' });
await handle.waitForPlayout(); // wait until playback finishes
await jobCtx.room.sipTransferParticipant({ transferTo: `tel:${humanAgentNumber}` });
Additional notes
• You do not need to change interruption settings just to ensure playout completes — sequencing the play + await + transfer is sufficient.
• If you want to support cancelling the transfer while the message plays (e.g., agent becomes available earlier), you can keep a reference to the SpeechHandle and cancel or check its state before transfer.
If you’d like, tell me which SDK (Python, Node, or another) and I can provide a copy-paste-ready snippet integrated into your transfer flow.
Sources: Agent speech and audio | LiveKit Documentation | How to detect when an agent has finished speaking | LiveKit