Skip to content

fix(desktop): reset voice state on session switch#61448

Open
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/desktop-session-voice-state-boundary
Open

fix(desktop): reset voice state on session switch#61448
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/desktop-session-voice-state-boundary

Conversation

@konsisumer

Copy link
Copy Markdown
Contributor

What does this PR do?

Resets Desktop composer voice state at the same session boundary that scopes the foreground transcript, so session switches cannot carry listening/read-aloud status into the newly selected chat.

Shared root cause

  • Desktop has a shared foreground chat/composer surface, while several state sources are session keyed by runtime id. The transcript cache already rejects background-session view writes in useSessionStateCache, but composer voice state still lived in component/module state and survived warm switches or cold unmount/remount paths.
  • This wires a session switch reset into useComposerVoice: warm switches disable the active voice conversation and call the conversation teardown, while cold unmounts stop the module-level voice playback singleton.
  • This folds in the voice-session reset approach from fix(desktop): stop voice status leaking across session switch (#46194) #46279 by @harjothkhara, adapted to the current extracted useComposerVoice structure.

How this fixes each issue

Supersedes

Supersedes #46279

Related Issue

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Security fix
  • Documentation update
  • Tests (adding or improving test coverage)
  • Refactor (no behavior change)
  • New skill (bundled or hub)

Changes Made

  • Added useEndVoiceOnSessionSwitch and useStopVoicePlaybackOnUnmount for Desktop composer voice session-boundary cleanup.
  • Wired the reset into useComposerVoice so warm switches call the current conversation teardown and cold unmounts stop global playback.
  • Added hook tests for initial mount, real session switches, no-session transitions, latest callback usage, and unmount playback cleanup.

How to Test

  1. Start a Desktop voice/read-aloud flow in session A until the composer shows listening, Preparing audio, or Speaking.
  2. Switch to session B from the sidebar while that voice state is active.
  3. Verify session B shows only its own chat/composer state and does not inherit session A's voice status.

Local checks:

  • npx prettier --write apps/desktop/src/app/chat/composer/hooks/use-composer-voice.ts apps/desktop/src/app/chat/composer/hooks/use-voice-session-reset.ts apps/desktop/src/app/chat/composer/hooks/use-voice-session-reset.test.ts passed.
  • git diff --check passed.
  • python scripts/check-windows-footguns.py apps/desktop/src/app/chat/composer/hooks/use-composer-voice.ts apps/desktop/src/app/chat/composer/hooks/use-voice-session-reset.ts apps/desktop/src/app/chat/composer/hooks/use-voice-session-reset.test.ts passed with no Python files scanned.
  • /opt/homebrew/bin/timeout -k 30 480 sh -c 'pytest tests/ -q -x --timeout=60 "$@"' sh was run and aborted during collection because this sandbox lacks fastapi/uvicorn; the lazy installer is blocked by Homebrew's externally managed Python.
  • npm --workspace apps/desktop run test:ui -- --run apps/desktop/src/app/chat/composer/hooks/use-voice-session-reset.test.ts could not start because vitest is missing. A bounded npm ci --ignore-scripts --workspace apps/desktop --include-workspace-root=false attempt failed on getaddrinfo ENOTFOUND registry.npmjs.org, and changed-file ESLint failed for the same network-restricted dependency resolution reason.

What platforms tested on

  • macOS on darwin-arm64 (local)

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature
  • I've run pytest tests/ -q and all tests pass (attempted; blocked by missing local Python dashboard deps)
  • I've added tests for my changes
  • I've tested on my platform: macOS on darwin-arm64

Documentation & Housekeeping

  • Documentation N/A
  • cli-config.yaml.example N/A
  • CONTRIBUTING.md / AGENTS.md N/A
  • Cross-platform impact considered
  • Tool descriptions/schemas N/A

Screenshots / Logs

N/A


This coordinated PR bundles a fix that spans several issues. Happy to split it back into focused per-issue PRs if you'd prefer to review them separately.

Refs #45738
Refs #46194

@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 9, 2026

@tonydwb tonydwb 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.

Code Review Summary

Verdict: LGTM

What the PR Does

Reset voice state on session switch to prevent stale voice state leaking between sessions.

Assessment

  • Small, well-scoped fix.

Reviewed by Hermes Agent

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 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.

3 participants