Skip to content

fix(voice): don't hold session.run() open on update_agent handoffs with long-lived on_enter#6500

Merged
longcw merged 2 commits into
livekit:mainfrom
k-zaher:fix/update-agent-run-deadlock
Jul 23, 2026
Merged

fix(voice): don't hold session.run() open on update_agent handoffs with long-lived on_enter#6500
longcw merged 2 commits into
livekit:mainfrom
k-zaher:fix/update-agent-run-deadlock

Conversation

@k-zaher

@k-zaher k-zaher commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What

session.run() deadlocks when a function tool calls session.update_agent(new_agent) and the new agent's on_enter awaits an AgentTask (or TaskGroup) that needs a future user turn to complete.

The chain: update_agent()_update_activity_task (watched by the active RunResult so the handoff result lands before run completion) → _update_activity(agent) with the default wait_on_enter=True → awaits the new agent's on_enter → which awaits an AgentTask that needs the next user turn. But the driver can't send the next turn until run() returns — a circular wait. The run hangs until an external timeout cancels everything (surfacing as ToolError: AgentTask ... is cancelled).

Both other activity-transition paths already guard against exactly this:

  • session.start() passes wait_on_enter=False (agent_session.py:916), which is why the examples/survey pattern (agent on_enter awaiting a whole TaskGroup) works when the agent is the starting agent.
  • AgentTask.__await_impl passes wait_on_enter=False with a comment describing this exact deadlock: "on_enter may spawn nested AgentTasks that require user input, but session.run() can't return until all watched handles complete — creating a circular wait."

update_agent() was the only path still waiting. Entering the same agent that works via session.start() through an update_agent() handoff deadlocks — reproduced on 1.6.4, 1.6.5, and 1.6.6.

Fix

Pass wait_on_enter=False in _update_activity_task, matching the other two paths.

Test

tests/test_update_agent_long_on_enter.py — FakeLLM-scripted: a greeter tool calls update_agent() into an agent whose on_enter awaits an AgentTask needing another user turn; asserts run() returns on the handoff turn and the task completes on the following turn. Deadlocks (times out) without the fix; passes with it.

Validation:

  • tests/test_agent_session.py, test_nested_agent_task.py, test_audio_recognition_handoff.py, test_agent_task_close_race.py, test_drain_timeout.py, test_tool_results_preserved_on_interruption.py, test_user_turn_exceeded.py, test_speech_handle_exception.py, test_agent_update_options.py + the new test: 116 passed.
  • examples/survey/test_survey_agent.py: 5 passed (live LLM).
  • A production voice agent using this shape (greeter agent routing via update_agent() to an agent whose on_enter drives a multi-task loop): its full offline suite of ~1000 tests passes against this patch; on current releases every workflow test deadlocks.

@k-zaher
k-zaher marked this pull request as ready for review July 21, 2026 17:21
@k-zaher
k-zaher requested a review from a team as a code owner July 21, 2026 17:21
@k-zaher
k-zaher force-pushed the fix/update-agent-run-deadlock branch from 001149e to f8ca38b Compare July 21, 2026 17:22
@CLAassistant

CLAassistant commented Jul 21, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@k-zaher
k-zaher force-pushed the fix/update-agent-run-deadlock branch from f8ca38b to ff44fab Compare July 21, 2026 17:22
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

Comment thread livekit-agents/livekit/agents/voice/agent_session.py
@longcw

longcw commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

thanks for the pr! could sign the CLA before we can merge

@k-zaher

k-zaher commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

I have signed the CLA but the bot is not picking up the updated status for some reason

@k-zaher
k-zaher force-pushed the fix/update-agent-run-deadlock branch from 7e969f9 to 0c0ee8e Compare July 23, 2026 10:27
@longcw
longcw merged commit 2369b74 into livekit:main Jul 23, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants