fix: fix voice recording stuck in continuous mode

- Track submitted state locally instead of using racy qsize() check
- Allow Ctrl+R to stop recording even while agent is running
- Add double-start guard to prevent concurrent recording attempts
This commit is contained in:
0xbyt4 2026-03-03 20:55:06 +03:00
parent dad865e920
commit d7425343ee

19
cli.py
View file

@ -3544,6 +3544,10 @@ class HermesCLI:
def _voice_start_recording(self):
"""Start capturing audio from the microphone."""
# Prevent double-start from concurrent threads
if self._voice_recording:
return
from tools.voice_mode import AudioRecorder, check_voice_requirements
reqs = check_voice_requirements()
@ -3606,6 +3610,8 @@ class HermesCLI:
def _voice_stop_and_transcribe(self):
"""Stop recording, transcribe via STT, and queue the transcript as input."""
submitted = False
wav_path = None
try:
if self._voice_recorder is None:
return
@ -3646,6 +3652,7 @@ class HermesCLI:
if result.get("success") and result.get("transcript", "").strip():
transcript = result["transcript"].strip()
self._pending_input.put(transcript)
submitted = True
elif result.get("success"):
_cprint(f"{_DIM}No speech detected.{_RST}")
else:
@ -3657,7 +3664,6 @@ class HermesCLI:
finally:
with self._voice_lock:
self._voice_processing = False
submitted = self._pending_input.qsize() > 0
if hasattr(self, '_app') and self._app:
self._app.invalidate()
# Clean up temp file
@ -4758,11 +4764,7 @@ class HermesCLI:
"""Toggle voice recording when voice mode is active."""
if not cli_ref._voice_mode:
return
if cli_ref._agent_running:
return
# Block recording during interactive prompts
if cli_ref._clarify_state or cli_ref._sudo_state or cli_ref._approval_state:
return
# Always allow STOPPING a recording (even when agent is running)
if cli_ref._voice_recording:
# Manual stop via Ctrl+R: stop continuous mode
with cli_ref._voice_lock:
@ -4774,6 +4776,11 @@ class HermesCLI:
daemon=True,
).start()
else:
# Guard: don't START recording during agent run or interactive prompts
if cli_ref._agent_running:
return
if cli_ref._clarify_state or cli_ref._sudo_state or cli_ref._approval_state:
return
try:
# Interrupt TTS if playing, so user can start talking
if not cli_ref._voice_tts_done.is_set():