Skip to content

fix(voice): block new user turns immediately on update_agent() to prevent transition delay#5396

Open
Panmax wants to merge 3 commits intolivekit:mainfrom
Panmax:fix/update-agent-pause-scheduling
Open

fix(voice): block new user turns immediately on update_agent() to prevent transition delay#5396
Panmax wants to merge 3 commits intolivekit:mainfrom
Panmax:fix/update-agent-pause-scheduling

Conversation

@Panmax
Copy link
Copy Markdown
Contributor

@Panmax Panmax commented Apr 9, 2026

Summary

Bug: When update_agent() is called, the old agent can still accept and process new user turns (including ambient noise) during the transition window, delaying the new agent's on_enter() by seconds.

Root cause: The async transition task (drain()_pause_scheduling_task()) doesn't run immediately, leaving a window where the old activity's scheduling task accepts new turns and triggers full LLM → TTS pipeline.

Fix: Introduce a lightweight _new_turns_blocked flag that is set synchronously in update_agent() to immediately block new user turns, while keeping _scheduling_paused untouched for _pause_scheduling_task() to function correctly.

This avoids the issue where directly setting _scheduling_paused = True would cause _pause_scheduling_task() to early-return and skip await asyncio.shield(self._scheduling_atask), which is needed to wait for in-flight speech tasks to complete.

Changes

  • agent_activity.py: Add _new_turns_blocked flag, checked at all user-turn entry points (_on_generation_created, on_preemptive_generation, on_end_of_turn, _on_user_turn_completed, _on_user_input_complete)
  • agent_session.py: update_agent() sets _new_turns_blocked = True instead of _scheduling_paused = True

What is NOT changed (intentionally)

  • _pause_scheduling_task() early-return guard — must only check _scheduling_paused
  • _schedule_speech(force=True) — tool responses during drain still work
  • _scheduling_task exit condition — only exits on formal pause signal
  • say()/generate_reply() routing — programmatic speech still routes to current activity during transition

Test plan

  • Call session.update_agent(new_agent) while there is ambient noise — new agent's on_enter() should fire promptly without the old agent processing a stray turn
  • Verify drain() properly awaits in-flight speech tasks before completing the transition
  • Verify normal agent transitions still work correctly
  • Verify that in-progress turns at the time of update_agent() complete without interruption

🤖 Generated with Claude Code

Previously, update_agent() only created an async transition task, leaving
the old activity's scheduling task free to accept new user turns until
drain() eventually called _pause_scheduling_task(). This caused the old
agent to process stray voice input (including noise) during the transition
window, delaying the new agent's on_enter() by seconds.

Synchronously set _scheduling_paused = True and wake the scheduling task
before creating the transition task, closing the race window.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

The previous approach directly set `_scheduling_paused = True` in
update_agent(), which caused _pause_scheduling_task() in drain() to
early-return and skip awaiting the scheduling task. This meant in-flight
speech tasks were not properly waited on before the transition proceeded.

Introduce `_new_turns_blocked` flag that only prevents new user turns
from being accepted, without interfering with _pause_scheduling_task()'s
lifecycle. drain() can now properly set _scheduling_paused and await
the scheduling task to ensure all in-flight speech completes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Panmax Panmax changed the title fix(voice): immediately pause old agent scheduling on update_agent() fix(voice): block new user turns immediately on update_agent() to prevent transition delay Apr 10, 2026
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.

2 participants