---
read_when:
    - Налаштування поведінки голосового оверлею
summary: Життєвий цикл голосового оверлею, коли слово активації та режим «натисни, щоб говорити» накладаються
title: Голосовий оверлей
x-i18n:
    generated_at: "2026-05-06T06:16:13Z"
    model: gpt-5.5
    provider: openai
    source_hash: 5b30f50512e557bd5a50f0e4e8b7955a847b3b554694347d56638581fcda9514
    source_path: platforms/mac/voice-overlay.md
    workflow: 16
---

# Життєвий цикл голосового накладання (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
  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)
