proud-lawyer-39815
02/23/2026, 3:23 PMtall-airline-16756
02/23/2026, 3:23 PMtall-airline-16756
02/23/2026, 3:24 PM@server.rtc_session(agent_name="my-agent")
async def entrypoint(ctx: JobContext):
# create a mutable flag
shutdown_flag = {"is_shutting_down": False}
async def shutdown_hook():
shutdown_flag["is_shutting_down"] = True
<http://logger.info|logger.info>("Shutdown initiated - freezing agent")
# short cleanup here
ctx.add_shutdown_callback(shutdown_hook)
# pass flag into whatever logic needs to observe it
while not shutdown_flag["is_shutting_down"]:
# normal agent work
await do_work_step()
# optional finalization after flag set
2) Track state in your Agent class (object-oriented)
class MyAgent(Agent):
def __init__(self):
super().__init__()
self.is_shutting_down = False
def freeze_agent(self):
self.is_shutting_down = True
# cancel timers, stop accepting new tasks, etc.
async def run(self):
while not self.is_shutting_down:
await self.process_next()
@server.rtc_session(agent_name="my-agent")
async def entrypoint(ctx: JobContext):
agent = MyAgent()
async def shutdown_hook():
agent.freeze_agent()
<http://logger.info|logger.info>("Shutdown initiated - freezing agent")
# short cleanup
ctx.add_shutdown_callback(shutdown_hook)
await agent.run()
Important operational notes
• Shutdown hooks should complete quickly: the framework waits 10 seconds by default before forcefully terminating the process. You can adjust this using shutdown_process_timeout in server options.
• When the process receives SIGTERM / SIGINT, the server uses drain_timeout (defaults to 30 minutes) to allow active jobs to finish.
If you’d like, I can:
• Show an example that cancels specific async tasks or listeners when freezing the agent.
• Provide an example that integrates the flag into your existing session/AgentSession flow.
Which would help you most?
Sources: Job lifecycle | LiveKit Documentation | Server options | LiveKit Documentationproud-lawyer-39815
02/23/2026, 3:39 PMtall-airline-16756
02/23/2026, 3:39 PMctx.add_shutdown_callback(...). That callback runs when the job is being terminated, so setting a flag there lets your agent know the job is shutting down and freeze behavior immediately.
• Session events: Use session events such as session.on("user_state_changed") to observe participant activity; when all participants leave or the session is ended, the job will move toward termination.
• Local state tracking: Since there’s no built-in state query, maintain your own job-state variable (e.g., is_shutting_down or job_state = "running"|"shutting_down"|"closed") and update it in your shutdown hook and other lifecycle points. Have your agent logic check that variable before starting work or between work items.
Important operational notes
• Shutdown hooks should finish quickly: the framework waits 10 seconds by default before forcefully terminating the process. You can change that with shutdown_process_timeout.
• When a SIGTERM/SIGINT arrives, the server will wait up to drain_timeout (default 30 minutes) for jobs to finish.
If you’d like, I can:
• Show a short example that exposes a job_state variable and updates it in shutdown hooks and session events.
• Show how to cancel running async tasks or listeners when the shutdown flag is set.
Which example would you prefer?
Sources: Job lifecycle | LiveKit Documentation | How to detect and handle silence during calls | LiveKit