flaky-hospital-13625
08/19/2025, 6:13 PMtall-airline-16756
08/19/2025, 6:13 PMtall-airline-16756
08/19/2025, 6:14 PMcreate_sip_participant
method with wait_until_answered=True
to pause until the call is either answered or fails. Wrapping this in a `try`/`except` block lets you catch errors and log SIP status codes and messages — super handy for troubleshooting.
• Create Custom Cleanup Functions: Think about adding a helper like hangup()
to gracefully end calls by deleting the room. Here’s a quick example:
async def hangup(self):
await job_ctx.api.room.delete_room(
api.DeleteRoomRequest(
room=job_ctx.room.name,
)
)
• Detect Voicemail: If you can spot when the call hits voicemail, you can trigger cleanup actions like hanging up right away to keep things tidy.
• Handle Timeouts: Setting up timeouts for inactivity is a smart move — you can then run cleanup tasks to close sessions and delete rooms if no one picks up.
• Clean Up Sessions Properly: Don’t forget to close API connections and free up resources in a cleanup()
method to keep everything running smoothly.
These steps should help you cover all your bases when calls go unanswered or get declined. If you want me to walk you through any part or give you more examples, just let me know — I’m here to help!flaky-hospital-13625
08/19/2025, 6:44 PMtall-airline-16756
08/19/2025, 6:45 PMctx.add_shutdown_callback()
to register a cleanup function that kicks in whenever the session ends for any reason. Here’s a quick example:
async def entrypoint(ctx: JobContext):
async def my_shutdown_hook():
<http://logger.info|logger.info>("Performing cleanup tasks")
# Your cleanup code here
ctx.add_shutdown_callback(my_shutdown_hook)
• Session Close Event: Another way is to listen for the session’s on("close")
event and handle cleanup when the session wraps up. Like this:
@session.on("close")
def on_close(ev: CloseEvent):
<http://logger.info|logger.info>(f"Session closed, reason: {ev.reason}")
# Perform cleanup here
• Agent on_exit
Method: You can also define an on_exit
method inside your Agent class to tidy things up when the agent session ends.
• Call Status Monitoring: Keep an eye on the sip.callStatus
attribute to catch different end scenarios like user hangup or timeout.
• Reusable Hangup Function: Consider making a handy helper function like hangup_call()
that deletes the room and ends the call for everyone involved.
Using these approaches will help make sure your cleanup runs smoothly no matter how the call ends. If you want me to walk you through any of these with more details or examples, just let me know—I’m here to help!flaky-hospital-13625
08/19/2025, 6:53 PMtall-airline-16756
08/19/2025, 6:54 PMSIGKILL
or something similar, the shutdown callbacks won’t get a chance to run. Try to make sure your process shuts down gracefully.
• Timeout Exceeded: Shutdown hooks need to finish within the default 60-second timeout. If your callback is taking longer, you can bump up the timeout by adjusting the shutdown_process_timeout
parameter in WorkerOptions
.
• Unhandled Exceptions: It’s a good idea to wrap your shutdown logic in `try`/`except` blocks. This way, if something goes wrong, it won’t stop other callbacks from running:
async def my_shutdown_hook():
try:
# Your cleanup code here
except Exception as e:
logger.error(f"Shutdown hook failed: {e}")
• Improper Session Termination: Make sure you’re calling ctx.connect()
or ctx.shutdown()
in your job’s entrypoint to properly manage the session lifecycle.
• Register Callbacks Early: Add your shutdown callbacks right at the start of your entrypoint function so they’re set up before any long-running tasks begin.
Hopefully, these tips help your shutdown callbacks run smoothly every time. If you hit any bumps or want to chat more about this, just let me know—I’m here to help!
Sources: chain-of-thought-tts/agent.py | examples/voice_agents/realtime_joke_teller.py | Inside a session | LiveKit Docs | Job lifecycle | LiveKit Docs