feat(voice): emit listening event between followup turns

После ответа Python сразу уходит в record() ждать follow-up
(FOLLOWUP_TIMEOUT), но планшет об этом не знал — оверлей тихо
скрывался и пользователю казалось что Cosmo его не слышит без
повторного wake-word.

Теперь между итерациями _conversation_loop шлётся notifier.listening() —
планшет показывает мягко пульсирующий орб с 'жду' + сохранённым
текстом прошлого ответа. Закрывается только по notifier.idle()
(таймаут тишины) или если пользователь что-то сказал (command).
This commit is contained in:
Cosmo
2026-04-23 13:55:39 +00:00
parent d1f95669e0
commit c7df540c0b
2 changed files with 11 additions and 1 deletions

View File

@@ -51,9 +51,13 @@ def _handle_reset(text: str, agent_id: str) -> bool:
def _conversation_loop(agent_id: str, agent_name: str = "Cosmo"): def _conversation_loop(agent_id: str, agent_name: str = "Cosmo"):
"""Основной цикл диалога. """Основной цикл диалога.
Первая запись — с большим таймаутом (MAX_DURATION), дальше — короткий FOLLOWUP_TIMEOUT.""" Первая запись — с большим таймаутом (MAX_DURATION), дальше — короткий FOLLOWUP_TIMEOUT.
Между итерациями шлём listening-event чтобы планшет показывал что всё ещё ждём."""
first = True first = True
while True: while True:
if not first:
# Follow-up — подсказываем планшету что слушаем, текст прошлого ответа сохраняется.
notifier.listening(agent_id)
timeout = MAX_DURATION if first else FOLLOWUP_TIMEOUT timeout = MAX_DURATION if first else FOLLOWUP_TIMEOUT
first = False first = False
text = record(initial_silence_timeout=timeout) text = record(initial_silence_timeout=timeout)

View File

@@ -72,3 +72,9 @@ def idle():
def error(text: str, agent_id: str = "cosmo"): def error(text: str, agent_id: str = "cosmo"):
_send("error", text=text, agent=agent_id) _send("error", text=text, agent=agent_id)
def listening(agent_id: str):
"""Голосовой ассистент слушает follow-up (после ответа) — планшет показывает
мягкую пульсацию, сохраняя текст предыдущего ответа."""
_send("listening", agent=agent_id)