Skip to content

fix(desktop): resume continuous voice listening after playback - #73690

Open
canderson26 wants to merge 1 commit into
NousResearch:mainfrom
canderson26:fix/desktop-voice-relisten
Open

fix(desktop): resume continuous voice listening after playback#73690
canderson26 wants to merge 1 commit into
NousResearch:mainfrom
canderson26:fix/desktop-voice-relisten

Conversation

@canderson26

@canderson26 canderson26 commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • restore automatic microphone relistening after normal streamed assistant speech
  • restore relistening after whole-text fallback speech
  • preserve a real user Stop across the streaming-to-fallback handoff
  • use null rather than 0 as the uninitialized playback-sequence sentinel
  • add hook-level regression coverage for the complete continuous-voice lifecycle

Root cause

startSpeechStream() and playSpeechText() stop/replace existing playback as part of normal startup, which advances $voicePlayback.sequence. Continuous voice captured the sequence before those expected startup bumps, then interpreted normal completion as an explicit user Stop and suppressed the next listening cycle.

Blindly recapturing after fallback startup introduced a second race: a real Stop while a failed stream waited to hand off to fallback speech could be erased. The revised hook preserves the streaming baseline, detects that Stop before fallback begins, and settles idle without reopening the microphone.

Test plan

  • Focused voice-conversation regression suite: 6/6
  • Full renderer/UI suite: 2,836/2,836
  • Electron/platform suite: 854 passed, 2 skipped
  • TypeScript checks
  • Focused ESLint
  • Full lint: 0 errors
  • Production renderer build
  • Packaged-app validation and fresh-install launch smoke test on macOS arm64

The regression matrix covers normal streaming completion, normal fallback completion, explicit Stop during streaming, explicit Stop during the stream-to-fallback wait, explicit Stop during fallback playback, and disabling voice mode during speech.

@canderson26
canderson26 force-pushed the fix/desktop-voice-relisten branch from 32a91a6 to 4d5517b Compare July 28, 2026 23:25
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) tool/tts Text-to-speech and transcription P3 Low — cosmetic, nice to have labels Jul 28, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #73649 reports the normal-playback microphone re-arm failure addressed here. #55581 and #54067 remain adjacent desktop voice-loop repairs with distinct playback-gating and re-arm mechanisms.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused lifecycle fix. The reported premise is present on current main: openLiveSpeech captures its sequence at apps/desktop/src/app/chat/composer/hooks/use-voice-conversation.ts:487, but startSpeechStream later calls stopVoicePlayback() at apps/desktop/src/lib/voice-playback.ts:331; that increments the sequence (apps/desktop/src/lib/voice-playback.ts:72) before normal completion reaches the stop check at use-voice-conversation.ts:285-295. The fallback path has the same ordering at use-voice-conversation.ts:461-463 and voice-playback.ts:438-440.

The PR's post-startup baseline captures and handoff-stop guard address those paths, and its regression matrix covers normal streaming/fallback completion plus the relevant explicit-stop cases.

Automated hermes-sweeper review.

@teknium1 teknium1 added the sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform label Jul 30, 2026
@andrexibiza

Copy link
Copy Markdown
Contributor

Vox Lockin lane 09 verification receipt:

  • Your PR is based on pre-rewrite main: git merge-tree against current main (70db671) conflicts in both use-voice-conversation.ts and its test file. Current main's hook has evolved past this PR (full-duplex barge-in, bargedRef, stoppedDuringStart handling, thinking-sound) and already contains the fix's intent: speechStartSequenceRef is captured AFTER playSpeechText's internal stop (so only a later external stop suppresses re-arm), and settleAfterSpeech suppresses re-arm only for genuine user stops.
  • The re-arm class is regression-tested on main: use-voice-conversation-rearm.test.tsx (5 tests — re-arm after streaming/fallback playback, Stop honored during stream setup, no fallback after Stop during discovery, no re-arm after external Stop) all pass at 70db671, plus the merged fix(desktop): rearm voice conversation after playback #73880 covered the underlying playback-sequence regression from feat(voice): streaming, conversational TTS with barge-in across all surfaces #69511.

Verdict: intent fully covered by merged #73880 + main's current hook; recommend closing this PR as superseded (no duplicate work opened).

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

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform tool/tts Text-to-speech and transcription type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants