diff --git a/docs/uk/plugins/voice-call.md b/docs/uk/plugins/voice-call.md
index a632e4a50..8c0382117 100644
--- a/docs/uk/plugins/voice-call.md
+++ b/docs/uk/plugins/voice-call.md
@@ -1,66 +1,102 @@
---
read_when:
- - Ви хочете здійснити вихідний голосовий дзвінок з OpenClaw
+ - Ви хочете здійснити вихідний голосовий виклик з OpenClaw
- Ви налаштовуєте або розробляєте плагін voice-call
-summary: 'Плагін Voice Call: вихідні + вхідні дзвінки через Twilio/Telnyx/Plivo (встановлення плагіна + конфігурація + CLI)'
-title: Плагін Voice call
+ - Вам потрібен голосовий зв’язок у реальному часі або потокова транскрипція в телефонії
+sidebarTitle: Voice call
+summary: Здійснюйте вихідні та приймайте вхідні голосові виклики через Twilio, Telnyx або Plivo, з необов’язковою голосовою взаємодією в реальному часі та потоковою транскрипцією
+title: Плагін голосових викликів
x-i18n:
- generated_at: "2026-04-25T19:29:27Z"
+ generated_at: "2026-04-26T05:46:13Z"
model: gpt-5.4
provider: openai
- source_hash: f6f6cb9346b63751756b8c6744b56486d1856b2d0f3b94082ced42c7435595d6
+ source_hash: 77b5e4b338b0c39c71accea7065af70fab695c8f34488ba0fbf7023f2f36f377
source_path: plugins/voice-call.md
workflow: 15
---
-Голосові дзвінки для OpenClaw через Plugin. Підтримує вихідні сповіщення та
-багатоходові розмови з політиками вхідних дзвінків.
+Голосові виклики для OpenClaw через Plugin. Підтримує вихідні сповіщення,
+багатокрокові розмови, повнодуплексний голосовий зв’язок у реальному часі, потокову
+транскрипцію та вхідні виклики з політиками списку дозволених номерів.
-Поточні провайдери:
+**Поточні провайдери:** `twilio` (Programmable Voice + Media Streams),
+`telnyx` (Call Control v2), `plivo` (Voice API + XML transfer + GetInput
+speech), `mock` (розробка/без мережі).
-- `twilio` (Programmable Voice + Media Streams)
-- `telnyx` (Call Control v2)
-- `plivo` (Voice API + XML transfer + GetInput speech)
-- `mock` (розробка/без мережі)
+
+Plugin Voice Call працює **всередині процесу Gateway**. Якщо ви використовуєте
+віддалений Gateway, установіть і налаштуйте Plugin на машині, де працює
+Gateway, а потім перезапустіть Gateway, щоб завантажити його.
+
-Швидка ментальна модель:
+## Швидкий старт
-- Встановіть Plugin
-- Перезапустіть Gateway
-- Налаштуйте в `plugins.entries.voice-call.config`
-- Використовуйте `openclaw voicecall ...` або інструмент `voice_call`
+
+
+
+
+ ```bash
+ openclaw plugins install @openclaw/voice-call
+ ```
+
+
+ ```bash
+ PLUGIN_SRC=./path/to/local/voice-call-plugin
+ openclaw plugins install "$PLUGIN_SRC"
+ cd "$PLUGIN_SRC" && pnpm install
+ ```
+
+
-## Де це працює (локально чи віддалено)
+ Після цього перезапустіть Gateway, щоб Plugin завантажився.
-Plugin Voice Call працює **всередині процесу Gateway**.
+
+
+ Укажіть конфігурацію в `plugins.entries.voice-call.config` (див.
+ [Конфігурація](#configuration) нижче для повної структури). Мінімально потрібні:
+ `provider`, облікові дані провайдера, `fromNumber` і
+ публічно доступна URL-адреса Webhook.
+
+
+ ```bash
+ openclaw voicecall setup
+ ```
-Якщо ви використовуєте віддалений Gateway, встановіть/налаштуйте Plugin на **машині, де працює Gateway**, а потім перезапустіть Gateway, щоб його завантажити.
+ Типовий вивід зручно читати в журналах чату та терміналах. Команда перевіряє
+ увімкнення Plugin, облікові дані провайдера, доступність Webhook і те,
+ що активний лише один аудіорежим (`streaming` або `realtime`). Для
+ скриптів використовуйте `--json`.
-## Встановлення
+
+
+ ```bash
+ openclaw voicecall smoke
+ openclaw voicecall smoke --to "+15555550123"
+ ```
-### Варіант A: встановити з npm (рекомендовано)
+ За замовчуванням обидві команди виконуються як dry run. Додайте `--yes`, щоб
+ справді здійснити короткий вихідний дзвінок-сповіщення:
-```bash
-openclaw plugins install @openclaw/voice-call
-```
+ ```bash
+ openclaw voicecall smoke --to "+15555550123" --yes
+ ```
-Після цього перезапустіть Gateway.
+
+
-### Варіант B: встановити з локальної папки (розробка, без копіювання)
-
-```bash
-PLUGIN_SRC=./path/to/local/voice-call-plugin
-openclaw plugins install "$PLUGIN_SRC"
-cd "$PLUGIN_SRC" && pnpm install
-```
-
-Після цього перезапустіть Gateway.
+
+Для Twilio, Telnyx і Plivo налаштування має визначатися як **публічна URL-адреса Webhook**.
+Якщо `publicUrl`, URL тунелю, URL Tailscale або резервний варіант serve
+визначається як loopback або приватний мережевий простір, налаштування завершиться помилкою замість
+запуску провайдера, який не зможе отримувати carrier Webhook.
+
## Конфігурація
-Задайте конфігурацію в `plugins.entries.voice-call.config`:
-
-Якщо `enabled` має значення true, але для вибраного провайдера відсутні облікові дані, під час запуску Gateway у журналах з’явиться попередження про незавершене налаштування з відсутніми ключами, і запуск runtime буде пропущено. Виконайте `openclaw voicecall setup`, щоб побачити ті самі відомості про готовність. Команди, RPC-виклики й інструменти агента все одно повертають точну інформацію про відсутню конфігурацію провайдера під час використання.
+Якщо `enabled: true`, але для вибраного провайдера відсутні облікові дані,
+під час запуску Gateway у журналі з’явиться попередження про неповне налаштування з відсутніми ключами, а
+запуск runtime буде пропущено. Команди, RPC-виклики та інструменти агента все одно
+повертатимуть точну відсутню конфігурацію провайдера під час використання.
```json5
{
@@ -77,15 +113,13 @@ cd "$PLUGIN_SRC" && pnpm install
accountSid: "ACxxxxxxxx",
authToken: "...",
},
-
telnyx: {
apiKey: "...",
connectionId: "...",
- // Публічний ключ webhook Telnyx з порталу Telnyx Mission Control
- // (рядок Base64; також можна задати через TELNYX_PUBLIC_KEY).
+ // Публічний ключ Webhook Telnyx з Mission Control Portal
+ // (Base64; також можна задати через TELNYX_PUBLIC_KEY).
publicKey: "...",
},
-
plivo: {
authId: "MAxxxxxxxxxxxxxxxxxxxx",
authToken: "...",
@@ -103,44 +137,17 @@ cd "$PLUGIN_SRC" && pnpm install
trustedProxyIPs: ["100.64.0.1"],
},
- // Публічний доступ (виберіть один варіант)
+ // Публічний доступ (виберіть один)
// publicUrl: "https://example.ngrok.app/voice/webhook",
// tunnel: { provider: "ngrok" },
- // tailscale: { mode: "funnel", path: "/voice/webhook" }
+ // tailscale: { mode: "funnel", path: "/voice/webhook" },
outbound: {
defaultMode: "notify", // notify | conversation
},
- streaming: {
- enabled: true,
- provider: "openai", // необов’язково; перший зареєстрований провайдер транскрипції в реальному часі, якщо не задано
- streamPath: "/voice/stream",
- providers: {
- openai: {
- apiKey: "sk-...", // необов’язково, якщо задано OPENAI_API_KEY
- model: "gpt-4o-transcribe",
- silenceDurationMs: 800,
- vadThreshold: 0.5,
- },
- },
- preStartTimeoutMs: 5000,
- maxPendingConnections: 32,
- maxPendingConnectionsPerIp: 4,
- maxConnections: 128,
- },
-
- realtime: {
- enabled: false,
- provider: "google", // необов’язково; перший зареєстрований провайдер голосу в реальному часі, якщо не задано
- toolPolicy: "safe-read-only",
- providers: {
- google: {
- model: "gemini-2.5-flash-native-audio-preview-12-2025",
- voice: "Kore",
- },
- },
- },
+ streaming: { enabled: true /* див. Потокова транскрипція */ },
+ realtime: { enabled: false /* див. Голосовий зв’язок у реальному часі */ },
},
},
},
@@ -148,324 +155,220 @@ cd "$PLUGIN_SRC" && pnpm install
}
```
-Перед тестуванням із реальним провайдером перевірте налаштування:
+
+
+ - Twilio, Telnyx і Plivo усі потребують **публічно доступної** URL-адреси Webhook.
+ - `mock` — це локальний провайдер для розробки (без мережевих викликів).
+ - Для Telnyx потрібен `telnyx.publicKey` (або `TELNYX_PUBLIC_KEY`), якщо лише `skipSignatureVerification` не має значення true.
+ - `skipSignatureVerification` призначено лише для локального тестування.
+ - На безкоштовному тарифі ngrok установіть `publicUrl` на точну URL-адресу ngrok; перевірка підпису завжди примусово увімкнена.
+ - `tunnel.allowNgrokFreeTierLoopbackBypass: true` дозволяє Webhook Twilio з недійсними підписами **лише** коли `tunnel.provider="ngrok"` і `serve.bind` — це loopback (локальний агент ngrok). Лише для локальної розробки.
+ - URL-адреси безкоштовного тарифу ngrok можуть змінюватися або додавати проміжну поведінку; якщо `publicUrl` зміниться, підписи Twilio перестануть проходити перевірку. Для production: надавайте перевагу стабільному домену або funnel у Tailscale.
+
+
+ - `streaming.preStartTimeoutMs` закриває сокети, які так і не надсилають коректний кадр `start`.
+ - `streaming.maxPendingConnections` обмежує загальну кількість неавтентифікованих сокетів до початку роботи.
+ - `streaming.maxPendingConnectionsPerIp` обмежує кількість неавтентифікованих сокетів до початку роботи на одну вихідну IP-адресу.
+ - `streaming.maxConnections` обмежує загальну кількість відкритих сокетів медіапотоку (очікування + активні).
+
+
+ Старіші конфігурації, що використовують `provider: "log"`, `twilio.from` або застарілі
+ ключі OpenAI у `streaming.*`, переписуються за допомогою `openclaw doctor --fix`.
+ Резервна сумісність runtime поки що все ще приймає старі ключі voice-call, але
+ шлях переписування — це `openclaw doctor --fix`, а shim сумісності —
+ тимчасовий.
-```bash
-openclaw voicecall setup
-```
+ Ключі потокової передачі, що мігруються автоматично:
-Типовий вивід зручно читати в журналах чату та сеансах термінала. Він перевіряє,
-чи увімкнено Plugin, чи наявні провайдер і облікові дані, чи налаштовано публічний доступ до webhook, і чи активний лише один аудіорежим. Для скриптів використовуйте
-`openclaw voicecall setup --json`.
+ - `streaming.sttProvider` → `streaming.provider`
+ - `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
+ - `streaming.sttModel` → `streaming.providers.openai.model`
+ - `streaming.silenceDurationMs` → `streaming.providers.openai.silenceDurationMs`
+ - `streaming.vadThreshold` → `streaming.providers.openai.vadThreshold`
-Для Twilio, Telnyx і Plivo налаштування має визначити публічний URL webhook. Якщо
-налаштований `publicUrl`, URL тунелю, URL Tailscale або резервний `serve`
-вказує на loopback чи простір приватної мережі, налаштування завершується помилкою замість запуску провайдера, який не може приймати реальні webhook від оператора.
-
-Для простого smoke-тесту без сюрпризів виконайте:
-
-```bash
-openclaw voicecall smoke
-openclaw voicecall smoke --to "+15555550123"
-```
-
-Друга команда все ще є dry run. Додайте `--yes`, щоб здійснити короткий вихідний
-дзвінок у режимі notify:
-
-```bash
-openclaw voicecall smoke --to "+15555550123" --yes
-```
-
-Примітки:
-
-- Twilio/Telnyx потребують **публічно доступного** URL webhook.
-- Plivo потребує **публічно доступного** URL webhook.
-- `mock` — це локальний провайдер для розробки (без мережевих викликів).
-- Якщо в старих конфігураціях досі використовується `provider: "log"`, `twilio.from` або застарілі ключі OpenAI `streaming.*`, виконайте `openclaw doctor --fix`, щоб переписати їх.
-- Telnyx потребує `telnyx.publicKey` (або `TELNYX_PUBLIC_KEY`), якщо лише `skipSignatureVerification` не має значення true.
-- `skipSignatureVerification` призначено лише для локального тестування.
-- Якщо ви використовуєте безкоштовний рівень ngrok, задайте `publicUrl` точно як URL ngrok; перевірка підпису завжди примусово виконується.
-- `tunnel.allowNgrokFreeTierLoopbackBypass: true` дозволяє webhook Twilio з недійсними підписами **лише** коли `tunnel.provider="ngrok"` і `serve.bind` є loopback (локальний агент ngrok). Використовуйте лише для локальної розробки.
-- URL безкоштовного рівня ngrok можуть змінюватися або додавати проміжну поведінку; якщо `publicUrl` зміниться, підписи Twilio не пройдуть перевірку. Для production краще використовувати стабільний домен або Tailscale funnel.
-- `realtime.enabled` запускає повноцінні голосові розмови voice-to-voice; не вмикайте його разом із `streaming.enabled`.
-- Типові параметри безпеки streaming:
- - `streaming.preStartTimeoutMs` закриває сокети, які так і не надсилають коректний кадр `start`.
-- `streaming.maxPendingConnections` обмежує загальну кількість неавтентифікованих pre-start сокетів.
-- `streaming.maxPendingConnectionsPerIp` обмежує кількість неавтентифікованих pre-start сокетів для кожної вихідної IP-адреси.
-- `streaming.maxConnections` обмежує загальну кількість відкритих сокетів медіапотоку (очікувані + активні).
-- Runtime fallback поки що все ще приймає ці старі ключі voice-call, але шлях переписування — це `openclaw doctor --fix`, а shim сумісності є тимчасовим.
+
+
## Голосові розмови в реальному часі
-`realtime` вибирає повнодуплексного провайдера голосу в реальному часі для аудіо
-живих дзвінків. Це окремо від `streaming`, який лише пересилає аудіо до
-провайдерів транскрипції в реальному часі.
+`realtime` вибирає повнодуплексного провайдера голосового зв’язку в реальному часі для живого аудіо виклику.
+Він відокремлений від `streaming`, який лише пересилає аудіо
+провайдерам транскрипції в реальному часі.
+
+
+`realtime.enabled` не можна поєднувати з `streaming.enabled`. Виберіть один
+аудіорежим на виклик.
+
Поточна поведінка runtime:
- `realtime.enabled` підтримується для Twilio Media Streams.
-- `realtime.enabled` не можна поєднувати з `streaming.enabled`.
-- `realtime.provider` є необов’язковим. Якщо не задано, Voice Call використовує першого
- зареєстрованого провайдера голосу в реальному часі.
-- Вбудовані провайдери голосу в реальному часі включають Google Gemini Live (`google`) і
- OpenAI (`openai`), зареєстровані їхніми Plugin провайдерів.
-- Необроблена конфігурація, якою керує провайдер, міститься в `realtime.providers.`.
-- Voice Call типово надає спільний інструмент реального часу `openclaw_agent_consult`.
- Модель реального часу може викликати його, коли абонент просить глибше
- міркування, актуальну інформацію або звичайні інструменти OpenClaw.
-- `realtime.toolPolicy` керує запуском consult:
- - `safe-read-only`: надавати інструмент consult і обмежувати звичайного агента
- інструментами `read`, `web_search`, `web_fetch`, `x_search`, `memory_search` і
- `memory_get`.
- - `owner`: надавати інструмент consult і дозволяти звичайному агенту використовувати звичайну
- політику інструментів агента.
- - `none`: не надавати інструмент consult. Користувацькі `realtime.tools` усе одно
- передаються провайдеру реального часу.
-- Ключі сеансу consult повторно використовують наявний голосовий сеанс, коли це можливо, а потім
- переходять до номера телефону абонента/одержувача, щоб подальші виклики consult зберігали
- контекст під час дзвінка.
-- Якщо `realtime.provider` вказує на незареєстрованого провайдера, або якщо взагалі не зареєстровано
- жодного провайдера голосу в реальному часі, Voice Call записує попередження в журнал і пропускає
- медіа реального часу замість того, щоб зламати весь Plugin.
+- `realtime.provider` є необов’язковим. Якщо його не задано, Voice Call використовує першого зареєстрованого провайдера голосового зв’язку в реальному часі.
+- Вбудовані провайдери голосового зв’язку в реальному часі: Google Gemini Live (`google`) і OpenAI (`openai`), зареєстровані їхніми Plugin провайдерів.
+- Необроблена конфігурація, що належить провайдеру, зберігається в `realtime.providers.`.
+- Voice Call за замовчуванням надає спільний інструмент реального часу `openclaw_agent_consult`. Модель реального часу може викликати його, коли абоненту потрібні глибші міркування, актуальна інформація або звичайні інструменти OpenClaw.
+- Якщо `realtime.provider` вказує на незареєстрованого провайдера або взагалі не зареєстровано жодного провайдера голосового зв’язку в реальному часі, Voice Call записує попередження в журнал і пропускає медіа реального часу замість помилки для всього Plugin.
+- Ключі сеансу consult повторно використовують наявний голосовий сеанс, коли це можливо, а потім повертаються до номера телефону того, хто дзвонить/кому дзвонять, щоб наступні consult-виклики зберігали контекст під час дзвінка.
-Типові налаштування реального часу Google Gemini Live:
+### Політика інструментів
-- API key: `realtime.providers.google.apiKey`, `GEMINI_API_KEY` або
- `GOOGLE_GENERATIVE_AI_API_KEY`
-- model: `gemini-2.5-flash-native-audio-preview-12-2025`
-- voice: `Kore`
+`realtime.toolPolicy` керує запуском consult:
-Приклад:
+| Політика | Поведінка |
+| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| `safe-read-only` | Надає інструмент consult і обмежує звичайного агента інструментами `read`, `web_search`, `web_fetch`, `x_search`, `memory_search` і `memory_get`. |
+| `owner` | Надає інструмент consult і дозволяє звичайному агенту використовувати стандартну політику інструментів агента. |
+| `none` | Не надає інструмент consult. Користувацькі `realtime.tools` усе одно передаються провайдеру реального часу. |
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- provider: "twilio",
- inboundPolicy: "allowlist",
- allowFrom: ["+15550005678"],
- realtime: {
- enabled: true,
- provider: "google",
- instructions: "Говори коротко. Викликай openclaw_agent_consult перед використанням глибших інструментів.",
- toolPolicy: "safe-read-only",
- providers: {
- google: {
- apiKey: "${GEMINI_API_KEY}",
- model: "gemini-2.5-flash-native-audio-preview-12-2025",
- voice: "Kore",
+### Приклади провайдерів реального часу
+
+
+
+ Типові значення: API-ключ із `realtime.providers.google.apiKey`,
+ `GEMINI_API_KEY` або `GOOGLE_GENERATIVE_AI_API_KEY`; модель
+ `gemini-2.5-flash-native-audio-preview-12-2025`; голос `Kore`.
+
+ ```json5
+ {
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ provider: "twilio",
+ inboundPolicy: "allowlist",
+ allowFrom: ["+15550005678"],
+ realtime: {
+ enabled: true,
+ provider: "google",
+ instructions: "Говори коротко. Викликай openclaw_agent_consult перед використанням глибших інструментів.",
+ toolPolicy: "safe-read-only",
+ providers: {
+ google: {
+ apiKey: "${GEMINI_API_KEY}",
+ model: "gemini-2.5-flash-native-audio-preview-12-2025",
+ voice: "Kore",
+ },
+ },
},
},
},
},
},
- },
- },
-}
-```
+ }
+ ```
-Замість цього використовуйте OpenAI:
-
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- realtime: {
- enabled: true,
- provider: "openai",
- providers: {
- openai: {
- apiKey: "${OPENAI_API_KEY}",
+
+
+ ```json5
+ {
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ realtime: {
+ enabled: true,
+ provider: "openai",
+ providers: {
+ openai: { apiKey: "${OPENAI_API_KEY}" },
+ },
},
},
},
},
},
- },
- },
-}
-```
+ }
+ ```
+
+
-Див. [Google provider](/uk/providers/google) і [OpenAI provider](/uk/providers/openai)
-для параметрів голосу в реальному часі, специфічних для провайдера.
+Див. [Google provider](/uk/providers/google) і
+[OpenAI provider](/uk/providers/openai) для параметрів голосового зв’язку в реальному часі,
+специфічних для провайдера.
-## Транскрипція streaming
+## Потокова транскрипція
-`streaming` вибирає провайдера транскрипції в реальному часі для аудіо живих дзвінків.
+`streaming` вибирає провайдера транскрипції в реальному часі для живого аудіо виклику.
Поточна поведінка runtime:
-- `streaming.provider` є необов’язковим. Якщо не задано, Voice Call використовує першого
- зареєстрованого провайдера транскрипції в реальному часі.
-- Вбудовані провайдери транскрипції в реальному часі включають Deepgram (`deepgram`),
- ElevenLabs (`elevenlabs`), Mistral (`mistral`), OpenAI (`openai`) і xAI
- (`xai`), зареєстровані їхніми Plugin провайдерів.
-- Необроблена конфігурація, якою керує провайдер, міститься в `streaming.providers.`.
-- Якщо `streaming.provider` вказує на незареєстрованого провайдера або якщо взагалі не зареєстровано
- жодного провайдера транскрипції в реальному часі, Voice Call записує попередження в журнал і
- пропускає медіапотік замість того, щоб зламати весь Plugin.
+- `streaming.provider` є необов’язковим. Якщо його не задано, Voice Call використовує першого зареєстрованого провайдера транскрипції в реальному часі.
+- Вбудовані провайдери транскрипції в реальному часі: Deepgram (`deepgram`), ElevenLabs (`elevenlabs`), Mistral (`mistral`), OpenAI (`openai`) і xAI (`xai`), зареєстровані їхніми Plugin провайдерів.
+- Необроблена конфігурація, що належить провайдеру, зберігається в `streaming.providers.`.
+- Якщо `streaming.provider` вказує на незареєстрованого провайдера або не зареєстровано жодного, Voice Call записує попередження в журнал і пропускає медіапотік замість помилки для всього Plugin.
-Типові налаштування транскрипції streaming OpenAI:
+### Приклади провайдерів потокової передачі
-- API key: `streaming.providers.openai.apiKey` або `OPENAI_API_KEY`
-- model: `gpt-4o-transcribe`
-- `silenceDurationMs`: `800`
-- `vadThreshold`: `0.5`
+
+
+ Типові значення: API-ключ `streaming.providers.openai.apiKey` або
+ `OPENAI_API_KEY`; модель `gpt-4o-transcribe`; `silenceDurationMs: 800`;
+ `vadThreshold: 0.5`.
-Типові налаштування транскрипції streaming xAI:
-
-- API key: `streaming.providers.xai.apiKey` або `XAI_API_KEY`
-- endpoint: `wss://api.x.ai/v1/stt`
-- `encoding`: `mulaw`
-- `sampleRate`: `8000`
-- `endpointingMs`: `800`
-- `interimResults`: `true`
-
-Приклад:
-
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- streaming: {
- enabled: true,
- provider: "openai",
- streamPath: "/voice/stream",
- providers: {
- openai: {
- apiKey: "sk-...", // необов’язково, якщо задано OPENAI_API_KEY
- model: "gpt-4o-transcribe",
- silenceDurationMs: 800,
- vadThreshold: 0.5,
+ ```json5
+ {
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ streaming: {
+ enabled: true,
+ provider: "openai",
+ streamPath: "/voice/stream",
+ providers: {
+ openai: {
+ apiKey: "sk-...", // необов’язково, якщо задано OPENAI_API_KEY
+ model: "gpt-4o-transcribe",
+ silenceDurationMs: 800,
+ vadThreshold: 0.5,
+ },
+ },
},
},
},
},
},
- },
- },
-}
-```
+ }
+ ```
-Замість цього використовуйте xAI:
+
+
+ Типові значення: API-ключ `streaming.providers.xai.apiKey` або `XAI_API_KEY`;
+ endpoint `wss://api.x.ai/v1/stt`; кодування `mulaw`; частота дискретизації `8000`;
+ `endpointingMs: 800`; `interimResults: true`.
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- streaming: {
- enabled: true,
- provider: "xai",
- streamPath: "/voice/stream",
- providers: {
- xai: {
- apiKey: "${XAI_API_KEY}", // необов’язково, якщо задано XAI_API_KEY
- endpointingMs: 800,
- language: "en",
+ ```json5
+ {
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ streaming: {
+ enabled: true,
+ provider: "xai",
+ streamPath: "/voice/stream",
+ providers: {
+ xai: {
+ apiKey: "${XAI_API_KEY}", // необов’язково, якщо задано XAI_API_KEY
+ endpointingMs: 800,
+ language: "en",
+ },
+ },
},
},
},
},
},
- },
- },
-}
-```
+ }
+ ```
-Застарілі ключі все ще автоматично мігруються за допомогою `openclaw doctor --fix`:
+
+
-- `streaming.sttProvider` → `streaming.provider`
-- `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
-- `streaming.sttModel` → `streaming.providers.openai.model`
-- `streaming.silenceDurationMs` → `streaming.providers.openai.silenceDurationMs`
-- `streaming.vadThreshold` → `streaming.providers.openai.vadThreshold`
+## TTS для викликів
-## Очищувач застарілих дзвінків
-
-Використовуйте `staleCallReaperSeconds`, щоб завершувати дзвінки, які ніколи не отримують термінальний webhook
-(наприклад, дзвінки в режимі notify, які ніколи не завершуються). Типове значення — `0`
-(вимкнено).
-
-Рекомендовані діапазони:
-
-- **Production:** `120`–`300` секунд для потоків у стилі notify.
-- Тримайте це значення **вищим за `maxDurationSeconds`**, щоб звичайні дзвінки могли
- завершитися. Хороша початкова точка — `maxDurationSeconds + 30–60` секунд.
-
-Приклад:
-
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- maxDurationSeconds: 300,
- staleCallReaperSeconds: 360,
- },
- },
- },
- },
-}
-```
-
-## Безпека Webhook
-
-Коли перед Gateway розташований проксі або тунель, Plugin відновлює
-публічний URL для перевірки підпису. Ці параметри керують тим,
-яким пересланим заголовкам довіряти.
-
-`webhookSecurity.allowedHosts` задає список дозволених хостів із пересланих заголовків.
-
-`webhookSecurity.trustForwardingHeaders` довіряє пересланим заголовкам без списку дозволених.
-
-`webhookSecurity.trustedProxyIPs` довіряє пересланим заголовкам, лише якщо
-віддалена IP-адреса запиту збігається зі списком.
-
-Захист від повторного відтворення webhook увімкнено для Twilio і Plivo. Повторно відтворені коректні webhook-запити
-підтверджуються, але пропускаються щодо побічних ефектів.
-
-Повороти розмови Twilio включають токен на кожен поворот у зворотних викликах ``, тож
-застарілі/повторно відтворені callback-и мовлення не можуть задовольнити новіший очікуваний поворот транскрипту.
-
-Неавтентифіковані webhook-запити відхиляються до читання тіла, якщо
-відсутні обов’язкові заголовки підпису провайдера.
-
-Webhook voice-call використовує спільний профіль тіла pre-auth (64 KB / 5 секунд)
-плюс обмеження кількості одночасних запитів на IP перед перевіркою підпису.
-
-Приклад зі стабільним публічним хостом:
-
-```json5
-{
- plugins: {
- entries: {
- "voice-call": {
- config: {
- publicUrl: "https://voice.example.com/voice/webhook",
- webhookSecurity: {
- allowedHosts: ["voice.example.com"],
- },
- },
- },
- },
- },
-}
-```
-
-## TTS для дзвінків
-
-Voice Call використовує основну конфігурацію `messages.tts` для
-потокового мовлення під час дзвінків. Ви можете перевизначити її в конфігурації Plugin із
-**тією самою структурою** — вона глибоко зливається з `messages.tts`.
+Voice Call використовує базову конфігурацію `messages.tts` для потокового
+синтезу мовлення під час викликів. Її можна перевизначити в конфігурації Plugin із
+**тією самою структурою** — вона глибоко об’єднується з `messages.tts`.
```json5
{
@@ -481,21 +384,23 @@ Voice Call використовує основну конфігурацію `mes
}
```
-Примітки:
+
+**Microsoft speech ігнорується для голосових викликів.** Аудіо телефонії потребує PCM;
+поточний транспорт Microsoft не надає телекомунікаційний PCM-вивід.
+
-- Застарілі ключі `tts.` у конфігурації Plugin (`openai`, `elevenlabs`, `microsoft`, `edge`) виправляються через `openclaw doctor --fix`; у збереженій конфігурації слід використовувати `tts.providers.`.
-- **Microsoft speech ігнорується для голосових дзвінків** (телефонному аудіо потрібен PCM; поточний транспорт Microsoft не надає вихід PCM для телефонії).
-- Основний TTS використовується, коли увімкнено потокову передачу медіа Twilio; в іншому разі дзвінки повертаються до рідних голосів провайдера.
-- Якщо медіапотік Twilio вже активний, Voice Call не повертається до TwiML ``. Якщо TTS телефонії недоступний у такому стані, запит на відтворення завершується помилкою замість змішування двох шляхів відтворення.
-- Коли TTS телефонії повертається до вторинного провайдера, Voice Call записує попередження з ланцюжком провайдерів (`from`, `to`, `attempts`) для налагодження.
-- Коли barge-in Twilio або завершення потоку очищає чергу очікування TTS, поставлені в чергу
- запити відтворення завершуються замість зависання абонентів, які очікують завершення
- відтворення.
+Примітки щодо поведінки:
-### Більше прикладів
+- Застарілі ключі `tts.` у конфігурації Plugin (`openai`, `elevenlabs`, `microsoft`, `edge`) виправляються за допомогою `openclaw doctor --fix`; збережена конфігурація має використовувати `tts.providers.`.
+- Базовий TTS використовується, коли увімкнено потокову передачу медіа Twilio; інакше виклики повертаються до голосів, вбудованих у провайдера.
+- Якщо потік медіа Twilio уже активний, Voice Call не повертається до TwiML ``. Якщо TTS для телефонії недоступний у цьому стані, запит на відтворення завершується помилкою замість змішування двох шляхів відтворення.
+- Коли TTS для телефонії повертається до вторинного провайдера, Voice Call записує попередження в журнал із ланцюжком провайдерів (`from`, `to`, `attempts`) для налагодження.
+- Коли barge-in Twilio або завершення потоку очищає чергу TTS, що очікує, запити на відтворення в черзі завершуються замість того, щоб змушувати абонентів чекати завершення відтворення.
-Використовувати лише основний TTS (без перевизначення):
+### Приклади TTS
+
+
```json5
{
messages: {
@@ -508,9 +413,8 @@ Voice Call використовує основну конфігурацію `mes
},
}
```
-
-Перевизначити на ElevenLabs лише для дзвінків (залишити основне типове значення деінде):
-
+
+
```json5
{
plugins: {
@@ -533,9 +437,8 @@ Voice Call використовує основну конфігурацію `mes
},
}
```
-
-Перевизначити лише модель OpenAI для дзвінків (приклад глибокого злиття):
-
+
+
```json5
{
plugins: {
@@ -556,63 +459,137 @@ Voice Call використовує основну конфігурацію `mes
},
}
```
+
+
-## Вхідні дзвінки
+## Вхідні виклики
-Типове значення політики вхідних дзвінків — `disabled`. Щоб увімкнути вхідні дзвінки, задайте:
+Політика вхідних викликів за замовчуванням має значення `disabled`. Щоб увімкнути вхідні виклики, задайте:
```json5
{
inboundPolicy: "allowlist",
allowFrom: ["+15550001234"],
- inboundGreeting: "Вітаю! Чим я можу допомогти?",
+ inboundGreeting: "Привіт! Чим я можу допомогти?",
}
```
-`inboundPolicy: "allowlist"` — це екранування caller ID з низьким рівнем гарантії. Plugin
-нормалізує надане провайдером значення `From` і порівнює його з `allowFrom`.
-Перевірка webhook автентифікує доставку провайдера та цілісність навантаження, але
-не доводить право власності на номер абонента PSTN/VoIP. Сприймайте `allowFrom` як
-фільтрацію caller ID, а не як сильну ідентичність абонента.
+
+`inboundPolicy: "allowlist"` — це екранування caller ID з низьким рівнем достовірності.
+Plugin нормалізує значення `From`, надане провайдером, і порівнює його з
+`allowFrom`. Перевірка Webhook автентифікує доставку провайдера та
+цілісність payload, але **не** доводить право власності на номер
+того, хто телефонує, у PSTN/VoIP. Розглядайте `allowFrom` як фільтрацію caller ID, а не як надійну
+ідентичність абонента.
+
-Автовідповіді використовують систему агента. Налаштовуйте за допомогою:
-
-- `responseModel`
-- `responseSystemPrompt`
-- `responseTimeoutMs`
+Автовідповіді використовують систему агента. Налаштовуйте їх за допомогою `responseModel`,
+`responseSystemPrompt` і `responseTimeoutMs`.
### Контракт озвученого виводу
-Для автовідповідей Voice Call додає до системного prompt суворий контракт озвученого виводу:
+Для автовідповідей Voice Call додає до системного промпту строгий контракт
+озвученого виводу:
-- `{"spoken":"..."}`
+```text
+{"spoken":"..."}
+```
-Потім Voice Call обережно витягує текст мовлення:
+Voice Call захищено витягує текст мовлення:
-- Ігнорує навантаження, позначені як вміст міркувань/помилок.
-- Аналізує прямий JSON, JSON у fenced-блоках або вбудовані ключі `"spoken"`.
-- Повертається до звичайного тексту й видаляє ймовірні вступні абзаци планування/мета.
+- Ігнорує payload, позначені як reasoning/error content.
+- Аналізує прямий JSON, JSON в огородженому блоці або вбудовані ключі `"spoken"`.
+- Повертається до звичайного тексту та видаляє ймовірні вступні абзаци з плануванням/метаінформацією.
-Це допомагає зосередити озвучення на тексті для абонента й уникнути витоку тексту планування в аудіо.
+Це допомагає зосередити озвучене відтворення на тексті для абонента й уникати
+потрапляння тексту планування в аудіо.
### Поведінка запуску розмови
-Для вихідних дзвінків `conversation` обробка першого повідомлення пов’язана зі станом відтворення в реальному часі:
+Для вихідних викликів `conversation` обробка першого повідомлення прив’язана до стану
+живого відтворення:
-- Очищення черги через barge-in й автовідповідь пригнічуються лише тоді, коли початкове привітання активно озвучується.
-- Якщо початкове відтворення завершується помилкою, дзвінок повертається до `listening`, а початкове повідомлення залишається в черзі для повторної спроби.
-- Початкове відтворення для потокової передачі Twilio починається після підключення потоку без додаткової затримки.
-- Barge-in перериває активне відтворення й очищає записи TTS Twilio, що стоять у черзі, але ще не почали відтворюватися.
- Очищені записи завершуються як пропущені, тож подальша логіка відповіді
- може продовжитися без очікування аудіо, яке ніколи не буде відтворене.
-- Голосові розмови в реальному часі використовують власний вступний поворот потоку реального часу. Voice Call не надсилає застаріле оновлення TwiML `` для цього початкового повідомлення, тож вихідні сеанси `` залишаються підключеними.
+- Очищення черги через barge-in і автовідповідь пригнічуються лише поки початкове привітання активно озвучується.
+- Якщо початкове відтворення завершується помилкою, виклик повертається до `listening`, а початкове повідомлення залишається в черзі для повторної спроби.
+- Початкове відтворення для потокової передачі Twilio запускається після підключення потоку без додаткової затримки.
+- Barge-in перериває активне відтворення й очищає записи TTS Twilio, що стоять у черзі, але ще не почали відтворюватися. Очищені записи завершуються як пропущені, тож подальша логіка відповіді може продовжитися без очікування аудіо, яке ніколи не буде відтворене.
+- Голосові розмови в реальному часі використовують власний початковий хід потоку реального часу. Voice Call **не** надсилає застаріле оновлення TwiML `` для цього початкового повідомлення, тому вихідні сеанси `` залишаються підключеними.
-### Пільговий період від’єднання потоку Twilio
+### Пільговий період при від’єднанні потоку Twilio
-Коли медіапотік Twilio від’єднується, Voice Call чекає `2000ms`, перш ніж автоматично завершити дзвінок:
+Коли медіапотік Twilio від’єднується, Voice Call чекає **2000 мс** перед
+автоматичним завершенням виклику:
-- Якщо потік повторно підключається протягом цього вікна, автозавершення скасовується.
-- Якщо після пільгового періоду потік не зареєстровано знову, дзвінок завершується, щоб запобігти завислим активним дзвінкам.
+- Якщо потік повторно підключається протягом цього вікна, авто-завершення скасовується.
+- Якщо після пільгового періоду жоден потік не реєструється повторно, виклик завершується, щоб запобігти зависанню активних викликів.
+
+## Очищувач застарілих викликів
+
+Використовуйте `staleCallReaperSeconds`, щоб завершувати виклики, які ніколи не отримують термінального
+Webhook (наприклад, виклики в режимі notify, які ніколи не завершуються). Значення за замовчуванням —
+`0` (вимкнено).
+
+Рекомендовані діапазони:
+
+- **Production:** `120`–`300` секунд для потоків у стилі notify.
+- Тримайте це значення **вищим за `maxDurationSeconds`**, щоб звичайні виклики могли завершитися. Гарна початкова точка — `maxDurationSeconds + 30–60` секунд.
+
+```json5
+{
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ maxDurationSeconds: 300,
+ staleCallReaperSeconds: 360,
+ },
+ },
+ },
+ },
+}
+```
+
+## Безпека Webhook
+
+Коли перед Gateway розташовано проксі або тунель, Plugin
+відновлює публічну URL-адресу для перевірки підпису. Ці параметри
+керують тим, яким forwarded headers довіряти:
+
+
+ Список дозволених хостів із forwarding headers.
+
+
+ Довіряти forwarded headers без списку дозволених.
+
+
+ Довіряти forwarded headers лише коли віддалена IP-адреса запиту збігається зі списком.
+
+
+Додатковий захист:
+
+- **Захист від повторного відтворення** Webhook увімкнено для Twilio і Plivo. Повторно відтворені коректні запити Webhook підтверджуються, але пропускаються для побічних ефектів.
+- Ходи розмови Twilio включають токен на кожен хід у callback ` `, тож застарілі/повторно відтворені callback мовлення не можуть задовольнити новіший хід транскрипції, що очікує.
+- Неавтентифіковані запити Webhook відхиляються ще до читання тіла, якщо відсутні обов’язкові заголовки підпису провайдера.
+- Webhook voice-call використовує спільний профіль тіла до автентифікації (64 КБ / 5 секунд) плюс обмеження на кількість одночасних запитів з однієї IP-адреси до перевірки підпису.
+
+Приклад зі стабільним публічним хостом:
+
+```json5
+{
+ plugins: {
+ entries: {
+ "voice-call": {
+ config: {
+ publicUrl: "https://voice.example.com/voice/webhook",
+ webhookSecurity: {
+ allowedHosts: ["voice.example.com"],
+ },
+ },
+ },
+ },
+ },
+}
+```
## CLI
@@ -625,41 +602,43 @@ openclaw voicecall dtmf --call-id --digits "ww123456#"
openclaw voicecall end --call-id
openclaw voicecall status --call-id
openclaw voicecall tail
-openclaw voicecall latency # узагальнює затримку поворотів із журналів
+openclaw voicecall latency # зведення затримки ходів із журналів
openclaw voicecall expose --mode funnel
```
-`latency` читає `calls.jsonl` зі стандартного шляху сховища voice-call. Використовуйте
-`--file `, щоб указати інший журнал, і `--last `, щоб обмежити аналіз
-останніми N записами (типово 200). Вивід включає p50/p90/p99 для затримки
-поворотів і часу очікування прослуховування.
+`latency` читає `calls.jsonl` зі стандартного шляху зберігання voice-call.
+Використовуйте `--file `, щоб указати інший журнал, і `--last `, щоб обмежити
+аналіз останніми N записами (типово 200). Вивід містить p50/p90/p99
+для затримки ходу та часу очікування прослуховування.
## Інструмент агента
-Назва інструмента: `voice_call`
+Назва інструмента: `voice_call`.
-Дії:
+| Дія | Аргументи |
+| --------------- | ------------------------ |
+| `initiate_call` | `message`, `to?`, `mode?` |
+| `continue_call` | `callId`, `message` |
+| `speak_to_user` | `callId`, `message` |
+| `send_dtmf` | `callId`, `digits` |
+| `end_call` | `callId` |
+| `get_status` | `callId` |
-- `initiate_call` (message, to?, mode?)
-- `continue_call` (callId, message)
-- `speak_to_user` (callId, message)
-- `send_dtmf` (callId, digits)
-- `end_call` (callId)
-- `get_status` (callId)
+Цей репозиторій містить відповідний документ skill за адресою `skills/voice-call/SKILL.md`.
-Цей репозиторій містить відповідний документ Skills за адресою `skills/voice-call/SKILL.md`.
+## Gateway RPC
-## RPC Gateway
-
-- `voicecall.initiate` (`to?`, `message`, `mode?`)
-- `voicecall.continue` (`callId`, `message`)
-- `voicecall.speak` (`callId`, `message`)
-- `voicecall.dtmf` (`callId`, `digits`)
-- `voicecall.end` (`callId`)
-- `voicecall.status` (`callId`)
+| Метод | Аргументи |
+| ------------------- | ------------------------ |
+| `voicecall.initiate` | `to?`, `message`, `mode?` |
+| `voicecall.continue` | `callId`, `message` |
+| `voicecall.speak` | `callId`, `message` |
+| `voicecall.dtmf` | `callId`, `digits` |
+| `voicecall.end` | `callId` |
+| `voicecall.status` | `callId` |
## Пов’язане
-- [Перетворення тексту на мовлення](/uk/tools/tts)
- [Режим розмови](/uk/nodes/talk)
+- [Перетворення тексту на мовлення](/uk/tools/tts)
- [Голосове пробудження](/uk/nodes/voicewake)