fix(cli): avoid voice TTS restart race

This commit is contained in:
tmdgusya
2026-05-03 14:12:28 +09:00
committed by Teknium
parent 314fe9f827
commit a1cb811cb8
2 changed files with 31 additions and 5 deletions

17
cli.py
View File

@@ -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

View File

@@ -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)