mammoth-shoe-93270
07/28/2025, 10:13 AMtall-airline-16756
07/28/2025, 10:13 AMtall-airline-16756
07/28/2025, 10:13 AMallow_interruptions=False when generating the goodbye message to prevent interruptions. Await the message generation to ensure it completes before proceeding. For example:
@function_tool
async def story_finished(self, context: RunContext[StoryData]):
self.session.interrupt()
await self.session.generate_reply(
instructions=f"say goodbye to {context.userdata.name}",
allow_interruptions=False
)
job_ctx = get_job_context()
await job_ctx.api.room.delete_room(api.DeleteRoomRequest(room=job_ctx.room.name))
1. Wait for Current Speech to Complete: If there is ongoing speech, wait for it to finish before proceeding with the hangup. For example:
@function_tool
async def end_call(self, ctx: RunContext):
current_speech = ctx.session.current_speech
if current_speech:
await current_speech.wait_for_playout()
await hangup_call()
1. Proper Session Drainage: Use session.drain() before closing to ensure all pending audio is processed. For example:
@function_tool
async def end_session(self):
await self.session.drain()
await self.session.aclose()
1. Avoid Premature Task Creation: Do not create the close task immediately after generating the reply. Instead, await the reply first. For example:
@function_tool
async def goodbye(self):
await self.session.generate_reply(instructions="instructions:say goodbye to the user")
self._close_session_task = asyncio.create_task(self.session.aclose())
By following these steps, you can ensure the goodbye message is fully delivered before the session ends.
Sources: Community & Support | livekit/livekit_composite | DeepWiki | examples/voice_agents/session_close_callback.py | Agents telephony integration | LiveKit Docs | basics/exit_message.py | Community & Support | livekit/livekit_composite | DeepWikimammoth-shoe-93270
07/28/2025, 10:46 AMSpeechHandle.wait_for_playout() from inside the function tool end_call that owns this SpeechHandle. This creates a circular wait: the speech handle is waiting for the function tool to complete, while the function tool is simultaneously waiting for the speech handle.tall-airline-16756
07/28/2025, 10:47 AMSpeechHandle.wait_for_playout() inside the same function that owns the speech handle, you're accidentally creating a circular dependency - kind of like getting tangled up in your own code. 😅
The good news? There's a super simple fix! Just switch to using RunContext.wait_for_playout(), which lets you wait for the assistant's response without causing any technical headaches. Think of it like taking a quick pause to make sure everything's in sync.
Here's how you can update your code to work perfectly:
async def my_function_tool(ctx: RunContext) -> str:
# Wait for the assistant's spoken response prior to running this tool
await ctx.wait_for_playout() # ✅ Correct approach
# Your tool logic here
return "Tool completed"
By using RunContext.wait_for_playout(), you'll ensure your function tool runs smoothly, without any pesky circular wait issues. Hope this helps make your coding journey a bit easier! 🌟
Sources: livekit-agents/livekit/agents/voice/background_audio.py