feat(voice): "Say <stop-phrase> to end the voice chat" notice on voice-mode start (CLI/TUI/desktop, i18n)

One owner for the wording: voice_stop_hint() in tools/voice_mode.py —
sources the phrase from voice.stop_phrases (first entry) so a custom
phrase renders correctly, and returns "" when the feature is disabled
(stop_phrases: []) so no surface shows a hint.

- CLI: printed in /voice on output (style-matched dim notice).
- TUI: voice.toggle action=on now carries stop_hint; the Ink client
  renders it in the "Voice mode enabled" block (older gateways omit
  the field — no hint, no crash).
- Desktop: the renderer voice loop never touches tools/voice_mode.py,
  so the phrase is read from config (voice.stop_phrases → $voiceStopPhrase
  store, seeded in use-hermes-config) and shown as an info toast when a
  voice conversation starts. i18n: en/ja/zh/zh-hant/ar.
This commit is contained in:
Teknium
2026-07-29 00:41:56 -07:00
parent 9e5f1b619c
commit 6fdfdc1597
18 changed files with 201 additions and 3 deletions
+15
View File
@@ -1161,6 +1161,21 @@ def is_voice_stop_phrase(transcript: str, stop_phrases: Optional[tuple] = None)
return cleaned in stop_phrases
def voice_stop_hint() -> str:
"""One-line 'Say "stop" to end the voice chat.' hint for voice-mode start.
Sources the phrase from ``voice.stop_phrases`` (first entry) so a custom
phrase renders correctly; returns "" when stop phrases are disabled
(``stop_phrases: []``) so surfaces show no hint at all. Every surface
that announces voice-mode start (CLI /voice on, TUI, desktop) uses this
one owner instead of hardcoding the wording.
"""
phrases = _load_voice_stop_phrases()
if not phrases:
return ""
return f'Say "{phrases[0]}" to end the voice chat.'
# ============================================================================
# STT dispatch
# ============================================================================