fix(cli): avoid voice TTS restart race
This commit is contained in:
17
cli.py
17
cli.py
@@ -8375,6 +8375,17 @@ class HermesCLI:
|
||||
_cprint(f"{_DIM}Voice auto-restart failed: {e}{_RST}")
|
||||
threading.Thread(target=_restart_recording, daemon=True).start()
|
||||
|
||||
def _voice_speak_response_async(self, text: str) -> None:
|
||||
"""Schedule TTS and mark it pending before continuous recording can restart."""
|
||||
if not self._voice_tts or not text:
|
||||
return
|
||||
self._voice_tts_done.clear()
|
||||
threading.Thread(
|
||||
target=self._voice_speak_response,
|
||||
args=(text,),
|
||||
daemon=True,
|
||||
).start()
|
||||
|
||||
def _voice_speak_response(self, text: str):
|
||||
"""Speak the agent's response aloud using TTS (runs in background thread)."""
|
||||
if not self._voice_tts:
|
||||
@@ -9535,11 +9546,7 @@ class HermesCLI:
|
||||
# Speak response aloud if voice TTS is enabled
|
||||
# Skip batch TTS when streaming TTS already handled it
|
||||
if self._voice_tts and response and not use_streaming_tts:
|
||||
threading.Thread(
|
||||
target=self._voice_speak_response,
|
||||
args=(response,),
|
||||
daemon=True,
|
||||
).start()
|
||||
self._voice_speak_response_async(response)
|
||||
|
||||
|
||||
# Re-queue the interrupt message (and any that arrived while we were
|
||||
|
||||
@@ -1040,6 +1040,25 @@ class TestDisableVoiceModeReal:
|
||||
class TestVoiceSpeakResponseReal:
|
||||
"""Tests _voice_speak_response with real CLI instance."""
|
||||
|
||||
def test_async_scheduling_clears_done_before_thread_start(self):
|
||||
cli = _make_voice_cli(_voice_tts=True)
|
||||
starts = []
|
||||
|
||||
class FakeThread:
|
||||
def __init__(self, target=None, args=(), daemon=None):
|
||||
self.target = target
|
||||
self.args = args
|
||||
self.daemon = daemon
|
||||
|
||||
def start(self):
|
||||
starts.append(cli._voice_tts_done.is_set())
|
||||
|
||||
with patch("cli.threading.Thread", FakeThread):
|
||||
cli._voice_speak_response_async("Hello")
|
||||
|
||||
assert starts == [False]
|
||||
assert not cli._voice_tts_done.is_set()
|
||||
|
||||
@patch("cli._cprint")
|
||||
def test_early_return_when_tts_off(self, _cp):
|
||||
cli = _make_voice_cli(_voice_tts=False)
|
||||
|
||||
Reference in New Issue
Block a user