hermes-agent/ui-tui/src
0xbyt4 98418afd5d fix(tui): break TTS→STT feedback loop + colorize REC badge
TTS feedback loop (hermes_cli/voice.py)

The VAD loop kept the microphone live while speak_text played the
agent's reply over the speakers, so the reply itself was picked up,
transcribed, and submitted — the agent then replied to its own echo
("Ha, looks like we're in a loop").

Ported cli.py:_voice_tts_done synchronisation:

- _tts_playing: threading.Event (initially set = "not playing").
- speak_text cancels the active recorder before opening the speakers,
  clears _tts_playing, and on exit waits 300 ms before re-starting the
  recorder — long enough for the OS audio device to settle so afplay
  and sounddevice don't race for it.
- _continuous_on_silence now waits on _tts_playing (up to 60 s) before
  re-arming the mic with another 300 ms gap, mirroring
  cli.py:10619-10621.  If the user flips voice off during the wait the
  loop exits cleanly instead of fighting for the device.

Without both halves the loop races: if the silence callback fires
before TTS starts it re-arms immediately; if TTS is already playing
the pause-and-resume path catches it.

Red REC badge (ui-tui appChrome + useMainApp)

Classic CLI (cli.py:_get_voice_status_fragments) renders "● REC" in
red and "◉ STT" in amber.  TUI was showing a dim "REC" with no dot,
making it hard to spot at a glance.  voiceLabel now emits the same
glyphs and appChrome colours them via t.color.error / t.color.warn,
falling back to dim for the idle label.
2026-04-23 16:18:15 -07:00
..
__tests__ feat(tui): match CLI's voice slash + VAD-continuous recording model 2026-04-23 16:18:15 -07:00
app fix(tui): break TTS→STT feedback loop + colorize REC badge 2026-04-23 16:18:15 -07:00
components fix(tui): break TTS→STT feedback loop + colorize REC badge 2026-04-23 16:18:15 -07:00
config chore(tui): /clean pass — inline one-off locals, tighten ConfirmPrompt 2026-04-19 07:55:38 -05:00
content fix(tui): input wrap width mismatch — last letter no longer flickers 2026-04-22 15:27:54 -05:00
domain refactor(ui-tui): clean touched resize and sticky prompt paths 2026-04-23 14:37:00 -05:00
hooks fix(tui): address PR #13231 review comments 2026-04-20 19:09:09 -05:00
lib fix(tui): route Ctrl+B to voice toggle, not composer input 2026-04-23 16:18:15 -07:00
protocol refactor(tui): /clean pass across ui-tui — 49 files, −217 LOC 2026-04-16 22:32:53 -05:00
types fix(tui): improve macOS paste and shortcut parity 2026-04-21 08:00:00 -07:00
app.tsx refactor(tui): store-driven turn state + slash registry + module split 2026-04-16 12:34:45 -05:00
banner.ts refactor(tui): /clean pass across ui-tui — 49 files, −217 LOC 2026-04-16 22:32:53 -05:00
entry.tsx fix(tui): drop main-screen banner flash, widen alt-screen clear on entry 2026-04-22 15:27:54 -05:00
gatewayClient.ts fix(tui): address PR #13231 review comments 2026-04-20 19:09:09 -05:00
gatewayTypes.ts feat(tui): match CLI's voice slash + VAD-continuous recording model 2026-04-23 16:18:15 -07:00
theme.ts feat(tui): subagent spawn observability overlay 2026-04-22 10:38:17 -05:00
types.ts feat(tui): subagent spawn observability overlay 2026-04-22 10:38:17 -05:00