mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(voice): silent cycles never end the chat while the agent is busy or TTS is playing
The continuous-voice no-speech counter (3 strikes -> voice off) counted every silent capture cycle unconditionally. During a long agent turn (thinking/tool-calling for minutes) or while TTS is speaking, the user is CORRECTLY silent — those cycles ended the voice chat under them. - hermes_cli/voice.py: new set_voice_busy_probe() seam + _voice_activity_held() (TTS-playing via the existing _tts_playing Event, agent-busy via the registered probe). Both the continuous-loop strike path and the force-transcribe single-shot strike path skip counting while held. Fail-open: a broken probe counts cycles as before. - tui_gateway/server.py: registers _any_session_running() as the probe on voice.record start (voice is process-global; any running session holds). - cli.py: classic CLI strike path skips counting while _agent_running or TTS playback is in flight. Stop phrase and barge-in still work during the hold (own paths). Includes a fixture fix for the #71083 cherry-pick: the fake tools.tts_tool module needs _load_tts_config (main's tts_streaming imports it).
This commit is contained in:
parent
be424703c4
commit
9e5f1b619c
5 changed files with 265 additions and 6 deletions
24
cli.py
24
cli.py
|
|
@ -12000,14 +12000,26 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
|
|||
pass
|
||||
|
||||
# Track consecutive no-speech cycles to avoid infinite restart loops.
|
||||
# While the agent is mid-turn or TTS is speaking, the user is
|
||||
# CORRECTLY silent (waiting/listening) — those cycles must not
|
||||
# count, or a multi-minute tool run ends the voice chat under
|
||||
# the user. The stop phrase and barge-in still work during the
|
||||
# hold (they run on their own paths above).
|
||||
stop_continuous_restart = False
|
||||
_activity_hold = bool(
|
||||
getattr(self, "_agent_running", False)
|
||||
or not self._voice_tts_done.is_set()
|
||||
)
|
||||
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}")
|
||||
stop_continuous_restart = True
|
||||
if _activity_hold:
|
||||
pass # held: keep listening without counting the cycle
|
||||
else:
|
||||
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}")
|
||||
stop_continuous_restart = True
|
||||
else:
|
||||
self._no_speech_count = 0
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue