fix(desktop): re-arm wake detector after a manual voice end

Ending a voice conversation manually left the wake detector paused for
good, so the wake word couldn't be used again. The composer paused the
detector on voice start but only resumed on the voiceConversationActive
-> false render; if ending voice tore the composer down first, that
render never landed and the resume was skipped.

Resume on unmount as well (latched on wakePausedRef so it fires exactly
once), and stop early-returning when the $gateway atom is momentarily
null. Add wake.pause/resume INFO logs for visibility.
This commit is contained in:
Brooklyn Nicholson 2026-06-27 00:25:21 -05:00 committed by Teknium
parent 813d9ffad0
commit dc4c2414f9
No known key found for this signature in database
2 changed files with 19 additions and 12 deletions

View file

@ -154,22 +154,25 @@ export function useComposerVoice({
)
const wakePausedRef = useRef(false)
useEffect(() => {
const gateway = $gateway.get()
if (!gateway) {
const resumeWakeIfPaused = useCallback(() => {
if (!wakePausedRef.current) {
return
}
wakePausedRef.current = false
void $gateway.get()?.request('wake.resume', {}).catch(() => undefined)
}, [])
useEffect(() => {
if (voiceConversationActive) {
wakePausedRef.current = true
void gateway.request('wake.pause', {}).catch(() => undefined)
} else if (wakePausedRef.current) {
wakePausedRef.current = false
void gateway.request('wake.resume', {}).catch(() => undefined)
void $gateway.get()?.request('wake.pause', {}).catch(() => undefined)
} else {
resumeWakeIfPaused()
}
}, [voiceConversationActive])
}, [resumeWakeIfPaused, voiceConversationActive])
useEffect(() => resumeWakeIfPaused, [resumeWakeIfPaused])
// Explicit start/end for the on-screen conversation controls (the hotkey uses
// the gated toggle above).

View file

@ -17712,8 +17712,9 @@ def _(rid, params: dict) -> dict:
try:
from tools.wake_word import pause_listening
pause_listening()
except Exception:
pass
logger.info("wake.pause: detector paused")
except Exception as e:
logger.debug("wake.pause failed: %s", e)
return _ok(rid, {"paused": True})
@ -17723,6 +17724,9 @@ def _(rid, params: dict) -> dict:
active = _wake_is_active()
if active:
_wake_resume_if_active()
logger.info("wake.resume: detector resumed")
else:
logger.info("wake.resume: ignored (listener not armed)")
return _ok(rid, {"resumed": active})