> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Голосовий оверлей

# Життєвий цикл голосового накладання (macOS)

Аудиторія: контриб’ютори застосунку macOS. Мета: забезпечити передбачувану поведінку голосового накладання, коли фраза активації та режим «натисни й говори» перетинаються.

## Поточний задум

* Якщо накладання вже видиме через фразу активації, а користувач натискає гарячу клавішу, сесія гарячої клавіші *приймає* наявний текст замість його скидання. Накладання залишається відкритим, доки гаряча клавіша утримується. Коли користувач відпускає її: надіслати, якщо є обрізаний текст, інакше закрити.
* Одна лише фраза активації досі автоматично надсилає після тиші; режим «натисни й говори» надсилає одразу після відпускання.

## Реалізовано (9 грудня 2025 р.)

* Сесії накладання тепер мають токен для кожного захоплення (фраза активації або режим «натисни й говори»). Оновлення часткового/фінального тексту, надсилання, закриття та рівня відкидаються, коли токен не збігається, що запобігає застарілим callback.
* Режим «натисни й говори» приймає будь-який видимий текст накладання як префікс (тож натискання гарячої клавіші, поки накладання активації відкрите, зберігає текст і додає нове мовлення). Він очікує до 1,5 с на фінальну транскрипцію, перш ніж повернутися до поточного тексту.
* Журналювання сигналу/накладання виводиться на рівні `info` в категоріях `voicewake.overlay`, `voicewake.ptt` і `voicewake.chime` (початок сесії, частковий текст, фінальний текст, надсилання, закриття, причина сигналу).

## Наступні кроки

1. **VoiceSessionCoordinator (actor)**
   * У кожен момент володіє рівно однією `VoiceSession`.
   * API (на основі токенів): `beginWakeCapture`, `beginPushToTalk`, `updatePartial`, `endCapture`, `cancel`, `applyCooldown`.
   * Відкидає callback із застарілими токенами (запобігає повторному відкриттю накладання старими розпізнавачами).
2. **VoiceSession (model)**
   * Поля: `token`, `source` (wakeWord|pushToTalk), зафіксований/тимчасовий текст, прапорці сигналу, таймери (автоматичне надсилання, бездіяльність), `overlayMode` (display|editing|sending), крайній строк cooldown.
3. **Прив’язка накладання**
   * `VoiceSessionPublisher` (`ObservableObject`) віддзеркалює активну сесію у SwiftUI.
   * `VoiceWakeOverlayView` рендериться лише через publisher; він ніколи не змінює глобальні singletons напряму.
   * Дії користувача в накладанні (`sendNow`, `dismiss`, `edit`) викликають координатор із токеном сесії.
4. **Уніфікований шлях надсилання**
   * На `endCapture`: якщо обрізаний текст порожній → закрити; інакше `performSend(session:)` (відтворює сигнал надсилання один раз, пересилає, закриває).
   * Режим «натисни й говори»: без затримки; фраза активації: необов’язкова затримка для автоматичного надсилання.
   * Застосувати короткий cooldown до wake runtime після завершення режиму «натисни й говори», щоб фраза активації не запускалася повторно негайно.
5. **Журналювання**
   * Координатор виводить журнали `.info` у subsystem `ai.openclaw`, категоріях `voicewake.overlay` і `voicewake.chime`.
   * Ключові події: `session_started`, `adopted_by_push_to_talk`, `partial`, `finalized`, `send`, `dismiss`, `cancel`, `cooldown`.

## Контрольний список налагодження

* Потоково переглядайте журнали під час відтворення завислого накладання:

  ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
  sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact
  ```

* Перевірте, що активний лише один токен сесії; застарілі callback має відкидати координатор.

* Переконайтеся, що відпускання в режимі «натисни й говори» завжди викликає `endCapture` з активним токеном; якщо текст порожній, очікуйте `dismiss` без сигналу чи надсилання.

## Кроки міграції (запропоновано)

1. Додати `VoiceSessionCoordinator`, `VoiceSession` і `VoiceSessionPublisher`.
2. Переробити `VoiceWakeRuntime`, щоб створювати/оновлювати/завершувати сесії замість прямого звернення до `VoiceWakeOverlayController`.
3. Переробити `VoicePushToTalk`, щоб приймати наявні сесії та викликати `endCapture` після відпускання; застосувати cooldown runtime.
4. Під’єднати `VoiceWakeOverlayController` до publisher; прибрати прямі виклики з runtime/PTT.
5. Додати інтеграційні тести для прийняття сесії, cooldown і закриття за порожнього тексту.

## Пов’язане

* [Застосунок macOS](/uk/platforms/macos)
* [Голосова активація (macOS)](/uk/platforms/mac/voicewake)
* [Режим розмови](/uk/nodes/talk)
