-
Notifications
You must be signed in to change notification settings - Fork 2.7k
fix(liveavatar): handle AudioSegmentEnd to properly signal playback completion #4605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(liveavatar): handle AudioSegmentEnd to properly signal playback completion #4605
Conversation
The _forward_audio() function in AvatarSession only handled rtc.AudioFrame objects, completely ignoring AudioSegmentEnd markers. This caused notify_playback_finished() to never be called when audio naturally ended, breaking the agent session's state machine. Root cause: QueueAudioOutput yields both rtc.AudioFrame and AudioSegmentEnd objects. The existing code only had an `if isinstance(audio_frame, rtc.AudioFrame)` check with no else/elif clause, so AudioSegmentEnd was silently dropped. Fix: Add an elif clause to detect AudioSegmentEnd and call notify_playback_finished(interrupted=False) to properly signal that audio playback completed naturally. This mirrors the existing interruption handling in _on_clear_buffer() which uses interrupted=True.
📝 WalkthroughWalkthroughAdded handling for Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✏️ Tip: You can disable this entire section by setting Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py (1)
25-25: Missing import forAudioSegmentEndcausesNameErrorat runtime.The static analysis correctly identifies that
AudioSegmentEndis used on line 219 but never imported. This will cause the code to fail at runtime.🐛 Proposed fix
-from livekit.agents.voice.avatar import QueueAudioOutput +from livekit.agents.voice.avatar import AudioSegmentEnd, QueueAudioOutput
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings
Files:
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py
🧬 Code graph analysis (1)
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py (2)
livekit-agents/livekit/agents/voice/avatar/_types.py (1)
AudioSegmentEnd(10-11)livekit-agents/livekit/agents/voice/speech_handle.py (1)
interrupted(83-84)
🪛 GitHub Check: ruff
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py
[failure] 219-219: Ruff (F821)
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py:219:46: F821 Undefined name AudioSegmentEnd
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: unit-tests
- GitHub Check: type-check (3.13)
- GitHub Check: type-check (3.9)
🔇 Additional comments (1)
livekit-plugins/livekit-plugins-liveavatar/livekit/plugins/liveavatar/avatar.py (1)
219-226: LGTM on the logic (once import is fixed).The handling correctly mirrors
_on_clear_bufferbut signals normal completion (interrupted=False) instead of interruption. The guard on_audio_playingand the state reset are appropriate.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Summary
This PR fixes a bug in the LiveAvatar plugin where
AudioSegmentEndmessages are ignored in the_forward_audio()function, causing the agent session to never receive playback completion signals.Problem
When using the LiveAvatar plugin, the agent session's state machine breaks:
listening→thinking→listeningspeakingstate is never reachednotify_playback_finished()is never called for normal audio completionRoot Cause
The
_forward_audio()function inavatar.pyiterates overself._audio_bufferwhich yields two types:rtc.AudioFrame- actual audio dataAudioSegmentEnd- marker indicating end of audio segmentHowever, only
rtc.AudioFrameis handled. WhenAudioSegmentEndis received, the loop continues without any action:This means
notify_playback_finished()is never called when audio naturally ends, only when interrupted (via_on_clear_buffer).Solution
Add an
elifclause to handleAudioSegmentEndand callnotify_playback_finished():Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.