fix(discord): process concurrent voice utterances - #43003
joelneleber wants to merge 2 commits into
Conversation
Verification ReviewReviewed: Well-structured concurrency improvement for Discord voice processing. Key changes:
Test coverage: 4 new tests covering default no-agent behavior, env opt-in, config opt-in, and concurrent speaker fan-out. Existing tests updated for No issues found. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the live-listening bottleneck: current main still awaits each utterance inline at plugins/platforms/discord/adapter.py:3179, so the concurrency direction addresses a real defect.
Problems
plugins/platforms/discord/adapter.py:610-611addsHERMES_DISCORD_VOICE_STT_CONCURRENCYandHERMES_DISCORD_VOICE_STT_MAX_PENDING; the PR also documentsHERMES_DISCORD_VOICE_TRANSCRIPT_AGENT_TURNSin.env.example. These are non-secret behavioral settings, whileAGENTS.md:102-106requires such configuration to useconfig.yaml.- Those two direct
int(os.getenv(...))calls make malformed values abort adapter construction instead of using a safe default. - The new fan-out test covers simultaneous starts, but not the stated semaphore cap, backlog drop, or leave-time cancellation contracts.
Suggested changes
- Re-scope the voice knobs to validated
discordconfig.yaml fields and add regression coverage for capacity, backlog, and cancellation behavior.
Automated hermes-sweeper review.
| self._voice_listen_tasks: Dict[int, asyncio.Task] = {} # guild_id -> listen loop | ||
| self._voice_input_tasks: Dict[int, set[asyncio.Task]] = {} # guild_id -> in-flight STT/callback work | ||
| self._voice_input_semaphore: Optional[asyncio.Semaphore] = None | ||
| self._voice_input_concurrency = max(1, int(os.getenv("HERMES_DISCORD_VOICE_STT_CONCURRENCY", "3"))) |
There was a problem hiding this comment.
This creates a user-facing non-secret HERMES_* behavior knob and raises ValueError for a malformed value during adapter construction. Please source this from validated discord config.yaml instead; AGENTS.md:102-106 reserves .env for secrets.
Summary
HERMES_DISCORD_VOICE_STT_CONCURRENCY, default 3), and bounded pending backlog (HERMES_DISCORD_VOICE_STT_MAX_PENDING, default 12).Root cause
When
receiver.check_silence()returned completed utterances for multiple speakers,_voice_listen_loop()processed them serially withawait _process_voice_input(...). PCM->WAV, STT, transcript posting, and optional callback latency for speaker 1 blocked speaker 2/3, and also paused further silence polling while STT was in flight.Tests
python -m py_compile plugins/platforms/discord/adapter.pypython -m pytest tests/gateway/test_voice_command.py::TestUDPKeepalive tests/gateway/test_voice_command.py::TestVoiceListenLoopConcurrency -q -o 'addopts='python -m pytest tests/gateway/test_voice_command.py tests/gateway/test_discord_opus.py tests/integration/test_voice_channel_flow.py -q -o 'addopts='Result:
168 passed, 22 skipped.Notes
This builds on the prior Discord voice transcription fix branch/runtime worktree because upstream PR #42611 is still unmerged.