Skip to content

fix(gateway): pre-wire voice callbacks on Discord adapters at startup - #11160

Closed
boroughnexus-cto wants to merge 1 commit into
NousResearch:mainfrom
boroughnexus-cto:fix/voice-callback-prewire-auto-join
Closed

fix(gateway): pre-wire voice callbacks on Discord adapters at startup#11160
boroughnexus-cto wants to merge 1 commit into
NousResearch:mainfrom
boroughnexus-cto:fix/voice-callback-prewire-auto-join

Conversation

@boroughnexus-cto

Copy link
Copy Markdown

Summary

When the Discord adapter auto-joins a voice channel on startup (via persistent voice config), the voice input and disconnect callbacks (_voice_input_callback, _on_voice_disconnect) have not yet been set by GatewayRunner. The gateway wires these callbacks lazily — only after the first join_voice_channel() call triggered by a user command — so auto-joined channels receive voice audio with no handler attached, silently dropping all speech input.

This fix iterates over Discord adapters in GatewayRunner.connect() after all platforms have connected and pre-wires the callbacks if they are not already set.

Changes

  • Added callback pre-wiring block in GatewayRunner.connect() after the "Gateway running" log line
  • Only sets callbacks when currently None — safe for non-auto-join deployments

Test Scenario

  1. Set DISCORD_VOICE_CHANNEL_ID=<channel_id> and DISCORD_VOICE_TIMEOUT=0 in .env
  2. Restart the gateway
  3. Speak in the voice channel immediately after the bot joins
  4. Without fix: audio is silently dropped (no transcript, no agent call)
  5. With fix: speech is transcribed and routed to the agent normally

Context

We've been running this fix in production for several days via a local patch. The callback wiring gap affects all deployments using persistent/auto-join voice channels, not just our setup.

🤖 Generated with Claude Code

When the Discord adapter auto-joins a voice channel on startup (e.g.
via DISCORD_VOICE_CHANNEL_ID or persistent voice config), the voice
input and disconnect callbacks have not yet been set by GatewayRunner.

The callbacks are wired lazily — only after the first join_voice_channel()
call triggered by a user command. This means auto-joined channels receive
voice audio with no handler attached, silently dropping all speech input
until the user manually re-joins the bot.

This fix iterates over Discord adapters after all platforms have connected
and pre-wires the callbacks if they are not already set. Safe for non-
auto-join deployments: callbacks are only set when currently None.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

@RuckVibeCodes RuckVibeCodes left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[gus-first-pass] Addressing auto-join functionality for Discord effectively; well structured and tested.

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

Copy link
Copy Markdown
Collaborator

Thanks for addressing the voice-input race. On current main, the stated startup path is not available: Discord voice channels are joined through /voice join / /voice channel (website/docs/user-guide/features/voice-mode.md:334-346), and that path already wires both callbacks before join_voice_channel() (gateway/run.py:12780-12794), covered by tests/gateway/test_voice_command.py:1407-1426.

Problems

  • The proposed startup-only callback assignment does not establish _voice_text_channels, _voice_sources, or voice-mode state. Current transcript handling relies on that mapping, populated after a successful join at gateway/run.py:12807-12812.

Suggested changes

  • Re-scope around a concrete current-main startup auto-join mechanism, including the required guild-to-text-channel/session linkage.
  • Add an end-to-end startup-path test that proves an immediate voice transcript reaches the agent route.

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

You were the earliest submitter of the voice-callback-wiring idea (Apr 2026) — thank you! #73517 merged @isheng-eqi's #61407, which supersedes this with reconnect + channel-binding coverage; the merged PR credits you as earliest.

(Landed via #73517, merge b8c38a451a.) Closing.

@teknium1 teknium1 closed this Jul 29, 2026
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 sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants