fix(discord): re-arm voice inactivity timer on user input - #106004
gaoanze888 wants to merge 1 commit into
Conversation
…ch#105974) Closes NousResearch#105974. The bot's own TTS playback re-arms the auto-disconnect inactivity timer via play_in_voice_channel's finally, but _process_voice_input (the STT path that hears the user) never called _reset_voice_timeout. In an active two-way voice conversation the bot silently disconnected exactly voice_channel_inactivity_timeout_seconds after joining, even if the user talked the whole time. - Call _reset_voice_timeout(guild_id) in _process_voice_input once a valid (non-hallucinated) transcript is detected, mirroring the playback-path re-arm pattern. The re-arm is gated on a successful transcript, so a silent channel still times out. Compatible with NousResearch#43165's /voice off fix: the handler returns early when mode==off, so re-arming there is a no-op. Tests: assert _process_voice_input re-arms on valid input (fails without the fix) and does NOT re-arm on failed STT. Mutation-verified.
|
Re: the triage note about #42597 — noting the relationship so it's easy to triage. #42597 ("keep voice meetings responsive", opened June, last updated July, This PR is the focused fix for #105974 (re-arm the voice inactivity timer on user input) — same one behavior, minimal scope, 2 new mutation-verified tests, no surrounding redesign. If a maintainer prefers to land the narrow fix first and let the broader redesign follow separately, this is ready; if they'd rather wait on #42597, that's fine too. |
|
Closing after a maintainer-style re-audit disproved this PR's root-cause premise. The PR parent already resets the inactivity timer in the real receive path: for user_id, pcm_data in completed:
if not self._is_allowed_user(...):
continue
self._reset_voice_timeout(guild_id)
await self._process_voice_input(...)The issue log confirms that reset fired: join was at 13:47:37, the accepted voice input was at 13:47:56, and disconnect was at 13:52:55 — approximately 300 seconds after the input, not 300 seconds after join. The added The actual unresolved signal in the report is that no further completed utterances / Thanks to @liuhao1024 for pointing out the timestamp evidence and existing caller reset. I should have traced the full caller lifecycle before opening this; closing to avoid consuming maintainer review time on a redundant fix. The receiver/transcription stall should be investigated separately with a focused reproduction. |
What does this PR do?
Fixes a silent mid-conversation disconnect: when the bot joins a Discord voice channel, the inactivity auto-leave timer is armed once. After that, user voice input does not reset the timer — so in an active two-way voice conversation the bot silently disconnects exactly
voice_channel_inactivity_timeout_seconds(default 300) after joining, even if the user is talking the whole time. This PR re-arms the timer on a successful user transcript.Related Issue
Closes #105974.
Type of Change
Changes Made
DiscordAdapter._reset_voice_timeout()was called from the playback paths (join_voice_channel,play_in_voice_channel'sfinally,play_ack_in_voice) but not from_process_voice_input()(the STT path that actually hears the user). The only thing that kept an auto-joined bot alive was its own TTS playback.The fix: call
_reset_voice_timeout(guild_id)in_process_voice_input()once a valid (non-hallucinated) transcript is detected, mirroring the playback-path re-arm pattern. Additive — one line plus a comment.Why this is safe:
/voice offfix:_voice_timeout_handlerreturns early when mode =="off", so re-arming there is a no-op (no spam, no disconnect)._reset_voice_timeoutcancels the existing task before re-arming, so calling it on every utterance does not accumulate timers.How to Test
New regression tests (
tests/gateway/test_discord_voice_timeout_rearm.py):test_process_voice_input_re_arms_inactivity_timeout— valid transcript →_reset_voice_timeoutcalled with the guild id. Fails without the fix (mutation-verified).test_process_voice_input_does_not_rearm_on_failed_stt— failed STT →_reset_voice_timeoutNOT called (the re-arm is correctly gated).Both pass with the fix; the positive test fails when the fix is reverted.
Checklist
Code
fix(discord): ...)/voice offspam fix, complementary not overlapping; Discord voice channel: auto-TTS never plays in VC — runner skips, base adapter sends file instead of playing in channel #101185 = sibling auto-join reply-to-text bug)Documentation & Housekeeping
_reset_voice_timeout; no public API or doc surface changed