После ответа Python сразу уходит в record() ждать follow-up
(FOLLOWUP_TIMEOUT), но планшет об этом не знал — оверлей тихо
скрывался и пользователю казалось что Cosmo его не слышит без
повторного wake-word.
Теперь между итерациями _conversation_loop шлётся notifier.listening() —
планшет показывает мягко пульсирующий орб с 'жду' + сохранённым
текстом прошлого ответа. Закрывается только по notifier.idle()
(таймаут тишины) или если пользователь что-то сказал (command).
When TABLET_URL and VOICE_API_KEY are set, the tablet handles TTS
via its ElevenLabs proxy — local speak() is skipped. Controlled
by TABLET_TTS_ENABLED (default true when tablet is configured).
- notifier.speak_locally() — gate used by all local speech paths
- llm._maybe_speak — no-op when tablet plays the voice
- modes._handle_reset — emits response event and skips local speak
when tablet TTS is on; keeps spoken fallback otherwise
Tablet side in smart-home-tablet repo: /api/voice/tts endpoint +
VoiceOverlay audio playback (commit ba2e… pending).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a thin HTTP bridge so the tablet at https://tablet.digital-home.site
shows a Siri-style overlay reflecting the current assistant state
(wake / command / response / idle / error). Non-fatal: if the tablet
is offline or TABLET_URL/VOICE_API_KEY are unset, events are silently
skipped and the assistant keeps working.
- satellite/notifier.py — POST /api/voice/event with bearer token,
reused requests.Session for keep-alive, 1.5s timeout
- satellite/modes.py — emits wake on activation, command after STT,
response after LLM, idle on timeout
- satellite/llm.py — emits error on gateway connection/timeout/HTTP
- .env.example documents TABLET_URL and VOICE_API_KEY
Tablet side (separate repo smart-home-tablet, commit 51c3d60) exposes
POST /api/voice/event + GET /api/voice/stream (SSE) and renders a
full-screen overlay in components/VoiceOverlay.tsx.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>