simplify(compat): voice_mode/transcription_common — drop 9 re-exports + the _configured_stop_phrases seam, repoint 3 callers + 4 test files

This commit is contained in:
Teknium
2026-09-03 13:30:31 -07:00
parent 707161e77b
commit 0515997887
9 changed files with 23 additions and 35 deletions
+2 -2
View File
@@ -454,7 +454,7 @@ class CLIVoiceMixin:
# Fail-closed echo guard: playback-phase capture has no echo cancellation, so
# a close match for what Hermes just spoke is speaker bleed, not a user turn.
if getattr(self, "_voice_barge_phase", None) == "playback":
from tools.voice_mode import is_tts_echo
from tools.voice_mode_transcript import is_tts_echo
if is_tts_echo(transcript, getattr(self, "_voice_last_tts_text", "")):
logger.debug(
"Dropping playback-phase barge transcript as TTS echo: %r", transcript)
@@ -529,7 +529,7 @@ class CLIVoiceMixin:
_cprint(f" {_DIM}{self._voice_record_key_label()} to start/stop recording{_RST}")
# Spoken-stop hint from voice.stop_phrases (first entry); "" when disabled.
try:
from tools.voice_mode import voice_stop_hint
from tools.voice_mode_transcript import voice_stop_hint
_stop_hint = voice_stop_hint()
except Exception:
_stop_hint = ""
+8 -9
View File
@@ -1802,10 +1802,12 @@ def test_voice_toggle_on_carries_stop_hint(monkeypatch):
monkeypatch.setitem(
sys.modules,
"tools.voice_mode",
types.SimpleNamespace(
check_voice_requirements=lambda: {"available": True, "details": ""},
voice_stop_hint=lambda: 'Say "halt" to end the voice chat.',
),
types.SimpleNamespace(check_voice_requirements=lambda: {"available": True, "details": ""}),
)
monkeypatch.setitem(
sys.modules,
"tools.voice_mode_transcript",
types.SimpleNamespace(voice_stop_hint=lambda: 'Say "halt" to end the voice chat.'),
)
monkeypatch.setenv("HERMES_VOICE", "0")
@@ -1817,11 +1819,8 @@ def test_voice_toggle_on_carries_stop_hint(monkeypatch):
# Disabled stop phrases → empty hint, clients show nothing.
monkeypatch.setitem(
sys.modules,
"tools.voice_mode",
types.SimpleNamespace(
check_voice_requirements=lambda: {"available": True, "details": ""},
voice_stop_hint=lambda: "",
),
"tools.voice_mode_transcript",
types.SimpleNamespace(voice_stop_hint=lambda: ""),
)
on_resp = _dispatch_sync(
{"id": "voice-on2", "method": "voice.toggle", "params": {"action": "on"}}
+1 -1
View File
@@ -630,7 +630,7 @@ class TestTypedVoiceStop:
# Hermetic: don't let a dev machine's voice.stop_phrases config
# change which utterances count as a stop phrase.
monkeypatch.setattr(
"tools.voice_mode._load_voice_stop_phrases", lambda: ("stop",)
"tools.voice_mode_transcript._load_voice_stop_phrases", lambda: ("stop",)
)
def test_typed_stop_ends_voice_chat_when_voice_on(self):
+6 -5
View File
@@ -13,7 +13,7 @@ from unittest.mock import patch
import pytest
from tools.voice_mode import (
from tools.voice_mode_transcript import (
DEFAULT_VOICE_STOP_PHRASES,
_load_voice_stop_phrases,
is_voice_stop_phrase,
@@ -25,12 +25,12 @@ class TestVoiceStopHint:
"""The 'Say "stop" to end the voice chat.' hint shown on voice-mode start."""
def test_default_phrase(self):
with patch("tools.voice_mode._load_voice_stop_phrases", return_value=("stop",)):
with patch("tools.voice_mode_transcript._load_voice_stop_phrases", return_value=("stop",)):
assert voice_stop_hint() == 'Say "stop" to end the voice chat.'
def test_disabled_phrases_show_no_hint(self):
with patch("tools.voice_mode._load_voice_stop_phrases", return_value=()):
with patch("tools.voice_mode_transcript._load_voice_stop_phrases", return_value=()):
assert voice_stop_hint() == ""
@@ -43,7 +43,7 @@ class TestIsVoiceStopPhrase:
def test_uses_config_when_phrases_omitted(self):
with patch("tools.voice_mode._load_voice_stop_phrases", return_value=("halt",)):
with patch("tools.voice_mode_transcript._load_voice_stop_phrases", return_value=("halt",)):
assert is_voice_stop_phrase("halt") is True
assert is_voice_stop_phrase("stop") is False
@@ -185,9 +185,10 @@ class TestStopPhraseSurvivesHallucinationFilter:
def _transcribe(self, text, phrases):
import tools.voice_mode as vm
import tools.voice_mode_transcript as vmt
with patch.object(
vm, "_load_voice_stop_phrases", return_value=tuple(phrases)
vmt, "_load_voice_stop_phrases", return_value=tuple(phrases)
), patch(
"tools.transcription_tools.transcribe_audio",
return_value={"success": True, "transcript": text},
+1 -1
View File
@@ -12,7 +12,7 @@ Contract:
instead of queuing it as the next user turn.
"""
from tools.voice_mode import is_tts_echo
from tools.voice_mode_transcript import is_tts_echo
class TestIsTtsEcho:
+1 -1
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
import logging
import os
import subprocess # noqa: F401 (type annotation only)
import subprocess
from typing import Any, Dict
from tools.tts_command_provider import _get_provider_section as _get_stt_section
+1 -6
View File
@@ -23,12 +23,7 @@ from typing import Any, Callable, Dict, List, Optional
logger = logging.getLogger(__name__)
from tools.voice_mode_transcript import ( # noqa: F401 - re-exported; tests patch tools.voice_mode.<name>
_voice_config, WHISPER_HALLUCINATIONS, _HALLUCINATION_REPEAT_RE, is_whisper_hallucination,
DEFAULT_VOICE_STOP_PHRASES, _load_voice_stop_phrases, is_voice_stop_phrase,
DEFAULT_TTS_ECHO_SIMILARITY_THRESHOLD, MIN_FRAGMENT_LENGTH_FOR_ECHO, _normalize_for_echo_compare,
is_tts_echo, voice_stop_hint,
)
from tools.voice_mode_transcript import _voice_config, is_voice_stop_phrase, is_whisper_hallucination
from hermes_constants import is_termux as _is_termux_environment
# ── Recording parameters ──
+2 -9
View File
@@ -56,19 +56,12 @@ def _load_voice_stop_phrases() -> tuple:
return DEFAULT_VOICE_STOP_PHRASES
def _configured_stop_phrases() -> tuple:
"""Resolve ``_load_voice_stop_phrases`` through ``tools.voice_mode`` so
``patch("tools.voice_mode._load_voice_stop_phrases")`` still takes effect."""
from tools import voice_mode as _vm
return _vm._load_voice_stop_phrases()
def is_voice_stop_phrase(transcript: str, stop_phrases: Optional[tuple] = None) -> bool:
"""True when *transcript* is EXACTLY a configured stop phrase. Deliberately strict: the whole
utterance — lowercased, surrounding punctuation stripped — must equal a phrase, so "stop doing
that and try again" still reaches the agent. ``voice.stop_phrases: []`` disables."""
cleaned = transcript.strip().lower().strip(".,!?;: \t\n\"'") if transcript else ""
return bool(cleaned) and cleaned in (_configured_stop_phrases() if stop_phrases is None else stop_phrases)
return bool(cleaned) and cleaned in (_load_voice_stop_phrases() if stop_phrases is None else stop_phrases)
# Similarity ratio (difflib.SequenceMatcher) above which a playback-phase barge transcript
@@ -113,5 +106,5 @@ def voice_stop_hint() -> str:
"""One-line 'Say "stop" to end the voice chat.' hint for voice-mode start, using the first
``voice.stop_phrases`` entry ("" when disabled). Every surface announcing voice-mode start
(CLI, TUI, desktop) uses this one owner instead of hardcoding the wording."""
phrases = _configured_stop_phrases()
phrases = _load_voice_stop_phrases()
return f'Say "{phrases[0]}" to end the voice chat.' if phrases else ""
+1 -1
View File
@@ -631,7 +631,7 @@ def _voice_toggle_mode(rid, params: dict) -> dict:
if enabled:
# Spoken-stop hint for the client; sourced from voice.stop_phrases, empty when disabled.
with contextlib.suppress(Exception):
from tools.voice_mode import voice_stop_hint
from tools.voice_mode_transcript import voice_stop_hint
stop_hint = voice_stop_hint()
# Speech output already on → warm the engine now, not on the first reply.
if _voice_tts_enabled():