diff --git a/docs/uk/channels/imessage.md b/docs/uk/channels/imessage.md
index 61c239a86..39ed4210f 100644
--- a/docs/uk/channels/imessage.md
+++ b/docs/uk/channels/imessage.md
@@ -2,13 +2,13 @@
read_when:
- Налаштування підтримки iMessage
- Налагодження надсилання/отримання iMessage
-summary: Застаріла підтримка iMessage через imsg (JSON-RPC через stdio). Для нових налаштувань слід використовувати BlueBubbles.
+summary: Застаріла підтримка iMessage через imsg (JSON-RPC через stdio). У нових налаштуваннях слід використовувати BlueBubbles.
title: iMessage
x-i18n:
- generated_at: "2026-04-05T17:58:18Z"
+ generated_at: "2026-04-21T21:27:21Z"
model: gpt-5.4
provider: openai
- source_hash: 086d85bead49f75d12ae6b14ac917af52375b6afd28f6af1a0dcbbc7fcb628a0
+ source_hash: fb9cc5a0bd4fbc7ff6f792e737bc4302a67f9ab6aa8231ff6f751fe6d732ca5d
source_path: channels/imessage.md
workflow: 15
---
@@ -16,21 +16,21 @@ x-i18n:
# iMessage (застаріле: imsg)
-Для нових розгортань iMessage використовуйте BlueBubbles.
+Для нових розгортань iMessage використовуйте BlueBubbles.
-Інтеграція `imsg` є застарілою та може бути видалена в одному з майбутніх випусків.
+Інтеграція `imsg` є застарілою і може бути вилучена в майбутньому випуску.
-Стан: застаріла зовнішня інтеграція CLI. Gateway запускає `imsg rpc` і обмінюється даними через JSON-RPC по stdio (без окремого демона/порту).
+Статус: застаріла зовнішня інтеграція CLI. Gateway запускає `imsg rpc` і обмінюється даними через JSON-RPC по stdio (без окремого демона/порту).
-
+
Бажаний шлях iMessage для нових налаштувань.
-
- Для приватних повідомлень iMessage типово використовується режим прив’язки.
+
+ Прямі повідомлення iMessage типово використовують режим сполучення.
-
+
Повний довідник полів iMessage.
@@ -40,7 +40,7 @@ x-i18n:
-
+
```bash
brew install steipete/tap/imsg
@@ -57,7 +57,7 @@ imsg rpc --help
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
- dbPath: "/Users//Library/Messages/chat.db",
+ dbPath: "/Users/user/Library/Messages/chat.db",
},
},
}
@@ -73,21 +73,21 @@ openclaw gateway
-
+
```bash
openclaw pairing list imessage
openclaw pairing approve imessage
```
- Запити на прив’язку спливають через 1 годину.
+ Запити на сполучення спливають через 1 годину.
- OpenClaw потребує лише сумісний зі stdio `cliPath`, тому ви можете вказати для `cliPath` обгортковий скрипт, який підключається через SSH до віддаленого Mac і запускає `imsg`.
+ OpenClaw потребує лише сумісний зі stdio `cliPath`, тож ви можете вказати в `cliPath` скрипт-обгортку, який підключається через SSH до віддаленого Mac і запускає `imsg`.
```bash
#!/usr/bin/env bash
@@ -104,8 +104,8 @@ exec ssh -T gateway-host imsg "$@"
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "user@gateway-host", // використовується для отримання вкладень через SCP
includeAttachments: true,
- // Необов’язково: перевизначити дозволені корені вкладень.
- // Типово включають /Users/*/Library/Messages/Attachments
+ // Необов’язково: перевизначити дозволені кореневі каталоги вкладень.
+ // Типово включає /Users/*/Library/Messages/Attachments
attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],
},
@@ -113,22 +113,22 @@ exec ssh -T gateway-host imsg "$@"
}
```
- Якщо `remoteHost` не задано, OpenClaw спробує автоматично визначити його, аналізуючи обгортковий SSH-скрипт.
- `remoteHost` має бути у форматі `host` або `user@host` (без пробілів або параметрів SSH).
- OpenClaw використовує сувору перевірку ключа хоста для SCP, тому ключ хоста ретранслятора вже має бути присутній у `~/.ssh/known_hosts`.
- Шляхи вкладень перевіряються відносно дозволених коренів (`attachmentRoots` / `remoteAttachmentRoots`).
+ Якщо `remoteHost` не задано, OpenClaw намагається автоматично визначити його, аналізуючи SSH-скрипт-обгортку.
+ `remoteHost` має бути у форматі `host` або `user@host` (без пробілів чи параметрів SSH).
+ OpenClaw використовує сувору перевірку ключа хоста для SCP, тому ключ хоста ретранслятора вже має бути наявний у `~/.ssh/known_hosts`.
+ Шляхи до вкладень перевіряються на відповідність дозволеним кореневим каталогам (`attachmentRoots` / `remoteAttachmentRoots`).
## Вимоги та дозволи (macOS)
-- У Messages має бути виконано вхід на Mac, де працює `imsg`.
-- Для контексту процесу, у якому працює OpenClaw/`imsg`, потрібен Full Disk Access (доступ до бази даних Messages).
+- У Messages має бути виконано вхід на Mac, де запускається `imsg`.
+- Для контексту процесу, у якому працює OpenClaw/`imsg`, потрібен Full Disk Access (доступ до БД Messages).
- Для надсилання повідомлень через Messages.app потрібен дозвіл Automation.
-Дозволи надаються для кожного контексту процесу окремо. Якщо gateway працює без графічного інтерфейсу (LaunchAgent/SSH), виконайте одноразову інтерактивну команду в цьому самому контексті, щоб викликати підказки:
+Дозволи надаються для кожного контексту процесу. Якщо gateway працює без графічного інтерфейсу (LaunchAgent/SSH), виконайте одноразову інтерактивну команду в тому самому контексті, щоб викликати запити:
```bash
imsg chats --limit 1
@@ -141,17 +141,17 @@ imsg send "test"
## Керування доступом і маршрутизація
-
+
`channels.imessage.dmPolicy` керує прямими повідомленнями:
- `pairing` (типово)
- `allowlist`
- - `open` (потрібно, щоб `allowFrom` включав `"*"`)
+ - `open` (потребує, щоб `allowFrom` містив `"*"`)
- `disabled`
Поле allowlist: `channels.imessage.allowFrom`.
- Записи allowlist можуть бути дескрипторами або цілями чату (`chat_id:*`, `chat_guid:*`, `chat_identifier:*`).
+ Записи allowlist можуть бути handle або цілі чату (`chat_id:*`, `chat_guid:*`, `chat_identifier:*`).
@@ -164,49 +164,49 @@ imsg send "test"
Allowlist відправників груп: `channels.imessage.groupAllowFrom`.
- Резервний механізм під час виконання: якщо `groupAllowFrom` не задано, перевірки відправників груп iMessage повертаються до `allowFrom`, якщо він доступний.
- Примітка щодо виконання: якщо `channels.imessage` повністю відсутній, середовище виконання повертається до `groupPolicy="allowlist"` і записує попередження в журнал (навіть якщо задано `channels.defaults.groupPolicy`).
+ Резервна логіка під час виконання: якщо `groupAllowFrom` не задано, перевірки відправників груп iMessage використовують `allowFrom`, якщо воно доступне.
+ Примітка щодо виконання: якщо `channels.imessage` повністю відсутній, під час виконання використовується `groupPolicy="allowlist"` і записується попередження в журнал (навіть якщо задано `channels.defaults.groupPolicy`).
- Керування згадками для груп:
+ Обмеження за згадками для груп:
- iMessage не має вбудованих метаданих згадок
- - виявлення згадок використовує regex-шаблони (`agents.list[].groupChat.mentionPatterns`, резервно — `messages.groupChat.mentionPatterns`)
- - без налаштованих шаблонів керування згадками неможливо забезпечити
+ - виявлення згадок використовує шаблони regex (`agents.list[].groupChat.mentionPatterns`, резервно `messages.groupChat.mentionPatterns`)
+ - якщо шаблони не налаштовані, обмеження за згадками неможливо забезпечити
- Керівні команди від авторизованих відправників можуть обходити вимогу згадки в групах.
+ Команди керування від авторизованих відправників можуть обходити обмеження за згадками в групах.
-
- - Для приватних повідомлень використовується пряма маршрутизація; для груп — групова.
- - За типовим `session.dmScope=main` приватні повідомлення iMessage зводяться до основної сесії агента.
- - Групові сесії ізольовані (`agent::imessage:group:`).
- - Відповіді маршрутизуються назад в iMessage з використанням метаданих каналу/цілі походження.
+
+ - DM використовують пряму маршрутизацію; групи — групову.
+ - Із типовим `session.dmScope=main` DM iMessage згортаються в основний сеанс агента.
+ - Групові сеанси ізольовані (`agent::imessage:group:`).
+ - Відповіді маршрутизуються назад в iMessage з використанням метаданих початкового каналу/цілі.
Поведінка потоків, схожих на групові:
- Деякі багатокористувацькі потоки iMessage можуть надходити з `is_group=false`.
- Якщо такий `chat_id` явно налаштований у `channels.imessage.groups`, OpenClaw обробляє його як груповий трафік (керування групами + ізоляція групової сесії).
+ Деякі багатосторонні потоки iMessage можуть надходити з `is_group=false`.
+ Якщо такий `chat_id` явно налаштовано в `channels.imessage.groups`, OpenClaw обробляє його як груповий трафік (групові обмеження + ізоляція групового сеансу).
## Прив’язки розмов ACP
-Застарілі чати iMessage також можна прив’язувати до сесій ACP.
+Застарілі чати iMessage також можна прив’язувати до сеансів ACP.
-Швидкий операторський сценарій:
+Швидкий потік дій оператора:
-- Виконайте `/acp spawn codex --bind here` у приватному повідомленні або дозволеному груповому чаті.
-- Подальші повідомлення в цій самій розмові iMessage маршрутизуються до створеної сесії ACP.
-- `/new` і `/reset` скидають цю саму прив’язану сесію ACP на місці.
-- `/acp close` закриває сесію ACP і видаляє прив’язку.
+- Виконайте `/acp spawn codex --bind here` у DM або дозволеному груповому чаті.
+- Майбутні повідомлення в цій самій розмові iMessage маршрутизуватимуться до створеного сеансу ACP.
+- `/new` і `/reset` скидають той самий прив’язаний сеанс ACP на місці.
+- `/acp close` закриває сеанс ACP і видаляє прив’язку.
Налаштовані постійні прив’язки підтримуються через записи верхнього рівня `bindings[]` з `type: "acp"` і `match.channel: "imessage"`.
`match.peer.id` може використовувати:
-- нормалізований дескриптор приватного повідомлення, наприклад `+15555550123` або `user@example.com`
+- нормалізований handle DM, наприклад `+15555550123` або `user@example.com`
- `chat_id:` (рекомендовано для стабільних групових прив’язок)
- `chat_guid:`
- `chat_identifier:`
@@ -241,23 +241,23 @@ imsg send "test"
}
```
-Див. [ACP Agents](/tools/acp-agents) щодо спільної поведінки прив’язок ACP.
+Див. [ACP Agents](/uk/tools/acp-agents) для спільної поведінки прив’язки ACP.
-## Сценарії розгортання
+## Шаблони розгортання
-
- Використовуйте окремий Apple ID і користувача macOS, щоб трафік бота був ізольований від вашого особистого профілю Messages.
+
+ Використовуйте окремий Apple ID і macOS-користувача, щоб трафік бота був ізольований від вашого особистого профілю Messages.
- Типовий сценарій:
+ Типовий потік:
- 1. Створіть окремого користувача macOS і ввійдіть у нього.
+ 1. Створіть окремого macOS-користувача і виконайте вхід.
2. Увійдіть у Messages з Apple ID бота в цьому користувачі.
- 3. Установіть `imsg` у цього користувача.
+ 3. Встановіть `imsg` для цього користувача.
4. Створіть SSH-обгортку, щоб OpenClaw міг запускати `imsg` у контексті цього користувача.
- 5. Вкажіть `channels.imessage.accounts..cliPath` і `.dbPath` на профіль цього користувача.
+ 5. Спрямуйте `channels.imessage.accounts..cliPath` і `.dbPath` на профіль цього користувача.
- Перший запуск може вимагати підтверджень у графічному інтерфейсі (Automation + Full Disk Access) у сесії цього користувача бота.
+ Під час першого запуску можуть знадобитися підтвердження через GUI (Automation + Full Disk Access) у сеансі цього користувача бота.
@@ -290,36 +290,36 @@ imsg send "test"
exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
```
- Використовуйте ключі SSH, щоб і SSH, і SCP були неінтерактивними.
- Спочатку переконайтеся, що ключ хоста довірений (наприклад, `ssh bot@mac-mini.tailnet-1234.ts.net`), щоб заповнити `known_hosts`.
+ Використовуйте SSH-ключі, щоб і SSH, і SCP працювали без взаємодії.
+ Спочатку переконайтеся, що ключ хоста довірений (наприклад, `ssh bot@mac-mini.tailnet-1234.ts.net`), щоб було заповнено `known_hosts`.
- iMessage підтримує конфігурацію для кожного облікового запису окремо в `channels.imessage.accounts`.
+ iMessage підтримує конфігурацію для кожного облікового запису в `channels.imessage.accounts`.
- Для кожного облікового запису можна перевизначити такі поля, як `cliPath`, `dbPath`, `allowFrom`, `groupPolicy`, `mediaMaxMb`, налаштування історії та allowlist коренів вкладень.
+ Для кожного облікового запису можна перевизначати такі поля, як `cliPath`, `dbPath`, `allowFrom`, `groupPolicy`, `mediaMaxMb`, налаштування історії та allowlist кореневих каталогів вкладень.
-## Медіа, фрагментація та цілі доставки
+## Медіа, розбиття на частини та цілі доставки
- - отримання вхідних вкладень є необов’язковим: `channels.imessage.includeAttachments`
- - шляхи віддалених вкладень можна отримувати через SCP, коли задано `remoteHost`
- - шляхи вкладень мають відповідати дозволеним кореням:
+ - отримання вхідних вкладень необов’язкове: `channels.imessage.includeAttachments`
+ - шляхи до віддалених вкладень можна отримувати через SCP, якщо задано `remoteHost`
+ - шляхи до вкладень мають відповідати дозволеним кореневим каталогам:
- `channels.imessage.attachmentRoots` (локально)
- `channels.imessage.remoteAttachmentRoots` (віддалений режим SCP)
- - типовий шаблон кореня: `/Users/*/Library/Messages/Attachments`
+ - типовий шаблон кореневого каталогу: `/Users/*/Library/Messages/Attachments`
- SCP використовує сувору перевірку ключа хоста (`StrictHostKeyChecking=yes`)
- - розмір вихідного медіа керується `channels.imessage.mediaMaxMb` (типово 16 MB)
+ - розмір вихідних медіа визначається `channels.imessage.mediaMaxMb` (типово 16 MB)
-
- - ліміт фрагмента тексту: `channels.imessage.textChunkLimit` (типово 4000)
- - режим фрагментації: `channels.imessage.chunkMode`
+
+ - ліміт частини тексту: `channels.imessage.textChunkLimit` (типово 4000)
+ - режим розбиття: `channels.imessage.chunkMode`
- `length` (типово)
- `newline` (розбиття спочатку за абзацами)
@@ -331,7 +331,7 @@ exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
- `chat_guid:...`
- `chat_identifier:...`
- Також підтримуються цілі-дескриптори:
+ Також підтримуються цілі-handle:
- `imessage:+1555...`
- `sms:+1555...`
@@ -344,11 +344,11 @@ imsg chats --limit 20
-## Запис конфігурації
+## Записи конфігурації
-iMessage типово дозволяє ініційований каналом запис конфігурації (для `/config set|unset`, коли `commands.config: true`).
+iMessage типово дозволяє ініційовані каналом записи конфігурації (для `/config set|unset`, коли `commands.config: true`).
-Вимкнення:
+Вимкнути:
```json5
{
@@ -360,11 +360,11 @@ iMessage типово дозволяє ініційований каналом
}
```
-## Усунення несправностей
+## Усунення неполадок
- Перевірте бінарний файл і підтримку RPC:
+ Перевірте двійковий файл і підтримку RPC:
```bash
imsg rpc --help
@@ -375,12 +375,12 @@ openclaw channels status --probe
-
+
Перевірте:
- `channels.imessage.dmPolicy`
- `channels.imessage.allowFrom`
- - підтвердження прив’язки (`openclaw pairing list imessage`)
+ - підтвердження сполучення (`openclaw pairing list imessage`)
@@ -389,8 +389,8 @@ openclaw channels status --probe
- `channels.imessage.groupPolicy`
- `channels.imessage.groupAllowFrom`
- - поведінку allowlist для `channels.imessage.groups`
- - налаштування шаблонів згадок (`agents.list[].groupChat.mentionPatterns`)
+ - поведінку allowlist у `channels.imessage.groups`
+ - конфігурацію шаблонів згадок (`agents.list[].groupChat.mentionPatterns`)
@@ -399,36 +399,36 @@ openclaw channels status --probe
- `channels.imessage.remoteHost`
- `channels.imessage.remoteAttachmentRoots`
- - автентифікацію ключами SSH/SCP з хоста gateway
- - наявність ключа хоста в `~/.ssh/known_hosts` на хості gateway
+ - автентифікацію ключем SSH/SCP з хоста gateway
+ - чи є ключ хоста в `~/.ssh/known_hosts` на хості gateway
- читабельність віддаленого шляху на Mac, де працює Messages
-
- Повторно виконайте в інтерактивному GUI-терміналі в тому самому контексті користувача/сесії та підтвердьте підказки:
+
+ Повторно запустіть в інтерактивному GUI-терміналі в тому самому контексті користувача/сеансу і підтвердьте запити:
```bash
imsg chats --limit 1
imsg send "test"
```
- Переконайтеся, що Full Disk Access і Automation надано для контексту процесу, у якому працює OpenClaw/`imsg`.
+ Переконайтеся, що Full Disk Access і Automation надано для контексту процесу, який запускає OpenClaw/`imsg`.
-## Вказівники на довідкові матеріали з конфігурації
+## Вказівники на довідник із конфігурації
-- [Довідник з конфігурації - iMessage](/gateway/configuration-reference#imessage)
-- [Конфігурація gateway](/gateway/configuration)
-- [Прив’язка](/channels/pairing)
-- [BlueBubbles](/channels/bluebubbles)
+- [Довідник із конфігурації - iMessage](/uk/gateway/configuration-reference#imessage)
+- [Конфігурація Gateway](/uk/gateway/configuration)
+- [Сполучення](/uk/channels/pairing)
+- [BlueBubbles](/uk/channels/bluebubbles)
## Пов’язане
-- [Огляд каналів](/channels) — усі підтримувані канали
-- [Прив’язка](/channels/pairing) — автентифікація приватних повідомлень і сценарій прив’язки
-- [Групи](/channels/groups) — поведінка групового чату та керування згадками
-- [Маршрутизація каналів](/channels/channel-routing) — маршрутизація сесій для повідомлень
-- [Безпека](/gateway/security) — модель доступу та посилення захисту
+- [Огляд каналів](/uk/channels) — усі підтримувані канали
+- [Сполучення](/uk/channels/pairing) — автентифікація DM і потік сполучення
+- [Групи](/uk/channels/groups) — поведінка групових чатів і обмеження за згадками
+- [Маршрутизація каналів](/uk/channels/channel-routing) — маршрутизація сеансів для повідомлень
+- [Безпека](/uk/gateway/security) — модель доступу та посилення захисту
diff --git a/docs/uk/channels/msteams.md b/docs/uk/channels/msteams.md
index 47da116f9..8e4e972e8 100644
--- a/docs/uk/channels/msteams.md
+++ b/docs/uk/channels/msteams.md
@@ -1,37 +1,36 @@
---
read_when:
- - Працюємо над функціями каналу Microsoft Teams
-summary: Статус підтримки бота Microsoft Teams, можливості та конфігурація
+ - Робота над функціями каналу Microsoft Teams
+summary: Статус підтримки бота Microsoft Teams, можливості та налаштування
title: Microsoft Teams
x-i18n:
- generated_at: "2026-04-21T20:37:36Z"
+ generated_at: "2026-04-21T21:27:20Z"
model: gpt-5.4
provider: openai
- source_hash: ed973d8948bc5c5b44f5bc28f361e883389ececc70403c6631fb18ee1254d542
+ source_hash: ee9d52fb2cc7801e84249a705e0fa2052d4afbb7ef58cee2d3362b3e7012348c
source_path: channels/msteams.md
workflow: 15
---
# Microsoft Teams
-> «Полиште всяку надію, ті, хто сюди входить».
+> «Полиште надію всяк, хто входить сюди».
-Оновлено: 2026-03-25
-
-Статус: підтримуються текст + вкладення в DM; надсилання файлів у канали/групи потребує `sharePointSiteId` + дозволів Graph (див. [Надсилання файлів у групових чатах](#sending-files-in-group-chats)). Опитування надсилаються через Adaptive Cards. Дії з повідомленнями надають явний `upload-file` для надсилань, де файл є основним.
+Статус: підтримуються текст + вкладення DM; надсилання файлів у канали/групи потребує `sharePointSiteId` + дозволів Graph (див. [Надсилання файлів у групових чатах](#sending-files-in-group-chats)). Опитування надсилаються через Adaptive Cards. Дії з повідомленнями надають явний `upload-file` для надсилань, де файл є основним.
## Вбудований Plugin
-Microsoft Teams постачається як вбудований Plugin у поточних релізах OpenClaw, тому в звичайній пакетованій збірці окреме встановлення не потрібне.
+Microsoft Teams постачається як вбудований Plugin у поточних релізах OpenClaw, тож
+в окремому встановленні немає потреби у звичайній пакетованій збірці.
-Якщо ви використовуєте старішу збірку або власне встановлення без вбудованого Teams,
+Якщо ви використовуєте старішу збірку або спеціальне встановлення, що не містить вбудований Teams,
встановіть його вручну:
```bash
openclaw plugins install @openclaw/msteams
```
-Локальний checkout (коли запускаєте з git-репозиторію):
+Локальний checkout (під час запуску з git-репозиторію):
```bash
openclaw plugins install ./path/to/local/msteams-plugin
@@ -42,8 +41,8 @@ openclaw plugins install ./path/to/local/msteams-plugin
## Швидке налаштування (для початківців)
1. Переконайтеся, що Plugin Microsoft Teams доступний.
- - Поточні пакетовані релізи OpenClaw уже містять його вбудованим.
- - У старіших/власних встановленнях його можна додати вручну командами вище.
+ - Поточні пакетовані релізи OpenClaw уже містять його вбудовано.
+ - У старіших/спеціальних встановленнях його можна додати вручну командами вище.
2. Створіть **Azure Bot** (App ID + client secret + tenant ID).
3. Налаштуйте OpenClaw з цими обліковими даними.
4. Відкрийте `/api/messages` (типово порт 3978) через публічний URL або тунель.
@@ -67,19 +66,19 @@ openclaw plugins install ./path/to/local/msteams-plugin
Для production-розгортань розгляньте використання [federated authentication](#federated-authentication-certificate--managed-identity) (сертифікат або managed identity) замість client secret.
-Примітка: групові чати типово заблоковані (`channels.msteams.groupPolicy: "allowlist"`). Щоб дозволити відповіді в групах, задайте `channels.msteams.groupAllowFrom` (або використайте `groupPolicy: "open"`, щоб дозволити будь-якому учаснику, за умови згадки).
+Примітка: групові чати типово заблоковані (`channels.msteams.groupPolicy: "allowlist"`). Щоб дозволити відповіді в групах, задайте `channels.msteams.groupAllowFrom` (або використайте `groupPolicy: "open"`, щоб дозволити будь-якому учаснику, з обов’язковою згадкою).
## Цілі
- Спілкуватися з OpenClaw через Teams DM, групові чати або канали.
-- Зберігати детерміновану маршрутизацію: відповіді завжди повертаються в канал, звідки вони надійшли.
-- Типово використовувати безпечну поведінку в каналах (потрібні згадки, якщо не налаштовано інакше).
+- Зберігати детерміновану маршрутизацію: відповіді завжди повертаються в той канал, звідки вони надійшли.
+- Типово використовувати безпечну поведінку каналу (згадки обов’язкові, якщо не налаштовано інакше).
-## Записи конфігурації
+## Запис конфігурації
-Типово Microsoft Teams дозволено записувати оновлення конфігурації, ініційовані `/config set|unset` (потрібно `commands.config: true`).
+Типово Microsoft Teams дозволено записувати оновлення конфігурації, ініційовані `/config set|unset` (потребує `commands.config: true`).
-Вимкнути можна так:
+Щоб вимкнути:
```json5
{
@@ -87,21 +86,21 @@ openclaw plugins install ./path/to/local/msteams-plugin
}
```
-## Контроль доступу (DM + групи)
+## Керування доступом (DM + групи)
**Доступ до DM**
-- Типово: `channels.msteams.dmPolicy = "pairing"`. Невідомі відправники ігноруються, доки їх не буде схвалено.
+- Типово: `channels.msteams.dmPolicy = "pairing"`. Невідомі відправники ігноруються, доки їх не схвалять.
- `channels.msteams.allowFrom` має використовувати стабільні AAD object ID.
-- UPN/display name є змінними; пряме зіставлення типово вимкнене й вмикається лише через `channels.msteams.dangerouslyAllowNameMatching: true`.
+- UPN/display name можуть змінюватися; пряме зіставлення типово вимкнене й вмикається лише через `channels.msteams.dangerouslyAllowNameMatching: true`.
- Майстер налаштування може зіставляти імена з ID через Microsoft Graph, якщо це дозволяють облікові дані.
-**Груповий доступ**
+**Доступ до груп**
-- Типово: `channels.msteams.groupPolicy = "allowlist"` (заблоковано, доки ви не додасте `groupAllowFrom`). Використайте `channels.defaults.groupPolicy`, щоб змінити типове значення, якщо його не задано.
-- `channels.msteams.groupAllowFrom` визначає, які відправники можуть ініціювати взаємодію в групових чатах/каналах (з резервним переходом до `channels.msteams.allowFrom`).
-- Установіть `groupPolicy: "open"`, щоб дозволити будь-якому учаснику (типово все одно потрібна згадка).
-- Щоб **заборонити всі канали**, установіть `channels.msteams.groupPolicy: "disabled"`.
+- Типово: `channels.msteams.groupPolicy = "allowlist"` (заблоковано, доки ви не додасте `groupAllowFrom`). Використовуйте `channels.defaults.groupPolicy`, щоб змінити типову поведінку, якщо значення не задане.
+- `channels.msteams.groupAllowFrom` визначає, які відправники можуть ініціювати дію в групових чатах/каналах (з резервним використанням `channels.msteams.allowFrom`).
+- Установіть `groupPolicy: "open"`, щоб дозволити будь-якого учасника (типово все одно потрібна згадка).
+- Щоб заборонити **усі канали**, задайте `channels.msteams.groupPolicy: "disabled"`.
Приклад:
@@ -118,12 +117,12 @@ openclaw plugins install ./path/to/local/msteams-plugin
**Teams + allowlist каналів**
-- Обмежуйте відповіді в групах/каналах, перелічивши команди Teams і канали в `channels.msteams.teams`.
+- Обмежуйте відповіді в групах/каналах, перелічуючи teams і канали в `channels.msteams.teams`.
- Ключі мають використовувати стабільні team ID і channel conversation ID.
-- Коли `groupPolicy="allowlist"` і присутній allowlist Teams, приймаються лише перелічені команди/канали (за умови згадки).
-- Майстер налаштування приймає записи `Team/Channel` і зберігає їх для вас.
-- Під час запуску OpenClaw зіставляє назви team/channel і allowlist користувачів з ID (коли це дозволяють дозволи Graph)
- і журналює це зіставлення; нерозпізнані назви team/channel зберігаються в тому вигляді, як були введені, але типово ігноруються для маршрутизації, якщо не ввімкнено `channels.msteams.dangerouslyAllowNameMatching: true`.
+- Коли `groupPolicy="allowlist"` і задано allowlist teams, приймаються лише перелічені teams/канали (з обов’язковою згадкою).
+- Майстер налаштування приймає записи `Team/Channel` і збереже їх для вас.
+- Під час запуску OpenClaw зіставляє team/channel та імена користувачів з ID (коли це дозволяють дозволи Graph)
+ і записує зіставлення в журнал; нерозпізнані назви team/channel зберігаються як введені, але типово ігноруються для маршрутизації, якщо не ввімкнено `channels.msteams.dangerouslyAllowNameMatching: true`.
Приклад:
@@ -147,11 +146,11 @@ openclaw plugins install ./path/to/local/msteams-plugin
## Як це працює
1. Переконайтеся, що Plugin Microsoft Teams доступний.
- - Поточні пакетовані релізи OpenClaw уже містять його вбудованим.
- - У старіших/власних встановленнях його можна додати вручну командами вище.
+ - Поточні пакетовані релізи OpenClaw уже містять його вбудовано.
+ - У старіших/спеціальних встановленнях його можна додати вручну командами вище.
2. Створіть **Azure Bot** (App ID + secret + tenant ID).
-3. Створіть **пакет застосунку Teams**, який посилається на бота й містить наведені нижче дозволи RSC.
-4. Завантажте/встановіть застосунок Teams у команду (або в особистий scope для DM).
+3. Зберіть **пакет застосунку Teams**, який посилається на бота й містить дозволи RSC нижче.
+4. Завантажте/встановіть застосунок Teams у team (або в personal scope для DM).
5. Налаштуйте `msteams` у `~/.openclaw/openclaw.json` (або через env vars) і запустіть Gateway.
6. Gateway типово слухає webhook-трафік Bot Framework на `/api/messages`.
@@ -164,18 +163,18 @@ openclaw plugins install ./path/to/local/msteams-plugin
1. Перейдіть до [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)
2. Заповніть вкладку **Basics**:
- | Поле | Значення |
+ | Field | Value |
| ------------------ | -------------------------------------------------------- |
| **Bot handle** | Назва вашого бота, наприклад `openclaw-msteams` (має бути унікальною) |
- | **Subscription** | Виберіть свою підписку Azure |
+ | **Subscription** | Виберіть вашу підписку Azure |
| **Resource group** | Створіть нову або використайте наявну |
- | **Pricing tier** | **Free** для dev/тестування |
+ | **Pricing tier** | **Free** для розробки/тестування |
| **Type of App** | **Single Tenant** (рекомендовано — див. примітку нижче) |
| **Creation type** | **Create new Microsoft App ID** |
-> **Сповіщення про застарівання:** створення нових multi-tenant ботів було застарілим після 2025-07-31. Для нових ботів використовуйте **Single Tenant**.
+> **Повідомлення про застарівання:** створення нових multi-tenant ботів застаріло після 2025-07-31. Для нових ботів використовуйте **Single Tenant**.
-3. Натисніть **Review + create** → **Create** (зачекайте приблизно 1–2 хвилини)
+3. Натисніть **Review + create** → **Create** (зачекайте ~1-2 хвилини)
### Крок 2: Отримайте облікові дані
@@ -185,10 +184,10 @@ openclaw plugins install ./path/to/local/msteams-plugin
4. У розділі **Certificates & secrets** → **New client secret** → скопіюйте **Value** → це ваш `appPassword`
5. Перейдіть до **Overview** → скопіюйте **Directory (tenant) ID** → це ваш `tenantId`
-### Крок 3: Налаштуйте Messaging endpoint
+### Крок 3: Налаштуйте кінцеву точку обміну повідомленнями
1. У Azure Bot → **Configuration**
-2. Установіть **Messaging endpoint** на URL вашого webhook:
+2. Установіть **Messaging endpoint** на ваш webhook URL:
- Production: `https://your-domain.com/api/messages`
- Локальна розробка: використайте тунель (див. [Локальна розробка](#local-development-tunneling) нижче)
@@ -198,7 +197,7 @@ openclaw plugins install ./path/to/local/msteams-plugin
2. Натисніть **Microsoft Teams** → Configure → Save
3. Прийміть Terms of Service
-## Federated Authentication (Certificate + Managed Identity)
+## Federated Authentication (сертифікат + managed identity)
> Додано в 2026.3.24
@@ -206,11 +205,11 @@ openclaw plugins install ./path/to/local/msteams-plugin
### Варіант A: автентифікація на основі сертифіката
-Використовуйте PEM-сертифікат, зареєстрований у вашому застосунку Entra ID app registration.
+Використовуйте PEM-сертифікат, зареєстрований у вашому застосунку Entra ID.
**Налаштування:**
-1. Згенеруйте або отримайте сертифікат (формат PEM із приватним ключем).
+1. Згенеруйте або отримайте сертифікат (формат PEM із private key).
2. У Entra ID → App Registration → **Certificates & secrets** → **Certificates** → завантажте публічний сертифікат.
**Конфігурація:**
@@ -237,19 +236,19 @@ openclaw plugins install ./path/to/local/msteams-plugin
### Варіант B: Azure Managed Identity
-Використовуйте Azure Managed Identity для автентифікації без пароля. Це ідеально для розгортань в інфраструктурі Azure (AKS, App Service, Azure VMs), де доступна managed identity.
+Використовуйте Azure Managed Identity для автентифікації без пароля. Це ідеальний варіант для розгортань в інфраструктурі Azure (AKS, App Service, Azure VM), де доступна managed identity.
**Як це працює:**
1. Pod/VM бота має managed identity (system-assigned або user-assigned).
-2. **Federated identity credential** пов’язує managed identity із застосунком Entra ID app registration.
-3. Під час виконання OpenClaw використовує `@azure/identity`, щоб отримувати токени з endpoint Azure IMDS (`169.254.169.254`).
-4. Токен передається в Teams SDK для автентифікації бота.
+2. **Federated identity credential** пов’язує managed identity із застосунком Entra ID.
+3. Під час виконання OpenClaw використовує `@azure/identity`, щоб отримувати токени з кінцевої точки Azure IMDS (`169.254.169.254`).
+4. Токен передається до Teams SDK для автентифікації бота.
**Передумови:**
- Інфраструктура Azure з увімкненою managed identity (AKS workload identity, App Service, VM)
-- Створений federated identity credential у застосунку Entra ID app registration
+- Створений federated identity credential у застосунку Entra ID
- Мережевий доступ до IMDS (`169.254.169.254:80`) з pod/VM
**Конфігурація (system-assigned managed identity):**
@@ -297,8 +296,8 @@ openclaw plugins install ./path/to/local/msteams-plugin
Для розгортань AKS із workload identity:
-1. **Увімкніть workload identity** у своєму кластері AKS.
-2. **Створіть federated identity credential** у застосунку Entra ID app registration:
+1. **Увімкніть workload identity** у вашому кластері AKS.
+2. **Створіть federated identity credential** у застосунку Entra ID:
```bash
az ad app federated-credential create --id --parameters '{
@@ -309,7 +308,7 @@ openclaw plugins install ./path/to/local/msteams-plugin
}'
```
-3. **Додайте анотацію до service account Kubernetes** із client ID застосунку:
+3. **Додайте анотацію до service account Kubernetes** з app client ID:
```yaml
apiVersion: v1
@@ -320,7 +319,7 @@ openclaw plugins install ./path/to/local/msteams-plugin
azure.workload.identity/client-id: ""
```
-4. **Додайте label до pod** для інʼєкції workload identity:
+4. **Додайте мітку pod** для ін’єкції workload identity:
```yaml
metadata:
@@ -328,21 +327,21 @@ openclaw plugins install ./path/to/local/msteams-plugin
azure.workload.identity/use: "true"
```
-5. **Переконайтеся в наявності мережевого доступу** до IMDS (`169.254.169.254`) — якщо використовується NetworkPolicy, додайте правило egress, що дозволяє трафік до `169.254.169.254/32` на порт 80.
+5. **Забезпечте мережевий доступ** до IMDS (`169.254.169.254`) — якщо ви використовуєте NetworkPolicy, додайте правило egress, яке дозволяє трафік до `169.254.169.254/32` на порт 80.
### Порівняння типів автентифікації
-| Метод | Конфігурація | Переваги | Недоліки |
+| Method | Config | Pros | Cons |
| -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- |
| **Client secret** | `appPassword` | Просте налаштування | Потрібна ротація секретів, менш безпечно |
-| **Certificate** | `authType: "federated"` + `certificatePath` | Немає спільного секрету в мережі | Додаткові витрати на керування сертифікатами |
-| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | Без пароля, не потрібно керувати секретами | Потрібна інфраструктура Azure |
+| **Certificate** | `authType: "federated"` + `certificatePath` | Немає спільного секрету в мережі | Додаткове навантаження на керування сертифікатами |
+| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | Автентифікація без пароля, не треба керувати секретами | Потрібна інфраструктура Azure |
-**Типова поведінка:** якщо `authType` не задано, OpenClaw типово використовує автентифікацію через client secret. Наявні конфігурації продовжують працювати без змін.
+**Поведінка за замовчуванням:** якщо `authType` не задано, OpenClaw типово використовує автентифікацію через client secret. Наявні конфігурації й надалі працюватимуть без змін.
## Локальна розробка (тунелювання)
-Teams не може дістатися до `localhost`. Для локальної розробки використовуйте тунель:
+Teams не може звертатися до `localhost`. Для локальної розробки використовуйте тунель:
**Варіант A: ngrok**
@@ -361,17 +360,17 @@ tailscale funnel 3978
## Teams Developer Portal (альтернатива)
-Замість ручного створення ZIP-файлу маніфесту, ви можете скористатися [Teams Developer Portal](https://dev.teams.microsoft.com/apps):
+Замість ручного створення ZIP-файлу маніфесту ви можете скористатися [Teams Developer Portal](https://dev.teams.microsoft.com/apps):
1. Натисніть **+ New app**
2. Заповніть базову інформацію (назва, опис, інформація про розробника)
3. Перейдіть до **App features** → **Bot**
-4. Виберіть **Enter a bot ID manually** і вставте App ID вашого Azure Bot
-5. Позначте scope: **Personal**, **Team**, **Group Chat**
+4. Виберіть **Enter a bot ID manually** і вставте ваш Azure Bot App ID
+5. Позначте області: **Personal**, **Team**, **Group Chat**
6. Натисніть **Distribute** → **Download app package**
7. У Teams: **Apps** → **Manage your apps** → **Upload a custom app** → виберіть ZIP
-Це часто простіше, ніж редагувати JSON-маніфести вручну.
+Часто це простіше, ніж редагувати JSON-маніфести вручну.
## Тестування бота
@@ -379,21 +378,21 @@ tailscale funnel 3978
1. У Azure Portal → ваш ресурс Azure Bot → **Test in Web Chat**
2. Надішліть повідомлення — ви маєте побачити відповідь
-3. Це підтверджує, що ваш endpoint webhook працює до налаштування Teams
+3. Це підтверджує, що ваш webhook endpoint працює до налаштування Teams
**Варіант B: Teams (після встановлення застосунку)**
-1. Встановіть застосунок Teams (sideload або через org catalog)
+1. Встановіть застосунок Teams (sideload або через каталог організації)
2. Знайдіть бота в Teams і надішліть DM
-3. Перевірте журнали Gateway на вхідну activity
+3. Перевірте журнали Gateway на вхідну активність
## Налаштування (мінімальний лише текстовий режим)
1. **Переконайтеся, що Plugin Microsoft Teams доступний**
- - Поточні пакетовані релізи OpenClaw уже містять його вбудованим.
- - У старіших/власних встановленнях його можна додати вручну:
+ - Поточні пакетовані релізи OpenClaw уже містять його вбудовано.
+ - У старіших/спеціальних встановленнях його можна додати вручну:
- З npm: `openclaw plugins install @openclaw/msteams`
- - Із локального checkout: `openclaw plugins install ./path/to/local/msteams-plugin`
+ - З локального checkout: `openclaw plugins install ./path/to/local/msteams-plugin`
2. **Реєстрація бота**
- Створіть Azure Bot (див. вище) і занотуйте:
@@ -402,12 +401,12 @@ tailscale funnel 3978
- Tenant ID (single-tenant)
3. **Маніфест застосунку Teams**
- - Додайте запис `bot` із `botId = `.
- - Scope: `personal`, `team`, `groupChat`.
- - `supportsFiles: true` (потрібно для обробки файлів в особистому scope).
+ - Додайте запис `bot` з `botId = `.
+ - Області: `personal`, `team`, `groupChat`.
+ - `supportsFiles: true` (обов’язково для обробки файлів у personal scope).
- Додайте дозволи RSC (нижче).
- Створіть іконки: `outline.png` (32x32) і `color.png` (192x192).
- - Заархівуйте всі три файли разом: `manifest.json`, `outline.png`, `color.png`.
+ - Запакуйте всі три файли разом: `manifest.json`, `outline.png`, `color.png`.
4. **Налаштуйте OpenClaw**
@@ -430,12 +429,12 @@ tailscale funnel 3978
- `MSTEAMS_APP_PASSWORD`
- `MSTEAMS_TENANT_ID`
- `MSTEAMS_AUTH_TYPE` (необов’язково: `"secret"` або `"federated"`)
- - `MSTEAMS_CERTIFICATE_PATH` (federated + certificate)
+ - `MSTEAMS_CERTIFICATE_PATH` (federated + сертифікат)
- `MSTEAMS_CERTIFICATE_THUMBPRINT` (необов’язково, не потрібен для автентифікації)
- `MSTEAMS_USE_MANAGED_IDENTITY` (federated + managed identity)
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID` (лише для user-assigned MI)
-5. **Endpoint бота**
+5. **Кінцева точка бота**
- Установіть Azure Bot Messaging Endpoint на:
- `https://:3978/api/messages` (або ваш вибраний path/port).
@@ -444,31 +443,31 @@ tailscale funnel 3978
## Дія інформації про учасника
-OpenClaw надає підтримувану Graph дію `member-info` для Microsoft Teams, щоб агенти й автоматизації могли напряму отримувати відомості про учасників каналу (display name, email, role) з Microsoft Graph.
+OpenClaw надає для Microsoft Teams дію `member-info`, що працює через Graph, щоб агенти й автоматизації могли напряму отримувати відомості про учасників каналу (display name, email, роль) із Microsoft Graph.
Вимоги:
- Дозвіл RSC `Member.Read.Group` (уже є в рекомендованому маніфесті)
-- Для міжкомандного пошуку: дозвіл Graph Application `User.Read.All` з admin consent
+- Для пошуку між teams: дозвіл Graph Application `User.Read.All` з admin consent
-Дія контролюється `channels.msteams.actions.memberInfo` (типово: увімкнено, коли доступні облікові дані Graph).
+Дія контролюється через `channels.msteams.actions.memberInfo` (типово: увімкнено, коли доступні облікові дані Graph).
## Контекст історії
-- `channels.msteams.historyLimit` визначає, скільки останніх повідомлень каналу/групи буде загорнуто в prompt.
+- `channels.msteams.historyLimit` керує кількістю недавніх повідомлень каналу/групи, які додаються до prompt.
- Використовує резервне значення з `messages.groupChat.historyLimit`. Установіть `0`, щоб вимкнути (типово 50).
-- Отримана історія гілки фільтрується за allowlist відправників (`allowFrom` / `groupAllowFrom`), тож початкове заповнення контексту гілки включає лише повідомлення від дозволених відправників.
-- Контекст quoted attachment (`ReplyTo*`, похідний від HTML відповіді Teams) наразі передається як отримано.
-- Інакше кажучи, allowlist керують тим, хто може запускати агента; сьогодні фільтруються лише окремі шляхи додаткового контексту.
-- Історію DM можна обмежити через `channels.msteams.dmHistoryLimit` (ходи користувача). Перевизначення для окремих користувачів: `channels.msteams.dms[""].historyLimit`.
+- Отримана історія треду фільтрується за allowlist відправників (`allowFrom` / `groupAllowFrom`), тож початкове наповнення контексту треду містить лише повідомлення від дозволених відправників.
+- Контекст цитованих вкладень (`ReplyTo*`, похідний від HTML відповіді Teams) зараз передається як отриманий.
+- Інакше кажучи, allowlists контролюють, хто може активувати агента; наразі фільтруються лише окремі шляхи додаткового контексту.
+- Історію DM можна обмежити через `channels.msteams.dmHistoryLimit` (ходи користувача). Перевизначення для конкретного користувача: `channels.msteams.dms[""].historyLimit`.
## Поточні дозволи Teams RSC (маніфест)
-Це **наявні resourceSpecific permissions** у нашому маніфесті застосунку Teams. Вони застосовуються лише в межах команди/чату, де встановлено застосунок.
+Це **наявні resourceSpecific permissions** у маніфесті нашого застосунку Teams. Вони діють лише в межах team/chat, де встановлено застосунок.
-**Для каналів (scope команди):**
+**Для каналів (область team):**
-- `ChannelMessage.Read.Group` (Application) — отримання тексту всіх повідомлень каналу без @mention
+- `ChannelMessage.Read.Group` (Application) — отримувати всі текстові повідомлення каналу без @mention
- `ChannelMessage.Send.Group` (Application)
- `Member.Read.Group` (Application)
- `Owner.Read.Group` (Application)
@@ -478,11 +477,11 @@ OpenClaw надає підтримувану Graph дію `member-info` для M
**Для групових чатів:**
-- `ChatMessage.Read.Chat` (Application) — отримання всіх повідомлень групового чату без @mention
+- `ChatMessage.Read.Chat` (Application) — отримувати всі повідомлення групового чату без @mention
-## Приклад маніфесту Teams (з редагуванням чутливих даних)
+## Приклад маніфесту Teams (із вилученими даними)
-Мінімальний, коректний приклад з обов’язковими полями. Замініть ID та URL.
+Мінімальний, коректний приклад із потрібними полями. Замініть ID та URL.
```json5
{
@@ -532,78 +531,78 @@ OpenClaw надає підтримувану Graph дію `member-info` для M
### Застереження щодо маніфесту (обов’язкові поля)
-- `bots[].botId` **має** збігатися з App ID Azure Bot.
-- `webApplicationInfo.id` **має** збігатися з App ID Azure Bot.
-- `bots[].scopes` мають включати поверхні, які ви плануєте використовувати (`personal`, `team`, `groupChat`).
-- `bots[].supportsFiles: true` потрібен для обробки файлів в особистому scope.
-- `authorization.permissions.resourceSpecific` мають включати читання/надсилання в канали, якщо ви хочете каналовий трафік.
+- `bots[].botId` **має** збігатися з Azure Bot App ID.
+- `webApplicationInfo.id` **має** збігатися з Azure Bot App ID.
+- `bots[].scopes` має включати поверхні, які ви плануєте використовувати (`personal`, `team`, `groupChat`).
+- `bots[].supportsFiles: true` є обов’язковим для обробки файлів у personal scope.
+- `authorization.permissions.resourceSpecific` має містити дозволи на читання/надсилання в канал, якщо вам потрібен трафік каналу.
### Оновлення наявного застосунку
-Щоб оновити вже встановлений застосунок Teams (наприклад, щоб додати дозволи RSC):
+Щоб оновити вже встановлений застосунок Teams (наприклад, додати дозволи RSC):
1. Оновіть `manifest.json` новими налаштуваннями
-2. **Збільште поле `version`** (наприклад, `1.0.0` → `1.1.0`)
-3. **Повторно заархівуйте** маніфест з іконками (`manifest.json`, `outline.png`, `color.png`)
+2. **Збільшіть поле `version`** (наприклад, `1.0.0` → `1.1.0`)
+3. **Повторно запакуйте в zip** маніфест разом з іконками (`manifest.json`, `outline.png`, `color.png`)
4. Завантажте новий zip:
- - **Варіант A (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → знайдіть свій застосунок → Upload new version
- - **Варіант B (Sideload):** у Teams → Apps → Manage your apps → Upload a custom app
-5. **Для каналів команди:** перевстановіть застосунок у кожній команді, щоб нові дозволи набули чинності
-6. **Повністю закрийте й знову запустіть Teams** (не просто закрийте вікно), щоб очистити кешовані метадані застосунку
+ - **Варіант A (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → знайдіть ваш застосунок → Upload new version
+ - **Варіант B (Sideload):** У Teams → Apps → Manage your apps → Upload a custom app
+5. **Для каналів team:** перевстановіть застосунок у кожній team, щоб нові дозволи набрали чинності
+6. **Повністю закрийте і знову запустіть Teams** (а не просто закрийте вікно), щоб очистити кешовані метадані застосунку
## Можливості: лише RSC проти Graph
-### З **лише Teams RSC** (застосунок встановлено, без дозволів Graph API)
+### Із **лише Teams RSC** (застосунок встановлено, без дозволів Microsoft Graph API)
Працює:
- Читання **текстового** вмісту повідомлень каналу.
- Надсилання **текстового** вмісту повідомлень каналу.
-- Отримання файлових вкладень у **personal (DM)**.
+- Отримання **особистих (DM)** файлових вкладень.
НЕ працює:
-- **Зображення або вміст файлів** у каналах/групах (payload містить лише HTML-заглушку).
-- Завантаження вкладень, що зберігаються в SharePoint/OneDrive.
-- Читання історії повідомлень (поза live webhook event).
+- Вміст **зображень або файлів** у каналах/групах (payload містить лише HTML-заглушку).
+- Завантаження вкладень, що зберігаються у SharePoint/OneDrive.
+- Читання історії повідомлень (поза межами живої webhook-події).
-### З **Teams RSC + дозволами Microsoft Graph Application**
+### Із **Teams RSC + дозволами Microsoft Graph Application**
Додається:
-- Завантаження hosted contents (зображення, вставлені в повідомлення).
-- Завантаження файлових вкладень, що зберігаються в SharePoint/OneDrive.
+- Завантаження hosted contents (зображень, вставлених у повідомлення).
+- Завантаження файлових вкладень, що зберігаються у SharePoint/OneDrive.
- Читання історії повідомлень каналу/чату через Graph.
### RSC проти Graph API
-| Можливість | Дозволи RSC | Graph API |
-| ---------------------- | -------------------- | ----------------------------------- |
-| **Повідомлення в реальному часі** | Так (через webhook) | Ні (лише polling) |
-| **Історичні повідомлення** | Ні | Так (можна запитувати історію) |
-| **Складність налаштування** | Лише маніфест застосунку | Потрібні admin consent + token flow |
-| **Працює офлайн** | Ні (має працювати) | Так (можна запитувати будь-коли) |
+| Capability | RSC Permissions | Graph API |
+| ----------------------- | -------------------- | ----------------------------------- |
+| **Real-time messages** | Так (через webhook) | Ні (лише polling) |
+| **Historical messages** | Ні | Так (можна запитувати історію) |
+| **Setup complexity** | Лише маніфест застосунку | Потребує admin consent + token flow |
+| **Works offline** | Ні (має бути запущено) | Так (можна запитувати будь-коли) |
-**Висновок:** RSC призначений для прослуховування в реальному часі; Graph API — для історичного доступу. Щоб наздоганяти пропущені повідомлення під час офлайну, вам потрібен Graph API з `ChannelMessage.Read.All` (потрібен admin consent).
+**Підсумок:** RSC призначено для прослуховування в реальному часі; Graph API — для історичного доступу. Щоб надолужувати пропущені повідомлення під час офлайну, вам потрібен Graph API з `ChannelMessage.Read.All` (потребує admin consent).
-## Graph-enabled media + history (потрібно для каналів)
+## Media + history з Graph (обов’язково для каналів)
-Якщо вам потрібні зображення/файли в **каналах** або потрібно отримувати **історію повідомлень**, необхідно ввімкнути дозволи Microsoft Graph і надати admin consent.
+Якщо вам потрібні зображення/файли в **каналах** або ви хочете отримувати **історію повідомлень**, потрібно ввімкнути дозволи Microsoft Graph і надати admin consent.
1. У **App Registration** Entra ID (Azure AD) додайте дозволи Microsoft Graph **Application permissions**:
- `ChannelMessage.Read.All` (вкладення каналів + історія)
- `Chat.Read.All` або `ChatMessage.Read.All` (групові чати)
2. **Надайте admin consent** для tenant.
-3. Збільште **версію маніфесту** застосунку Teams, повторно завантажте його й **перевстановіть застосунок у Teams**.
+3. Збільшіть **версію маніфесту** застосунку Teams, повторно завантажте його й **перевстановіть застосунок у Teams**.
4. **Повністю закрийте й знову запустіть Teams**, щоб очистити кешовані метадані застосунку.
-**Додатковий дозвіл для згадок користувачів:** @mentions користувачів працюють відразу для користувачів у поточній розмові. Однак якщо ви хочете динамічно шукати й згадувати користувачів, які **не перебувають у поточній розмові**, додайте дозвіл `User.Read.All` (Application) і надайте admin consent.
+**Додатковий дозвіл для згадок користувачів:** @mentions користувачів працюють одразу для користувачів у розмові. Однак якщо ви хочете динамічно шукати й згадувати користувачів, які **не перебувають у поточній розмові**, додайте дозвіл `User.Read.All` (Application) і надайте admin consent.
## Відомі обмеження
### Тайм-аути webhook
-Teams доставляє повідомлення через HTTP webhook. Якщо обробка триває надто довго (наприклад, через повільні відповіді LLM), ви можете побачити:
+Teams доставляє повідомлення через HTTP webhook. Якщо обробка триває надто довго (наприклад, повільні відповіді LLM), ви можете побачити:
- тайм-аути Gateway
- повторні спроби Teams доставити повідомлення (що спричиняє дублікати)
@@ -615,38 +614,38 @@ OpenClaw обробляє це, швидко повертаючи відпові
Markdown у Teams більш обмежений, ніж у Slack або Discord:
-- Базове форматування працює: **жирний**, _курсив_, `code`, посилання
+- Працює базове форматування: **жирний**, _курсив_, `code`, посилання
- Складний markdown (таблиці, вкладені списки) може відображатися некоректно
- Adaptive Cards підтримуються для опитувань і semantic presentation sends (див. нижче)
## Конфігурація
-Ключові налаштування (див. `/gateway/configuration` для спільних шаблонів каналів):
+Основні параметри (див. `/gateway/configuration` для спільних шаблонів каналів):
- `channels.msteams.enabled`: увімкнути/вимкнути канал.
- `channels.msteams.appId`, `channels.msteams.appPassword`, `channels.msteams.tenantId`: облікові дані бота.
- `channels.msteams.webhook.port` (типово `3978`)
- `channels.msteams.webhook.path` (типово `/api/messages`)
- `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled` (типово: pairing)
-- `channels.msteams.allowFrom`: allowlist для DM (рекомендовано AAD object ID). Майстер налаштування зіставляє імена з ID під час налаштування, коли доступний доступ до Graph.
-- `channels.msteams.dangerouslyAllowNameMatching`: аварійний перемикач для повторного ввімкнення зіставлення за змінними UPN/display-name та прямої маршрутизації за назвами team/channel.
+- `channels.msteams.allowFrom`: allowlist для DM (рекомендовано AAD object ID). Майстер налаштування під час setup зіставляє імена з ID, коли доступний доступ до Graph.
+- `channels.msteams.dangerouslyAllowNameMatching`: аварійний перемикач для повторного ввімкнення зіставлення за змінюваними UPN/display-name і прямої маршрутизації за назвами team/channel.
- `channels.msteams.textChunkLimit`: розмір фрагмента вихідного тексту.
- `channels.msteams.chunkMode`: `length` (типово) або `newline`, щоб розбивати за порожніми рядками (межами абзаців) перед розбиттям за довжиною.
- `channels.msteams.mediaAllowHosts`: allowlist для хостів вхідних вкладень (типово домени Microsoft/Teams).
- `channels.msteams.mediaAuthAllowHosts`: allowlist для додавання заголовків Authorization під час повторних спроб отримання медіа (типово хости Graph + Bot Framework).
- `channels.msteams.requireMention`: вимагати @mention у каналах/групах (типово true).
- `channels.msteams.replyStyle`: `thread | top-level` (див. [Стиль відповіді](#reply-style-threads-vs-posts)).
-- `channels.msteams.teams..replyStyle`: перевизначення для окремої команди.
-- `channels.msteams.teams..requireMention`: перевизначення для окремої команди.
-- `channels.msteams.teams..tools`: типові перевизначення політики інструментів для команди (`allow`/`deny`/`alsoAllow`), які використовуються, коли немає перевизначення для каналу.
-- `channels.msteams.teams..toolsBySender`: типові перевизначення політики інструментів для команди за відправником (підтримується wildcard `"*"`).
-- `channels.msteams.teams..channels..replyStyle`: перевизначення для окремого каналу.
-- `channels.msteams.teams..channels..requireMention`: перевизначення для окремого каналу.
-- `channels.msteams.teams..channels..tools`: перевизначення політики інструментів для каналу (`allow`/`deny`/`alsoAllow`).
-- `channels.msteams.teams..channels..toolsBySender`: перевизначення політики інструментів для каналу за відправником (підтримується wildcard `"*"`).
+- `channels.msteams.teams..replyStyle`: перевизначення для конкретної team.
+- `channels.msteams.teams..requireMention`: перевизначення для конкретної team.
+- `channels.msteams.teams..tools`: типові перевизначення політики інструментів для team (`allow`/`deny`/`alsoAllow`), які використовуються, коли немає перевизначення для каналу.
+- `channels.msteams.teams..toolsBySender`: типові перевизначення політики інструментів для team за відправником (`"*"` wildcard підтримується).
+- `channels.msteams.teams..channels..replyStyle`: перевизначення для конкретного каналу.
+- `channels.msteams.teams..channels..requireMention`: перевизначення для конкретного каналу.
+- `channels.msteams.teams..channels..tools`: перевизначення політики інструментів для конкретного каналу (`allow`/`deny`/`alsoAllow`).
+- `channels.msteams.teams..channels..toolsBySender`: перевизначення політики інструментів для конкретного каналу за відправником (`"*"` wildcard підтримується).
- Ключі `toolsBySender` мають використовувати явні префікси:
- `id:`, `e164:`, `username:`, `name:` (застарілі ключі без префікса, як і раніше, зіставляються лише з `id:`).
-- `channels.msteams.actions.memberInfo`: увімкнути або вимкнути дію інформації про учасника на основі Graph (типово: увімкнено, коли доступні облікові дані Graph).
+ `id:`, `e164:`, `username:`, `name:` (застарілі ключі без префікса все ще зіставляються лише з `id:`).
+- `channels.msteams.actions.memberInfo`: увімкнути або вимкнути дію інформації про учасника, що працює через Graph (типово: увімкнено, коли доступні облікові дані Graph).
- `channels.msteams.authType`: тип автентифікації — `"secret"` (типово) або `"federated"`.
- `channels.msteams.certificatePath`: шлях до PEM-файлу сертифіката (federated + автентифікація сертифікатом).
- `channels.msteams.certificateThumbprint`: thumbprint сертифіката (необов’язково, не потрібен для автентифікації).
@@ -654,29 +653,29 @@ Markdown у Teams більш обмежений, ніж у Slack або Discord:
- `channels.msteams.managedIdentityClientId`: client ID для user-assigned managed identity.
- `channels.msteams.sharePointSiteId`: SharePoint site ID для вивантаження файлів у групових чатах/каналах (див. [Надсилання файлів у групових чатах](#sending-files-in-group-chats)).
-## Маршрутизація й сесії
+## Маршрутизація та сесії
- Ключі сесій відповідають стандартному формату агента (див. [/concepts/session](/uk/concepts/session)):
- - Direct messages спільно використовують основну сесію (`agent::`).
+ - Прямі повідомлення використовують основну сесію (`agent::`).
- Повідомлення каналу/групи використовують conversation id:
- `agent::msteams:channel:`
- `agent::msteams:group:`
-## Стиль відповіді: Threads проти Posts
+## Стиль відповіді: треди проти дописів
Нещодавно Teams запровадив два стилі UI каналів поверх тієї самої базової моделі даних:
-| Стиль | Опис | Рекомендований `replyStyle` |
-| ---------------------- | --------------------------------------------------------- | --------------------------- |
-| **Posts** (класичний) | Повідомлення відображаються як картки з гілками відповідей під ними | `thread` (типово) |
-| **Threads** (як у Slack) | Повідомлення йдуть лінійно, більше схоже на Slack | `top-level` |
+| Style | Description | Recommended `replyStyle` |
+| ------------------------ | --------------------------------------------------------- | ------------------------ |
+| **Posts** (classic) | Повідомлення відображаються як картки з тредовими відповідями під ними | `thread` (типово) |
+| **Threads** (Slack-like) | Повідомлення йдуть лінійно, більше схоже на Slack | `top-level` |
-**Проблема:** API Teams не показує, який стиль UI використовує канал. Якщо використати неправильний `replyStyle`:
+**Проблема:** Teams API не показує, який саме стиль UI використовує канал. Якщо використовувати неправильний `replyStyle`:
-- `thread` у каналі стилю Threads → відповіді виглядають незграбно вкладеними
-- `top-level` у каналі стилю Posts → відповіді з’являються як окремі повідомлення верхнього рівня, а не в гілці
+- `thread` у каналі зі стилем Threads → відповіді відображаються незручно вкладеними
+- `top-level` у каналі зі стилем Posts → відповіді з’являються як окремі дописи верхнього рівня, а не в треді
-**Рішення:** Налаштуйте `replyStyle` для кожного каналу залежно від того, як налаштований канал:
+**Рішення:** налаштуйте `replyStyle` для кожного каналу залежно від того, як налаштований канал:
```json5
{
@@ -701,44 +700,44 @@ Markdown у Teams більш обмежений, ніж у Slack або Discord:
**Поточні обмеження:**
-- **DM:** зображення й файлові вкладення працюють через API файлів ботів Teams.
-- **Канали/групи:** вкладення живуть у сховищі M365 (SharePoint/OneDrive). Payload webhook містить лише HTML-заглушку, а не фактичні байти файлу. **Для завантаження вкладень каналу потрібні дозволи Graph API**.
-- Для явних надсилань, де файл є основним, використовуйте `action=upload-file` з `media` / `filePath` / `path`; необов’язковий `message` стає супровідним текстом/коментарем, а `filename` перевизначає назву завантаженого файлу.
+- **DM:** зображення й файлові вкладення працюють через file API бота Teams.
+- **Канали/групи:** вкладення зберігаються в M365 storage (SharePoint/OneDrive). Payload webhook містить лише HTML-заглушку, а не фактичні байти файлу. Для завантаження вкладень каналу **потрібні дозволи Graph API**.
+- Для явного надсилання, де файл є основним, використовуйте `action=upload-file` з `media` / `filePath` / `path`; необов’язковий `message` стає супровідним текстом/коментарем, а `filename` перевизначає ім’я завантаженого файлу.
-Без дозволів Graph повідомлення каналів із зображеннями надходитимуть лише як текст (вміст зображення для бота недоступний).
-Типово OpenClaw завантажує медіа лише з хостів Microsoft/Teams. Перевизначайте це через `channels.msteams.mediaAllowHosts` (використайте `["*"]`, щоб дозволити будь-який хост).
-Заголовки Authorization додаються лише для хостів у `channels.msteams.mediaAuthAllowHosts` (типово хости Graph + Bot Framework). Тримайте цей список строгим (уникайте multi-tenant суфіксів).
+Без дозволів Graph повідомлення каналів із зображеннями отримуватимуться лише як текст (вміст зображення боту недоступний).
+Типово OpenClaw завантажує медіа лише з hostname Microsoft/Teams. Перевизначте це через `channels.msteams.mediaAllowHosts` (використайте `["*"]`, щоб дозволити будь-який хост).
+Заголовки Authorization додаються лише для хостів у `channels.msteams.mediaAuthAllowHosts` (типово хости Graph + Bot Framework). Тримайте цей список суворим (уникайте multi-tenant suffixes).
## Надсилання файлів у групових чатах
-Боти можуть надсилати файли в DM через потік FileConsentCard (вбудований). Однак **надсилання файлів у групових чатах/каналах** потребує додаткового налаштування:
+Боти можуть надсилати файли в DM, використовуючи потік FileConsentCard (вбудований). Однак **надсилання файлів у групових чатах/каналах** потребує додаткового налаштування:
-| Контекст | Як надсилаються файли | Потрібне налаштування |
-| ------------------------ | ---------------------------------------- | ----------------------------------------------- |
-| **DM** | FileConsentCard → користувач приймає → бот вивантажує | Працює одразу |
-| **Групові чати/канали** | Вивантаження в SharePoint → посилання для спільного доступу | Потрібні `sharePointSiteId` + дозволи Graph |
-| **Зображення (будь-який контекст)** | Inline у кодуванні Base64 | Працює одразу |
+| Context | How files are sent | Setup needed |
+| ------------------------ | -------------------------------------------- | ----------------------------------------------- |
+| **DMs** | FileConsentCard → користувач приймає → бот вивантажує | Працює одразу |
+| **Group chats/channels** | Вивантаження до SharePoint → посилання для спільного доступу | Потрібні `sharePointSiteId` + дозволи Graph |
+| **Images (any context)** | Inline у форматі Base64 | Працює одразу |
### Чому груповим чатам потрібен SharePoint
-Боти не мають особистого диска OneDrive (endpoint Graph API `/me/drive` не працює для application identities). Щоб надсилати файли в групових чатах/каналах, бот вивантажує їх на **сайт SharePoint** і створює посилання для спільного доступу.
+Боти не мають особистого диска OneDrive (кінцева точка Graph API `/me/drive` не працює для application identities). Щоб надсилати файли в групових чатах/каналах, бот вивантажує їх на **сайт SharePoint** і створює посилання для спільного доступу.
### Налаштування
-1. **Додайте дозволи Graph API** в Entra ID (Azure AD) → App Registration:
- - `Sites.ReadWrite.All` (Application) — вивантаження файлів у SharePoint
- - `Chat.Read.All` (Application) — необов’язково, вмикає посилання для спільного доступу для окремих користувачів
+1. **Додайте дозволи Graph API** у Entra ID (Azure AD) → App Registration:
+ - `Sites.ReadWrite.All` (Application) — вивантаження файлів до SharePoint
+ - `Chat.Read.All` (Application) — необов’язково, вмикає посилання для спільного доступу на рівні користувачів
2. **Надайте admin consent** для tenant.
3. **Отримайте ваш SharePoint site ID:**
```bash
- # Через Graph Explorer або curl з чинним токеном:
+ # Через Graph Explorer або curl з дійсним токеном:
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
- # Приклад: для сайту за адресою "contoso.sharepoint.com/sites/BotFiles"
+ # Приклад: для сайту "contoso.sharepoint.com/sites/BotFiles"
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
@@ -760,40 +759,40 @@ Markdown у Teams більш обмежений, ніж у Slack або Discord:
### Поведінка спільного доступу
-| Дозвіл | Поведінка спільного доступу |
-| --------------------------------------- | ---------------------------------------------------------- |
-| `Sites.ReadWrite.All` only | Посилання для спільного доступу на рівні організації (доступне будь-кому в org) |
-| `Sites.ReadWrite.All` + `Chat.Read.All` | Посилання для спільного доступу для окремих користувачів (доступне лише учасникам чату) |
+| Permission | Sharing behavior |
+| --------------------------------------- | --------------------------------------------------------- |
+| `Sites.ReadWrite.All` only | Посилання для спільного доступу на всю організацію (доступне будь-кому в організації) |
+| `Sites.ReadWrite.All` + `Chat.Read.All` | Посилання для спільного доступу на рівні користувачів (доступне лише учасникам чату) |
-Спільний доступ для окремих користувачів безпечніший, оскільки доступ до файлу мають лише учасники чату. Якщо дозвіл `Chat.Read.All` відсутній, бот повертається до спільного доступу на рівні організації.
+Спільний доступ на рівні користувачів безпечніший, оскільки лише учасники чату можуть отримати доступ до файлу. Якщо дозвіл `Chat.Read.All` відсутній, бот повертається до спільного доступу на всю організацію.
### Резервна поведінка
-| Сценарій | Результат |
-| ------------------------------------------------ | --------------------------------------------------- |
-| Груповий чат + файл + налаштовано `sharePointSiteId` | Вивантаження в SharePoint, надсилання посилання для спільного доступу |
-| Груповий чат + файл + немає `sharePointSiteId` | Спроба вивантаження в OneDrive (може не вдатися), надсилання лише тексту |
-| Особистий чат + файл | Потік FileConsentCard (працює без SharePoint) |
-| Будь-який контекст + зображення | Inline у кодуванні Base64 (працює без SharePoint) |
+| Scenario | Result |
+| ------------------------------------------------- | -------------------------------------------------- |
+| Груповий чат + файл + налаштовано `sharePointSiteId` | Вивантаження до SharePoint, надсилання посилання для спільного доступу |
+| Груповий чат + файл + немає `sharePointSiteId` | Спроба вивантаження в OneDrive (може завершитися помилкою), надсилається лише текст |
+| Особистий чат + файл | Потік FileConsentCard (працює без SharePoint) |
+| Будь-який контекст + зображення | Inline у форматі Base64 (працює без SharePoint) |
### Де зберігаються файли
-Вивантажені файли зберігаються в папці `/OpenClawShared/` у типовій бібліотеці документів налаштованого сайту SharePoint.
+Вивантажені файли зберігаються в папці `/OpenClawShared/` у стандартній бібліотеці документів налаштованого сайту SharePoint.
## Опитування (Adaptive Cards)
-OpenClaw надсилає опитування Teams як Adaptive Cards (рідного API опитувань Teams немає).
+OpenClaw надсилає опитування Teams як Adaptive Cards (власного API опитувань у Teams немає).
- CLI: `openclaw message poll --channel msteams --target conversation: ...`
- Голоси записуються Gateway у `~/.openclaw/msteams-polls.json`.
-- Gateway має залишатися онлайн, щоб записувати голоси.
-- Опитування поки не публікують підсумки результатів автоматично (за потреби перегляньте файл сховища).
+- Щоб записувати голоси, Gateway має залишатися онлайн.
+- Підсумкові зведення результатів опитувань поки не публікуються автоматично (за потреби перевіряйте файл сховища).
## Картки presentation
-Надсилайте семантичні payload presentation користувачам Teams або в розмови через інструмент `message` або CLI. OpenClaw відтворює їх як Teams Adaptive Cards із загального контракту presentation.
+Надсилайте семантичні payload presentation користувачам або розмовам Teams за допомогою інструмента `message` або CLI. OpenClaw відтворює їх як Teams Adaptive Cards на основі узагальненого контракту presentation.
-Параметр `presentation` приймає семантичні блоки. Якщо задано `presentation`, текст повідомлення є необов’язковим.
+Параметр `presentation` приймає семантичні блоки. Якщо передано `presentation`, текст повідомлення не є обов’язковим.
**Інструмент агента:**
@@ -817,18 +816,18 @@ openclaw message send --channel msteams \
--presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}'
```
-Докладно про формат цілі див. [Формати цілі](#target-formats) нижче.
+Докладніше про формат target див. у [Формати target](#target-formats) нижче.
-## Формати цілі
+## Формати target
-Цілі MSTeams використовують префікси, щоб розрізняти користувачів і розмови:
+Target у MSTeams використовують префікси, щоб розрізняти користувачів і розмови:
-| Тип цілі | Формат | Приклад |
-| ---------------------- | -------------------------------- | --------------------------------------------------- |
-| Користувач (за ID) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
-| Користувач (за ім’ям) | `user:` | `user:John Smith` (потрібен Graph API) |
-| Група/канал | `conversation:` | `conversation:19:abc123...@thread.tacv2` |
-| Група/канал (raw) | `` | `19:abc123...@thread.tacv2` (якщо містить `@thread`) |
+| Target type | Format | Example |
+| ------------------- | -------------------------------- | --------------------------------------------------- |
+| Користувач (за ID) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
+| Користувач (за ім’ям) | `user:` | `user:John Smith` (потребує Graph API) |
+| Група/канал | `conversation:` | `conversation:19:abc123...@thread.tacv2` |
+| Група/канал (raw) | `` | `19:abc123...@thread.tacv2` (якщо містить `@thread`) |
**Приклади CLI:**
@@ -836,7 +835,7 @@ openclaw message send --channel msteams \
# Надіслати користувачу за ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
-# Надіслати користувачу за display name (викликає пошук через Graph API)
+# Надіслати користувачу за display name (запускає Graph API lookup)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Надіслати в груповий чат або канал
@@ -870,94 +869,94 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread.
}
```
-Примітка: без префікса `user:` імена типово трактуються як цілі групи/команди. Завжди використовуйте `user:`, коли націлюєтеся на людей за display name.
+Примітка: без префікса `user:` імена типово трактуються як цілі групи/team. Завжди використовуйте `user:`, коли адресуєте повідомлення людям за display name.
## Проактивні повідомлення
- Проактивні повідомлення можливі лише **після** взаємодії користувача, оскільки саме тоді ми зберігаємо посилання на розмову.
-- Див. `/gateway/configuration` для `dmPolicy` і керування через allowlist.
+- Див. `/gateway/configuration` для `dmPolicy` і обмеження через allowlist.
-## ID команд і каналів (поширена пастка)
+## ID team і channel (типова пастка)
-Параметр запиту `groupId` в URL Teams — **НЕ** той ID команди, який використовується для конфігурації. Натомість витягуйте ID зі шляху URL:
+Параметр запиту `groupId` в URL Teams — **НЕ** той team ID, який використовується для конфігурації. Натомість витягуйте ID зі шляху URL:
-**URL команди:**
+**URL team:**
```
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
- ID команди (декодуйте URL)
+ Team ID (декодуйте URL)
```
-**URL каналу:**
+**URL channel:**
```
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
- ID каналу (декодуйте URL)
+ Channel ID (декодуйте URL)
```
**Для конфігурації:**
-- ID команди = сегмент шляху після `/team/` (після URL-декодування, наприклад `19:Bk4j...@thread.tacv2`)
-- ID каналу = сегмент шляху після `/channel/` (після URL-декодування)
+- Team ID = сегмент шляху після `/team/` (після декодування URL, наприклад, `19:Bk4j...@thread.tacv2`)
+- Channel ID = сегмент шляху після `/channel/` (після декодування URL)
- Параметр запиту `groupId` **ігноруйте**
## Приватні канали
Боти мають обмежену підтримку в приватних каналах:
-| Функція | Стандартні канали | Приватні канали |
-| --------------------------- | ----------------- | --------------------- |
-| Встановлення бота | Так | Обмежено |
-| Повідомлення в реальному часі (webhook) | Так | Може не працювати |
-| Дозволи RSC | Так | Можуть поводитися інакше |
-| @mentions | Так | Якщо бот доступний |
-| Історія через Graph API | Так | Так (з дозволами) |
+| Feature | Standard Channels | Private Channels |
+| ---------------------------- | ----------------- | --------------------- |
+| Встановлення бота | Так | Обмежено |
+| Повідомлення в реальному часі (webhook) | Так | Може не працювати |
+| Дозволи RSC | Так | Можуть працювати інакше |
+| @mentions | Так | Якщо бот доступний |
+| Історія через Graph API | Так | Так (за наявності дозволів) |
-**Обхідні варіанти, якщо приватні канали не працюють:**
+**Обхідні шляхи, якщо приватні канали не працюють:**
1. Використовуйте стандартні канали для взаємодії з ботом
2. Використовуйте DM — користувачі завжди можуть писати боту напряму
-3. Використовуйте Graph API для історичного доступу (потрібен `ChannelMessage.Read.All`)
+3. Використовуйте Graph API для історичного доступу (потребує `ChannelMessage.Read.All`)
-## Усунення несправностей
+## Усунення проблем
-### Поширені проблеми
+### Типові проблеми
- **Зображення не відображаються в каналах:** відсутні дозволи Graph або admin consent. Перевстановіть застосунок Teams і повністю закрийте/заново відкрийте Teams.
-- **Немає відповідей у каналі:** типово потрібні згадки; установіть `channels.msteams.requireMention=false` або налаштуйте це для окремої команди/каналу.
-- **Невідповідність версій (Teams усе ще показує старий маніфест):** видаліть і повторно додайте застосунок та повністю закрийте Teams, щоб оновити стан.
-- **401 Unauthorized від webhook:** це очікувано під час ручного тестування без Azure JWT — означає, що endpoint досяжний, але автентифікація не пройшла. Для коректної перевірки використовуйте Azure Web Chat.
+- **Немає відповідей у каналі:** згадки типово обов’язкові; задайте `channels.msteams.requireMention=false` або налаштуйте це для конкретної team/channel.
+- **Невідповідність версій (Teams досі показує старий маніфест):** видаліть і знову додайте застосунок та повністю закрийте Teams, щоб оновити дані.
+- **401 Unauthorized від webhook:** очікувана поведінка під час ручного тестування без Azure JWT — означає, що endpoint доступний, але автентифікація не пройшла. Для коректної перевірки використовуйте Azure Web Chat.
### Помилки завантаження маніфесту
-- **"Icon file cannot be empty":** маніфест посилається на файли іконок розміром 0 байтів. Створіть коректні PNG-іконки (`outline.png` 32x32, `color.png` 192x192).
-- **"webApplicationInfo.Id already in use":** застосунок усе ще встановлений в іншій команді/чаті. Спочатку знайдіть і видаліть його або зачекайте 5–10 хвилин на поширення змін.
-- **"Something went wrong" під час завантаження:** завантажте через [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com), відкрийте DevTools у браузері (F12) → вкладка Network і перевірте тіло відповіді на фактичну помилку.
-- **Sideload не працює:** спробуйте "Upload an app to your org's app catalog" замість "Upload a custom app" — це часто обходить обмеження sideload.
+- **"Icon file cannot be empty":** маніфест посилається на файли іконок розміром 0 байт. Створіть коректні PNG-іконки (`outline.png` 32x32, `color.png` 192x192).
+- **"webApplicationInfo.Id already in use":** застосунок усе ще встановлений в іншій team/chat. Спочатку знайдіть і видаліть його або зачекайте 5–10 хвилин на поширення змін.
+- **"Something went wrong" під час завантаження:** замість цього завантажуйте через [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com), відкрийте DevTools у браузері (F12) → вкладка Network і перевірте тіло відповіді на фактичну помилку.
+- **Не вдається sideload:** спробуйте "Upload an app to your org's app catalog" замість "Upload a custom app" — це часто обходить обмеження sideload.
### Дозволи RSC не працюють
1. Переконайтеся, що `webApplicationInfo.id` точно збігається з App ID вашого бота
-2. Повторно завантажте застосунок і перевстановіть його в команді/чаті
-3. Перевірте, чи адміністратор вашої org не заблокував дозволи RSC
-4. Підтвердьте, що використовуєте правильний scope: `ChannelMessage.Read.Group` для команд, `ChatMessage.Read.Chat` для групових чатів
+2. Повторно завантажте застосунок і перевстановіть його в team/chat
+3. Перевірте, чи адміністратор вашої організації не заблокував дозволи RSC
+4. Підтвердьте, що ви використовуєте правильну область: `ChannelMessage.Read.Group` для teams, `ChatMessage.Read.Chat` для групових чатів
## Посилання
- [Create Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - посібник із налаштування Azure Bot
-- [Teams Developer Portal](https://dev.teams.microsoft.com/apps) - створення та керування застосунками Teams
+- [Teams Developer Portal](https://dev.teams.microsoft.com/apps) - створення/керування застосунками Teams
- [Teams app manifest schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema)
- [Receive channel messages with RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc)
- [RSC permissions reference](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent)
-- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (для каналу/групи потрібен Graph)
+- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (для channel/group потрібен Graph)
- [Proactive messaging](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)
## Пов’язане
-- [Channels Overview](/uk/channels) — усі підтримувані канали
+- [Огляд каналів](/uk/channels) — усі підтримувані канали
- [Pairing](/uk/channels/pairing) — автентифікація DM і потік pairing
-- [Groups](/uk/channels/groups) — поведінка групового чату й керування через згадки
-- [Channel Routing](/uk/channels/channel-routing) — маршрутизація сесій для повідомлень
-- [Security](/uk/gateway/security) — модель доступу та посилення захисту
+- [Групи](/uk/channels/groups) — поведінка групового чату та обмеження через згадки
+- [Маршрутизація каналів](/uk/channels/channel-routing) — маршрутизація сесій для повідомлень
+- [Безпека](/uk/gateway/security) — модель доступу та посилення захисту
diff --git a/docs/uk/channels/troubleshooting.md b/docs/uk/channels/troubleshooting.md
index b455db263..3b3e63703 100644
--- a/docs/uk/channels/troubleshooting.md
+++ b/docs/uk/channels/troubleshooting.md
@@ -1,25 +1,25 @@
---
read_when:
- - Транспорт каналу показує, що підключено, але відповіді не працюють
- - Потрібні перевірки, специфічні для каналу, перед переходом до детальної документації провайдера
-summary: Швидке усунення несправностей на рівні каналу з характерними ознаками збоїв і виправленнями для кожного каналу
-title: Усунення несправностей каналу
+ - Транспорт каналу показує, що підключено, але відповіді не надсилаються
+ - Потрібні перевірки для конкретного каналу, перш ніж заглиблюватися в документацію провайдера
+summary: Швидке усунення несправностей на рівні каналів із характерними ознаками збоїв і виправленнями для кожного каналу
+title: Усунення несправностей каналів
x-i18n:
- generated_at: "2026-04-21T00:17:12Z"
+ generated_at: "2026-04-21T21:27:21Z"
model: gpt-5.4
provider: openai
- source_hash: 69e9e8f093bee1c7aafc244d6b999a957b7571cc125096d72060d0df52bf52c0
+ source_hash: 8c57934b52086ea5f41565c5aae77ef6fa772cf7d56a6427655a844a5c63d1c6
source_path: channels/troubleshooting.md
workflow: 15
---
-# Усунення несправностей каналу
+# Усунення несправностей каналів
Використовуйте цю сторінку, коли канал підключається, але працює неправильно.
## Послідовність команд
-Спочатку виконайте їх у такому порядку:
+Спочатку запускайте їх у такому порядку:
```bash
openclaw status
@@ -34,7 +34,7 @@ openclaw channels status --probe
- `Runtime: running`
- `Connectivity probe: ok`
- `Capability: read-only`, `write-capable` або `admin-capable`
-- Перевірка каналу показує, що транспорт підключено і, де підтримується, `works` або `audit ok`
+- Перевірка каналу показує, що транспорт підключено і, де це підтримується, `works` або `audit ok`
## WhatsApp
@@ -43,100 +43,100 @@ openclaw channels status --probe
| Симптом | Найшвидша перевірка | Виправлення |
| ------------------------------- | ------------------------------------------------ | ------------------------------------------------------------ |
| Підключено, але немає відповідей у DM | `openclaw pairing list whatsapp` | Підтвердьте відправника або змініть політику DM/список дозволених. |
-| Повідомлення групи ігноруються | Перевірте `requireMention` і шаблони згадок у конфігурації | Згадайте бота або пом’якшіть політику згадок для цієї групи. |
+| Повідомлення в групі ігноруються | Перевірте `requireMention` і шаблони згадування в конфігурації | Згадайте бота або пом’якште політику згадування для цієї групи. |
| Випадкові відключення/цикли повторного входу | `openclaw channels status --probe` + журнали | Увійдіть знову та переконайтеся, що каталог облікових даних справний. |
-Повне усунення несправностей: [/channels/whatsapp#troubleshooting](/uk/channels/whatsapp#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей WhatsApp](/uk/channels/whatsapp#troubleshooting)
## Telegram
### Характерні ознаки збоїв Telegram
-| Симптом | Найшвидша перевірка | Виправлення |
-| ----------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
-| Є `/start`, але немає придатного потоку відповідей | `openclaw pairing list telegram` | Підтвердьте сполучення або змініть політику DM. |
-| Бот онлайн, але група мовчить | Перевірте вимогу згадки та режим приватності бота | Вимкніть режим приватності для видимості в групі або згадайте бота. |
-| Помилки надсилання з мережевими помилками | Перегляньте журнали на наявність збоїв викликів Telegram API | Виправте маршрутизацію DNS/IPv6/проксі до `api.telegram.org`. |
-| Опитування зависає або повільно перепідключається | `openclaw logs --follow` для діагностики опитування | Оновіться; якщо перезапуски є хибнопозитивними, налаштуйте `pollingStallThresholdMs`. Постійні зависання все ще вказують на проксі/DNS/IPv6. |
-| `setMyCommands` відхиляється під час запуску | Перегляньте журнали на `BOT_COMMANDS_TOO_MUCH` | Зменште кількість команд Telegram для Plugin/Skills/користувацьких команд або вимкніть нативні меню. |
-| Після оновлення список дозволених вас блокує | `openclaw security audit` і списки дозволених у конфігурації | Виконайте `openclaw doctor --fix` або замініть `@username` на числові ID відправників. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| ----------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
+| `/start`, але немає придатного потоку відповідей | `openclaw pairing list telegram` | Підтвердьте pairing або змініть політику DM. |
+| Бот онлайн, але група мовчить | Перевірте вимогу згадування та режим приватності бота | Вимкніть режим приватності для видимості в групі або згадайте бота. |
+| Надсилання завершується помилками мережі | Перегляньте журнали на наявність збоїв викликів Telegram API | Виправте маршрутизацію DNS/IPv6/proxy до `api.telegram.org`. |
+| Polling зависає або повільно перепідключається | `openclaw logs --follow` для діагностики polling | Оновіться; якщо перезапуски є хибнопозитивними, налаштуйте `pollingStallThresholdMs`. Постійні зависання все ще вказують на proxy/DNS/IPv6. |
+| `setMyCommands` відхиляється під час запуску | Перегляньте журнали на `BOT_COMMANDS_TOO_MUCH` | Зменште кількість команд Telegram від plugin/skill/custom або вимкніть нативні меню. |
+| Після оновлення список дозволених вас блокує | `openclaw security audit` і списки дозволених у конфігурації | Запустіть `openclaw doctor --fix` або замініть `@username` на числові ID відправників. |
-Повне усунення несправностей: [/channels/telegram#troubleshooting](/uk/channels/telegram#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей Telegram](/uk/channels/telegram#troubleshooting)
## Discord
### Характерні ознаки збоїв Discord
-| Симптом | Найшвидша перевірка | Виправлення |
-| ------------------------------- | -------------------------------- | ------------------------------------------------------------- |
-| Бот онлайн, але немає відповідей у guild | `openclaw channels status --probe` | Дозвольте guild/channel і перевірте intent вмісту повідомлень. |
-| Повідомлення групи ігноруються | Перевірте журнали на відкидання через вимогу згадки | Згадайте бота або встановіть `requireMention: false` для guild/channel. |
-| Відсутні відповіді в DM | `openclaw pairing list discord` | Підтвердьте сполучення DM або скоригуйте політику DM. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| ------------------------------- | ------------------------------------ | ------------------------------------------------------------ |
+| Бот онлайн, але немає відповідей у guild | `openclaw channels status --probe` | Дозвольте guild/channel і перевірте intent для вмісту повідомлень. |
+| Повідомлення в групі ігноруються | Перевірте журнали на drops через вимогу згадування | Згадайте бота або встановіть `requireMention: false` для guild/channel. |
+| Немає відповідей у DM | `openclaw pairing list discord` | Підтвердьте DM pairing або скоригуйте політику DM. |
-Повне усунення несправностей: [/channels/discord#troubleshooting](/uk/channels/discord#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей Discord](/uk/channels/discord#troubleshooting)
## Slack
### Характерні ознаки збоїв Slack
-| Симптом | Найшвидша перевірка | Виправлення |
-| -------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Socket mode підключено, але немає відповідей | `openclaw channels status --probe` | Перевірте токен застосунку, токен бота та потрібні області доступу; звертайте увагу на `botTokenStatus` / `appTokenStatus = configured_unavailable` у конфігураціях на основі SecretRef. |
-| DM заблоковані | `openclaw pairing list slack` | Підтвердьте сполучення або пом’якшіть політику DM. |
-| Повідомлення каналу ігноруються | Перевірте `groupPolicy` і список дозволених каналів | Дозвольте канал або змініть політику на `open`. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| -------------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Socket mode підключено, але немає відповідей | `openclaw channels status --probe` | Перевірте app token + bot token і потрібні scopes; зверніть увагу на `botTokenStatus` / `appTokenStatus = configured_unavailable` у конфігураціях на базі SecretRef. |
+| DM заблоковано | `openclaw pairing list slack` | Підтвердьте pairing або пом’якште політику DM. |
+| Повідомлення каналу ігнорується | Перевірте `groupPolicy` і список дозволених каналів | Дозвольте канал або змініть політику на `open`. |
-Повне усунення несправностей: [/channels/slack#troubleshooting](/uk/channels/slack#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей Slack](/uk/channels/slack#troubleshooting)
-## iMessage and BlueBubbles
+## iMessage і BlueBubbles
-### Характерні ознаки збоїв iMessage and BlueBubbles
+### Характерні ознаки збоїв iMessage і BlueBubbles
| Симптом | Найшвидша перевірка | Виправлення |
| -------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------ |
-| Немає вхідних подій | Перевірте доступність Webhook/сервера та дозволи застосунку | Виправте URL Webhook або стан сервера BlueBubbles. |
-| Можна надсилати, але немає прийому на macOS | Перевірте дозволи приватності macOS для автоматизації Messages | Повторно надайте дозволи TCC і перезапустіть процес каналу. |
-| Відправника DM заблоковано | `openclaw pairing list imessage` або `openclaw pairing list bluebubbles` | Підтвердьте сполучення або оновіть список дозволених. |
+| Немає вхідних подій | Перевірте досяжність Webhook/сервера та дозволи застосунку | Виправте URL Webhook або стан сервера BlueBubbles. |
+| Можна надсилати, але немає прийому на macOS | Перевірте дозволи конфіденційності macOS для автоматизації Messages | Повторно надайте дозволи TCC і перезапустіть процес каналу. |
+| Відправника DM заблоковано | `openclaw pairing list imessage` або `openclaw pairing list bluebubbles` | Підтвердьте pairing або оновіть список дозволених. |
Повне усунення несправностей:
-- [/channels/imessage#troubleshooting](/uk/channels/imessage#troubleshooting)
-- [/channels/bluebubbles#troubleshooting](/uk/channels/bluebubbles#troubleshooting)
+- [Усунення несправностей iMessage](/uk/channels/imessage#troubleshooting)
+- [Усунення несправностей BlueBubbles](/uk/channels/bluebubbles#troubleshooting)
## Signal
### Характерні ознаки збоїв Signal
-| Симптом | Найшвидша перевірка | Виправлення |
-| ------------------------------- | ----------------------------------- | ------------------------------------------------------------- |
-| Демон доступний, але бот мовчить | `openclaw channels status --probe` | Перевірте URL/обліковий запис демона `signal-cli` і режим receive. |
-| DM заблоковано | `openclaw pairing list signal` | Підтвердьте відправника або скоригуйте політику DM. |
-| Не спрацьовують відповіді в групі | Перевірте список дозволених груп і шаблони згадок | Додайте відправника/групу або послабте обмеження. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| ------------------------------- | --------------------------------------- | ------------------------------------------------------------- |
+| Daemon доступний, але бот мовчить | `openclaw channels status --probe` | Перевірте URL/account daemon `signal-cli` і режим receive. |
+| DM заблоковано | `openclaw pairing list signal` | Підтвердьте відправника або скоригуйте політику DM. |
+| Відповіді в групі не спрацьовують | Перевірте список дозволених груп і шаблони згадування | Додайте відправника/групу або послабте правила фільтрації. |
-Повне усунення несправностей: [/channels/signal#troubleshooting](/uk/channels/signal#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей Signal](/uk/channels/signal#troubleshooting)
## QQ Bot
### Характерні ознаки збоїв QQ Bot
-| Симптом | Найшвидша перевірка | Виправлення |
-| ------------------------------- | ------------------------------------------ | ---------------------------------------------------------------- |
-| Бот відповідає "gone to Mars" | Перевірте `appId` і `clientSecret` у конфігурації | Задайте облікові дані або перезапустіть Gateway. |
-| Немає вхідних повідомлень | `openclaw channels status --probe` | Перевірте облікові дані на QQ Open Platform. |
-| Голос не транскрибується | Перевірте конфігурацію провайдера STT | Налаштуйте `channels.qqbot.stt` або `tools.media.audio`. |
-| Ініційовані ботом повідомлення не надходять | Перевірте вимоги QQ platform до взаємодій | QQ може блокувати ініційовані ботом повідомлення без недавньої взаємодії. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| ------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------ |
+| Бот відповідає "gone to Mars" | Перевірте `appId` і `clientSecret` у конфігурації | Установіть облікові дані або перезапустіть Gateway. |
+| Немає вхідних повідомлень | `openclaw channels status --probe` | Перевірте облікові дані на QQ Open Platform. |
+| Голос не транскрибується | Перевірте конфігурацію провайдера STT | Налаштуйте `channels.qqbot.stt` або `tools.media.audio`. |
+| Проактивні повідомлення не надходять | Перевірте вимоги платформи QQ щодо взаємодії | QQ може блокувати повідомлення, ініційовані ботом, без недавньої взаємодії. |
-Повне усунення несправностей: [/channels/qqbot#troubleshooting](/uk/channels/qqbot#troubleshooting)
+Повне усунення несправностей: [Усунення несправностей QQ Bot](/uk/channels/qqbot#troubleshooting)
## Matrix
### Характерні ознаки збоїв Matrix
-| Симптом | Найшвидша перевірка | Виправлення |
-| ----------------------------------- | ----------------------------------- | -------------------------------------------------------------------------- |
-| Вхід виконано, але повідомлення кімнати ігноруються | `openclaw channels status --probe` | Перевірте `groupPolicy`, список дозволених кімнат і обмеження на згадки. |
-| DM не обробляються | `openclaw pairing list matrix` | Підтвердьте відправника або скоригуйте політику DM. |
-| Зашифровані кімнати не працюють | `openclaw matrix verify status` | Повторно верифікуйте пристрій, а потім перевірте `openclaw matrix verify backup status`. |
-| Відновлення резервної копії очікує/пошкоджене | `openclaw matrix verify backup status` | Виконайте `openclaw matrix verify backup restore` або повторіть із ключем відновлення. |
-| Кроспідписування/bootstrap виглядає неправильно | `openclaw matrix verify bootstrap` | За один прохід виправте secret storage, кроспідписування та стан резервних копій. |
+| Симптом | Найшвидша перевірка | Виправлення |
+| ----------------------------------- | --------------------------------------- | ------------------------------------------------------------------------- |
+| Вхід виконано, але повідомлення кімнат ігноруються | `openclaw channels status --probe` | Перевірте `groupPolicy`, список дозволених кімнат і фільтрацію за згадуванням. |
+| DM не обробляються | `openclaw pairing list matrix` | Підтвердьте відправника або скоригуйте політику DM. |
+| Зашифровані кімнати не працюють | `openclaw matrix verify status` | Повторно підтвердьте пристрій, потім перевірте `openclaw matrix verify backup status`. |
+| Відновлення резервної копії очікується/зламане | `openclaw matrix verify backup status` | Запустіть `openclaw matrix verify backup restore` або повторіть із recovery key. |
+| Cross-signing/bootstrap виглядає неправильно | `openclaw matrix verify bootstrap` | Виправте secret storage, cross-signing і стан резервної копії за один прохід. |
-Повне налаштування та конфігурація: [Matrix](/uk/channels/matrix)
+Повне налаштування і конфігурація: [Matrix](/uk/channels/matrix)
diff --git a/docs/uk/ci.md b/docs/uk/ci.md
index e2a5a2aa8..bd3f24eae 100644
--- a/docs/uk/ci.md
+++ b/docs/uk/ci.md
@@ -1,89 +1,89 @@
---
read_when:
- - Вам потрібно зрозуміти, чому завдання CI було або не було запущено
- - Ви налагоджуєте збої перевірок GitHub Actions
-summary: Граф завдань CI, шлюзи області змін і локальні еквіваленти команд
+ - Вам потрібно зрозуміти, чому завдання CI було або не було запущене
+ - Ви налагоджуєте перевірки GitHub Actions, що завершилися з помилкою
+summary: Граф завдань CI, обмеження за областю змін і локальні еквіваленти команд
title: Конвеєр CI
x-i18n:
- generated_at: "2026-04-21T18:05:48Z"
+ generated_at: "2026-04-21T21:27:24Z"
model: gpt-5.4
provider: openai
- source_hash: 4d01a178402976cdf7c3c864695e8a12d3f7d1d069a77ea1b02a8aef2a3497f7
+ source_hash: ae08bad6cbd0f2eced6c88a792a11bc1c2b1a2bfb003a56f70ff328a2739d3fc
source_path: ci.md
workflow: 15
---
# Конвеєр CI
-CI запускається для кожного push у `main` і для кожного pull request. Він використовує розумне визначення області змін, щоб пропускати дорогі завдання, коли змінено лише нерелевантні частини.
+CI запускається для кожного push у `main` і для кожного pull request. Він використовує розумне обмеження за областю змін, щоб пропускати дорогі завдання, коли змінено лише не пов’язані ділянки.
## Огляд завдань
-| Завдання | Призначення | Коли запускається |
-| -------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------- |
-| `preflight` | Виявляє зміни лише в документації, області змін, змінені розширення та будує маніфест CI | Завжди для push і PR не в чернетці |
-| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для push і PR не в чернетці |
-| `security-dependency-audit` | Аудит production lockfile без залежностей на основі advisories npm | Завжди для push і PR не в чернетці |
-| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для push і PR не в чернетці |
-| `build-artifacts` | Один раз збирає `dist/` і Control UI, завантажує повторно використовувані артефакти для downstream-завдань | Зміни, релевантні для Node |
-| `checks-fast-core` | Швидкі Linux-етапи перевірки коректності, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні для Node |
-| `checks-fast-contracts-channels` | Розшардовані перевірки контрактів каналів зі стабільним агрегованим результатом | Зміни, релевантні для Node |
-| `checks-node-extensions` | Повні шарди тестів bundled-plugin для всього набору розширень | Зміни, релевантні для Node |
-| `checks-node-core-test` | Шарди тестів core Node, за винятком каналів, bundled, контрактних і extension-етапів | Зміни, релевантні для Node |
-| `extension-fast` | Цільові тести лише для змінених bundled plugins | Коли виявлено зміни в розширеннях |
-| `check` | Розшардований еквівалент основного локального шлюзу: production types, lint, guards, test types і strict smoke | Зміни, релевантні для Node |
-| `check-additional` | Шарди архітектурних, boundary, extension-surface guards, package-boundary і gateway-watch перевірок | Зміни, релевантні для Node |
-| `build-smoke` | Smoke-тести зібраного CLI і smoke-перевірка пам’яті під час запуску | Зміни, релевантні для Node |
-| `checks` | Решта Linux Node-етапів: тести каналів і сумісність Node 22 лише для push | Зміни, релевантні для Node |
-| `check-docs` | Форматування документації, lint і перевірка на биті посилання | Документацію змінено |
+| Завдання | Призначення | Коли запускається |
+| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
+| `preflight` | Виявляє зміни лише в документації, змінені області, змінені extensions і збирає маніфест CI | Завжди для push і PR, що не є draft |
+| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для push і PR, що не є draft |
+| `security-dependency-audit` | Аудит production lockfile без залежностей щодо попереджень npm | Завжди для push і PR, що не є draft |
+| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для push і PR, що не є draft |
+| `build-artifacts` | Один раз збирає `dist/` і Control UI, вивантажує повторно використовувані артефакти для наступних завдань | Зміни, релевантні для Node |
+| `checks-fast-core` | Швидкі Linux-етапи перевірки коректності, як-от bundled/plugin-contract/protocol перевірки | Зміни, релевантні для Node |
+| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні для Node |
+| `checks-node-extensions` | Повні шарди тестів bundled-plugin для всього набору extension | Зміни, релевантні для Node |
+| `checks-node-core-test` | Шарди основних Node-тестів, без каналів, bundled, contract і extension-етапів | Зміни, релевантні для Node |
+| `extension-fast` | Цільові тести лише для змінених bundled plugins | Коли виявлено зміни в extension |
+| `check` | Шардований еквівалент основного локального gate: production types, lint, guards, test types і strict smoke | Зміни, релевантні для Node |
+| `check-additional` | Шарди архітектури, меж, guards поверхні extension, package-boundary і gateway-watch | Зміни, релевантні для Node |
+| `build-smoke` | Smoke-тести зібраного CLI і smoke-тест пам’яті під час запуску | Зміни, релевантні для Node |
+| `checks` | Решта Linux Node-етапів: тести каналів і сумісність лише для push із Node 22 | Зміни, релевантні для Node |
+| `check-docs` | Форматування документації, lint і перевірки битих посилань | Документацію змінено |
| `skills-python` | Ruff + pytest для Skills на базі Python | Зміни, релевантні для Python Skills |
-| `checks-windows` | Windows-специфічні тестові етапи | Зміни, релевантні для Windows |
-| `macos-node` | Етап тестів TypeScript на macOS із використанням спільних зібраних артефактів | Зміни, релевантні для macOS |
-| `macos-swift` | Swift lint, build і тести для застосунку macOS | Зміни, релевантні для macOS |
-| `android` | Матриця збірки та тестів Android | Зміни, релевантні для Android |
+| `checks-windows` | Специфічні для Windows етапи тестування | Зміни, релевантні для Windows |
+| `macos-node` | Етап TypeScript-тестів на macOS із використанням спільних зібраних артефактів | Зміни, релевантні для macOS |
+| `macos-swift` | Swift lint, збірка і тести для застосунку macOS | Зміни, релевантні для macOS |
+| `android` | Матриця збірки і тестів Android | Зміни, релевантні для Android |
-## Порядок Fail-Fast
+## Порядок швидкого завершення з помилкою
-Завдання впорядковано так, щоб дешеві перевірки завершувалися з помилкою раніше, ніж запускаються дорогі:
+Завдання впорядковано так, щоб дешеві перевірки завершувалися з помилкою раніше, ніж запустяться дорогі:
1. `preflight` вирішує, які етапи взагалі існують. Логіка `docs-scope` і `changed-scope` — це кроки всередині цього завдання, а не окремі завдання.
-2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` завершуються швидко, не чекаючи важчих матричних завдань артефактів і платформ.
-3. `build-artifacts` виконується паралельно зі швидкими Linux-етапами, щоб downstream-споживачі могли почати роботу, щойно спільна збірка буде готова.
-4. Після цього розгалужуються важчі платформні та runtime-етапи: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`.
+2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко завершуються з помилкою, не очікуючи важчих завдань з артефактами й платформеними матрицями.
+3. `build-artifacts` виконується паралельно зі швидкими Linux-етапами, щоб наступні споживачі могли стартувати, щойно буде готова спільна збірка.
+4. Після цього розгалужуються важчі платформені й runtime-етапи: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`.
-Логіка області змін розміщена в `scripts/ci-changed-scope.mjs` і покрита unit-тестами в `src/scripts/ci-changed-scope.test.ts`.
-Окремий workflow `install-smoke` повторно використовує той самий скрипт області змін через власне завдання `preflight`. Він обчислює `run_install_smoke` із вужчого сигналу changed-smoke, тому Docker/install smoke запускається лише для змін, релевантних до встановлення, пакування та контейнерів.
+Логіка областей змін міститься в `scripts/ci-changed-scope.mjs` і покрита unit-тестами в `src/scripts/ci-changed-scope.test.ts`.
+Окремий workflow `install-smoke` повторно використовує той самий скрипт обмеження області через власне завдання `preflight`. Він обчислює `run_install_smoke` із вужчого сигналу changed-smoke, тому Docker/install smoke запускається лише для змін, релевантних до install, packaging і container.
-Логіка локальних changed-lanes розміщена в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний шлюз суворіший щодо архітектурних меж, ніж широка область платформ у CI: зміни core production запускають typecheck core prod плюс тести core, зміни лише в core tests запускають лише typecheck/tests для core tests, зміни extension production запускають typecheck extension prod плюс тести розширень, а зміни лише в extension tests запускають лише typecheck/tests для extension tests. Зміни в public Plugin SDK або plugin-contract розширюють перевірку до validation розширень, тому що розширення залежать від цих core-контрактів. Невідомі зміни в корені/config безпечно переводять виконання на всі етапи.
+Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний gate суворіший щодо архітектурних меж, ніж широке платформене обмеження області в CI: зміни core production запускають core prod typecheck плюс core tests, зміни лише core tests запускають лише core test typecheck/tests, зміни extension production запускають extension prod typecheck плюс extension tests, а зміни лише extension tests запускають лише extension test typecheck/tests. Зміни в публічному Plugin SDK або plugin-contract розширюють перевірку на extension, оскільки extensions залежать від цих контрактів core. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency. Невідомі зміни в root/config безпечно розширюються до всіх етапів.
-Для push матриця `checks` додає етап `compat-node22`, який запускається лише для push. Для pull request цей етап пропускається, і матриця залишається зосередженою на звичайних test/channel-етапах.
+Для push матриця `checks` додає етап `compat-node22`, який запускається лише для push. Для pull request цей етап пропускається, і матриця зосереджується на звичайних test/channel-етапах.
-Найповільніші сімейства тестів Node розбиті на include-file шарди, щоб кожне завдання залишалося невеликим: channel contracts розділяють покриття registry і core на вісім зважених шардів кожне, тести auto-reply reply command поділено на чотири шарди за include-pattern, а інші великі групи auto-reply reply prefix — на два шарди кожна. `check-additional` також відокремлює compile/canary-роботи package-boundary від runtime topology gateway/architecture-робіт.
+Найповільніші сімейства Node-тестів розбиті на include-file шарди, щоб кожне завдання залишалося невеликим: контракти каналів розділяють registry і core coverage на вісім зважених шардів кожен, тести команд відповіді auto-reply розділяються на чотири шарди за include-pattern, а інші великі групи префіксів відповідей auto-reply — на два шарди кожна. `check-additional` також відокремлює compile/canary-роботи package-boundary від gateway/architecture-робіт топології runtime.
-GitHub може позначати замінені новішими завдання як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Сприймайте це як шум CI, якщо лише найновіший запуск для того самого ref також не завершується з помилкою. Агреговані shard-перевірки явно вказують на цей випадок скасування, щоб його було легше відрізнити від помилки тесту.
+GitHub може позначати замінені новішими завдання як `cancelled`, коли новіший push надходить у той самий PR або ref `main`. Сприймайте це як шум CI, якщо тільки найновіший запуск для того самого ref також не завершується з помилкою. Агреговані шардові перевірки явно вказують на цей випадок скасування, щоб його було легше відрізнити від збою тесту.
## Runners
| Runner | Завдання |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `blacksmith-16vcpu-ubuntu-2404` | `preflight`, `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, Linux checks, docs checks, Python Skills, `android` |
+| `blacksmith-16vcpu-ubuntu-2404` | `preflight`, `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, Linux-перевірки, перевірки документації, Python Skills, `android` |
| `blacksmith-32vcpu-windows-2025` | `checks-windows` |
-| `blacksmith-12vcpu-macos-latest` | `macos-node`, `macos-swift` у `openclaw/openclaw`; для forks використовується fallback на `macos-latest` |
+| `blacksmith-12vcpu-macos-latest` | `macos-node`, `macos-swift` у `openclaw/openclaw`; для fork використовується запасний варіант `macos-latest` |
## Локальні еквіваленти
```bash
-pnpm changed:lanes # переглянути локальний класифікатор changed-lanes для origin/main...HEAD
-pnpm check:changed # розумний локальний шлюз: змінені typecheck/lint/tests за boundary-етапом
-pnpm check # швидкий локальний шлюз: production tsgo + розшардований lint + паралельні швидкі guards
+pnpm changed:lanes # переглянути локальний класифікатор changed-lane для origin/main...HEAD
+pnpm check:changed # розумний локальний gate: changed typecheck/lint/tests за граничним етапом
+pnpm check # швидкий локальний gate: production tsgo + шардований lint + паралельні швидкі guards
pnpm check:test-types
-pnpm check:timed # той самий шлюз із вимірюванням часу для кожного етапу
+pnpm check:timed # той самий gate з таймінгами для кожного етапу
pnpm build:strict-smoke
pnpm check:architecture
pnpm test:gateway:watch-regression
pnpm test # тести vitest
pnpm test:channels
pnpm test:contracts:channels
-pnpm check:docs # форматування docs + lint + перевірка битих посилань
-pnpm build # збірка dist, коли важливі етапи CI artifact/build-smoke
+pnpm check:docs # форматування документації + lint + биті посилання
+pnpm build # зібрати dist, коли важливі етапи CI artifact/build-smoke
```
diff --git a/docs/uk/help/testing.md b/docs/uk/help/testing.md
index ffe083120..3251de4da 100644
--- a/docs/uk/help/testing.md
+++ b/docs/uk/help/testing.md
@@ -1,146 +1,148 @@
---
read_when:
- Запуск тестів локально або в CI
- - Додавання регресійних тестів для багів моделі/провайдера
+ - Додавання регресій для помилок моделі/провайдера
- Налагодження поведінки Gateway + агента
-summary: 'Набір тестування: набори unit/e2e/live, Docker-ранери та що охоплює кожен тест'
+summary: 'Набір для тестування: модульні/e2e/live набори, Docker-раннери та що покриває кожен тест'
title: Тестування
x-i18n:
- generated_at: "2026-04-21T20:52:30Z"
+ generated_at: "2026-04-21T21:27:25Z"
model: gpt-5.4
provider: openai
- source_hash: 6f890d6aa69925e09c5847b7fa082f3076b3bc79aae3e72445c750633a2451fa
+ source_hash: 9e69c0080dc8fd07e91e89171b5b67c27f4768e99db0fcdaf98eb9830c57d80e
source_path: help/testing.md
workflow: 15
---
# Тестування
-OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір Docker-ранерів.
+OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір Docker-раннерів.
Цей документ — посібник «як ми тестуємо»:
-- Що охоплює кожен набір (і що він навмисно _не_ охоплює)
-- Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження)
+- Що покриває кожен набір (і що він навмисно _не_ покриває)
+- Які команди запускати для типових робочих процесів (локально, перед push, налагодження)
- Як live-тести знаходять облікові дані та вибирають моделі/провайдерів
-- Як додавати регресійні тести для реальних проблем моделей/провайдерів
+- Як додавати регресії для реальних проблем моделі/провайдера
## Швидкий старт
У більшості випадків:
-- Повний контрольний прогін (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test`
+- Повний gate (очікується перед push): `pnpm build && pnpm check && pnpm check:test-types && pnpm test`
- Швидший локальний запуск повного набору на потужній машині: `pnpm test:max`
- Прямий цикл спостереження Vitest: `pnpm test:watch`
- Пряме націлювання на файл тепер також маршрутизує шляхи extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
-- Під час ітерації над однією помилкою спочатку віддавайте перевагу точковим запускам.
+- Коли ітеруєте над однією помилкою, спочатку віддавайте перевагу цільовим запускам.
- QA-сайт на базі Docker: `pnpm qa:lab:up`
-- QA-набір у Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
+- QA lane на базі Linux VM: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
-Коли ви змінюєте тести або хочете більше впевненості:
+Коли ви змінюєте тести або хочете додаткової впевненості:
-- Контрольний прогін покриття: `pnpm test:coverage`
+- Gate покриття: `pnpm test:coverage`
- Набір E2E: `pnpm test:e2e`
-Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані):
+Коли налагоджуєте реальних провайдерів/моделі (потрібні справжні облікові дані):
-- Live-набір (моделі + перевірки інструментів/зображень Gateway): `pnpm test:live`
-- Точково запустити один live-файл у тихому режимі: `pnpm test:live -- src/agents/models.profiles.live.test.ts`
-- Перевірка вартості Moonshot/Kimi: якщо встановлено `MOONSHOT_API_KEY`, виконайте
- `openclaw models list --provider moonshot --json`, потім виконайте ізольований
+- Набір live (моделі + probe tool/image для Gateway): `pnpm test:live`
+- Тихо націлитися на один live-файл: `pnpm test:live -- src/agents/models.profiles.live.test.ts`
+- Smoke-тест вартості Moonshot/Kimi: коли встановлено `MOONSHOT_API_KEY`, запустіть
+ `openclaw models list --provider moonshot --json`, потім запустіть ізольований
`openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`
- для `moonshot/kimi-k2.6`. Переконайтеся, що JSON показує Moonshot/K2.6, а
- транскрипт асистента зберігає нормалізований `usage.cost`.
+ проти `moonshot/kimi-k2.6`. Переконайтеся, що JSON повідомляє про Moonshot/K2.6, а
+ транскрипт помічника зберігає нормалізований `usage.cost`.
-Порада: коли вам потрібен лише один проблемний випадок, звужуйте live-тести через змінні середовища allowlist, описані нижче.
+Порада: коли вам потрібен лише один випадок, що падає, віддавайте перевагу звуженню live-тестів через змінні середовища allowlist, описані нижче.
-## QA-ранери для окремих сценаріїв
+## Раннери, специфічні для QA
-Ці команди доповнюють основні набори тестів, коли вам потрібен реалістичний QA-lab:
+Ці команди розташовані поруч з основними тестовими наборами, коли вам потрібен реалізм qa-lab:
- `pnpm openclaw qa suite`
- - Запускає QA-сценарії з репозиторію безпосередньо на хості.
- - За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими Gateway-воркерами. Для `qa-channel` типовий рівень паралельності — 4 (обмежений кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати кількість воркерів, або `--concurrency 1` для старого послідовного режиму.
- - Завершується з ненульовим кодом, якщо будь-який сценарій падає. Використовуйте `--allow-failures`, якщо вам потрібні артефакти без аварійного коду завершення.
- - Підтримує режими провайдерів `live-frontier`, `mock-openai` і `aimock`.
- `aimock` запускає локальний сервер провайдера на базі AIMock для експериментального покриття фікстур і моків протоколу без заміни сценарно-орієнтованого режиму `mock-openai`.
+ - Запускає QA-сценарії на базі репозиторію безпосередньо на хості.
+ - За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими worker Gateway. Для `qa-channel` за замовчуванням використовується concurrency 4 (обмежується кількістю вибраних сценаріїв). Використовуйте `--concurrency `, щоб налаштувати кількість worker, або `--concurrency 1` для старішого послідовного lane.
+ - Завершується з ненульовим кодом, якщо будь-який сценарій завершується помилкою. Використовуйте `--allow-failures`, коли вам потрібні артефакти без коду завершення з помилкою.
+ - Підтримує режими провайдера `live-frontier`, `mock-openai` і `aimock`.
+ `aimock` запускає локальний сервер провайдера на базі AIMock для експериментального
+ покриття fixture і protocol-mock без заміни lane `mock-openai`, що враховує сценарії.
- `pnpm openclaw qa suite --runner multipass`
- - Запускає той самий QA-набір у тимчасовій Linux VM через Multipass.
- - Використовує ту саму поведінку вибору сценаріїв, що й `qa suite` на хості.
+ - Запускає той самий QA-набір усередині тимчасової Multipass Linux VM.
+ - Зберігає ту саму поведінку вибору сценаріїв, що й `qa suite` на хості.
- Повторно використовує ті самі прапорці вибору провайдера/моделі, що й `qa suite`.
- - У live-запусках передає підтримувані QA-входи автентифікації, які практично використовувати в гостьовій системі:
- ключі провайдерів із env, шлях до конфігурації QA live provider та `CODEX_HOME`, якщо він є.
- - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб гостьова система могла записувати назад через змонтовану робочу область.
- - Записує стандартний QA-звіт і підсумок, а також логи Multipass у
+ - Live-запуски пересилають підтримувані QA-входи автентифікації, які практичні для guest:
+ ключі провайдера на основі env, шлях конфігурації QA live provider і `CODEX_HOME`,
+ якщо він присутній.
+ - Каталоги виводу мають залишатися в межах кореня репозиторію, щоб guest міг записувати назад через змонтований workspace.
+ - Записує звичайний QA-звіт і підсумок, а також логи Multipass у
`.artifacts/qa-e2e/...`.
- `pnpm qa:lab:up`
- Запускає QA-сайт на базі Docker для QA-роботи в операторському стилі.
- `pnpm test:docker:bundled-channel-deps`
- - Пакує та встановлює поточну збірку OpenClaw у Docker, запускає Gateway
- зі сконфігурованим OpenAI, потім вмикає Telegram і Discord через редагування конфігурації.
- - Перевіряє, що перший перезапуск Gateway встановлює runtime-залежності кожного вбудованого channel Plugin на вимогу, а другий перезапуск не перевстановлює залежності, які вже були активовані.
+ - Пакує й установлює поточну збірку OpenClaw у Docker, запускає Gateway
+ з налаштованим OpenAI, потім вмикає Telegram і Discord через редагування config.
+ - Перевіряє, що перезапуск Gateway уперше встановлює runtime-залежності кожного bundled channel plugin на вимогу, а другий перезапуск не перевстановлює залежності, які вже були активовані.
- `pnpm openclaw qa aimock`
- Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування протоколу.
- `pnpm openclaw qa matrix`
- - Запускає Matrix live QA lane проти тимчасового homeserver Tuwunel на базі Docker.
- - Цей QA-хост наразі призначений лише для репозиторію/розробки. Пакетні інсталяції OpenClaw не постачають `qa-lab`, тому не надають `openclaw qa`.
- - Чекаути репозиторію завантажують вбудований ранер напряму; окремий крок встановлення Plugin не потрібен.
- - Створює трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) і одну приватну кімнату, потім запускає дочірній QA Gateway із реальним Matrix Plugin як транспортом SUT.
- - За замовчуванням використовує закріплений стабільний образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Замініть через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, якщо потрібно протестувати інший образ.
- - Matrix не надає спільних прапорців джерела облікових даних, оскільки цей lane локально створює тимчасових користувачів.
- - Записує Matrix QA-звіт, підсумок, артефакт observed-events і комбінований лог stdout/stderr у `.artifacts/qa-e2e/...`.
+ - Запускає lane live QA Matrix проти тимчасового homeserver Tuwunel на базі Docker.
+ - Цей QA host наразі призначений лише для repo/dev. Запаковані інсталяції OpenClaw не постачають `qa-lab`, тому не надають `openclaw qa`.
+ - Checkout-и репозиторію завантажують bundled runner безпосередньо; окремий крок встановлення plugin не потрібен.
+ - Підготовлює трьох тимчасових користувачів Matrix (`driver`, `sut`, `observer`) плюс одну приватну кімнату, а потім запускає дочірній QA gateway із реальним Matrix plugin як транспортом SUT.
+ - За замовчуванням використовує pinned stable-образ Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Перевизначайте через `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE`, коли потрібно протестувати інший образ.
+ - Matrix не надає спільних прапорців джерела облікових даних, оскільки lane локально створює тимчасових користувачів.
+ - Записує QA-звіт Matrix, підсумок, артефакт observed-events і комбінований лог виводу stdout/stderr у `.artifacts/qa-e2e/...`.
- `pnpm openclaw qa telegram`
- - Запускає Telegram live QA lane проти реальної приватної групи, використовуючи токени ботів driver і SUT з env.
+ - Запускає lane live QA Telegram проти реальної приватної групи, використовуючи токени ботів driver і SUT із env.
- Потребує `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` і `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. Ідентифікатор групи має бути числовим Telegram chat id.
- - Підтримує `--credential-source convex` для спільних пулінгових облікових даних. Типово використовуйте режим env, або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб перейти на pooled leases.
- - Завершується з ненульовим кодом, якщо будь-який сценарій падає. Використовуйте `--allow-failures`, якщо вам потрібні артефакти без аварійного коду завершення.
+ - Підтримує `--credential-source convex` для спільних pooled credentials. За замовчуванням використовуйте режим env або встановіть `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`, щоб увімкнути pooled lease.
+ - Завершується з ненульовим кодом, якщо будь-який сценарій завершується помилкою. Використовуйте `--allow-failures`, коли вам потрібні артефакти без коду завершення з помилкою.
- Потребує двох різних ботів в одній приватній групі, причому бот SUT має мати Telegram username.
- Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у `@BotFather` для обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі.
- - Записує Telegram QA-звіт, підсумок і артефакт observed-messages у `.artifacts/qa-e2e/...`.
+ - Записує QA-звіт Telegram, підсумок і артефакт observed-messages у `.artifacts/qa-e2e/...`.
-Live transport lanes мають спільний стандартний контракт, щоб нові транспорти не розходилися в поведінці:
+Live transport lane мають спільний стандартний контракт, щоб нові транспорти не дрейфували:
-`qa-channel` залишається широким синтетичним QA-набором і не входить до матриці покриття live transport.
+`qa-channel` залишається широким синтетичним QA-набором і не є частиною матриці покриття live transport.
-| Lane | Canary | Блокування згадок | Блок allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальша відповідь у треді | Ізоляція тредів | Спостереження за реакціями | Команда help |
-| -------- | ------ | ----------------- | -------------- | ------------------------- | ----------------------------- | -------------------------- | --------------- | -------------------------- | ------------ |
-| Matrix | x | x | x | x | x | x | x | x | |
-| Telegram | x | | | | | | | | x |
+| Lane | Canary | Gating згадок | Блок allowlist | Відповідь верхнього рівня | Відновлення після перезапуску | Подальша відповідь у thread | Ізоляція thread | Спостереження реакцій | Команда help |
+| -------- | ------ | -------------- | --------------- | ------------------------- | ----------------------------- | --------------------------- | --------------- | --------------------- | ------------ |
+| Matrix | x | x | x | x | x | x | x | x | |
+| Telegram | x | | | | | | | | x |
-### Спільні Telegram-облікові дані через Convex (v1)
+### Спільні облікові дані Telegram через Convex (v1)
Коли для `openclaw qa telegram` увімкнено `--credential-source convex` (або `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`),
-QA lab отримує ексклюзивну оренду з пулу на базі Convex, надсилає Heartbeat
-для цієї оренди, поки lane працює, і звільняє оренду під час завершення.
+QA lab отримує ексклюзивний lease із пулу на базі Convex, надсилає Heartbeat
+цього lease, поки lane працює, і звільняє lease під час завершення роботи.
-Каркас еталонного проєкту Convex:
+Еталонний scaffold проєкту Convex:
- `qa/convex-credential-broker/`
Обов’язкові змінні середовища:
-- `OPENCLAW_QA_CONVEX_SITE_URL` (наприклад, `https://your-deployment.convex.site`)
+- `OPENCLAW_QA_CONVEX_SITE_URL` (наприклад `https://your-deployment.convex.site`)
- Один секрет для вибраної ролі:
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` для `maintainer`
- `OPENCLAW_QA_CONVEX_SECRET_CI` для `ci`
- Вибір ролі облікових даних:
- CLI: `--credential-role maintainer|ci`
- - Значення env за замовчуванням: `OPENCLAW_QA_CREDENTIAL_ROLE` (типово `ci` у CI, інакше `maintainer`)
+ - Значення env за замовчуванням: `OPENCLAW_QA_CREDENTIAL_ROLE` (у CI за замовчуванням `ci`, інакше `maintainer`)
Необов’язкові змінні середовища:
-- `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (типово `1200000`)
-- `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (типово `30000`)
-- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (типово `90000`)
-- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (типово `15000`)
-- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (типово `/qa-credentials/v1`)
+- `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (за замовчуванням `1200000`)
+- `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (за замовчуванням `30000`)
+- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (за замовчуванням `90000`)
+- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (за замовчуванням `15000`)
+- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (за замовчуванням `/qa-credentials/v1`)
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (необов’язковий trace id)
-- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback URL-адреси Convex `http://` лише для локальної розробки.
+- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` дозволяє loopback `http://` URL Convex лише для локальної розробки.
У звичайному режимі `OPENCLAW_QA_CONVEX_SITE_URL` має використовувати `https://`.
-Адміністраторські команди maintainer (додавання/видалення/перелік пулу) вимагають саме
-`OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`.
+Адміністративні команди maintainer (додавання/видалення/перелік пулу) потребують
+саме `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`.
CLI-хелпери для maintainer:
@@ -150,7 +152,7 @@ pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id
```
-Використовуйте `--json` для машиночитаного виводу в скриптах і утилітах CI.
+Використовуйте `--json` для машиночитаного виводу в скриптах та утилітах CI.
Контракт endpoint за замовчуванням (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`):
@@ -170,7 +172,7 @@ pnpm openclaw qa credentials remove --credential-id
- `POST /admin/remove` (лише секрет maintainer)
- Запит: `{ credentialId, actorId }`
- Успіх: `{ status: "ok", changed, credential }`
- - Захист активної оренди: `{ status: "error", code: "LEASE_ACTIVE", ... }`
+ - Захист активного lease: `{ status: "error", code: "LEASE_ACTIVE", ... }`
- `POST /admin/list` (лише секрет maintainer)
- Запит: `{ kind?, status?, includePayload?, limit? }`
- Успіх: `{ status: "ok", credentials, count }`
@@ -183,55 +185,55 @@ pnpm openclaw qa credentials remove --credential-id
### Додавання каналу до QA
-Щоб додати канал до markdown-системи QA, потрібні рівно дві речі:
+Додавання каналу до markdown QA system потребує рівно двох речей:
-1. Транспортний адаптер для каналу.
-2. Набір сценаріїв, який перевіряє контракт каналу.
+1. Транспортного адаптера для каналу.
+2. Пакета сценаріїв, який перевіряє контракт каналу.
-Не додавайте новий кореневий QA-командний простір верхнього рівня, якщо спільний хост `qa-lab`
-може керувати цим процесом.
+Не додавайте новий корінь команди QA верхнього рівня, коли спільний host `qa-lab`
+може володіти цим процесом.
-`qa-lab` відповідає за спільну хостову механіку:
+`qa-lab` володіє спільною механікою host:
-- кореневу команду `openclaw qa`
-- запуск і зупинку наборів
-- паралельність воркерів
-- запис артефактів
-- генерацію звітів
-- виконання сценаріїв
+- коренем команди `openclaw qa`
+- запуском і завершенням набору
+- concurrency worker
+- записом артефактів
+- генерацією звітів
+- виконанням сценаріїв
- alias сумісності для старіших сценаріїв `qa-channel`
-Runner Plugins відповідають за транспортний контракт:
+Plugin раннера володіють транспортним контрактом:
- як `openclaw qa ` монтується під спільним коренем `qa`
-- як конфігурується Gateway для цього транспорту
+- як Gateway налаштовується для цього транспорту
- як перевіряється готовність
- як інжектуються вхідні події
- як спостерігаються вихідні повідомлення
-- як надаються транскрипти та нормалізований стан транспорту
-- як виконуються дії, що спираються на транспорт
-- як обробляється специфічне для транспорту скидання або очищення
+- як надаються транскрипти та нормалізований транспортний стан
+- як виконуються дії на базі транспорту
+- як обробляються скидання або очищення, специфічні для транспорту
-Мінімальний поріг впровадження нового каналу:
+Мінімальна планка впровадження для нового каналу така:
1. Залишайте `qa-lab` власником спільного кореня `qa`.
-2. Реалізуйте transport runner на спільному хостовому seam `qa-lab`.
-3. Залишайте транспортно-специфічну механіку всередині runner Plugin або channel harness.
-4. Монтуйте ранер як `openclaw qa ` замість реєстрації конкуруючої кореневої команди.
- Runner Plugins повинні оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` з `runtime-api.ts`.
- Підтримуйте `runtime-api.ts` легким; ліниве виконання CLI і раннера має залишатися за окремими entrypoint.
+2. Реалізуйте transport runner на спільному host seam `qa-lab`.
+3. Залишайте механіку, специфічну для транспорту, усередині plugin раннера або channel harness.
+4. Монтуйте раннер як `openclaw qa `, а не реєструйте конкуруючий кореневий command.
+ Plugin раннера мають оголошувати `qaRunners` у `openclaw.plugin.json` і експортувати відповідний масив `qaRunnerCliRegistrations` із `runtime-api.ts`.
+ Зберігайте `runtime-api.ts` легким; ліниве виконання CLI та раннера має залишатися за окремими entrypoint.
5. Створюйте або адаптуйте markdown-сценарії в тематичних каталогах `qa/scenarios/`.
-6. Використовуйте узагальнені хелпери сценаріїв для нових сценаріїв.
-7. Зберігайте наявні alias сумісності робочими, якщо в репозиторії не виконується навмисна міграція.
+6. Для нових сценаріїв використовуйте загальні helper сценаріїв.
+7. Зберігайте працездатність наявних alias сумісності, якщо лише репозиторій не виконує навмисну міграцію.
-Правило прийняття рішення суворе:
+Правило ухвалення рішення є суворим:
- Якщо поведінку можна один раз виразити в `qa-lab`, розміщуйте її в `qa-lab`.
-- Якщо поведінка залежить від одного channel transport, залишайте її в цьому runner Plugin або plugin harness.
-- Якщо сценарію потрібна нова можливість, яку може використовувати більше ніж один канал, додайте узагальнений хелпер замість channel-specific гілки в `suite.ts`.
-- Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій transport-specific і явно зазначайте це в контракті сценарію.
+- Якщо поведінка залежить від одного channel transport, зберігайте її в plugin раннера цього каналу або в harness plugin.
+- Якщо сценарію потрібна нова можливість, яку може використовувати більше ніж один канал, додайте загальний helper замість channel-specific branch у `suite.ts`.
+- Якщо певна поведінка має сенс лише для одного transport, залишайте сценарій transport-specific і явно вказуйте це в контракті сценарію.
-Бажані назви узагальнених хелперів для нових сценаріїв:
+Бажані назви загальних helper для нових сценаріїв:
- `waitForTransportReady`
- `waitForChannelReady`
@@ -246,7 +248,7 @@ Runner Plugins відповідають за транспортний контр
- `formatTransportTranscript`
- `resetTransport`
-Для наявних сценаріїв залишаються доступними alias сумісності, зокрема:
+Alias сумісності залишаються доступними для наявних сценаріїв, зокрема:
- `waitForQaChannelReady`
- `waitForOutboundMessage`
@@ -254,248 +256,248 @@ Runner Plugins відповідають за транспортний контр
- `formatConversationTranscript`
- `resetBus`
-Нова робота над каналами має використовувати узагальнені назви хелперів.
-Alias сумісності існують, щоб уникнути міграції одним днем, а не як зразок для
-авторингу нових сценаріїв.
+Нова робота з каналами має використовувати загальні назви helper.
+Alias сумісності існують, щоб уникнути міграції в один день, а не як модель для
+створення нових сценаріїв.
-## Набори тестів (що і де запускається)
+## Набори тестів (що де запускається)
-Сприймайте набори як «зростання реалістичності» (і зростання нестабільності/вартості):
+Думайте про набори як про «зростаючий реалізм» (і зростаючу нестабільність/вартість):
-### Unit / integration (типово)
+### Unit / integration (за замовчуванням)
- Команда: `pnpm test`
-- Конфігурація: десять послідовних shard-запусків (`vitest.full-*.config.ts`) поверх наявних scoped Vitest project
-- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelisted node-тести `ui`, охоплені `vitest.unit.config.ts`
+- Config: десять послідовних запусків shard (`vitest.full-*.config.ts`) по наявних scoped Vitest project
+- Файли: інвентарі core/unit у `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` і whitelist-тести node в `ui`, що покриваються `vitest.unit.config.ts`
- Обсяг:
- Чисті unit-тести
- - In-process integration-тести (автентифікація gateway, маршрутизація, інструменти, парсинг, конфігурація)
- - Детерміновані регресії для відомих багів
+ - In-process integration-тести (автентифікація gateway, маршрутизація, tooling, парсинг, config)
+ - Детерміновані регресії для відомих помилок
- Очікування:
- Запускається в CI
- Реальні ключі не потрібні
- Має бути швидким і стабільним
-- Примітка про projects:
- - `pnpm test` без цільового файлу тепер запускає одинадцять менших shard-конфігурацій (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського процесу native root-project. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати нерелевантні набори.
- - `pnpm test --watch` усе ще використовує граф project із native root `vitest.config.ts`, оскільки цикл watch із кількома shard непрактичний.
- - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped lanes, тому `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` уникає повної вартості запуску root project.
- - `pnpm test:changed` розгортає змінені git-шляхи в ті самі scoped lanes, коли diff торкається лише routable source/test-файлів; редагування config/setup все ще повертаються до широкого повторного запуску root-project.
- - `pnpm check:changed` — це звичайний розумний локальний контрольний прогін для вузької роботи. Він класифікує diff на core, core tests, extensions, extension tests, apps, docs і tooling, а потім запускає відповідні lanes typecheck/lint/test. Зміни в публічному Plugin SDK і plugin-contract включають перевірку extension, оскільки extensions залежать від цих core-контрактів.
- - Import-light unit-тести з agents, commands, plugins, helper auto-reply, `plugin-sdk` та подібних чистих утилітних областей маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy файли залишаються на наявних lanes.
- - Окремі helper source-файли `plugin-sdk` і `commands` також зіставляють запуски в changed-режимі з явними sibling-тестами в цих легких lanes, тому редагування helper уникають повторного запуску повного важкого набору для цього каталогу.
- - `auto-reply` тепер має три окремі bucket: top-level core helper, top-level integration-тести `reply.*` і піддерево `src/auto-reply/reply/**`. Це прибирає найважчу роботу harness reply з дешевих тестів status/chunk/token.
-- Примітка про embedded runner:
- - Коли ви змінюєте входи виявлення message-tool або runtime-контекст compaction,
+- Примітка щодо project:
+ - Ненацілений `pnpm test` тепер запускає одинадцять менших shard config (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського native root-project process. Це зменшує піковий RSS на завантажених машинах і не дозволяє роботі auto-reply/extension витісняти не пов’язані набори.
+ - `pnpm test --watch` усе ще використовує native root-граф project `vitest.config.ts`, оскільки цикл watch із багатьма shard непрактичний.
+ - `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped lane, тому `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` не сплачує повну ціну запуску root project.
+ - `pnpm test:changed` розгортає змінені git-шляхи в ті самі scoped lane, коли diff торкається лише routable source/test-файлів; редагування config/setup все ще повертаються до широкого повторного запуску root-project.
+ - `pnpm check:changed` — це звичайний розумний локальний gate для вузької роботи. Він класифікує diff на core, тести core, extensions, тести extension, apps, docs, метадані релізу та tooling, а потім запускає відповідні lane typecheck/lint/test. Зміни public Plugin SDK і plugin-contract включають валідацію extension, оскільки extensions залежать від цих контрактів core. Зміни версій лише в метаданих релізу запускають цільові перевірки version/config/root-dependency замість повного набору, із guard, який відхиляє зміни package поза полем версії верхнього рівня.
+ - Unit-тести з легкими імпортами з agents, commands, plugins, helper auto-reply, `plugin-sdk` та подібних чистих утилітних областей маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; stateful/runtime-heavy файли залишаються в наявних lane.
+ - Вибрані helper source-файли `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними sibling-тестами в цих легких lane, тому редагування helper не призводять до повторного запуску повного важкого набору для цього каталогу.
+ - `auto-reply` тепер має три спеціальні bucket: helper верхнього рівня core, integration-тести верхнього рівня `reply.*` і піддерево `src/auto-reply/reply/**`. Це не дозволяє найважчій роботі harness reply потрапляти до дешевих тестів status/chunk/token.
+- Примітка щодо embedded runner:
+ - Коли ви змінюєте входи виявлення message-tool або runtime-контекст Compaction,
зберігайте обидва рівні покриття.
- - Додавайте точкові helper-регресії для чистих меж routing/normalization.
- - Також підтримуйте в доброму стані integration-набори embedded runner:
+ - Додавайте цільові helper-регресії для чистих меж routing/normalization.
+ - Також підтримуйте здоровими integration-набори embedded runner:
`src/agents/pi-embedded-runner/compact.hooks.test.ts`,
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` і
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`.
- - Ці набори перевіряють, що scoped id і поведінка compaction усе ще проходять
- через реальні шляхи `run.ts` / `compact.ts`; лише helper-тести не є
- достатньою заміною для цих integration-шляхів.
-- Примітка про pool:
- - Базова конфігурація Vitest тепер типово використовує `threads`.
- - Спільна конфігурація Vitest також фіксує `isolate: false` і використовує non-isolated runner для root projects, e2e і live configs.
- - Кореневий lane UI зберігає свій `jsdom` setup та optimizer, але тепер також працює на спільному non-isolated runner.
- - Кожен shard `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false` зі спільної конфігурації Vitest.
- - Спільний launcher `scripts/run-vitest.mjs` тепер також типово додає `--no-maglev` для дочірніх Node-процесів Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Встановіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, якщо потрібно порівняти зі стандартною поведінкою V8.
-- Примітка про швидку локальну ітерацію:
- - `pnpm changed:lanes` показує, які архітектурні lanes запускає diff.
- - Pre-commit hook запускає `pnpm check:changed --staged` після staged formatting/linting, тому core-only commits не платять ціну extension-тестів, якщо не торкаються публічних контрактів для extensions.
- - `pnpm test:changed` маршрутизує через scoped lanes, коли змінені шляхи чисто зіставляються з меншим набором.
- - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, лише з вищим лімітом воркерів.
- - Автоматичне масштабування локальних воркерів тепер навмисно консервативне й також знижує навантаження, коли host load average вже високе, тому кілька одночасних запусків Vitest типово завдають менше шкоди.
- - Базова конфігурація Vitest позначає files projects/config як `forceRerunTriggers`, щоб rerun у changed-режимі залишалися коректними, коли змінюється test wiring.
- - Конфігурація зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете одну явну локацію кешу для прямого профілювання.
-- Примітка про perf-debug:
- - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість import плюс вивід деталізації import.
- - `pnpm test:perf:imports:changed` обмежує той самий вигляд профілювання файлами, зміненими від `origin/main`.
-- `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований `test:changed` із native шляхом root-project для цього committed diff і виводить wall time плюс macOS max RSS.
-- `pnpm test:perf:changed:bench -- --worktree` виконує benchmark поточного брудного дерева, маршрутизуючи список змінених файлів через `scripts/test-projects.mjs` і root-конфігурацію Vitest.
- - `pnpm test:perf:profile:main` записує main-thread CPU profile для накладних витрат запуску і transform у Vitest/Vite.
- - `pnpm test:perf:profile:runner` записує профілі CPU+heap runner для unit-набору з вимкненим file parallelism.
+ - Ці набори перевіряють, що scoped id і поведінка Compaction усе ще проходять
+ через реальні шляхи `run.ts` / `compact.ts`; тести лише helper не є
+ достатньою заміною цим integration-шляхам.
+- Примітка щодо pool:
+ - Базовий config Vitest тепер за замовчуванням використовує `threads`.
+ - Спільний config Vitest також фіксує `isolate: false` і використовує non-isolated runner у root project, e2e і live config.
+ - Root lane UI зберігає свої налаштування `jsdom` і optimizer, але тепер теж працює на спільному non-isolated runner.
+ - Кожен shard `pnpm test` успадковує ті самі значення за замовчуванням `threads` + `isolate: false` зі спільного config Vitest.
+ - Спільний launcher `scripts/run-vitest.mjs` тепер також за замовчуванням додає `--no-maglev` для дочірніх Node-process Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Установіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, якщо потрібно порівняти зі стандартною поведінкою V8.
+- Примітка щодо швидких локальних ітерацій:
+ - `pnpm changed:lanes` показує, які архітектурні lane запускає diff.
+ - Хук pre-commit запускає `pnpm check:changed --staged` після staged formatting/linting, тому commit-и лише core не оплачують вартість тестів extension, якщо не торкаються публічних контрактів для extension. Commit-и лише з метаданими релізу залишаються на цільовому lane version/config/root-dependency.
+ - `pnpm test:changed` маршрутизує через scoped lane, коли змінені шляхи чисто зіставляються з меншим набором.
+ - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, лише з вищим лімітом worker.
+ - Автомасштабування локальних worker тепер навмисно консервативне та також зменшує навантаження, коли середнє навантаження хоста вже високе, тому кілька одночасних запусків Vitest за замовчуванням завдають менше шкоди.
+ - Базовий config Vitest позначає файли project/config як `forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними, коли змінюється wiring тестів.
+ - Config зберігає ввімкненим `OPENCLAW_VITEST_FS_MODULE_CACHE` на підтримуваних хостах; установіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете одну явну локацію кешу для прямого профілювання.
+- Примітка щодо налагодження продуктивності:
+ - `pnpm test:perf:imports` вмикає звітування Vitest про тривалість імпортів плюс вивід розбивки імпортів.
+ - `pnpm test:perf:imports:changed` обмежує той самий профілювальний вигляд файлами, зміненими від `origin/main`.
+- `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований `test:changed` із native root-project path для цього зафіксованого diff і виводить wall time плюс macOS max RSS.
+- `pnpm test:perf:changed:bench -- --worktree` вимірює поточне dirty tree, маршрутизуючи список змінених файлів через `scripts/test-projects.mjs` і root Vitest config.
+ - `pnpm test:perf:profile:main` записує CPU-profile основного потоку для накладних витрат запуску та transform Vitest/Vite.
+ - `pnpm test:perf:profile:runner` записує CPU+heap profile раннера для unit-набору з вимкненим паралелізмом файлів.
-### E2E (gateway smoke)
+### E2E (smoke Gateway)
- Команда: `pnpm test:e2e`
-- Конфігурація: `vitest.e2e.config.ts`
+- Config: `vitest.e2e.config.ts`
- Файли: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts`
-- Типові параметри runtime:
+- Значення runtime за замовчуванням:
- Використовує Vitest `threads` з `isolate: false`, як і решта репозиторію.
- - Використовує адаптивну кількість воркерів (CI: до 2, локально: 1 за замовчуванням).
- - Типово запускається в тихому режимі, щоб зменшити накладні витрати на console I/O.
-- Корисні override:
- - `OPENCLAW_E2E_WORKERS=`, щоб примусово задати кількість воркерів (максимум 16).
+ - Використовує адаптивних worker (CI: до 2, локально: 1 за замовчуванням).
+ - За замовчуванням працює в silent mode, щоб зменшити накладні витрати на console I/O.
+- Корисні перевизначення:
+ - `OPENCLAW_E2E_WORKERS=`, щоб примусово задати кількість worker (обмежено 16).
- `OPENCLAW_E2E_VERBOSE=1`, щоб знову ввімкнути докладний вивід у консоль.
- Обсяг:
- - End-to-end поведінка gateway із кількома екземплярами
- - Поверхні WebSocket/HTTP, спарювання вузлів і складніша мережева взаємодія
+ - Наскрізна поведінка багатьох екземплярів Gateway
+ - Поверхні WebSocket/HTTP, pairing Node і важчий networking
- Очікування:
- Запускається в CI (коли ввімкнено в pipeline)
- Реальні ключі не потрібні
- - Більше рухомих частин, ніж у unit-тестах (може бути повільніше)
+ - Більше рухомих частин, ніж у unit-тестах (може бути повільнішим)
-### E2E: smoke OpenShell backend
+### E2E: smoke backend OpenShell
- Команда: `pnpm test:e2e:openshell`
- Файл: `test/openshell-sandbox.e2e.test.ts`
- Обсяг:
- Запускає ізольований Gateway OpenShell на хості через Docker
- Створює sandbox із тимчасового локального Dockerfile
- - Перевіряє backend OpenShell в OpenClaw через реальні `sandbox ssh-config` + SSH exec
- - Перевіряє remote-canonical поведінку файлової системи через sandbox fs bridge
+ - Перевіряє backend OpenShell в OpenClaw через реальні `sandbox ssh-config` + виконання SSH
+ - Перевіряє remote-canonical поведінку файлової системи через міст fs sandbox
- Очікування:
- - Лише opt-in; не входить до типового запуску `pnpm test:e2e`
+ - Лише opt-in; не є частиною стандартного запуску `pnpm test:e2e`
- Потребує локального CLI `openshell` і працездатного Docker daemon
- - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, потім знищує тестові gateway і sandbox
-- Корисні override:
- - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого e2e-набору
- - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб вказати нестандартний CLI-бінарник або wrapper script
+ - Використовує ізольовані `HOME` / `XDG_CONFIG_HOME`, а потім знищує test gateway і sandbox
+- Корисні перевизначення:
+ - `OPENCLAW_E2E_OPENSHELL=1`, щоб увімкнути тест під час ручного запуску ширшого набору e2e
+ - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`, щоб указати нестандартний бінарний файл CLI або wrapper-скрипт
### Live (реальні провайдери + реальні моделі)
- Команда: `pnpm test:live`
-- Конфігурація: `vitest.live.config.ts`
+- Config: `vitest.live.config.ts`
- Файли: `src/**/*.live.test.ts`
-- Типово: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`)
+- За замовчуванням: **увімкнено** через `pnpm test:live` (встановлює `OPENCLAW_LIVE_TEST=1`)
- Обсяг:
- «Чи справді цей провайдер/модель працює _сьогодні_ з реальними обліковими даними?»
- - Виявлення змін формату провайдера, особливостей виклику інструментів, проблем автентифікації та поведінки rate limit
+ - Виявлення змін формату провайдера, особливостей виклику tool, проблем автентифікації та поведінки rate limit
- Очікування:
- - За задумом нестабільний у CI (реальні мережі, реальні політики провайдерів, квоти, збої)
- - Коштує грошей / використовує rate limits
- - Краще запускати звужені піднабори, а не «все»
-- Live-запуски підвантажують `~/.profile`, щоб отримати відсутні API-ключі.
-- За замовчуванням live-запуски все одно ізолюють `HOME` і копіюють матеріали config/auth у тимчасовий test home, щоб unit-фікстури не могли змінити ваш реальний `~/.openclaw`.
-- Встановлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли вам свідомо потрібно, щоб live-тести використовували ваш реальний домашній каталог.
-- `pnpm test:live` тепер типово використовує тихіший режим: він зберігає вивід прогресу `[live] ...`, але приглушує додаткове повідомлення `~/.profile` і вимикає логи bootstrap Gateway/шум Bonjour. Встановіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете повернути повні стартові логи.
-- Ротація API-ключів (залежно від провайдера): встановіть `*_API_KEYS` у форматі з комами/крапками з комою або `*_API_KEY_1`, `*_API_KEY_2` (наприклад, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) або override для конкретного live-запуску через `OPENCLAW_LIVE_*_KEY`; тести повторюються у відповідь на rate limit.
-- Вивід progress/Heartbeat:
- - Live-набори тепер виводять рядки прогресу в stderr, щоб довгі виклики провайдера було видно як активні, навіть коли перехоплення консолі Vitest тихе.
- - `vitest.live.config.ts` вимикає перехоплення консолі у Vitest, тому рядки progress провайдера/gateway одразу транслюються під час live-запусків.
+ - Навмисно нестабільний для CI (реальні мережі, реальні політики провайдерів, квоти, збої)
+ - Коштує грошей / використовує rate limit
+ - Краще запускати звужені підмножини, а не «все»
+- Live-запуски використовують `~/.profile`, щоб підхопити відсутні API-ключі.
+- За замовчуванням live-запуски все ще ізолюють `HOME` і копіюють material config/auth у тимчасовий test home, щоб unit-fixture не могли змінити ваш реальний `~/.openclaw`.
+- Установлюйте `OPENCLAW_LIVE_USE_REAL_HOME=1` лише тоді, коли свідомо хочете, щоб live-тести використовували ваш реальний домашній каталог.
+- `pnpm test:live` тепер за замовчуванням працює в тихішому режимі: він зберігає вивід прогресу `[live] ...`, але приховує додаткове повідомлення `~/.profile` і приглушує логи bootstrap Gateway/шум Bonjour. Установіть `OPENCLAW_LIVE_TEST_QUIET=0`, якщо хочете знову отримати повні логи запуску.
+- Ротація API-ключів (специфічно для провайдера): установіть `*_API_KEYS` у форматі з комами/крапками з комою або `*_API_KEY_1`, `*_API_KEY_2` (наприклад, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) або використовуйте перевизначення для конкретного live-запуску через `OPENCLAW_LIVE_*_KEY`; тести повторюють спроби у відповідь на rate limit.
+- Вивід прогресу/Heartbeat:
+ - Live-набори тепер виводять рядки прогресу до stderr, щоб довгі виклики провайдера було видно як активні навіть тоді, коли захоплення консолі Vitest працює тихо.
+ - `vitest.live.config.ts` вимикає перехоплення консолі Vitest, тому рядки прогресу провайдера/Gateway одразу транслюються під час live-запусків.
- Налаштовуйте Heartbeat для direct-model через `OPENCLAW_LIVE_HEARTBEAT_MS`.
- - Налаштовуйте Heartbeat gateway/probe через `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`.
+ - Налаштовуйте Heartbeat для gateway/probe через `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`.
## Який набір мені запускати?
Використовуйте цю таблицю рішень:
- Редагуєте логіку/тести: запускайте `pnpm test` (і `pnpm test:coverage`, якщо змінили багато)
-- Торкаєтесь мережевої взаємодії gateway / протоколу WS / спарювання: додайте `pnpm test:e2e`
-- Налагоджуєте «мій бот не працює» / збої конкретного провайдера / виклик інструментів: запускайте звужений `pnpm test:live`
+- Торкаєтеся мережевої взаємодії Gateway / протоколу WS / pairing: додайте `pnpm test:e2e`
+- Налагоджуєте «мій бот не працює» / збої, специфічні для провайдера / виклик tool: запускайте звужений `pnpm test:live`
-## Live: перевірка можливостей Android Node
+## Live: огляд можливостей Android Node
- Тест: `src/gateway/android-node.capabilities.live.test.ts`
- Скрипт: `pnpm android:test:integration`
-- Мета: викликати **кожну команду, яку наразі оголошує** підключений Android Node, і перевірити поведінку контракту команд.
+- Мета: викликати **кожну команду, яку наразі рекламує** підключений Android Node, і перевірити поведінку контракту команд.
- Обсяг:
- - Попередньо підготовлене/ручне налаштування (набір не встановлює, не запускає і не спаровує застосунок).
- - Перевірка `node.invoke` у Gateway команда за командою для вибраного Android Node.
+ - Попередньо підготовлене/ручне налаштування (набір не встановлює/не запускає/не pair-ить app).
+ - Перевірка gateway `node.invoke` для вибраного Android Node, команда за командою.
- Обов’язкове попереднє налаштування:
- - Android-застосунок уже підключений і спарений із Gateway.
- - Застосунок утримується на передньому плані.
- - Дозволи/згода на захоплення надані для можливостей, які ви очікуєте успішно пройти.
-- Необов’язкові override цілі:
+ - Android app уже підключено й pair-ено з Gateway.
+ - App має залишатися на передньому плані.
+ - Для можливостей, які ви очікуєте як успішні, мають бути надані дозволи/згода на захоплення.
+- Необов’язкові перевизначення цілі:
- `OPENCLAW_ANDROID_NODE_ID` або `OPENCLAW_ANDROID_NODE_NAME`.
- `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`.
-- Повні деталі налаштування Android: [Android App](/uk/platforms/android)
+- Повні відомості про налаштування Android: [Android App](/uk/platforms/android)
-## Live: smoke моделей (ключі профілів)
+## Live: smoke-тест моделі (ключі profile)
Live-тести поділено на два шари, щоб можна було ізолювати збої:
-- «Direct model» показує, чи взагалі провайдер/модель може відповідати з наданим ключем.
-- «Gateway smoke» показує, що повний конвеєр gateway+agent працює для цієї моделі (сесії, історія, інструменти, політика sandbox тощо).
+- «Direct model» показує, чи провайдер/модель взагалі може відповісти з наданим ключем.
+- «Gateway smoke» показує, чи повний pipeline gateway+agent працює для цієї моделі (сесії, історія, tools, політика sandbox тощо).
-### Шар 1: Пряме завершення моделі (без gateway)
+### Шар 1: Direct model completion (без Gateway)
- Тест: `src/agents/models.profiles.live.test.ts`
- Мета:
- - Перелічити виявлені моделі
- - Використати `getApiKeyForModel` для вибору моделей, для яких у вас є облікові дані
+ - Перерахувати виявлені моделі
+ - Використати `getApiKeyForModel`, щоб вибрати моделі, для яких у вас є облікові дані
- Виконати невелике completion для кожної моделі (і цільові регресії там, де потрібно)
- Як увімкнути:
- `pnpm test:live` (або `OPENCLAW_LIVE_TEST=1`, якщо викликаєте Vitest напряму)
-- Встановіть `OPENCLAW_LIVE_MODELS=modern` (або `all`, alias для modern), щоб справді запустити цей набір; інакше його буде пропущено, щоб `pnpm test:live` залишався зосередженим на gateway smoke
+- Установіть `OPENCLAW_LIVE_MODELS=modern` (або `all`, alias для modern), щоб справді запустити цей набір; інакше його буде пропущено, щоб `pnpm test:live` залишався зосередженим на gateway smoke
- Як вибирати моделі:
- - `OPENCLAW_LIVE_MODELS=modern`, щоб запустити сучасний allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
- - `OPENCLAW_LIVE_MODELS=all` — це alias для сучасного allowlist
+ - `OPENCLAW_LIVE_MODELS=modern`, щоб запустити modern allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
+ - `OPENCLAW_LIVE_MODELS=all` — це alias для modern allowlist
- або `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."` (allowlist через кому)
- - Прогони modern/all типово мають підібрану межу з високим сигналом; встановіть `OPENCLAW_LIVE_MAX_MODELS=0` для вичерпного modern-прогону або додатне число для меншої межі.
+ - Режими modern/all sweep за замовчуванням мають підібрану межу з високим сигналом; установіть `OPENCLAW_LIVE_MAX_MODELS=0` для вичерпного modern sweep або додатне число для меншої межі.
- Як вибирати провайдерів:
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"` (allowlist через кому)
- Звідки беруться ключі:
- - Типово: зі сховища профілів і резервних env-джерел
- - Встановіть `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб вимагати **лише сховище профілів**
+ - За замовчуванням: сховище profile і резервні значення з env
+ - Установіть `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати **лише сховище profile**
- Навіщо це існує:
- - Відокремлює «API провайдера зламане / ключ недійсний» від «конвеєр gateway agent зламаний»
- - Містить невеликі ізольовані регресії (приклад: replay reasoning у OpenAI Responses/Codex Responses + потоки tool-call)
+ - Відокремлює «API провайдера зламане / ключ недійсний» від «pipeline gateway agent зламаний»
+ - Містить невеликі ізольовані регресії (приклад: OpenAI Responses/Codex Responses reasoning replay + потоки tool-call)
### Шар 2: Gateway + smoke dev agent (що насправді робить "@openclaw")
- Тест: `src/gateway/gateway-models.profiles.live.test.ts`
- Мета:
- - Підняти in-process Gateway
- - Створити/оновити сесію `agent:dev:*` (override моделі для кожного запуску)
- - Ітеруватися по моделях із ключами та перевіряти:
- - «змістовну» відповідь (без інструментів)
- - що реальний виклик інструмента працює (перевірка `read`)
- - необов’язкові додаткові перевірки інструментів (перевірка `exec+read`)
- - що шляхи регресій OpenAI (лише tool-call → наступний крок) і далі працюють
-- Деталі перевірок probe (щоб можна було швидко пояснювати збої):
- - probe `read`: тест записує файл із nonce у workspace і просить агента `read` його та повернути nonce.
- - probe `exec+read`: тест просить агента через `exec` записати nonce у тимчасовий файл, а потім прочитати його назад через `read`.
- - image probe: тест додає згенерований PNG (cat + рандомізований код) і очікує, що модель поверне `cat `.
+ - Запустити in-process Gateway
+ - Створити/пропатчити сесію `agent:dev:*` (перевизначення моделі для кожного запуску)
+ - Ітерувати моделі-з-ключами й перевіряти:
+ - «змістовну» відповідь (без tools)
+ - що реальний виклик tool працює (probe `read`)
+ - необов’язкові додаткові probe tool (probe `exec+read`)
+ - що шляхи регресії OpenAI (лише tool-call → подальша відповідь) продовжують працювати
+- Деталі probe (щоб ви могли швидко пояснювати збої):
+ - probe `read`: тест записує файл із nonce у workspace і просить agent виконати `read` цього файла та повернути nonce назад.
+ - probe `exec+read`: тест просить agent через `exec` записати nonce у тимчасовий файл, а потім через `read` прочитати його назад.
+ - probe image: тест прикріплює згенерований PNG (cat + рандомізований код) і очікує, що модель поверне `cat `.
- Посилання на реалізацію: `src/gateway/gateway-models.profiles.live.test.ts` і `src/gateway/live-image-probe.ts`.
- Як увімкнути:
- `pnpm test:live` (або `OPENCLAW_LIVE_TEST=1`, якщо викликаєте Vitest напряму)
- Як вибирати моделі:
- - Типово: сучасний allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
- - `OPENCLAW_LIVE_GATEWAY_MODELS=all` — це alias для сучасного allowlist
+ - За замовчуванням: modern allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
+ - `OPENCLAW_LIVE_GATEWAY_MODELS=all` — це alias для modern allowlist
- Або встановіть `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (або список через кому), щоб звузити вибір
- - Прогони modern/all для gateway типово мають підібрану межу з високим сигналом; встановіть `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` для вичерпного modern-прогону або додатне число для меншої межі.
-- Як вибирати провайдерів (уникнути «все з OpenRouter»):
+ - Режими modern/all для gateway sweep за замовчуванням мають підібрану межу з високим сигналом; установіть `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` для вичерпного modern sweep або додатне число для меншої межі.
+- Як вибирати провайдерів (уникайте «усе через OpenRouter»):
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (allowlist через кому)
-- Перевірки tool + image завжди увімкнені в цьому live-тесті:
- - probe `read` + probe `exec+read` (навантаження на інструменти)
- - image probe запускається, коли модель оголошує підтримку image input
- - Потік (на високому рівні):
- - Тест генерує крихітний PNG із «CAT» + випадковим кодом (`src/gateway/live-image-probe.ts`)
+- Probe tool + image у цьому live-тесті завжди ввімкнені:
+ - probe `read` + probe `exec+read` (навантаження на tool)
+ - probe image запускається, коли модель рекламує підтримку image input
+ - Потік (високорівнево):
+ - Тест генерує крихітний PNG з «CAT» + випадковим кодом (`src/gateway/live-image-probe.ts`)
- Надсилає його через `agent` `attachments: [{ mimeType: "image/png", content: "" }]`
- Gateway парсить attachments у `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`)
- - Embedded agent пересилає мультимодальне повідомлення користувача моделі
- - Перевірка: відповідь містить `cat` + код (OCR tolerance: незначні помилки дозволені)
+ - Embedded agent пересилає multimodal user message моделі
+ - Перевірка: відповідь містить `cat` + код (допуск OCR: незначні помилки дозволені)
-Порада: щоб побачити, що можна протестувати на вашій машині (і точні ідентифікатори `provider/model`), виконайте:
+Порада: щоб побачити, що саме можна тестувати на вашій машині (і точні ідентифікатори `provider/model`), запустіть:
```bash
openclaw models list
openclaw models list --json
```
-## Live: smoke CLI backend (Claude, Codex, Gemini або інші локальні CLI)
+## Live: smoke-тест backend CLI (Claude, Codex, Gemini або інші локальні CLI)
- Тест: `src/gateway/gateway-cli-backend.live.test.ts`
-- Мета: перевірити конвеєр Gateway + agent за допомогою локального CLI backend, не торкаючись вашої типової конфігурації.
-- Типові значення smoke для конкретного backend живуть у визначенні `cli-backend.ts` extension-власника.
+- Мета: перевірити pipeline Gateway + agent, використовуючи локальний backend CLI, не торкаючись вашого config за замовчуванням.
+- Значення smoke за замовчуванням, специфічні для backend, містяться у визначенні `cli-backend.ts` extension-власника.
- Увімкнення:
- `pnpm test:live` (або `OPENCLAW_LIVE_TEST=1`, якщо викликаєте Vitest напряму)
- `OPENCLAW_LIVE_CLI_BACKEND=1`
-- Типові значення:
- - Типовий provider/model: `claude-cli/claude-sonnet-4-6`
- - Поведінка command/args/image береться з метаданих Plugin CLI backend-власника.
-- Override (необов’язково):
+- Значення за замовчуванням:
+ - Провайдер/модель за замовчуванням: `claude-cli/claude-sonnet-4-6`
+ - Поведінка command/args/image походить із метаданих plugin CLI backend-власника.
+- Перевизначення (необов’язково):
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"`
- `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"`
- `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'`
- - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1`, щоб надіслати реальне image-вкладення (шляхи інжектуються в prompt).
- - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"`, щоб передавати шляхи файлів зображень як CLI args замість інжекції в prompt.
- - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (або `"list"`), щоб керувати способом передавання image args, коли встановлено `IMAGE_ARG`.
+ - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1`, щоб надіслати реальне image attachment (шляхи інжектуються в prompt).
+ - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"`, щоб передавати шляхи до файлів image як аргументи CLI замість інжекції в prompt.
+ - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (або `"list"`), щоб керувати тим, як передаються аргументи image, коли встановлено `IMAGE_ARG`.
- `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1`, щоб надіслати другий хід і перевірити потік resume.
- - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0`, щоб вимкнути типову перевірку безперервності тієї самої сесії Claude Sonnet -> Opus (встановіть `1`, щоб примусово ввімкнути її, коли вибрана модель підтримує ціль перемикання).
+ - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0`, щоб вимкнути стандартний probe безперервності тієї самої сесії Claude Sonnet -> Opus (установіть `1`, щоб примусово ввімкнути його, коли вибрана модель підтримує ціль перемикання).
Приклад:
@@ -505,13 +507,13 @@ OPENCLAW_LIVE_CLI_BACKEND=1 \
pnpm test:live src/gateway/gateway-cli-backend.live.test.ts
```
-Docker-рецепт:
+Рецепт Docker:
```bash
pnpm test:docker:live-cli-backend
```
-Docker-рецепти для одного провайдера:
+Рецепти Docker для одного провайдера:
```bash
pnpm test:docker:live-cli-backend:claude
@@ -522,38 +524,38 @@ pnpm test:docker:live-cli-backend:gemini
Примітки:
-- Docker-ранер розташовано в `scripts/test-live-cli-backend-docker.sh`.
-- Він запускає live smoke CLI-backend усередині Docker-образу репозиторію від імені непривілейованого користувача `node`.
-- Він визначає метадані CLI smoke із extension-власника, а потім встановлює відповідний Linux CLI-пакет (`@anthropic-ai/claude-code`, `@openai/codex` або `@google/gemini-cli`) у кешований записуваний префікс `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (типово: `~/.cache/openclaw/docker-cli-tools`).
-- `pnpm test:docker:live-cli-backend:claude-subscription` потребує portable Claude Code subscription OAuth через `~/.claude/.credentials.json` з `claudeAiOauth.subscriptionType` або `CLAUDE_CODE_OAUTH_TOKEN` із `claude setup-token`. Спочатку він доводить прямий `claude -p` у Docker, потім запускає два ходи Gateway CLI-backend без збереження env-змінних ключа Anthropic API. Цей lane підписки типово вимикає probe Claude MCP/tool та image, оскільки Claude зараз маршрутизує використання сторонніх застосунків через додаткове usage billing замість звичайних лімітів плану підписки.
-- Live smoke CLI-backend тепер перевіряє той самий наскрізний потік для Claude, Codex і Gemini: текстовий хід, хід із класифікацією зображення, потім виклик інструмента MCP `cron`, перевірений через Gateway CLI.
-- Типовий smoke для Claude також оновлює сесію із Sonnet до Opus і перевіряє, що відновлена сесія все ще пам’ятає попередню нотатку.
+- Docker-раннер розташований у `scripts/test-live-cli-backend-docker.sh`.
+- Він запускає live smoke CLI-backend усередині Docker-образу репозиторію від імені non-root користувача `node`.
+- Він визначає метадані smoke CLI із extension-власника, а потім установлює відповідний Linux-пакет CLI (`@anthropic-ai/claude-code`, `@openai/codex` або `@google/gemini-cli`) у кешований записуваний префікс за адресою `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (за замовчуванням: `~/.cache/openclaw/docker-cli-tools`).
+- `pnpm test:docker:live-cli-backend:claude-subscription` потребує portable OAuth підписки Claude Code через `~/.claude/.credentials.json` з `claudeAiOauth.subscriptionType` або `CLAUDE_CODE_OAUTH_TOKEN` із `claude setup-token`. Спочатку він перевіряє прямий `claude -p` у Docker, а потім запускає два ходи Gateway CLI-backend без збереження env API-ключів Anthropic. Цей lane підписки за замовчуванням вимикає Claude MCP/tool і probe image, оскільки Claude наразі маршрутизує використання стороннього застосунку через білінг додаткового використання, а не звичайні ліміти плану підписки.
+- Live smoke CLI-backend тепер перевіряє той самий наскрізний потік для Claude, Codex і Gemini: текстовий хід, хід класифікації image, потім виклик tool MCP `cron`, перевірений через CLI Gateway.
+- Стандартний smoke для Claude також патчить сесію із Sonnet на Opus і перевіряє, що відновлена сесія все ще пам’ятає попередню нотатку.
-## Live: smoke ACP bind (`/acp spawn ... --bind here`)
+## Live: smoke-тест ACP bind (`/acp spawn ... --bind here`)
- Тест: `src/gateway/gateway-acp-bind.live.test.ts`
-- Мета: перевірити реальний потік conversation-bind ACP із live ACP agent:
+- Мета: перевірити реальний потік bind conversation ACP з live ACP agent:
- надіслати `/acp spawn --bind here`
- - прив’язати синтетичну розмову message-channel на місці
- - надіслати звичайне подальше повідомлення в тій самій розмові
- - перевірити, що подальше повідомлення потрапляє до транскрипту прив’язаної ACP session
+ - прив’язати синтетичну conversation message-channel на місці
+ - надіслати звичайну подальшу відповідь у цій самій conversation
+ - переконатися, що подальша відповідь потрапляє в transcript прив’язаної сесії ACP
- Увімкнення:
- `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts`
- `OPENCLAW_LIVE_ACP_BIND=1`
-- Типові значення:
- - ACP agents у Docker: `claude,codex,gemini`
+- Значення за замовчуванням:
+ - ACP agent у Docker: `claude,codex,gemini`
- ACP agent для прямого `pnpm test:live ...`: `claude`
- - Синтетичний канал: контекст розмови в стилі Slack DM
+ - Синтетичний channel: контекст conversation у стилі Slack DM
- ACP backend: `acpx`
-- Override:
+- Перевизначення:
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=codex`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'`
- Примітки:
- - Цей lane використовує поверхню gateway `chat.send` з admin-only synthetic originating-route fields, щоб тести могли прикріплювати контекст message-channel, не вдаючи зовнішню доставку.
- - Коли `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` не встановлено, тест використовує вбудований реєстр агентів Plugin `acpx` для вибраного ACP harness agent.
+ - Цей lane використовує поверхню gateway `chat.send` з admin-only синтетичними полями originating-route, щоб тести могли прикріплювати контекст message-channel, не імітуючи зовнішню доставку.
+ - Коли `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` не встановлено, тест використовує вбудований реєстр agent plugin `acpx` для вибраного harness agent ACP.
Приклад:
@@ -563,13 +565,13 @@ OPENCLAW_LIVE_ACP_BIND=1 \
pnpm test:live src/gateway/gateway-acp-bind.live.test.ts
```
-Docker-рецепт:
+Рецепт Docker:
```bash
pnpm test:docker:live-acp-bind
```
-Docker-рецепти для одного агента:
+Рецепти Docker для одного agent:
```bash
pnpm test:docker:live-acp-bind:claude
@@ -579,31 +581,31 @@ pnpm test:docker:live-acp-bind:gemini
Примітки щодо Docker:
-- Docker-ранер розташовано в `scripts/test-live-acp-bind-docker.sh`.
-- За замовчуванням він запускає smoke ACP bind послідовно для всіх підтримуваних live CLI agents: `claude`, `codex`, потім `gemini`.
+- Docker-раннер розташований у `scripts/test-live-acp-bind-docker.sh`.
+- За замовчуванням він запускає smoke ACP bind для всіх підтримуваних live CLI agent послідовно: `claude`, `codex`, потім `gemini`.
- Використовуйте `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` або `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini`, щоб звузити матрицю.
-- Він підвантажує `~/.profile`, переносить відповідні матеріали CLI auth у контейнер, встановлює `acpx` у записуваний npm-префікс, а потім встановлює потрібний live CLI (`@anthropic-ai/claude-code`, `@openai/codex` або `@google/gemini-cli`), якщо його бракує.
-- Усередині Docker ранер встановлює `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`, щоб acpx зберігав env-змінні провайдера з підвантаженого профілю доступними для дочірнього harness CLI.
+- Він використовує `~/.profile`, переносить відповідний auth material CLI до контейнера, установлює `acpx` у записуваний npm-префікс, а потім установлює потрібний live CLI (`@anthropic-ai/claude-code`, `@openai/codex` або `@google/gemini-cli`), якщо його немає.
+- Усередині Docker раннер установлює `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`, щоб acpx зберігав env-змінні провайдера з підключеного profile доступними для дочірнього harness CLI.
-## Live: smoke harness app-server Codex
+## Live: smoke-тест harness app-server Codex
-- Мета: перевірити Codex harness, яким володіє Plugin, через звичайний метод gateway
+- Мета: перевірити harness Codex, яким володіє plugin, через звичайний метод gateway
`agent`:
- - завантажити вбудований Plugin `codex`
+ - завантажити bundled plugin `codex`
- вибрати `OPENCLAW_AGENT_RUNTIME=codex`
- надіслати перший хід gateway agent до `codex/gpt-5.4`
- - надіслати другий хід до тієї самої сесії OpenClaw і перевірити, що потік
+ - надіслати другий хід до тієї самої сесії OpenClaw і перевірити, що thread
app-server може відновитися
- - запустити `/codex status` і `/codex models` через той самий шлях gateway
- command
+ - запустити `/codex status` і `/codex models` через той самий шлях
+ команди gateway
- Тест: `src/gateway/gateway-codex-harness.live.test.ts`
- Увімкнення: `OPENCLAW_LIVE_CODEX_HARNESS=1`
-- Типова модель: `codex/gpt-5.4`
-- Необов’язковий image probe: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
-- Необов’язковий MCP/tool probe: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
-- Smoke-тест встановлює `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, щоб зламаний Codex
- harness не міг пройти, тихо переключившись назад на PI.
-- Автентифікація: `OPENAI_API_KEY` із shell/profile, плюс необов’язково скопійовані
+- Модель за замовчуванням: `codex/gpt-5.4`
+- Необов’язковий probe image: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
+- Необов’язковий probe MCP/tool: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
+- Цей smoke встановлює `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, щоб зламаний Codex
+ harness не міг пройти перевірку через тихий fallback до Pi.
+- Auth: `OPENAI_API_KEY` з shell/profile, плюс необов’язково скопійовані
`~/.codex/auth.json` і `~/.codex/config.toml`
Локальний рецепт:
@@ -617,7 +619,7 @@ OPENCLAW_LIVE_CODEX_HARNESS=1 \
pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts
```
-Docker-рецепт:
+Рецепт Docker:
```bash
source ~/.profile
@@ -626,52 +628,52 @@ pnpm test:docker:live-codex-harness
Примітки щодо Docker:
-- Docker-ранер розташовано в `scripts/test-live-codex-harness-docker.sh`.
-- Він підвантажує змонтований `~/.profile`, передає `OPENAI_API_KEY`, копіює файли
- автентифікації Codex CLI, якщо вони є, встановлює `@openai/codex` у записуваний змонтований npm
- префікс, готує дерево вихідного коду, а потім запускає лише live-тест Codex-harness.
-- Docker типово вмикає image і MCP/tool probes. Встановіть
+- Docker-раннер розташований у `scripts/test-live-codex-harness-docker.sh`.
+- Він використовує змонтований `~/.profile`, передає `OPENAI_API_KEY`, копіює файли
+ auth Codex CLI, якщо вони є, установлює `@openai/codex` у записуваний змонтований npm
+ префікс, підготовлює дерево вихідного коду, а потім запускає лише live-тест Codex-harness.
+- Docker за замовчуванням вмикає probe image і MCP/tool. Установіть
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` або
- `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0`, коли вам потрібен вужчий налагоджувальний запуск.
+ `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0`, коли потрібен вужчий запуск для налагодження.
- Docker також експортує `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, як і live
- конфігурація тесту, тому fallback `openai-codex/*` або PI не може приховати регресію
+ config тесту, щоб fallback `openai-codex/*` або Pi не міг приховати регресію
Codex harness.
### Рекомендовані live-рецепти
-Вузькі, явні allowlist найшвидші й найменш нестабільні:
+Вузькі, явні allowlist — найшвидші та найменш нестабільні:
-- Одна модель, direct (без gateway):
+- Одна модель, direct (без Gateway):
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts`
- Одна модель, gateway smoke:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
-- Виклик інструментів для кількох провайдерів:
+- Виклик tool для кількох провайдерів:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
-- Фокус на Google (ключ API Gemini + Antigravity):
- - Gemini (ключ API): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
+- Фокус на Google (API-ключ Gemini + Antigravity):
+ - Gemini (API-ключ): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Antigravity (OAuth): `OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
Примітки:
-- `google/...` використовує Gemini API (ключ API).
-- `google-antigravity/...` використовує міст OAuth Antigravity (endpoint агента в стилі Cloud Code Assist).
-- `google-gemini-cli/...` використовує локальний Gemini CLI на вашій машині (окрема автентифікація + особливості tooling).
+- `google/...` використовує Gemini API (API-ключ).
+- `google-antigravity/...` використовує міст OAuth Antigravity (endpoint agent у стилі Cloud Code Assist).
+- `google-gemini-cli/...` використовує локальний Gemini CLI на вашій машині (окрема auth + особливості tooling).
- Gemini API проти Gemini CLI:
- - API: OpenClaw викликає розміщений Google Gemini API через HTTP (автентифікація ключем API / профілем); саме це більшість користувачів мають на увазі під «Gemini».
- - CLI: OpenClaw викликає локальний бінарник `gemini`; він має власну автентифікацію та може поводитися інакше (streaming/підтримка інструментів/розсинхрон версій).
+ - API: OpenClaw викликає хостований Gemini API від Google через HTTP (auth через API-ключ / profile); це те, що більшість користувачів мають на увазі під «Gemini».
+ - CLI: OpenClaw звертається до локального бінарного файла `gemini`; він має власну auth і може поводитися інакше (streaming/підтримка tool/розбіжність версій).
-## Live: матриця моделей (що ми охоплюємо)
+## Live: матриця моделей (що ми покриваємо)
-Фіксованого «списку моделей CI» немає (live — це opt-in), але це **рекомендовані** моделі, які варто регулярно покривати на dev-машині з ключами.
+Фіксованого «списку моделей CI» немає (live — це opt-in), але це **рекомендовані** моделі, які варто регулярно покривати на машині розробника з ключами.
-### Сучасний smoke-набір (виклик інструментів + image)
+### Modern smoke-набір (виклик tool + image)
-Це запуск «поширених моделей», який ми очікуємо підтримувати в робочому стані:
+Це запуск «поширених моделей», який ми очікуємо підтримувати працездатним:
-- OpenAI (не Codex): `openai/gpt-5.4` (необов’язково: `openai/gpt-5.4-mini`)
+- OpenAI (не-Codex): `openai/gpt-5.4` (необов’язково: `openai/gpt-5.4-mini`)
- OpenAI Codex: `openai-codex/gpt-5.4`
- Anthropic: `anthropic/claude-opus-4-6` (або `anthropic/claude-sonnet-4-6`)
- Google (Gemini API): `google/gemini-3.1-pro-preview` і `google/gemini-3-flash-preview` (уникайте старіших моделей Gemini 2.x)
@@ -679,12 +681,12 @@ pnpm test:docker:live-codex-harness
- Z.AI (GLM): `zai/glm-4.7`
- MiniMax: `minimax/MiniMax-M2.7`
-Запустіть gateway smoke з інструментами + image:
+Запуск gateway smoke з tools + image:
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
-### Базовий рівень: виклик інструментів (Read + необов’язковий Exec)
+### Базовий рівень: виклик tool (Read + необов’язковий Exec)
-Оберіть щонайменше одну модель для кожного сімейства провайдерів:
+Виберіть щонайменше одну модель для кожної родини провайдерів:
- OpenAI: `openai/gpt-5.4` (або `openai/gpt-5.4-mini`)
- Anthropic: `anthropic/claude-opus-4-6` (або `anthropic/claude-sonnet-4-6`)
@@ -692,81 +694,81 @@ pnpm test:docker:live-codex-harness
- Z.AI (GLM): `zai/glm-4.7`
- MiniMax: `minimax/MiniMax-M2.7`
-Необов’язкове додаткове покриття (бажано мати):
+Необов’язкове додаткове покриття (було б добре мати):
- xAI: `xai/grok-4` (або найновіша доступна)
-- Mistral: `mistral/`… (оберіть одну модель із підтримкою інструментів, яку у вас увімкнено)
+- Mistral: `mistral/`… (виберіть одну модель із підтримкою `tools`, яку у вас ввімкнено)
- Cerebras: `cerebras/`… (якщо у вас є доступ)
-- LM Studio: `lmstudio/`… (локально; виклик інструментів залежить від режиму API)
+- LM Studio: `lmstudio/`… (локально; виклик tool залежить від режиму API)
-### Vision: надсилання image (вкладення → мультимодальне повідомлення)
+### Vision: надсилання image (attachment → multimodal message)
-Додайте щонайменше одну модель із підтримкою image у `OPENCLAW_LIVE_GATEWAY_MODELS` (варіанти Claude/Gemini/OpenAI із підтримкою vision тощо), щоб перевірити image probe.
+Додайте принаймні одну модель із підтримкою image до `OPENCLAW_LIVE_GATEWAY_MODELS` (Claude/Gemini/OpenAI vision-capable варіанти тощо), щоб перевірити probe image.
-### Агрегатори / альтернативні gateway
+### Aggregator-и / альтернативні Gateway
Якщо у вас увімкнені ключі, ми також підтримуємо тестування через:
-- OpenRouter: `openrouter/...` (сотні моделей; використовуйте `openclaw models scan`, щоб знайти кандидатів із підтримкою інструментів та image)
-- OpenCode: `opencode/...` для Zen і `opencode-go/...` для Go (автентифікація через `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`)
+- OpenRouter: `openrouter/...` (сотні моделей; використовуйте `openclaw models scan`, щоб знайти кандидатів із підтримкою tool+image)
+- OpenCode: `opencode/...` для Zen і `opencode-go/...` для Go (auth через `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`)
-Інші провайдери, які можна включити до live-матриці (якщо у вас є облікові дані/конфігурація):
+Більше провайдерів, які можна включити до live-матриці (якщо у вас є облікові дані/config):
- Вбудовані: `openai`, `openai-codex`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot`
-- Через `models.providers` (кастомні endpoint): `minimax` (cloud/API), а також будь-який сумісний із OpenAI/Anthropic proxy (LM Studio, vLLM, LiteLLM тощо)
+- Через `models.providers` (custom endpoint): `minimax` (cloud/API), а також будь-який сумісний із OpenAI/Anthropic proxy (LM Studio, vLLM, LiteLLM тощо)
-Порада: не намагайтеся жорстко прописати в документації «усі моделі». Авторитетний список — це те, що повертає `discoverModels(...)` на вашій машині, плюс ті ключі, які доступні.
+Порада: не намагайтеся жорстко прописати в документації «усі моделі». Авторитетний список — це те, що повертає `discoverModels(...)` на вашій машині + які ключі доступні.
## Облікові дані (ніколи не комітьте)
Live-тести знаходять облікові дані так само, як і CLI. Практичні наслідки:
-- Якщо CLI працює, live-тести мають знаходити ті самі ключі.
-- Якщо live-тест каже «немає облікових даних», налагоджуйте це так само, як налагоджували б `openclaw models list` / вибір моделі.
+- Якщо CLI працює, live-тести повинні знаходити ті самі ключі.
+- Якщо live-тест повідомляє «немає облікових даних», налагоджуйте це так само, як налагоджували б `openclaw models list` / вибір моделі.
-- Профілі автентифікації для кожного агента: `~/.openclaw/agents//agent/auth-profiles.json` (саме це означає «ключі профілів» у live-тестах)
-- Конфігурація: `~/.openclaw/openclaw.json` (або `OPENCLAW_CONFIG_PATH`)
-- Застарілий каталог стану: `~/.openclaw/credentials/` (копіюється до staged live home, якщо існує, але це не основне сховище ключів профілів)
-- Локальні live-запуски типово копіюють активну конфігурацію, файли `auth-profiles.json` для кожного агента, застарілий каталог `credentials/` і підтримувані зовнішні каталоги CLI auth у тимчасовий test home; staged live home пропускають `workspace/` і `sandboxes/`, а override шляхів `agents.*.workspace` / `agentDir` видаляються, щоб probes не працювали у вашому реальному host workspace.
+- Auth profile для кожного agent: `~/.openclaw/agents//agent/auth-profiles.json` (це і є те, що в live-тестах означає «ключі profile»)
+- Config: `~/.openclaw/openclaw.json` (або `OPENCLAW_CONFIG_PATH`)
+- Каталог legacy state: `~/.openclaw/credentials/` (копіюється до staged live home, якщо існує, але це не основне сховище ключів profile)
+- Локальні live-запуски за замовчуванням копіюють активний config, файли `auth-profiles.json` для кожного agent, legacy `credentials/` і підтримувані зовнішні каталоги auth CLI до тимчасового test home; staged live home пропускають `workspace/` і `sandboxes/`, а перевизначення шляху `agents.*.workspace` / `agentDir` видаляються, щоб probe не торкалися вашого реального workspace хоста.
-Якщо ви хочете покладатися на env-ключі (наприклад, експортовані у вашому `~/.profile`), запускайте локальні тести після `source ~/.profile`, або використовуйте Docker-ранери нижче (вони можуть монтувати `~/.profile` у контейнер).
+Якщо ви хочете покладатися на ключі з env (наприклад, експортовані у вашому `~/.profile`), запускайте локальні тести після `source ~/.profile` або використовуйте Docker-раннери нижче (вони можуть монтувати `~/.profile` у контейнер).
-## Live: Deepgram (транскрипція аудіо)
+## Live Deepgram (транскрипція аудіо)
- Тест: `src/media-understanding/providers/deepgram/audio.live.test.ts`
- Увімкнення: `DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts`
-## Live: планування кодування BytePlus
+## Live BytePlus coding plan
- Тест: `src/agents/byteplus.live.test.ts`
- Увімкнення: `BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts`
-- Необов’язковий override моделі: `BYTEPLUS_CODING_MODEL=ark-code-latest`
+- Необов’язкове перевизначення моделі: `BYTEPLUS_CODING_MODEL=ark-code-latest`
-## Live: медіа workflow ComfyUI
+## Live ComfyUI workflow media
- Тест: `extensions/comfy/comfy.live.test.ts`
- Увімкнення: `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts`
- Обсяг:
- - Перевіряє вбудовані шляхи comfy для зображень, відео та `music_generate`
- - Пропускає кожну можливість, якщо `models.providers.comfy.` не налаштовано
- - Корисно після змін у надсиланні workflow comfy, polling, завантаженнях або реєстрації Plugin
+ - Перевіряє bundled-шляхи comfy для image, video і `music_generate`
+ - Пропускає кожну можливість, якщо не налаштовано `models.providers.comfy.`
+ - Корисно після змін у поданні workflow comfy, polling, завантаженнях або реєстрації plugin
-## Live: генерація зображень
+## Live: генерація image
- Тест: `src/image-generation/runtime.live.test.ts`
- Команда: `pnpm test:live src/image-generation/runtime.live.test.ts`
- Harness: `pnpm test:live:media image`
- Обсяг:
- - Перелічує кожен зареєстрований Plugin провайдера генерації зображень
- - Завантажує відсутні env-змінні провайдера з вашого login shell (`~/.profile`) перед виконанням probe
- - Типово використовує live/env API-ключі раніше за збережені профілі auth, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
+ - Перераховує кожен зареєстрований plugin провайдера генерації image
+ - Завантажує відсутні env-змінні провайдера з вашого login shell (`~/.profile`) перед probe
+ - За замовчуванням віддає перевагу live/env API-ключам над збереженими auth profile, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
- Пропускає провайдерів без придатної auth/profile/model
- - Запускає стандартні варіанти генерації зображень через спільну runtime-можливість:
+ - Запускає стандартні варіанти генерації image через спільну runtime-можливість:
- `google:flash-generate`
- `google:pro-generate`
- `google:pro-edit`
- `openai:default-generate`
-- Поточні вбудовані провайдери, які покриваються:
+- Поточні bundled-провайдери, що покриваються:
- `openai`
- `google`
- Необов’язкове звуження:
@@ -774,7 +776,7 @@ Live-тести знаходять облікові дані так само, я
- `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"`
- Необов’язкова поведінка auth:
- - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth зі сховища профілів та ігнорувати override лише з env
+ - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth сховища profile й ігнорувати перевизначення лише з env
## Live: генерація музики
@@ -782,23 +784,23 @@ Live-тести знаходять облікові дані так само, я
- Увімкнення: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media music`
- Обсяг:
- - Перевіряє спільний вбудований шлях провайдерів генерації музики
- - Наразі охоплює Google і MiniMax
- - Завантажує env-змінні провайдера з вашого login shell (`~/.profile`) перед виконанням probe
- - Типово використовує live/env API-ключі раніше за збережені профілі auth, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
+ - Перевіряє спільний bundled-шлях провайдера генерації музики
+ - Наразі покриває Google і MiniMax
+ - Завантажує env-змінні провайдера з вашого login shell (`~/.profile`) перед probe
+ - За замовчуванням віддає перевагу live/env API-ключам над збереженими auth profile, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
- Пропускає провайдерів без придатної auth/profile/model
- Запускає обидва оголошені runtime-режими, коли вони доступні:
- - `generate` з введенням лише prompt
+ - `generate` з input лише на основі prompt
- `edit`, коли провайдер оголошує `capabilities.edit.enabled`
- Поточне покриття спільного lane:
- `google`: `generate`, `edit`
- `minimax`: `generate`
- - `comfy`: окремий live-файл Comfy, а не цей спільний прогін
+ - `comfy`: окремий live-файл Comfy, а не цей спільний sweep
- Необов’язкове звуження:
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"`
- Необов’язкова поведінка auth:
- - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth зі сховища профілів та ігнорувати override лише з env
+ - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth сховища profile й ігнорувати перевизначення лише з env
## Live: генерація відео
@@ -806,42 +808,42 @@ Live-тести знаходять облікові дані так само, я
- Увімкнення: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media video`
- Обсяг:
- - Перевіряє спільний вбудований шлях провайдерів генерації відео
- - Типово використовує безпечний для релізу шлях smoke: провайдери без FAL, один запит text-to-video на провайдера, односекундний prompt про лобстера та обмеження операції для кожного провайдера з `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (типово `180000`)
- - Типово пропускає FAL, тому що затримка черги на боці провайдера може домінувати над часом релізу; передайте `--video-providers fal` або `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"`, щоб запустити його явно
- - Завантажує env-змінні провайдера з вашого login shell (`~/.profile`) перед виконанням probe
- - Типово використовує live/env API-ключі раніше за збережені профілі auth, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
+ - Перевіряє спільний bundled-шлях провайдера генерації відео
+ - За замовчуванням використовує безпечний для релізу smoke-шлях: провайдери не-FAL, один запит text-to-video на провайдера, односекундний lobster prompt і обмеження операції для кожного провайдера через `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (за замовчуванням `180000`)
+ - За замовчуванням пропускає FAL, оскільки затримка черги на боці провайдера може домінувати в часі релізу; передайте `--video-providers fal` або `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"`, щоб запустити його явно
+ - Завантажує env-змінні провайдера з вашого login shell (`~/.profile`) перед probe
+ - За замовчуванням віддає перевагу live/env API-ключам над збереженими auth profile, щоб застарілі тестові ключі в `auth-profiles.json` не маскували реальні облікові дані shell
- Пропускає провайдерів без придатної auth/profile/model
- - Типово запускає лише `generate`
- - Встановіть `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1`, щоб також запускати оголошені режими transform, коли вони доступні:
- - `imageToVideo`, коли провайдер оголошує `capabilities.imageToVideo.enabled`, а вибраний провайдер/модель приймає локальний image input на основі buffer у спільному прогоні
- - `videoToVideo`, коли провайдер оголошує `capabilities.videoToVideo.enabled`, а вибраний провайдер/модель приймає локальний video input на основі buffer у спільному прогоні
- - Поточні оголошені, але пропущені провайдери `imageToVideo` у спільному прогоні:
- - `vydra`, тому що вбудований `veo3` підтримує лише text, а вбудований `kling` вимагає віддалений image URL
- - Покриття Vydra для конкретного провайдера:
+ - За замовчуванням запускає лише `generate`
+ - Установіть `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1`, щоб також запускати оголошені режими transform, коли вони доступні:
+ - `imageToVideo`, коли провайдер оголошує `capabilities.imageToVideo.enabled` і вибраний провайдер/модель приймає локальний input image на основі buffer у спільному sweep
+ - `videoToVideo`, коли провайдер оголошує `capabilities.videoToVideo.enabled` і вибраний провайдер/модель приймає локальний input video на основі buffer у спільному sweep
+ - Поточні оголошені, але пропущені провайдери `imageToVideo` у спільному sweep:
+ - `vydra`, тому що bundled `veo3` підтримує лише text, а bundled `kling` вимагає віддалений URL image
+ - Покриття Vydra, специфічне для провайдера:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts`
- - цей файл запускає `veo3` text-to-video плюс lane `kling`, який типово використовує фікстуру віддаленого image URL
+ - цей файл запускає `veo3` text-to-video, а також lane `kling`, який за замовчуванням використовує fixture із віддаленим URL image
- Поточне live-покриття `videoToVideo`:
- лише `runway`, коли вибрана модель — `runway/gen4_aleph`
- - Поточні оголошені, але пропущені провайдери `videoToVideo` у спільному прогоні:
- - `alibaba`, `qwen`, `xai`, тому що ці шляхи зараз вимагають віддалені URL-адреси посилань `http(s)` / MP4
- - `google`, тому що поточний спільний lane Gemini/Veo використовує локальний input на основі buffer, і цей шлях не приймається у спільному прогоні
- - `openai`, тому що поточний спільний lane не має гарантій доступу до специфічних для org можливостей video inpaint/remix
+ - Поточні оголошені, але пропущені провайдери `videoToVideo` у спільному sweep:
+ - `alibaba`, `qwen`, `xai`, тому що ці шляхи наразі вимагають віддалені референсні URL `http(s)` / MP4
+ - `google`, тому що поточний спільний lane Gemini/Veo використовує локальний input на основі buffer, а цей шлях не приймається у спільному sweep
+ - `openai`, тому що поточний спільний lane не гарантує доступ до org-specific inpaint/remix відео
- Необов’язкове звуження:
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
- - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""`, щоб включити кожного провайдера в типовий прогін, включно з FAL
- - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000`, щоб зменшити обмеження операції для кожного провайдера під час агресивного smoke-прогону
+ - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""`, щоб включити кожного провайдера у стандартний sweep, зокрема FAL
+ - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000`, щоб зменшити ліміт операції для кожного провайдера для агресивного smoke-запуску
- Необов’язкова поведінка auth:
- - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth зі сховища профілів та ігнорувати override лише з env
+ - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб примусово використовувати auth сховища profile й ігнорувати перевизначення лише з env
-## Media live harness
+## Harness live media
- Команда: `pnpm test:live:media`
- Призначення:
- - Запускає спільні live-набори для image, music і video через один native entrypoint репозиторію
+ - Запускає спільні live-набори image, music і video через один repo-native entrypoint
- Автоматично завантажує відсутні env-змінні провайдера з `~/.profile`
- - Типово автоматично звужує кожен набір до провайдерів, які зараз мають придатну auth
+ - За замовчуванням автоматично звужує кожен набір до провайдерів, які зараз мають придатну auth
- Повторно використовує `scripts/test-live.mjs`, тому поведінка Heartbeat і тихого режиму залишається узгодженою
- Приклади:
- `pnpm test:live:media`
@@ -849,89 +851,90 @@ Live-тести знаходять облікові дані так само, я
- `pnpm test:live:media video --video-providers openai,runway --all-providers`
- `pnpm test:live:media music --quiet`
-## Docker-ранери (необов’язкові перевірки «працює в Linux»)
+## Docker-раннери (необов’язкові перевірки «працює в Linux»)
-Ці Docker-ранери поділяються на дві групи:
+Ці Docker-раннери поділяються на дві групи:
-- Ранери live-model: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний live-файл із ключами профілів усередині Docker-образу репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог конфігурації та workspace (і підвантажують `~/.profile`, якщо його змонтовано). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`.
-- Docker live-ранери типово використовують меншу межу smoke, щоб повний Docker-прогін залишався практичним:
- `test:docker:live-models` типово використовує `OPENCLAW_LIVE_MAX_MODELS=12`, а
- `test:docker:live-gateway` типово використовує `OPENCLAW_LIVE_GATEWAY_SMOKE=1`,
+- Live-model раннери: `test:docker:live-models` і `test:docker:live-gateway` запускають лише відповідний їм live-файл ключів profile усередині Docker-образу репозиторію (`src/agents/models.profiles.live.test.ts` і `src/gateway/gateway-models.profiles.live.test.ts`), монтують ваш локальний каталог config і workspace (а також використовують `~/.profile`, якщо його змонтовано). Відповідні локальні entrypoint — `test:live:models-profiles` і `test:live:gateway-profiles`.
+- Docker live-раннери за замовчуванням використовують менший smoke-ліміт, щоб повний Docker sweep залишався практичним:
+ `test:docker:live-models` за замовчуванням використовує `OPENCLAW_LIVE_MAX_MODELS=12`, а
+ `test:docker:live-gateway` за замовчуванням використовує `OPENCLAW_LIVE_GATEWAY_SMOKE=1`,
`OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`,
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` і
- `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Замінюйте ці env-змінні, коли
+ `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Перевизначайте ці env-змінні, коли
вам явно потрібне більше вичерпне сканування.
-- `test:docker:all` один раз збирає live Docker-образ через `test:docker:live-build`, а потім повторно використовує його для двох Docker live-lane.
-- Ранери smoke контейнерів: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` і `test:docker:plugins` піднімають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.
+- `test:docker:all` один раз збирає live Docker-образ через `test:docker:live-build`, а потім повторно використовує його для двох Docker lane live.
+- Smoke-раннери контейнерів: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` і `test:docker:plugins` запускають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.
-Docker-ранери live-model також bind-mount лише потрібні CLI auth home (або всі підтримувані, коли запуск не звужено), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без змінення сховища auth на хості:
+Docker-раннери live-model також bind-mount-ять лише потрібні home-каталоги auth CLI (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени, не змінюючи auth store хоста:
- Direct models: `pnpm test:docker:live-models` (скрипт: `scripts/test-live-models-docker.sh`)
- Smoke ACP bind: `pnpm test:docker:live-acp-bind` (скрипт: `scripts/test-live-acp-bind-docker.sh`)
-- Smoke CLI backend: `pnpm test:docker:live-cli-backend` (скрипт: `scripts/test-live-cli-backend-docker.sh`)
-- Smoke app-server harness Codex: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`)
+- Smoke backend CLI: `pnpm test:docker:live-cli-backend` (скрипт: `scripts/test-live-cli-backend-docker.sh`)
+- Smoke harness app-server Codex: `pnpm test:docker:live-codex-harness` (скрипт: `scripts/test-live-codex-harness-docker.sh`)
- Gateway + dev agent: `pnpm test:docker:live-gateway` (скрипт: `scripts/test-live-gateway-models-docker.sh`)
- Live smoke Open WebUI: `pnpm test:docker:openwebui` (скрипт: `scripts/e2e/openwebui-docker.sh`)
-- Майстер onboarding (TTY, повне scaffold): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`)
+- Wizard onboarding (TTY, повне scaffolding): `pnpm test:docker:onboard` (скрипт: `scripts/e2e/onboard-docker.sh`)
- Мережева взаємодія Gateway (два контейнери, автентифікація WS + health): `pnpm test:docker:gateway-network` (скрипт: `scripts/e2e/gateway-network-docker.sh`)
-- Міст каналу MCP (ініціалізований Gateway + stdio bridge + smoke сирого notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`)
-- Plugins (smoke встановлення + alias `/plugin` + семантика перезапуску Claude-bundle): `pnpm test:docker:plugins` (скрипт: `scripts/e2e/plugins-docker.sh`)
+- Міст каналу MCP (seeded Gateway + stdio bridge + raw smoke notification-frame Claude): `pnpm test:docker:mcp-channels` (скрипт: `scripts/e2e/mcp-channels-docker.sh`)
+- Plugin-и (smoke встановлення + alias `/plugin` + семантика перезапуску Claude-bundle): `pnpm test:docker:plugins` (скрипт: `scripts/e2e/plugins-docker.sh`)
-Docker-ранери live-model також bind-mount поточний checkout лише для читання та
-готують його у тимчасовий workdir усередині контейнера. Це зберігає runtime-образ
-компактним, водночас дозволяючи запускати Vitest точно на вашому локальному вихідному коді/конфігурації.
-Етап підготовки пропускає великі локальні кеші та вихідні дані збірки застосунків, як-от
-`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` і локальні для застосунку каталоги `.build` або
+Docker-раннери live-model також bind-mount-ять поточний checkout лише для читання і
+розгортають його у тимчасовий workdir усередині контейнера. Це зберігає runtime-образ
+тонким, але водночас дозволяє запускати Vitest точно на вашому локальному source/config.
+Крок підготовки пропускає великі локальні кеші та результати збірки app, як-от
+`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` і локальні для app каталоги `.build` або
виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання
машинно-специфічних артефактів.
-Вони також встановлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-probe Gateway не запускали
-реальні воркери каналів Telegram/Discord тощо всередині контейнера.
+Вони також установлюють `OPENCLAW_SKIP_CHANNELS=1`, щоб live-probe Gateway не запускали
+реальні worker каналів Telegram/Discord тощо всередині контейнера.
`test:docker:live-models` усе ще запускає `pnpm test:live`, тому також передавайте
-`OPENCLAW_LIVE_GATEWAY_*`, коли вам потрібно звузити або виключити live-покриття gateway з цього Docker lane.
-`test:docker:openwebui` — це smoke вищого рівня на сумісність: він запускає
-контейнер Gateway OpenClaw з увімкненими сумісними з OpenAI HTTP endpoint,
-запускає закріплений контейнер Open WebUI проти цього gateway, входить через
+`OPENCLAW_LIVE_GATEWAY_*`, коли потрібно звузити або виключити live-покриття Gateway
+з цього Docker lane.
+`test:docker:openwebui` — це smoke сумісності вищого рівня: він запускає
+контейнер Gateway OpenClaw з увімкненими HTTP-endpoint, сумісними з OpenAI,
+запускає pinned-контейнер Open WebUI проти цього Gateway, входить через
Open WebUI, перевіряє, що `/api/models` показує `openclaw/default`, а потім надсилає
-реальний chat-запит через proxy Open WebUI `/api/chat/completions`.
-Перший запуск може бути помітно повільнішим, тому що Docker може потребувати завантаження
-образу Open WebUI, а Open WebUI може потребувати завершення власного cold-start налаштування.
+реальний chat-запит через proxy `/api/chat/completions` Open WebUI.
+Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження
+образу Open WebUI, а самому Open WebUI може знадобитися завершити власне cold-start налаштування.
Цей lane очікує придатний ключ live-моделі, а `OPENCLAW_PROFILE_FILE`
-(типово `~/.profile`) — основний спосіб надати його в Dockerized-запусках.
+(за замовчуванням `~/.profile`) є основним способом надати його в Dockerized-запусках.
Успішні запуски виводять невеликий JSON payload на кшталт `{ "ok": true, "model":
"openclaw/default", ... }`.
`test:docker:mcp-channels` навмисно детермінований і не потребує
-реального облікового запису Telegram, Discord або iMessage. Він піднімає ініціалізований контейнер Gateway,
-запускає другий контейнер, який виконує `openclaw mcp serve`, а потім
-перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень,
-поведінку черги live-подій, маршрутизацію вихідного надсилання та сповіщення в стилі Claude про канал +
-дозволи через реальний stdio MCP bridge. Перевірка сповіщень
-безпосередньо аналізує сирі stdio MCP frames, тож smoke перевіряє те, що
-міст справді випромінює, а не лише те, що випадково показує конкретний клієнтський SDK.
+реального облікового запису Telegram, Discord або iMessage. Він запускає seeded
+контейнер Gateway, запускає другий контейнер, який стартує `openclaw mcp serve`, а потім
+перевіряє виявлення conversation із маршрутизацією, читання transcript, метадані attachment,
+поведінку черги live-подій, маршрутизацію outbound send і сповіщення про канал +
+дозволи у стилі Claude через реальний stdio MCP bridge. Перевірка сповіщень
+напряму аналізує raw-кадри stdio MCP, тому smoke перевіряє те, що міст
+насправді випромінює, а не лише те, що певний SDK клієнта випадково надає на поверхню.
-Ручний smoke plain-language thread для ACP (не CI):
+Ручний smoke thread ACP простою мовою (не CI):
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...`
-- Залишайте цей скрипт для регресійних робочих процесів і налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тому не видаляйте його.
+- Зберігайте цей скрипт для робочих процесів регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації thread ACP, тому не видаляйте його.
Корисні env-змінні:
-- `OPENCLAW_CONFIG_DIR=...` (типово: `~/.openclaw`) монтується в `/home/node/.openclaw`
-- `OPENCLAW_WORKSPACE_DIR=...` (типово: `~/.openclaw/workspace`) монтується в `/home/node/.openclaw/workspace`
-- `OPENCLAW_PROFILE_FILE=...` (типово: `~/.profile`) монтується в `/home/node/.profile` і підвантажується перед запуском тестів
-- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише env-змінні, підвантажені з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace та без зовнішніх mount для CLI auth
-- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (типово: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих CLI-інсталяцій усередині Docker
-- Зовнішні каталоги/файли CLI auth у `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` перед стартом тестів
- - Типові каталоги: `.minimax`
- - Типові файли: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json`
- - Звужені запуски провайдерів монтують лише потрібні каталоги/файли, визначені з `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS`
- - Override вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, наприклад `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`
+- `OPENCLAW_CONFIG_DIR=...` (за замовчуванням: `~/.openclaw`) монтується в `/home/node/.openclaw`
+- `OPENCLAW_WORKSPACE_DIR=...` (за замовчуванням: `~/.openclaw/workspace`) монтується в `/home/node/.openclaw/workspace`
+- `OPENCLAW_PROFILE_FILE=...` (за замовчуванням: `~/.profile`) монтується в `/home/node/.profile` і використовується перед запуском тестів
+- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`, щоб перевіряти лише env-змінні, отримані з `OPENCLAW_PROFILE_FILE`, використовуючи тимчасові каталоги config/workspace і без монтування auth зовнішнього CLI
+- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (за замовчуванням: `~/.cache/openclaw/docker-cli-tools`) монтується в `/home/node/.npm-global` для кешованих установлень CLI всередині Docker
+- Зовнішні каталоги/файли auth CLI під `$HOME` монтуються лише для читання під `/host-auth...`, а потім копіюються в `/home/node/...` перед стартом тестів
+ - Каталоги за замовчуванням: `.minimax`
+ - Файли за замовчуванням: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json`
+ - Звужені запуски провайдера монтують лише потрібні каталоги/файли, які визначаються з `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS`
+ - Можна перевизначити вручну через `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` або список через кому, наприклад `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...`, щоб звузити запуск
-- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб фільтрувати провайдерів у контейнері
-- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використовувати наявний образ `openclaw:local-live` для повторних запусків, яким не потрібна перебудова
-- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб переконатися, що облікові дані беруться зі сховища профілів (а не з env)
-- `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку gateway відкриває для smoke Open WebUI
-- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб override nonce-check prompt, використаний smoke Open WebUI
-- `OPENWEBUI_IMAGE=...`, щоб override закріплений тег образу Open WebUI
+- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`, щоб відфільтрувати провайдерів у контейнері
+- `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб повторно використовувати наявний образ `openclaw:local-live` для повторних запусків, яким не потрібна нова збірка
+- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`, щоб переконатися, що облікові дані походять зі сховища profile (а не з env)
+- `OPENCLAW_OPENWEBUI_MODEL=...`, щоб вибрати модель, яку Gateway надає для smoke Open WebUI
+- `OPENCLAW_OPENWEBUI_PROMPT=...`, щоб перевизначити prompt перевірки nonce, який використовує smoke Open WebUI
+- `OPENWEBUI_IMAGE=...`, щоб перевизначити pinned-тег образу Open WebUI
## Перевірка документації
@@ -940,95 +943,95 @@ Open WebUI, перевіряє, що `/api/models` показує `openclaw/defa
## Офлайнова регресія (безпечна для CI)
-Це регресії «реального конвеєра» без реальних провайдерів:
+Це регресії «реального pipeline» без реальних провайдерів:
-- Виклик інструментів Gateway (mock OpenAI, реальний цикл gateway + agent): `src/gateway/gateway.test.ts` (випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
-- Майстер Gateway (WS `wizard.start`/`wizard.next`, запис конфігурації + примусова auth): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config")
+- Виклик tool у Gateway (mock OpenAI, реальний цикл gateway + agent): `src/gateway/gateway.test.ts` (випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
+- Wizard Gateway (WS `wizard.start`/`wizard.next`, записує config + примусову auth): `src/gateway/gateway.test.ts` (випадок: "runs wizard over ws and writes auth token config")
-## Оцінювання надійності агента (Skills)
+## Оцінювання надійності agent (Skills)
-У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агента»:
+У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності agent»:
-- Mock tool-calling через реальний цикл gateway + agent (`src/gateway/gateway.test.ts`).
-- Наскрізні потоки майстра, які перевіряють wiring сесії та ефекти конфігурації (`src/gateway/gateway.test.ts`).
+- Mock-виклик tool через реальний цикл gateway + agent (`src/gateway/gateway.test.ts`).
+- Наскрізні потоки wizard, які перевіряють wiring сесії та ефекти config (`src/gateway/gateway.test.ts`).
-Що ще бракує для Skills (див. [Skills](/uk/tools/skills)):
+Чого все ще бракує для Skills (див. [Skills](/uk/tools/skills)):
-- **Прийняття рішень:** коли Skills перелічено в prompt, чи вибирає агент правильний skill (або уникає нерелевантних)?
-- **Відповідність:** чи читає агент `SKILL.md` перед використанням і чи дотримується обов’язкових кроків/args?
-- **Контракти робочих процесів:** багатокрокові сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox.
+- **Вибір рішення:** коли Skills перелічені в prompt, чи вибирає agent правильний skill (або уникає нерелевантних)?
+- **Відповідність:** чи читає agent `SKILL.md` перед використанням і чи виконує потрібні кроки/аргументи?
+- **Контракти workflow:** багатокрокові сценарії, які перевіряють порядок tool, перенесення історії сесії та межі sandbox.
-Майбутні eval мають насамперед залишатися детермінованими:
+Майбутні eval спочатку мають залишатися детермінованими:
-- Runner сценаріїв із mock-провайдерами для перевірки викликів інструментів + порядку, читання skill-файлів і wiring сесії.
-- Невеликий набір сценаріїв, зосереджених на skills (використати чи уникнути, gating, prompt injection).
-- Необов’язкові live eval (opt-in, з обмеженням через env) лише після того, як безпечний для CI набір буде готовий.
+- Раннер сценаріїв, що використовує mock-провайдерів для перевірки викликів tool + порядку, читання skill-файлів і wiring сесії.
+- Невеликий набір сценаріїв, зосереджених на skill (використовувати чи уникати, gating, prompt injection).
+- Необов’язкові live eval (opt-in, з керуванням через env) — лише після того, як буде готовий безпечний для CI набір.
-## Контрактні тести (форма Plugin і channel)
+## Контрактні тести (форма plugin і channel)
-Контрактні тести перевіряють, що кожен зареєстрований Plugin і channel відповідає своєму
-контракту інтерфейсу. Вони ітеруються по всіх виявлених Plugin і запускають набір
-перевірок форми та поведінки. Типовий unit lane `pnpm test` навмисно
-пропускає ці спільні seam- і smoke-файли; запускайте контрактні команди явно,
+Контрактні тести перевіряють, що кожен зареєстрований plugin і channel відповідає
+контракту свого інтерфейсу. Вони проходять по всіх виявлених plugin і запускають
+набір перевірок форми та поведінки. Стандартний unit lane `pnpm test` навмисно
+пропускає ці файли спільних seam і smoke; запускайте контрактні команди явно,
коли торкаєтеся спільних поверхонь channel або provider.
### Команди
- Усі контракти: `pnpm test:contracts`
-- Лише контракти каналів: `pnpm test:contracts:channels`
-- Лише контракти провайдерів: `pnpm test:contracts:plugins`
+- Лише контракти channel: `pnpm test:contracts:channels`
+- Лише контракти provider: `pnpm test:contracts:plugins`
-### Контракти каналів
+### Контракти channel
Розташовані в `src/channels/plugins/contracts/*.contract.test.ts`:
-- **plugin** - Базова форма Plugin (id, name, capabilities)
-- **setup** - Контракт майстра налаштування
+- **plugin** - Базова форма plugin (id, name, capabilities)
+- **setup** - Контракт wizard налаштування
- **session-binding** - Поведінка прив’язки сесії
- **outbound-payload** - Структура payload повідомлення
- **inbound** - Обробка вхідних повідомлень
-- **actions** - Обробники дій каналу
-- **threading** - Обробка ID тредів
-- **directory** - API каталогу/ростеру
-- **group-policy** - Застосування групової політики
+- **actions** - Обробники дій channel
+- **threading** - Обробка ID thread
+- **directory** - API каталогу/списку учасників
+- **group-policy** - Застосування політики групи
-### Контракти статусу провайдера
+### Контракти статусу provider
Розташовані в `src/plugins/contracts/*.contract.test.ts`.
-- **status** - Перевірки статусу каналу
-- **registry** - Форма реєстру Plugin
+- **status** - Probe статусу channel
+- **registry** - Форма реєстру plugin
-### Контракти провайдерів
+### Контракти provider
Розташовані в `src/plugins/contracts/*.contract.test.ts`:
-- **auth** - Контракт потоку автентифікації
-- **auth-choice** - Вибір/селектор автентифікації
+- **auth** - Контракт потоку auth
+- **auth-choice** - Вибір/selection auth
- **catalog** - API каталогу моделей
-- **discovery** - Виявлення Plugin
-- **loader** - Завантаження Plugin
-- **runtime** - Runtime провайдера
-- **shape** - Форма/інтерфейс Plugin
-- **wizard** - Майстер налаштування
+- **discovery** - Виявлення plugin
+- **loader** - Завантаження plugin
+- **runtime** - Runtime provider
+- **shape** - Форма/інтерфейс plugin
+- **wizard** - Wizard налаштування
### Коли запускати
-- Після зміни export або subpath у plugin-sdk
-- Після додавання або зміни channel чи provider Plugin
-- Після рефакторингу реєстрації або виявлення Plugin
+- Після зміни export або підшляхів plugin-sdk
+- Після додавання чи зміни channel або provider plugin
+- Після рефакторингу реєстрації plugin або виявлення
Контрактні тести запускаються в CI і не потребують реальних API-ключів.
## Додавання регресій (рекомендації)
-Коли ви виправляєте проблему провайдера/моделі, виявлену в live:
+Коли ви виправляєте проблему provider/model, виявлену в live:
-- Якщо можливо, додайте безпечну для CI регресію (mock/stub провайдер або фіксація точної трансформації форми запиту)
-- Якщо це за своєю природою лише live-випадок (rate limits, політики auth), залишайте live-тест вузьким і opt-in через env-змінні
-- Віддавайте перевагу найменшому шару, який виявляє баг:
- - баг перетворення/повторення запиту провайдера → direct models test
- - баг у конвеєрі session/history/tool gateway → gateway live smoke або безпечний для CI gateway mock test
-- Захисна межа traversal SecretRef:
- - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef з метаданих реєстру (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегментів traversal відхиляються.
- - Якщо ви додаєте нове сімейство цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно падає на некласифікованих target id, щоб нові класи не можна було тихо пропустити.
+- За можливості додайте безпечну для CI регресію (mock/stub provider або захопіть точне перетворення форми запиту)
+- Якщо проблема за своєю природою лише live (rate limit, політики auth), залишайте live-тест вузьким і opt-in через env-змінні
+- Віддавайте перевагу найменшому шару, який виявляє помилку:
+ - помилка перетворення/повторного відтворення запиту provider → тест direct models
+ - помилка pipeline Gateway session/history/tool → gateway live smoke або безпечний для CI mock-тест Gateway
+- Захисне правило обходу SecretRef:
+ - `src/secrets/exec-secret-ref-id-parity.test.ts` виводить одну вибіркову ціль для кожного класу SecretRef із метаданих реєстру (`listSecretTargetRegistryEntries()`), а потім перевіряє, що exec id сегмента обходу відхиляються.
+ - Якщо ви додаєте нову родину цілей SecretRef `includeInPlan` у `src/secrets/target-registry-data.ts`, оновіть `classifyTargetClass` у цьому тесті. Тест навмисно падає на некласифікованих target id, щоб нові класи не можна було тихо пропустити.
diff --git a/docs/uk/providers/index.md b/docs/uk/providers/index.md
index f4d906f55..0f748ddaa 100644
--- a/docs/uk/providers/index.md
+++ b/docs/uk/providers/index.md
@@ -1,29 +1,29 @@
---
read_when:
- Ви хочете вибрати постачальника моделей
- - Вам потрібен швидкий огляд підтримуваних бекендів LLM
-summary: Постачальники моделей (LLM), які підтримуються OpenClaw
+ - Вам потрібен короткий огляд підтримуваних бекендів LLM
+summary: Постачальники моделей (LLM), що підтримуються OpenClaw
title: Каталог постачальників
x-i18n:
- generated_at: "2026-04-13T07:24:23Z"
+ generated_at: "2026-04-21T21:27:20Z"
model: gpt-5.4
provider: openai
- source_hash: 3bc682d008119719826f71f74959ab32bedf14214459f5e6ac9cb70371d3c540
+ source_hash: 7d77e5da93d71c48ea97460c6be56fbbe8279d9240a8101e1b35fdafb657737e
source_path: providers/index.md
workflow: 15
---
# Постачальники моделей
-OpenClaw може використовувати багато постачальників LLM. Виберіть постачальника, пройдіть автентифікацію, а потім установіть
-модель за замовчуванням як `provider/model`.
+OpenClaw може використовувати багато постачальників LLM. Виберіть постачальника, пройдіть автентифікацію, а потім задайте
+модель за замовчуванням у форматі `provider/model`.
-Шукаєте документацію щодо каналів чату (WhatsApp/Telegram/Discord/Slack/Mattermost (Plugin)/тощо)? Див. [Channels](/uk/channels).
+Шукаєте документацію для чат-каналів (WhatsApp/Telegram/Discord/Slack/Mattermost (plugin)/тощо)? Див. [Channels](/uk/channels).
## Швидкий старт
1. Пройдіть автентифікацію у постачальника (зазвичай через `openclaw onboard`).
-2. Установіть модель за замовчуванням:
+2. Задайте модель за замовчуванням:
```json5
{
@@ -37,21 +37,21 @@ OpenClaw може використовувати багато постачаль
- [Amazon Bedrock](/uk/providers/bedrock)
- [Anthropic (API + Claude CLI)](/uk/providers/anthropic)
- [Arcee AI (моделі Trinity)](/uk/providers/arcee)
-- [BytePlus (міжнародний)](/uk/concepts/model-providers#byteplus-international)
+- [BytePlus (міжнародна версія)](/uk/concepts/model-providers#byteplus-international)
- [Chutes](/uk/providers/chutes)
-- [ComfyUI](/uk/providers/comfy)
- [Cloudflare AI Gateway](/uk/providers/cloudflare-ai-gateway)
+- [ComfyUI](/uk/providers/comfy)
- [DeepSeek](/uk/providers/deepseek)
- [fal](/uk/providers/fal)
- [Fireworks](/uk/providers/fireworks)
- [GitHub Copilot](/uk/providers/github-copilot)
-- [моделі GLM](/uk/providers/glm)
+- [Моделі GLM](/uk/providers/glm)
- [Google (Gemini)](/uk/providers/google)
-- [Groq (LPU inference)](/uk/providers/groq)
-- [Hugging Face (Inference)](/uk/providers/huggingface)
+- [Groq (LPU-інференс)](/uk/providers/groq)
+- [Hugging Face (інференс)](/uk/providers/huggingface)
- [inferrs (локальні моделі)](/uk/providers/inferrs)
- [Kilocode](/uk/providers/kilocode)
-- [LiteLLM (уніфікований Gateway)](/uk/providers/litellm)
+- [LiteLLM (уніфікований шлюз)](/uk/providers/litellm)
- [LM Studio (локальні моделі)](/uk/providers/lmstudio)
- [MiniMax](/uk/providers/minimax)
- [Mistral](/uk/providers/mistral)
@@ -70,28 +70,29 @@ OpenClaw може використовувати багато постачаль
- [StepFun](/uk/providers/stepfun)
- [Synthetic](/uk/providers/synthetic)
- [Together AI](/uk/providers/together)
-- [Venice (Venice AI, з акцентом на конфіденційність)](/uk/providers/venice)
+- [Venice (Venice AI, з акцентом на приватність)](/uk/providers/venice)
- [Vercel AI Gateway](/uk/providers/vercel-ai-gateway)
-- [Vydra](/uk/providers/vydra)
- [vLLM (локальні моделі)](/uk/providers/vllm)
- [Volcengine (Doubao)](/uk/providers/volcengine)
+- [Vydra](/uk/providers/vydra)
- [xAI](/uk/providers/xai)
- [Xiaomi](/uk/providers/xiaomi)
- [Z.AI](/uk/providers/zai)
-## Спільні сторінки огляду
+## Спільні оглядові сторінки
-- [Додаткові вбудовані варіанти](/uk/providers/models#additional-bundled-provider-variants) - Anthropic Vertex, Copilot Proxy і Gemini CLI OAuth
-- [Генерація зображень](/uk/tools/image-generation) - спільний інструмент `image_generate`, вибір постачальника та перемикання при відмові
-- [Генерація музики](/uk/tools/music-generation) - спільний інструмент `music_generate`, вибір постачальника та перемикання при відмові
-- [Генерація відео](/uk/tools/video-generation) - спільний інструмент `video_generate`, вибір постачальника та перемикання при відмові
+- [Додаткові вбудовані варіанти](/uk/providers/models#additional-bundled-provider-variants) - Anthropic Vertex, Copilot Proxy та Gemini CLI OAuth
+- [Генерація зображень](/uk/tools/image-generation) - Спільний інструмент `image_generate`, вибір постачальника та failover
+- [Генерація музики](/uk/tools/music-generation) - Спільний інструмент `music_generate`, вибір постачальника та failover
+- [Генерація відео](/uk/tools/video-generation) - Спільний інструмент `video_generate`, вибір постачальника та failover
-## Постачальники транскрибування
+## Постачальники транскрипції
-- [Deepgram (транскрибування аудіо)](/uk/providers/deepgram)
+- [Deepgram (транскрипція аудіо)](/uk/providers/deepgram)
## Інструменти спільноти
- [Claude Max API Proxy](/uk/providers/claude-max-api-proxy) - Проксі спільноти для облікових даних підписки Claude (перед використанням перевірте політику/умови Anthropic)
-Повний каталог постачальників (xAI, Groq, Mistral тощо) і розширену конфігурацію див. у розділі [Постачальники моделей](/uk/concepts/model-providers).
+Щоб переглянути повний каталог постачальників (xAI, Groq, Mistral тощо) і розширену конфігурацію,
+див. [Постачальники моделей](/uk/concepts/model-providers).
diff --git a/docs/uk/reference/test.md b/docs/uk/reference/test.md
index 2f4f54a8c..9b40e8eb5 100644
--- a/docs/uk/reference/test.md
+++ b/docs/uk/reference/test.md
@@ -1,13 +1,13 @@
---
read_when:
- Запуск або виправлення тестів
-summary: Як запускати тести локально (`vitest`) і коли використовувати режими force/coverage
+summary: Як запускати тести локально (`vitest`) і коли використовувати режими `force`/`coverage`
title: Тести
x-i18n:
- generated_at: "2026-04-20T22:38:11Z"
+ generated_at: "2026-04-21T21:27:24Z"
model: gpt-5.4
provider: openai
- source_hash: 04bdcbc3a1121f4c460cd9060f581a49dfc6fa65c4b9ddb9c87db81c4a535166
+ source_hash: ed665840ef2c7728da8ec923eb3ea2878d9b20a841cb2fe4116a7f6334567b8e
source_path: reference/test.md
workflow: 15
---
@@ -16,35 +16,35 @@ x-i18n:
- Повний набір для тестування (набори тестів, live, Docker): [Тестування](/uk/help/testing)
-- `pnpm test:force`: Завершує будь-який завислий процес gateway, який утримує стандартний control port, а потім запускає повний набір Vitest з ізольованим портом gateway, щоб серверні тести не конфліктували із запущеним екземпляром. Використовуйте це, якщо попередній запуск gateway залишив зайнятим порт 18789.
-- `pnpm test:coverage`: Запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це перевірка покриття unit-тестів для завантажених файлів, а не загальнорепозиторне покриття всіх файлів. Порогові значення: 70% для lines/functions/statements і 55% для branches. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit coverage, замість того щоб вважати всі вихідні файли розділених lane непокритими.
-- `pnpm test:coverage:changed`: Запускає unit coverage лише для файлів, змінених відносно `origin/main`.
-- `pnpm test:changed`: розгортає змінені git-шляхи у scoped lane Vitest, коли diff торкається лише routable source/test файлів. Зміни конфігурації/налаштування все одно повертаються до native root projects run, щоб за потреби зміни wiring запускали ширший повторний прогін.
-- `pnpm changed:lanes`: показує архітектурні lane, які запускаються diff відносно `origin/main`.
-- `pnpm check:changed`: запускає smart changed gate для diff відносно `origin/main`. Він запускає core-роботу з core test lane, роботу extensions — з extension test lane, зміни лише в тестах — тільки з test typecheck/tests, а також розширює зміни в публічному Plugin SDK або plugin-contract до валідації extensions.
-- `pnpm test`: маршрутизує явні цілі файлів/директорій через scoped lane Vitest. Запуски без цілі використовують фіксовані shard groups і розгортаються до leaf config для локального паралельного виконання; група extension завжди розгортається до per-extension shard config, а не до одного великого root-project process.
-- Повні запуски та запуски extension shard оновлюють локальні дані таймінгів у `.artifacts/vitest-shard-timings.json`; наступні запуски використовують ці таймінги для балансування повільних і швидких shard. Встановіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт таймінгів.
-- Вибрані файли тестів `plugin-sdk` і `commands` тепер маршрутизуються через окремі легкі lane, які зберігають лише `test/setup.ts`, залишаючи resource-heavy випадки на їхніх наявних lane.
-- Вибрані вихідні helper-файли `plugin-sdk` і `commands` також маплять `pnpm test:changed` на явні sibling-тести в цих легких lane, щоб дрібні зміни helper не перезапускали важкі набори, що спираються на runtime.
-- `auto-reply` тепер також розділено на три окремі config (`core`, `top-level`, `reply`), щоб harness для reply не домінував над легшими top-level тестами status/token/helper.
-- Базова конфігурація Vitest тепер за замовчуванням використовує `pool: "threads"` і `isolate: false`, а спільний non-isolated runner увімкнено в конфігураціях усього репозиторію.
+- `pnpm test:force`: Завершує будь-який завислий процес gateway, що утримує типовий порт керування, а потім запускає повний набір Vitest з ізольованим портом gateway, щоб тести сервера не конфліктували із запущеним екземпляром. Використовуйте це, коли попередній запуск gateway залишив зайнятим порт 18789.
+- `pnpm test:coverage`: Запускає набір unit-тестів із покриттям V8 (через `vitest.unit.config.ts`). Це перевірка покриття unit-тестів для завантажених файлів, а не покриття всіх файлів у всьому репозиторії. Порогові значення: 70% для lines/functions/statements і 55% для branches. Оскільки `coverage.all` має значення false, перевірка вимірює файли, завантажені набором unit-тестів із покриттям, замість того щоб вважати всі файли вихідного коду у розбитих lane непокритими.
+- `pnpm test:coverage:changed`: Запускає unit-покриття лише для файлів, змінених відносно `origin/main`.
+- `pnpm test:changed`: розгортає змінені git-шляхи в scoped lane Vitest, коли diff зачіпає лише routable файли вихідного коду/тестів. Зміни конфігурації/налаштування все одно повертаються до нативного запуску root projects, щоб за потреби зміни у зв’язуванні запускали ширший прогін.
+- `pnpm changed:lanes`: показує архітектурні lane, що запускаються diff відносно `origin/main`.
+- `pnpm check:changed`: запускає розумну перевірку changed gate для diff відносно `origin/main`. Вона запускає core-роботу разом із core test lanes, роботу extension — разом із extension test lanes, зміни лише в тестах — лише з test typecheck/tests, розширює зміни публічного Plugin SDK або plugin-contract до перевірки extension, а також залишає version bump лише в release metadata на цільових перевірках version/config/root-dependency.
+- `pnpm test`: маршрутизує явні цілі файлів/каталогів через scoped lane Vitest. Запуски без цілі використовують фіксовані shard-групи й розгортаються до leaf configs для локального паралельного виконання; група extension завжди розгортається до per-extension shard configs, а не до одного великого процесу root-project.
+- Повні запуски та запуски extension shard оновлюють локальні дані часу в `.artifacts/vitest-shard-timings.json`; наступні запуски використовують ці значення часу для балансування повільних і швидких shard. Встановіть `OPENCLAW_TEST_PROJECTS_TIMINGS=0`, щоб ігнорувати локальний артефакт часу.
+- Вибрані тестові файли `plugin-sdk` і `commands` тепер маршрутизуються через окремі легкі lane, які зберігають лише `test/setup.ts`, залишаючи важкі з погляду runtime кейси в їхніх наявних lane.
+- Вибрані допоміжні файли вихідного коду `plugin-sdk` і `commands` також зіставляють `pnpm test:changed` з явними sibling tests у цих легких lane, щоб невеликі зміни helper не перезапускали важкі набори, прив’язані до runtime.
+- `auto-reply` тепер також розбивається на три окремі конфігурації (`core`, `top-level`, `reply`), щоб harness для reply не домінував над легшими top-level тестами status/token/helper.
+- Базова конфігурація Vitest тепер типово використовує `pool: "threads"` і `isolate: false`, а спільний неізольований runner увімкнено в конфігураціях усього репозиторію.
- `pnpm test:channels` запускає `vitest.channels.config.ts`.
-- `pnpm test:extensions` і `pnpm test extensions` запускають усі shard extensions/plugins. Важкі channel extensions і OpenAI працюють як окремі shard; інші групи extensions залишаються згрупованими. Використовуйте `pnpm test extensions/` для одного lane вбудованого Plugin.
-- `pnpm test:perf:imports`: вмикає звітність Vitest про import-duration та import-breakdown, при цьому все ще використовує маршрутизацію scoped lane для явних цілей файлів/директорій.
-- `pnpm test:perf:imports:changed`: те саме профілювання import, але лише для файлів, змінених відносно `origin/main`.
-- `pnpm test:perf:changed:bench -- --ref ` порівнює продуктивність маршрутизованого режиму changed із native root-project run для того самого закоміченого git diff.
-- `pnpm test:perf:changed:bench -- --worktree` порівнює продуктивність поточного набору змін у worktree без попереднього коміту.
-- `pnpm test:perf:profile:main`: записує CPU profile для головного потоку Vitest (`.artifacts/vitest-main-profile`).
-- `pnpm test:perf:profile:runner`: записує CPU + heap profiles для unit runner (`.artifacts/vitest-runner-profile`).
-- Інтеграція Gateway: opt-in через `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` або `pnpm test:gateway`.
-- `pnpm test:e2e`: запускає наскрізні smoke-тести gateway (парування multi-instance WS/HTTP/node). За замовчуванням використовує `threads` + `isolate: false` з adaptive workers у `vitest.e2e.config.ts`; налаштовуйте через `OPENCLAW_E2E_WORKERS=` і встановіть `OPENCLAW_E2E_VERBOSE=1` для докладних логів.
-- `pnpm test:live`: запускає live-тести provider (minimax/zai). Потрібні API keys і `LIVE=1` (або provider-specific `*_LIVE_TEST=1`) для зняття skip.
-- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, виконує вхід через Open WebUI, перевіряє `/api/models`, а потім запускає реальний проксійований чат через `/api/chat/completions`. Потребує придатного live model key (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не вважається стабільним для CI так, як звичайні unit/e2e набори.
-- `pnpm test:docker:mcp-channels`: запускає seeded контейнер Gateway і другий контейнер клієнта, який запускає `openclaw mcp serve`, а потім перевіряє routed conversation discovery, читання transcript, metadata вкладень, поведінку live event queue, маршрутизацію outbound send і сповіщення про channel + permissions у стилі Claude через реальний stdio bridge. Перевірка сповіщень Claude читає сирі stdio MCP frames безпосередньо, щоб smoke-тест відображав те, що bridge реально надсилає.
+- `pnpm test:extensions` і `pnpm test extensions` запускають усі shard extension/plugin. Важкі channel extensions і OpenAI запускаються як окремі shard; інші групи extension залишаються згрупованими. Використовуйте `pnpm test extensions/` для одного lane вбудованого plugin.
+- `pnpm test:perf:imports`: вмикає звіти Vitest про тривалість імпорту та деталізацію імпортів, при цьому все ще використовує маршрутизацію scoped lane для явних цілей файлів/каталогів.
+- `pnpm test:perf:imports:changed`: те саме профілювання імпортів, але лише для файлів, змінених відносно `origin/main`.
+- `pnpm test:perf:changed:bench -- --ref ` виконує benchmark маршрутизованого changed-режиму проти нативного запуску root-project для того самого закоміченого git diff.
+- `pnpm test:perf:changed:bench -- --worktree` виконує benchmark поточного набору змін у worktree без попереднього коміту.
+- `pnpm test:perf:profile:main`: записує CPU-профіль для головного потоку Vitest (`.artifacts/vitest-main-profile`).
+- `pnpm test:perf:profile:runner`: записує CPU + heap-профілі для unit runner (`.artifacts/vitest-runner-profile`).
+- Інтеграція Gateway: вмикається через `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` або `pnpm test:gateway`.
+- `pnpm test:e2e`: запускає smoke-тести gateway end-to-end (парування multi-instance WS/HTTP/node). Типово використовує `threads` + `isolate: false` з адаптивною кількістю workers у `vitest.e2e.config.ts`; налаштовуйте через `OPENCLAW_E2E_WORKERS=` і встановіть `OPENCLAW_E2E_VERBOSE=1` для докладних журналів.
+- `pnpm test:live`: запускає live-тести provider (minimax/zai). Потребує API-ключів і `LIVE=1` (або provider-specific `*_LIVE_TEST=1`) для зняття пропуску.
+- `pnpm test:docker:openwebui`: запускає Dockerized OpenClaw + Open WebUI, виконує вхід через Open WebUI, перевіряє `/api/models`, а потім запускає реальний проксійований чат через `/api/chat/completions`. Потребує придатного ключа live model (наприклад, OpenAI у `~/.profile`), завантажує зовнішній образ Open WebUI і не вважається настільки стабільним для CI, як звичайні набори unit/e2e.
+- `pnpm test:docker:mcp-channels`: запускає seeded контейнер Gateway і другий контейнер-клієнт, який запускає `openclaw mcp serve`, а потім перевіряє routed conversation discovery, читання transcript, метадані вкладень, поведінку черги live events, outbound send routing і сповіщення про channel + permissions у стилі Claude через реальний міст stdio. Перевірка сповіщень Claude читає сирі stdio MCP-кадри безпосередньо, щоб smoke-тест відображав те, що міст справді надсилає.
## Локальний PR gate
-Для локальних перевірок перед злиттям/проходження gate PR виконайте:
+Для локальних перевірок перед приземленням PR/gate запустіть:
- `pnpm check:changed`
- `pnpm check`
@@ -53,27 +53,27 @@ x-i18n:
- `pnpm test`
- `pnpm check:docs`
-Якщо `pnpm test` дає flaky-результат на навантаженому хості, перезапустіть один раз, перш ніж вважати це регресією, а потім ізолюйте через `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте:
+Якщо `pnpm test` дає флейк на навантаженому хості, перезапустіть один раз, перш ніж вважати це регресією, а потім ізолюйте через `pnpm test `. Для хостів з обмеженою пам’яттю використовуйте:
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
-## Бенч затримки моделі (локальні ключі)
+## Benchmark затримки моделі (локальні ключі)
Скрипт: [`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)
Використання:
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
-- Необов’язкові змінні середовища: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY`
-- Типовий prompt: “Reply with a single word: ok. No punctuation or extra text.”
+- Необов’язкові env: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY`
+- Типовий prompt: “Відповідай одним словом: ok. Без розділових знаків або додаткового тексту.”
Останній запуск (2025-12-31, 20 запусків):
- minimax median 1279ms (min 1114, max 2431)
- opus median 2454ms (min 1224, max 3170)
-## Бенч запуску CLI
+## Benchmark запуску CLI
Скрипт: [`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)
@@ -94,29 +94,29 @@ x-i18n:
- `pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu`
- `pnpm tsx scripts/bench-cli-startup.ts --json`
-Пресети:
+Набори preset:
- `startup`: `--version`, `--help`, `health`, `health --json`, `status --json`, `status`
- `real`: `health`, `status`, `status --json`, `sessions`, `sessions --json`, `agents list --json`, `gateway status`, `gateway status --json`, `gateway health --json`, `config get gateway.port`
-- `all`: обидва пресети
+- `all`: обидва набори preset
-Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл exit-code/signal і зведення max RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують V8 profiles для кожного запуску, тож збір таймінгів і profiles використовує той самий harness.
+Вивід містить `sampleCount`, avg, p50, p95, min/max, розподіл exit-code/signal і підсумки max RSS для кожної команди. Необов’язкові `--cpu-prof-dir` / `--heap-prof-dir` записують V8-профілі для кожного запуску, щоб вимірювання часу та збирання профілів використовували один і той самий harness.
-Правила збереження виводу:
+Умовності для збереженого виводу:
- `pnpm test:startup:bench:smoke` записує цільовий smoke-артефакт у `.artifacts/cli-startup-bench-smoke.json`
-- `pnpm test:startup:bench:save` записує артефакт повного набору в `.artifacts/cli-startup-bench-all.json` з `runs=5` і `warmup=1`
-- `pnpm test:startup:bench:update` оновлює закомічений baseline fixture у `test/fixtures/cli-startup-bench.json` з `runs=5` і `warmup=1`
+- `pnpm test:startup:bench:save` записує артефакт повного набору в `.artifacts/cli-startup-bench-all.json`, використовуючи `runs=5` і `warmup=1`
+- `pnpm test:startup:bench:update` оновлює закомічений baseline fixture у `test/fixtures/cli-startup-bench.json`, використовуючи `runs=5` і `warmup=1`
Закомічений fixture:
- `test/fixtures/cli-startup-bench.json`
-- Оновіть через `pnpm test:startup:bench:update`
-- Порівняйте поточні результати з fixture через `pnpm test:startup:bench:check`
+- Оновлення через `pnpm test:startup:bench:update`
+- Порівняння поточних результатів із fixture через `pnpm test:startup:bench:check`
## Onboarding E2E (Docker)
-Docker є необов’язковим; це потрібно лише для containerized smoke-тестів onboarding.
+Docker необов’язковий; це потрібно лише для containerized smoke-тестів onboarding.
Повний cold-start flow у чистому Linux-контейнері:
@@ -124,11 +124,11 @@ Docker є необов’язковим; це потрібно лише для c
scripts/e2e/onboard-docker.sh
```
-Цей скрипт керує інтерактивним wizard через pseudo-tty, перевіряє файли config/workspace/session, а потім запускає gateway і виконує `openclaw health`.
+Цей скрипт проходить інтерактивний майстер через pseudo-tty, перевіряє файли config/workspace/session, потім запускає gateway і виконує `openclaw health`.
-## QR import smoke (Docker)
+## Smoke-тест імпорту QR (Docker)
-Гарантує, що `qrcode-terminal` завантажується в підтримуваних Docker runtime Node (Node 24 за замовчуванням, Node 22 сумісний):
+Гарантує, що `qrcode-terminal` завантажується в підтримуваних runtime Node у Docker (типово Node 24, сумісність із Node 22):
```bash
pnpm test:docker:qr