---
read_when:
    - Налаштування поведінки голосового накладання
summary: Життєвий цикл голосового оверлею, коли активація за ключовим словом і режим «натисни й говори» перекриваються
title: Голосове накладання
x-i18n:
    generated_at: "2026-07-12T13:28:06Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: eef571c3e8d41a97779537b1b373fab25b08f63575b50e5019f6c5fbcb782c52
    source_path: platforms/mac/voice-overlay.md
    workflow: 16
---

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

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

## Поведінка

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

## Реалізація

- `VoiceSessionCoordinator` (`apps/macos/Sources/OpenClaw/VoiceSessionCoordinator.swift`) — єдиний власник активного голосового сеансу. Це одноелементний об’єкт `@MainActor @Observable`, а не актор. API: `startSession`, `updatePartial`, `finalize`, `sendNow`, `dismiss`, `updateLevel`, `snapshot`. Кожен сеанс містить токен `UUID`; виклики із застарілим або невідповідним токеном відкидаються.
- `VoiceWakeOverlayController` (`VoiceWakeOverlayController+Session.swift`) відтворює накладання та передає дії користувача (`requestSend`, `dismiss`) назад через координатор за допомогою токена сеансу. Він ніколи сам не володіє станом сеансу.
- Режим «натисни й говори» (`VoicePushToTalk.begin()`) приймає весь текст видимого накладання як `adoptedPrefix` (через `VoiceSessionCoordinator.shared.snapshot()`), тому натискання гарячої клавіші під час відображення накладання активації за ключовим словом зберігає текст і додає до нього нове мовлення. Після відпускання він очікує остаточну транскрипцію до 1,5 с, а потім використовує поточний текст як резервний варіант.
- Під час `dismiss` накладання викликає `VoiceSessionCoordinator.overlayDidDismiss`, що запускає `VoiceWakeRuntime.refresh(state:)`, тому ручне закриття кнопкою X, закриття через порожній текст і закриття після надсилання відновлюють прослуховування ключового слова.
- Уніфікований шлях надсилання: якщо після обрізання пробілів текст порожній, закрити; інакше `sendNow` один раз відтворює сигнал надсилання, пересилає дані через `VoiceWakeForwarder`, а потім закриває накладання.

## Журналювання

Підсистема голосових функцій — `ai.openclaw`; кожен компонент записує журнали у власній категорії:

| Категорія               | Компонент                                       |
| ----------------------- | ----------------------------------------------- |
| `voicewake.coordinator` | `VoiceSessionCoordinator`                       |
| `voicewake.overlay`     | `VoiceWakeOverlayController`/`VoiceWakeOverlay` |
| `voicewake.ptt`         | Гаряча клавіша та захоплення в режимі «натисни й говори» |
| `voicewake.runtime`     | Середовище виконання активації за ключовим словом |
| `voicewake.chime`       | Відтворення звукового сигналу                   |
| `voicewake.sync`        | Синхронізація глобальних налаштувань            |
| `voicewake.forward`     | Пересилання транскрипції                        |
| `voicewake.meter`       | Монітор рівня мікрофона                         |

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

- Транслюйте журнали під час відтворення проблеми із завислим накладанням:

  ```bash
  sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact
  ```

- Переконайтеся, що активний лише один токен сеансу; застарілі зворотні виклики відкидаються координатором.
- Переконайтеся, що відпускання клавіші режиму «натисни й говори» завжди викликає `end()` з активним токеном; якщо текст порожній, очікуйте закриття без звукового сигналу та надсилання.

## Пов’язані матеріали

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