From f44f34ea902baec4fc2e929ea9f8eef5c7cd32ae Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Sun, 26 Apr 2026 05:47:36 +0000 Subject: [PATCH] chore(i18n): refresh uk translations --- docs/uk/plugins/voice-call.md | 807 +++++++++++++++++----------------- 1 file changed, 393 insertions(+), 414 deletions(-) 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)