fix(desktop): never replay hydrated session history in auto-speak; lock mute/re-arm semantics - #78194
Open
andrexibiza wants to merge 1 commit into
Open
andrexibiza wants to merge 1 commit into
andrexibiza wants to merge 1 commit into
Conversation
…ck mute/re-arm semantics Switching sessions with Read Responses Aloud enabled could speak the newly opened session's last reply from HISTORY: the sessionId re-arm consumed whatever the store held at switch time, but history hydrates asynchronously, so a completed reply arriving afterwards looked unspoken and got read aloud. Gate auto-speak on the session having started a fresh turn: completed replies that hydrate before any new turn (or pending reply) are consumed silently. Approach ported from NousResearch#64390 (authored by @kannishk), rebased onto current main with the composer-scope wiring and repo lint conventions. Also adds mute-semantics regressions for the NousResearch#74337 class: muting mid-turn cancels the recorder and holds the reply, unmute returns the loop to listening after settle, and muting during playback never wedges the loop. Tests: 60 vitest UI tests pass (8 files) including new use-auto-speak-replies.test.tsx (2) and mute semantics (3); tsc + eslint clean; git diff --check clean. Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
This was referenced Aug 4, 2026
13 tasks
Contributor
Author
|
The current head |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related #64390 #73649 #73691 #73880 #74337 #78098 #78118
What changed and why
Desktop voice-conversation reliability residuals (Lane 09 of the Vox Lockin campaign).
1. Auto-speak replays hydrated session history after a session switch (fixes #64390)
With Read Responses Aloud enabled, switching sessions could speak the newly opened session's last reply from history — an old reply the user already heard — because:
sessionIdre-arm inuseAutoSpeakRepliesconsumes whatever reply sits in the store at switch time, butFix: gate auto-speak on the session having started a fresh turn. While the gate is armed (after a session switch / toggle-on / mount), completed replies are consumed silently; only a pending assistant reply or a new turn (
busy) opens the gate. Ported from #64390's approach (authored by @kannishk) — the open PR conflicts with current main, so the change is rebased onto main's composer-scope wiring (useComposerScope().$messages,ownsAmbientCue) and the repo's eslint conventions.2. Mute semantics locked by regression tests (#74337 class)
The "can remain muted after reply playback" report shares its root with #73649 (fixed by merged #73880 — re-arm after playback is now covered by the existing
use-voice-conversation-rearm.test.tsx). This PR adds the complementary mute-contract regressions touse-voice-conversation.test.tsx:No production code change was needed for the mute path: on current main
mutedonly ever flips via usertoggleMute(never spontaneously), and the re-arm class is covered by #73880. The tests lock that contract so the class can't silently regress.How to test
cd apps/desktop npx vitest run src/app/chat/composer/hooks/use-auto-speak-replies.test.tsx \ src/app/chat/composer/hooks/use-voice-conversation.test.tsx \ src/app/chat/composer/hooks/use-voice-conversation-rearm.test.tsx \ src/lib/voice-stop-word.test.ts src/lib/speech-text.test.ts \ src/store/voice-prefs.test.ts src/app/settings/voice-field-visible.test.ts \ src/app/settings/voice-provider-fields.test.tsExpected: 8 files, 60 tests, all passing (was 55; +2 auto-speak session-switch regressions, +3 mute-semantics regressions).
npx tsc -p tsconfig.json --noEmit,npx eslinton the touched files, andgit diff --checkare all clean.Platforms tested
Why this matters to users
Fixes #64390
Related: #74337 (class regression-locked; re-arm root fixed by #73880), #73649 (verified fixed on main), #73691 (verified covered — desktop auto-speak is client-side, closed NOT_PLANNED), #78098 (verified fixed by #78118).
Credit: session-switch gating approach salvaged from #64390, authored by @kannishk.
Part of #74337
Part of #78207
Part of #79890