fix: wrap sd.InputStream in try-except and fix config key name

- AudioRecorder.start() now catches InputStream errors gracefully
  with a clear error message about microphone availability
- Fix config key mismatch: cli.py was reading "push_to_talk_key"
  but config.py defines "record_key" -- now consistent
- Add format conversion from config format ("ctrl+b") to
  prompt_toolkit format ("c-b")
This commit is contained in:
0xbyt4
2026-03-09 13:12:57 +03:00
parent a8838a7ae5
commit fc893f98f4
2 changed files with 20 additions and 10 deletions

9
cli.py
View File

@@ -3825,7 +3825,8 @@ class HermesCLI:
tts_status = " (TTS enabled)" if self._voice_tts else ""
try:
from hermes_cli.config import load_config
_ptt_key = load_config().get("voice", {}).get("push_to_talk_key", "c-b")
_raw_ptt = load_config().get("voice", {}).get("record_key", "ctrl+b")
_ptt_key = _raw_ptt.lower().replace("ctrl+", "c-").replace("alt+", "a-")
except Exception:
_ptt_key = "c-b"
_ptt_display = _ptt_key.replace("c-", "Ctrl+").upper()
@@ -4818,11 +4819,13 @@ class HermesCLI:
self._should_exit = True
event.app.exit()
# Voice push-to-talk key: configurable via config.yaml (voice.push_to_talk_key)
# Voice push-to-talk key: configurable via config.yaml (voice.record_key)
# Default: Ctrl+B (avoids conflict with Ctrl+R readline reverse-search)
# Config uses "ctrl+b" format; prompt_toolkit expects "c-b" format.
try:
from hermes_cli.config import load_config
_voice_key = load_config().get("voice", {}).get("push_to_talk_key", "c-b")
_raw_key = load_config().get("voice", {}).get("record_key", "ctrl+b")
_voice_key = _raw_key.lower().replace("ctrl+", "c-").replace("alt+", "a-")
except Exception:
_voice_key = "c-b"

View File

@@ -291,13 +291,20 @@ class AudioRecorder:
if cb:
threading.Thread(target=cb, daemon=True).start()
self._stream = sd.InputStream(
samplerate=SAMPLE_RATE,
channels=CHANNELS,
dtype=DTYPE,
callback=_callback,
)
self._stream.start()
try:
self._stream = sd.InputStream(
samplerate=SAMPLE_RATE,
channels=CHANNELS,
dtype=DTYPE,
callback=_callback,
)
self._stream.start()
except Exception as e:
self._stream = None
raise RuntimeError(
f"Failed to open audio input stream: {e}. "
"Check that a microphone is connected and accessible."
) from e
self._recording = True
logger.info("Voice recording started (rate=%d, channels=%d)", SAMPLE_RATE, CHANNELS)