From ee5f20bdf2365272ede48d9ebf14c49d697c0644 Mon Sep 17 00:00:00 2001 From: brunopirz Date: Wed, 24 Jun 2026 13:15:04 -0300 Subject: [PATCH] fix(voice): prevent restart race when continuous mode stops after 3 no-speech cycles When voice continuous mode detects 3 consecutive no-speech cycles it sets _voice_continuous = False and previously did an immediate eturn. The restart guard if self._voice_continuous and not submitted and not self._voice_recording came *after* the early return, so the thread could never restart. However a timing window existed: if _voice_start_recording was already queued from a prior iteration, the eturn bypassed the guard while the thread was already in flight. Replace the bare eturn with a stop_continuous_restart boolean evaluated in the same if that guards _restart_recording. This ensures both branches read a consistent no-restart signal and no recording thread is spawned after the user's session has been intentionally halted. --- cli.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli.py b/cli.py index 3ed1b73a28c..899b1f5f656 100644 --- a/cli.py +++ b/cli.py @@ -11913,13 +11913,14 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): pass # Track consecutive no-speech cycles to avoid infinite restart loops. + stop_continuous_restart = False if not submitted: self._no_speech_count = getattr(self, '_no_speech_count', 0) + 1 if self._no_speech_count >= 3: self._voice_continuous = False self._no_speech_count = 0 _cprint(f"{_DIM}No speech detected 3 times, continuous mode stopped.{_RST}") - return + stop_continuous_restart = True else: self._no_speech_count = 0 @@ -11927,7 +11928,12 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): # restart recording so the user can keep talking. # (When transcript IS submitted, process_loop handles restart # after chat() completes.) - if self._voice_continuous and not submitted and not self._voice_recording: + if ( + self._voice_continuous + and not submitted + and not self._voice_recording + and not stop_continuous_restart + ): self._voice_restart_recording_async() def _voice_speak_response_async(self, text: str) -> None: