Skip to content

fix(discord): voice inactivity timeout fires under /voice off, spamming the channel - #43165

Closed
xxxigm wants to merge 2 commits into
NousResearch:mainfrom
xxxigm:fix/discord-voice-timeout-voice-off
Closed

xxxigm wants to merge 2 commits into
NousResearch:mainfrom
xxxigm:fix/discord-voice-timeout-voice-off

Conversation

@xxxigm

@xxxigm xxxigm commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Reported by PanBartosz. When a user switches to /voice off, the bot stays connected to the voice channel (correct — leaving is /voice leave), but the 300s inactivity timer (VOICE_TIMEOUT in plugins/platforms/discord/adapter.py) only counts the bot's own audio playback as activity. Under voice-off nothing ever resets it, so every 5 minutes _voice_timeout_handler() disconnects and posts "Left voice channel (inactivity timeout)." — repeating each time the bot rejoins.

Confirmed on main: _reset_voice_timeout() is only called from playback paths (join_voice_channel, play_in_voice_channel, play_ack_in_voice); no text-only or listening path resets it, and /voice off neither cancels the timer nor disconnects.

Fix

  • The adapter now learns the live voice-reply mode through a _voice_mode_getter wired from gateway/run.py (next to the existing _on_voice_disconnect/_voice_input_callback wiring). _voice_timeout_handler() skips the auto-disconnect while the mode is off, honoring /voice off (text-only, stay connected) vs /voice leave (disconnect) — consistent with the docs.
  • It also resets the timer when a user actually speaks to the bot (_voice_listen_loop), so an active listener isn't dropped mid-conversation. This also covers the broader case the report hints at: a voice-on session that only ever sends text (no bot audio) would otherwise hit the same 5-minute disconnect.

Genuine inactivity (a speaking mode with no one talking and no bot audio) still auto-disconnects as before.

Test plan

  • scripts/run_tests.sh tests/gateway/test_voice_command.py (183 passed, incl. new test_timeout_skips_disconnect_when_voice_mode_off and test_timeout_still_disconnects_when_voice_mode_active)
  • Manual (Discord): /voice join/voice off → wait >5 min → bot stays connected, no "inactivity timeout" message.
  • Manual (Discord): /voice join, keep talking past 5 min → bot stays; go silent >5 min in a speaking mode → auto-disconnects.

Made with Cursor

xxxigm added 2 commits June 10, 2026 07:04
The voice inactivity timer (VOICE_TIMEOUT) only counted the bot's OWN audio
playback as activity. Under /voice off (text-only replies, but still in the
channel — leaving is /voice leave) nothing ever reset it, so every 300s the bot
disconnected and spammed "Left voice channel (inactivity timeout)."

The adapter now learns the live voice-reply mode via a getter wired from run.py
and skips the auto-disconnect while mode is off. It also resets the timer when a
user actually speaks to the bot, so an active listener (incl. voice-on
text-only sessions that never play audio) isn't dropped mid-conversation.
Assert the inactivity handler skips disconnect (and the channel spam) when the
voice-mode getter reports "off", and still disconnects on genuine inactivity
when the mode is active.
@PanBartosz

Copy link
Copy Markdown

@xxxigm Thanks, this is exactly the problem and the fix seems to target exactly the part of logic that is missing. Hope this will get merged!

@liuhao1024

Copy link
Copy Markdown
Contributor

Verification comment from code review — this PR is clean.

The fix addresses a real user-facing bug: /voice off deliberately keeps the bot in the voice channel (text-only replies), but the inactivity timer fires every VOICE_TIMEOUT seconds because it only counts the bot's own audio as activity. This PR:

  1. Wires a _voice_mode_getter callback from run.py to adapter, so the timeout handler can check if voice mode is "off" and skip auto-disconnect.
  2. Resets the inactivity timer when a user speaks (not just bot playback), preventing mid-conversation disconnects in voice-on text-only sessions.

The getattr + try/except guard on _voice_mode_getter is defensive — if the callback isn't set, the handler falls through to the existing disconnect behavior. No risk of regression on the normal voice path.

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/discord Discord bot adapter P2 Medium — degraded but workaround exists labels Jun 10, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Merged via PR #43328. Your commits were cherry-picked onto current main with your authorship preserved in git log (rebase-merge). Thanks for the fix and the tests — and thanks to @PanBartosz for the precise root-cause report.

#43328

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/discord Discord bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants