little-king-41579
02/16/2026, 2:44 PMtall-airline-16756
02/16/2026, 2:44 PMtall-airline-16756
02/16/2026, 2:45 PMAgentTask is running in an AgentSession using the Python framework.
Short answer:
• You can close the session at any time by calling session.shutdown() (e.g., await session.shutdown(drain=True) for a graceful shutdown).
• You cannot update the active agent while an AgentTask is running because the task takes exclusive control of the session. You must wait until the task finishes before calling session.update_agent(...).
What’s happening under the hood (brief):
• When an AgentTask runs, it suspends the main agent’s control of the session until the task completes.
• Calling session.shutdown() begins session cleanup and will stop the task and agent lifecycle (it’s the proper way to end everything from inside task or agent code).
• session.update_agent() only succeeds after control returns to the main agent (i.e., after the task completes with self.complete(result) or otherwise finishes).
Practical options you can use
• Close the session from inside the task:
a. Inside your task coroutine, call:
await session.shutdown(drain=True) # or drain=False
1. This will gracefully stop the session and clean up I/O/speech as configured.
• Modify behavior without replacing the agent:
◦ If you need different behavior while the task runs, change the agent’s internal state or tools from inside the task rather than trying to swap the agent.
• Update the agent after the task completes:
a. Let the task finish (e.g., call self.complete(result)).
b. Once control returns to the main agent, call:
await session.update_agent(NewAgent())
If you’d like, tell me:
• A short snippet of how you currently start the AgentTask and AgentSession (redact any secrets), and
• Whether you want to fully stop the session or simply change agent behavior while the task runs.
I can then suggest a concrete code example tailored to your flow.
Sources: Job lifecycle | LiveKit Documentation | Agents and handoffs | LiveKit Documentationlittle-king-41579
02/16/2026, 3:01 PMtall-airline-16756
02/16/2026, 3:01 PMAgentTask (so control returns to the main agent), then call session.update_agent(...). This follows the lifecycle rules: the task must finish before the agent can be replaced.
Notes:
• Replace class/function names with your actual implementations.
• Redact any secrets before running.
Example:
import asyncio
# Example AgentTask implementation
class MyAgentTask:
def __init__(self, session):
self.session = session
self._completed = asyncio.Event()
self.result = None
async def run(self):
# Task does work here. This coroutine has exclusive control of the session.
try:
# Simulate work
for i in range(5):
print("Task working...", i)
await asyncio.sleep(1)
# Optional: check some condition to finish early
if some_condition_to_complete():
await self.complete({"status": "early_complete"})
return
# Normal completion
await self.complete({"status": "done"})
except Exception as e:
# If you want to shutdown session on error:
await self.session.shutdown(drain=True)
raise
async def complete(self, result):
# Mark the task completed and store result
self.result = result
self._completed.set()
# Return control to the main agent by simply finishing run()
# If there are other cleanup steps, do them here.
print("Task completed with:", result)
async def wait_completed(self):
await self._completed.wait()
return self.result
def some_condition_to_complete():
# Replace with your actual condition logic
return False
# Example main agent flow that starts the task and waits, then updates the agent
async def main_agent_flow(session):
# Start the AgentTask (run concurrently or awaited depending on framework)
task = MyAgentTask(session)
# Start the task concurrently so the session is controlled by the task
task_coro = asyncio.create_task(task.run())
# Option A: Wait for task to signal completion, then update agent
result = await task.wait_completed()
print("Received task result:", result)
# Now it's safe to update the agent because the task finished
await session.update_agent(NewAgent()) # Replace NewAgent with your agent class
print("Agent updated after task completion")
# Optionally wait for task coroutine to finish fully (if needed)
await task_coro
# Example NewAgent placeholder
class NewAgent:
pass
# Example usage entrypoint
async def example_entrypoint(session):
await main_agent_flow(session)
# If running standalone for testing:
# asyncio.run(example_entrypoint(your_session_instance))
If instead you want to force the session to stop from inside the task (which will end the task and agent lifecycle), call shutdown:
await session.shutdown(drain=True) # Graceful shutdown; use drain=False to skip draining speech
If you share a short snippet of how you currently start tasks and your session object, I can adapt the example to your exact framework setup (e.g., AgentTask base class names or how you schedule tasks).