---
read_when:
    - Настройка поведения голосового оверлея
summary: Жизненный цикл голосового оверлея при одновременном использовании фразы активации и функции «нажми и говори»
title: Голосовое наложение
x-i18n:
    generated_at: "2026-07-13T18:25:35Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 24
    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](/ru/platforms/macos)
- [Голосовая активация (macOS)](/ru/platforms/mac/voicewake)
- [Режим разговора](/ru/nodes/talk)
