diff --git a/docs/uk/channels/discord.md b/docs/uk/channels/discord.md index 494d11cfa..19ecb5f61 100644 --- a/docs/uk/channels/discord.md +++ b/docs/uk/channels/discord.md @@ -4,44 +4,44 @@ read_when: summary: Статус підтримки бота Discord, можливості та налаштування title: Discord x-i18n: - generated_at: "2026-04-23T06:42:24Z" + generated_at: "2026-04-23T08:25:11Z" model: gpt-5.4 provider: openai - source_hash: 0bee2c419651701f7ab57e46a4c0c473c83596eb9bd2156bac3c6117513236ab + source_hash: 1160a0b221bc3251722a81c00c65ee7c2001efce345248727f1f3c8580a0e953 source_path: channels/discord.md workflow: 15 --- # Discord (Bot API) -Статус: готово для приватних повідомлень і каналів серверів через офіційний шлюз Discord. +Статус: готово для приватних повідомлень і каналів гільдій через офіційний gateway Discord. - - Discord DMs за замовчуванням використовують режим сполучення. + + За замовчуванням приватні повідомлення Discord працюють у режимі підключення. - + Нативна поведінка команд і каталог команд. - - Діагностика між каналами та процес відновлення. + + Міжканальна діагностика та процес відновлення. ## Швидке налаштування -Вам потрібно створити новий застосунок із ботом, додати бота на свій сервер і сполучити його з OpenClaw. Ми рекомендуємо додати бота на власний приватний сервер. Якщо у вас його ще немає, [спочатку створіть його](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (виберіть **Create My Own > For me and my friends**). +Вам потрібно створити новий застосунок із ботом, додати бота на свій сервер і підключити його до OpenClaw. Ми рекомендуємо додавати бота на власний приватний сервер. Якщо у вас його ще немає, [спочатку створіть його](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (оберіть **Create My Own > For me and my friends**). - + Перейдіть до [Discord Developer Portal](https://discord.com/developers/applications) і натисніть **New Application**. Назвіть його, наприклад, "OpenClaw". - Натисніть **Bot** на бічній панелі. Установіть **Username** на ту назву, якою ви називаєте свого агента OpenClaw. + Натисніть **Bot** на бічній панелі. Установіть **Username** на назву, якою ви називаєте свого агента OpenClaw. - - Усе ще на сторінці **Bot**, прокрутіть униз до **Privileged Gateway Intents** і ввімкніть: + + Все ще на сторінці **Bot**, прокрутіть вниз до **Privileged Gateway Intents** і увімкніть: - **Message Content Intent** (обов’язково) - **Server Members Intent** (рекомендовано; обов’язково для списків дозволених ролей і зіставлення імен з ID) @@ -50,25 +50,25 @@ x-i18n: - Прокрутіть угору на сторінці **Bot** і натисніть **Reset Token**. + Поверніться вгору на сторінці **Bot** і натисніть **Reset Token**. - Попри назву, це створює ваш перший токен — нічого не «скидається». + Попри назву, це генерує ваш перший токен — нічого не «скидається». - Скопіюйте токен і збережіть його десь. Це ваш **Bot Token**, і він скоро знадобиться. + Скопіюйте токен і збережіть його десь. Це ваш **Bot Token**, і він вам скоро знадобиться. - - Натисніть **OAuth2** на бічній панелі. Ви згенеруєте URL-запрошення з правильними дозволами, щоб додати бота на свій сервер. + + Натисніть **OAuth2** на бічній панелі. Ви згенеруєте URL запрошення з потрібними дозволами, щоб додати бота на свій сервер. - Прокрутіть униз до **OAuth2 URL Generator** і ввімкніть: + Прокрутіть вниз до **OAuth2 URL Generator** і увімкніть: - `bot` - `applications.commands` - Унизу з’явиться розділ **Bot Permissions**. Увімкніть принаймні: + Нижче з’явиться розділ **Bot Permissions**. Увімкніть щонайменше: **General Permissions** - View Channels @@ -79,31 +79,31 @@ x-i18n: - Attach Files - Add Reactions (необов’язково) - Це базовий набір для звичайних текстових каналів. Якщо ви плануєте публікувати в гілках Discord, зокрема у процесах форумних або медіаканалів, які створюють або продовжують гілку, також увімкніть **Send Messages in Threads**. - Скопіюйте згенерований URL унизу, вставте його в браузер, виберіть свій сервер і натисніть **Continue** для підключення. Тепер ви маєте бачити свого бота на сервері Discord. + Це базовий набір для звичайних текстових каналів. Якщо ви плануєте публікувати в обговореннях Discord, зокрема у сценаріях форумних або медіаканалів, що створюють або продовжують обговорення, також увімкніть **Send Messages in Threads**. + Скопіюйте згенерований URL внизу, вставте його у браузер, виберіть свій сервер і натисніть **Continue**, щоб підключити. Тепер ви маєте побачити свого бота на Discord-сервері. - Повернувшись у застосунок Discord, вам потрібно ввімкнути Developer Mode, щоб можна було копіювати внутрішні ID. + Повернувшись у застосунок Discord, вам потрібно увімкнути Developer Mode, щоб можна було копіювати внутрішні ID. 1. Натисніть **User Settings** (значок шестерні поруч із вашим аватаром) → **Advanced** → увімкніть **Developer Mode** - 2. Клацніть правою кнопкою миші по **значку сервера** на бічній панелі → **Copy Server ID** - 3. Клацніть правою кнопкою миші по **власному аватару** → **Copy User ID** + 2. Клацніть правою кнопкою миші на **значку сервера** на бічній панелі → **Copy Server ID** + 3. Клацніть правою кнопкою миші на **власному аватарі** → **Copy User ID** Збережіть свій **Server ID** і **User ID** разом із Bot Token — на наступному кроці ви передасте всі три значення в OpenClaw. - - Щоб сполучення працювало, Discord має дозволяти вашому боту надсилати вам DMs. Клацніть правою кнопкою миші по **значку сервера** → **Privacy Settings** → увімкніть **Direct Messages**. + + Щоб підключення працювало, Discord має дозволяти вашому боту надсилати вам приватні повідомлення. Клацніть правою кнопкою миші на **значку сервера** → **Privacy Settings** → увімкніть **Direct Messages**. - Це дозволяє учасникам сервера (зокрема ботам) надсилати вам DMs. Залишайте це ввімкненим, якщо хочете використовувати Discord DMs з OpenClaw. Якщо ви плануєте використовувати лише канали сервера, після сполучення DMs можна вимкнути. + Це дозволяє учасникам сервера (включно з ботами) надсилати вам приватні повідомлення. Залиште це увімкненим, якщо хочете використовувати приватні повідомлення Discord з OpenClaw. Якщо ви плануєте використовувати лише канали гільдії, після підключення можна вимкнути приватні повідомлення. - - Токен вашого Discord-бота є секретом (як пароль). Задайте його на машині, де працює OpenClaw, перш ніж писати своєму агенту. + + Токен вашого Discord-бота — це секрет (як пароль). Задайте його на машині, де працює OpenClaw, перш ніж писати своєму агенту. ```bash export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN" @@ -113,20 +113,20 @@ openclaw config set channels.discord.enabled true --strict-json openclaw gateway ``` - Якщо OpenClaw уже працює як фоновий сервіс, перезапустіть його через застосунок OpenClaw для Mac або зупинивши й знову запустивши процес `openclaw gateway run`. + Якщо OpenClaw уже працює як фонова служба, перезапустіть його через застосунок OpenClaw для Mac або зупинивши й знову запустивши процес `openclaw gateway run`. - + - Напишіть своєму агенту OpenClaw у будь-якому вже наявному каналі (наприклад, Telegram) і скажіть це. Якщо Discord — ваш перший канал, натомість скористайтеся вкладкою CLI / config. + Напишіть своєму агенту OpenClaw у будь-якому наявному каналі (наприклад, Telegram) і скажіть йому це. Якщо Discord — ваш перший канал, замість цього використайте вкладку CLI / config. - > "Я вже задав токен свого Discord-бота в config. Будь ласка, заверши налаштування Discord з User ID `` і Server ID ``." + > "Я вже задав токен свого Discord-бота в конфігурації. Будь ласка, заверши налаштування Discord з User ID `` і Server ID ``." - Якщо ви надаєте перевагу файловій конфігурації, задайте: + Якщо ви віддаєте перевагу файловій конфігурації, задайте: ```json5 { @@ -143,27 +143,27 @@ openclaw gateway } ``` - Резервне значення env для облікового запису за замовчуванням: + Резервна змінна середовища для облікового запису за замовчуванням: ```bash DISCORD_BOT_TOKEN=... ``` - Підтримуються значення `token` у відкритому тексті. Значення SecretRef також підтримуються для `channels.discord.token` у провайдерах env/file/exec. Див. [Керування секретами](/uk/gateway/secrets). + Підтримуються відкриті значення `token`. Також підтримуються значення SecretRef для `channels.discord.token` у провайдерах env/file/exec. Див. [Керування секретами](/uk/gateway/secrets). - - Дочекайтеся, поки шлюз буде запущено, а потім надішліть DM своєму боту в Discord. Він відповість кодом сполучення. + + Дочекайтеся, поки gateway запуститься, а потім надішліть приватне повідомлення своєму боту в Discord. Він відповість кодом підключення. - Надішліть код сполучення своєму агенту в наявному каналі: + Надішліть код підключення своєму агенту в наявному каналі: - > "Підтвердь цей код сполучення Discord: ``" + > "Підтвердь цей код підключення Discord: ``" @@ -175,31 +175,31 @@ openclaw pairing approve discord - Термін дії кодів сполучення спливає через 1 годину. + Термін дії кодів підключення спливає через 1 годину. - Тепер ви маєте змогу спілкуватися зі своїм агентом у Discord через DM. + Тепер ви маєте змогу спілкуватися зі своїм агентом у Discord через приватні повідомлення. -Визначення токенів залежить від облікового запису. Значення токенів у config мають пріоритет над резервним значенням env. `DISCORD_BOT_TOKEN` використовується лише для облікового запису за замовчуванням. -Для розширених вихідних викликів (інструмент повідомлень/дії каналу) явний `token` використовується для цього конкретного виклику. Це стосується дій надсилання та читання/перевірки (наприклад, read/search/fetch/thread/pins/permissions). Політика облікового запису й параметри повторних спроб усе ще беруться з вибраного облікового запису в активному знімку runtime. +Визначення токена враховує обліковий запис. Значення токена в конфігурації мають пріоритет над резервною змінною середовища. `DISCORD_BOT_TOKEN` використовується лише для облікового запису за замовчуванням. +Для розширених вихідних викликів (інструмент повідомлень/дії каналу) явний `token` використовується для цього виклику. Це застосовується до дій надсилання й читання/перевірки (наприклад, read/search/fetch/thread/pins/permissions). Політика облікового запису/налаштування повторних спроб усе ще беруться з вибраного облікового запису в активному знімку runtime. -## Рекомендовано: налаштуйте робочий простір сервера +## Рекомендовано: налаштуйте робочий простір гільдії -Коли DMs уже працюють, ви можете налаштувати свій сервер Discord як повноцінний робочий простір, де кожен канал отримує окрему сесію агента з власним контекстом. Це рекомендовано для приватних серверів, де єте лише ви та ваш бот. +Щойно приватні повідомлення запрацюють, ви зможете налаштувати свій Discord-сервер як повноцінний робочий простір, де кожен канал отримує власну сесію агента з власним контекстом. Це рекомендовано для приватних серверів, де є лише ви та ваш бот. - - Це дозволяє вашому агенту відповідати в будь-якому каналі вашого сервера, а не лише в DMs. + + Це дозволяє вашому агенту відповідати в будь-якому каналі на вашому сервері, а не лише в приватних повідомленнях. - > "Додай мій Discord Server ID `` до списку дозволених серверів" + > "Додай мій Discord Server ID `` до списку дозволених гільдій" - + ```json5 { @@ -223,14 +223,14 @@ openclaw pairing approve discord - За замовчуванням ваш агент відповідає в каналах сервера лише тоді, коли його згадано через @mention. Для приватного сервера, імовірно, ви захочете, щоб він відповідав на кожне повідомлення. + За замовчуванням ваш агент відповідає в каналах гільдії лише тоді, коли його згадано через @mention. Для приватного сервера, ймовірно, ви захочете, щоб він відповідав на кожне повідомлення. > "Дозволь моєму агенту відповідати на цьому сервері без @mention" - - Установіть `requireMention: false` у конфігурації сервера: + + Задайте `requireMention: false` у конфігурації гільдії: ```json5 { @@ -251,58 +251,58 @@ openclaw pairing approve discord - - За замовчуванням довготривала пам’ять (`MEMORY.md`) завантажується лише в сесіях DM. У каналах сервера `MEMORY.md` автоматично не завантажується. + + За замовчуванням довготривала пам’ять (`MEMORY.md`) завантажується лише в сесіях приватних повідомлень. У каналах гільдії `MEMORY.md` автоматично не завантажується. > "Коли я ставлю запитання в каналах Discord, використовуй memory_search або memory_get, якщо тобі потрібен довготривалий контекст із MEMORY.md." - Якщо вам потрібен спільний контекст у кожному каналі, помістіть сталі інструкції в `AGENTS.md` або `USER.md` (вони впроваджуються в кожну сесію). Довготривалі нотатки зберігайте в `MEMORY.md` і звертайтеся до них за потреби через інструменти пам’яті. + Якщо вам потрібен спільний контекст у кожному каналі, розмістіть стабільні інструкції в `AGENTS.md` або `USER.md` (вони впроваджуються для кожної сесії). Довготривалі нотатки зберігайте в `MEMORY.md` і звертайтеся до них за потреби через інструменти пам’яті. -Тепер створіть кілька каналів на своєму сервері Discord і починайте спілкування. Ваш агент може бачити назву каналу, і кожен канал отримує власну ізольовану сесію — тож ви можете налаштувати `#coding`, `#home`, `#research` або будь-що, що відповідає вашому робочому процесу. +Тепер створіть кілька каналів на своєму Discord-сервері й почніть спілкування. Ваш агент може бачити назву каналу, і кожен канал отримує власну ізольовану сесію — тож ви можете налаштувати `#coding`, `#home`, `#research` або будь-що, що відповідає вашому робочому процесу. ## Модель runtime -- Gateway керує підключенням Discord. -- Маршрутизація відповідей детермінована: вхідні повідомлення Discord повертаються назад у Discord. +- Gateway керує з’єднанням Discord. +- Маршрутизація відповідей детермінована: вхідні повідомлення Discord повертаються в Discord. - За замовчуванням (`session.dmScope=main`) прямі чати використовують спільну основну сесію агента (`agent:main:main`). -- Канали сервера мають ізольовані ключі сесій (`agent::discord:channel:`). -- Групові DMs ігноруються за замовчуванням (`channels.discord.dm.groupEnabled=false`). -- Нативні слеш-команди виконуються в ізольованих сесіях команд (`agent::discord:slash:`), водночас передаючи `CommandTargetSessionKey` до маршрутизованої сесії розмови. +- Канали гільдії мають ізольовані ключі сесій (`agent::discord:channel:`). +- Групові приватні повідомлення за замовчуванням ігноруються (`channels.discord.dm.groupEnabled=false`). +- Нативні slash-команди виконуються в ізольованих командних сесіях (`agent::discord:slash:`), водночас зберігаючи `CommandTargetSessionKey` для маршрутизованої сесії розмови. ## Форумні канали -Форумні та медіаканали Discord приймають лише публікації в гілках. OpenClaw підтримує два способи їх створення: +Форумні та медіаканали Discord приймають лише публікації в обговореннях. OpenClaw підтримує два способи їх створення: -- Надішліть повідомлення до батьківського форуму (`channel:`), щоб автоматично створити гілку. Заголовок гілки бере перший непорожній рядок вашого повідомлення. -- Використайте `openclaw message thread create`, щоб створити гілку безпосередньо. Не передавайте `--message-id` для форумних каналів. +- Надішліть повідомлення батьківському форуму (`channel:`), щоб автоматично створити обговорення. Заголовок обговорення використовує перший непорожній рядок вашого повідомлення. +- Використайте `openclaw message thread create`, щоб створити обговорення напряму. Не передавайте `--message-id` для форумних каналів. -Приклад: надсилання до батьківського форуму для створення гілки +Приклад: надсилання в батьківський форум для створення обговорення ```bash openclaw message send --channel discord --target channel: \ --message "Topic title\nBody of the post" ``` -Приклад: явне створення форумної гілки +Приклад: явне створення форумного обговорення ```bash openclaw message thread create --channel discord --target channel: \ --thread-name "Topic title" --message "Body of the post" ``` -Батьківські форуми не приймають компоненти Discord. Якщо вам потрібні компоненти, надсилайте в саму гілку (`channel:`). +Батьківські форуми не приймають компоненти Discord. Якщо вам потрібні компоненти, надсилайте в саме обговорення (`channel:`). ## Інтерактивні компоненти -OpenClaw підтримує контейнери компонентів Discord v2 для повідомлень агента. Використовуйте інструмент повідомлень із корисним навантаженням `components`. Результати взаємодії повертаються агенту як звичайні вхідні повідомлення та дотримуються наявних налаштувань Discord `replyToMode`. +OpenClaw підтримує контейнери компонентів Discord v2 для повідомлень агента. Використовуйте інструмент повідомлень із корисним навантаженням `components`. Результати взаємодії маршрутизуються назад до агента як звичайні вхідні повідомлення й дотримуються наявних налаштувань Discord `replyToMode`. Підтримувані блоки: @@ -310,21 +310,21 @@ OpenClaw підтримує контейнери компонентів Discord - Рядки дій дозволяють до 5 кнопок або одне меню вибору - Типи вибору: `string`, `user`, `role`, `mentionable`, `channel` -За замовчуванням компоненти одноразові. Установіть `components.reusable=true`, щоб дозволити багаторазове використання кнопок, виборів і форм до завершення строку їх дії. +За замовчуванням компоненти одноразові. Установіть `components.reusable=true`, щоб дозволити багаторазове використання кнопок, списків вибору та форм, доки не спливе їхній термін дії. -Щоб обмежити, хто може натискати кнопку, установіть `allowedUsers` для цієї кнопки (Discord user IDs, теги або `*`). Якщо це налаштовано, користувачі без збігу отримають епізодичну відмову. +Щоб обмежити, хто може натискати кнопку, установіть `allowedUsers` для цієї кнопки (ID користувачів Discord, теги або `*`). Якщо налаштовано, користувачі, які не збігаються, отримають ефемерну відмову. -Слеш-команди `/model` і `/models` відкривають інтерактивний вибір моделі з випадними списками провайдера й моделі та кроком Submit. Якщо не встановлено `commands.modelsWrite=false`, `/models add` також підтримує додавання нового запису провайдера/моделі з чату, а нові моделі з’являються без перезапуску шлюзу. Відповідь вибору є епізодичною, і скористатися нею може лише користувач, який викликав команду. +Slash-команди `/model` і `/models` відкривають інтерактивний вибір моделі з випадними списками провайдера й моделі та кроком Submit. Якщо не задано `commands.modelsWrite=false`, `/models add` також підтримує додавання нового запису провайдера/моделі з чату, а нові додані моделі з’являються без перезапуску gateway. Відповідь вибору є ефемерною, і використовувати її може лише користувач, який викликав команду. Вкладення файлів: - Блоки `file` мають вказувати на посилання вкладення (`attachment://`) -- Надайте вкладення через `media`/`path`/`filePath` (один файл); для кількох файлів використовуйте `media-gallery` -- Використовуйте `filename`, щоб перевизначити назву завантаження, коли вона має відповідати посиланню вкладення +- Надайте вкладення через `media`/`path`/`filePath` (один файл); використовуйте `media-gallery` для кількох файлів +- Використовуйте `filename`, щоб перевизначити ім’я завантаження, коли воно має збігатися з посиланням вкладення Модальні форми: -- Додайте `components.modal` із до 5 полів +- Додайте `components.modal` із до 5 полями - Типи полів: `text`, `checkbox`, `radio`, `select`, `role-select`, `user-select` - OpenClaw автоматично додає кнопку запуску @@ -385,15 +385,15 @@ OpenClaw підтримує контейнери компонентів Discord ## Керування доступом і маршрутизація - - `channels.discord.dmPolicy` керує доступом до DM (застаріле: `channels.discord.dm.policy`): + + `channels.discord.dmPolicy` керує доступом до приватних повідомлень (застаріле: `channels.discord.dm.policy`): - `pairing` (за замовчуванням) - `allowlist` - - `open` (потребує, щоб `channels.discord.allowFrom` містив `"*"`; застаріле: `channels.discord.dm.allowFrom`) + - `open` (потрібно, щоб `channels.discord.allowFrom` містив `"*"`; застаріле: `channels.discord.dm.allowFrom`) - `disabled` - Якщо політика DM не є open, невідомі користувачі блокуються (або отримують запит на сполучення в режимі `pairing`). + Якщо політика приватних повідомлень не відкрита, невідомі користувачі блокуються (або отримують запит на підключення в режимі `pairing`). Пріоритет для кількох облікових записів: @@ -401,32 +401,32 @@ OpenClaw підтримує контейнери компонентів Discord - Іменовані облікові записи успадковують `channels.discord.allowFrom`, якщо їхній власний `allowFrom` не задано. - Іменовані облікові записи не успадковують `channels.discord.accounts.default.allowFrom`. - Формат цілі DM для доставки: + Формат цілі приватного повідомлення для доставки: - `user:` - згадка `<@id>` - Числові ID без префікса є неоднозначними й відхиляються, якщо явно не вказано тип цілі user/channel. + Числові ID без префікса є неоднозначними та відхиляються, якщо явно не вказано тип цілі користувача/каналу. - - Обробка серверів керується через `channels.discord.groupPolicy`: + + Обробка гільдій керується через `channels.discord.groupPolicy`: - `open` - `allowlist` - `disabled` - Безпечне базове значення, коли існує `channels.discord`, — `allowlist`. + Безпечна базова поведінка, коли існує `channels.discord`, — `allowlist`. Поведінка `allowlist`: - - сервер має відповідати `channels.discord.guilds` (переважно `id`, також приймається slug) - - необов’язкові списки дозволених відправників: `users` (рекомендовано сталі ID) і `roles` (лише ID ролей); якщо налаштовано будь-який із них, відправники дозволяються, коли вони відповідають `users` АБО `roles` - - пряме зіставлення за ім’ям/тегом за замовчуванням вимкнене; вмикайте `channels.discord.dangerouslyAllowNameMatching: true` лише як аварійний режим сумісності - - імена/теги підтримуються для `users`, але ID безпечніші; `openclaw security audit` попереджає, коли використовуються записи імен/тегів - - якщо для сервера налаштовано `channels`, канали поза списком відхиляються - - якщо сервер не має блоку `channels`, дозволяються всі канали в цьому сервері зі списку дозволених + - гільдія має збігатися з `channels.discord.guilds` (переважно `id`, також приймається slug) + - необов’язкові списки дозволених відправників: `users` (рекомендовано стабільні ID) і `roles` (лише ID ролей); якщо налаштовано будь-який із них, відправники дозволяються, коли вони збігаються з `users` АБО `roles` + - пряме зіставлення за іменем/тегом за замовчуванням вимкнене; увімкніть `channels.discord.dangerouslyAllowNameMatching: true` лише як аварійний режим сумісності + - імена/теги підтримуються для `users`, але ID безпечніші; `openclaw security audit` попереджає, коли використовуються записи з іменами/тегами + - якщо для гільдії налаштовано `channels`, канали, яких немає в списку, забороняються + - якщо для гільдії немає блоку `channels`, дозволяються всі канали в цій гільдії зі списку дозволених Приклад: @@ -452,23 +452,23 @@ OpenClaw підтримує контейнери компонентів Discord } ``` - Якщо ви лише задаєте `DISCORD_BOT_TOKEN` і не створюєте блок `channels.discord`, резервне значення runtime буде `groupPolicy="allowlist"` (із попередженням у логах), навіть якщо `channels.defaults.groupPolicy` дорівнює `open`. + Якщо ви лише задали `DISCORD_BOT_TOKEN` і не створили блок `channels.discord`, резервна поведінка runtime — `groupPolicy="allowlist"` (із попередженням у логах), навіть якщо `channels.defaults.groupPolicy` має значення `open`. - - Повідомлення сервера за замовчуванням обмежуються згадками. + + Повідомлення в гільдіях за замовчуванням вимагають згадки. - Визначення згадок включає: + Виявлення згадки включає: - явну згадку бота - - налаштовані шаблони згадок (`agents.list[].groupChat.mentionPatterns`, резервне значення `messages.groupChat.mentionPatterns`) - - неявну поведінку reply-to-bot у підтримуваних випадках + - налаштовані шаблони згадок (`agents.list[].groupChat.mentionPatterns`, резервно `messages.groupChat.mentionPatterns`) + - неявну поведінку відповіді боту в підтримуваних випадках - `requireMention` налаштовується для кожного сервера/каналу (`channels.discord.guilds...`). - `ignoreOtherMentions` за потреби відкидає повідомлення, які згадують іншого користувача/роль, але не бота (крім @everyone/@here). + `requireMention` налаштовується для кожної гільдії/каналу окремо (`channels.discord.guilds...`). + `ignoreOtherMentions` за бажанням відкидає повідомлення, які згадують іншого користувача/роль, але не бота (за винятком @everyone/@here). - Групові DMs: + Групові приватні повідомлення: - за замовчуванням: ігноруються (`dm.groupEnabled=false`) - необов’язковий список дозволених через `dm.groupChannels` (ID каналів або slug) @@ -478,7 +478,7 @@ OpenClaw підтримує контейнери компонентів Discord ### Маршрутизація агентів на основі ролей -Використовуйте `bindings[].match.roles`, щоб маршрутизувати учасників серверів Discord до різних агентів за ID ролі. Прив’язки на основі ролей приймають лише ID ролей і обчислюються після прив’язок peer або parent-peer та перед прив’язками лише на рівні сервера. Якщо прив’язка також задає інші поля відповідності (наприклад, `peer` + `guildId` + `roles`), усі налаштовані поля мають збігатися. +Використовуйте `bindings[].match.roles`, щоб маршрутизувати учасників гільдії Discord до різних агентів за ID ролі. Прив’язки на основі ролей приймають лише ID ролей і обчислюються після прив’язок peer або parent-peer та перед прив’язками лише на рівні гільдії. Якщо прив’язка також задає інші поля зіставлення (наприклад, `peer` + `guildId` + `roles`), усі налаштовані поля мають збігатися. ```json5 { @@ -513,13 +513,13 @@ OpenClaw підтримує контейнери компонентів Discord - + У **Bot -> Privileged Gateway Intents** увімкніть: - Message Content Intent - Server Members Intent (рекомендовано) - Presence intent є необов’язковим і потрібне лише якщо ви хочете отримувати оновлення статусу присутності. Установлення статусу присутності бота (`setPresence`) не потребує ввімкнення оновлень присутності для учасників. + Presence intent є необов’язковим і потрібен лише якщо ви хочете отримувати оновлення присутності. Налаштування присутності бота (`setPresence`) не потребує ввімкнення оновлень присутності для учасників. @@ -539,7 +539,7 @@ OpenClaw підтримує контейнери компонентів Discord - Attach Files - Add Reactions (необов’язково) - Це базовий набір для звичайних текстових каналів. Якщо ви плануєте публікувати в гілках Discord, зокрема у процесах форумних або медіаканалів, які створюють або продовжують гілку, також увімкніть **Send Messages in Threads**. + Це базовий набір для звичайних текстових каналів. Якщо ви плануєте публікувати в обговореннях Discord, зокрема у сценаріях форумних або медіаканалів, що створюють або продовжують обговорення, також увімкніть **Send Messages in Threads**. Уникайте `Administrator`, якщо він не потрібен явно. @@ -556,21 +556,21 @@ OpenClaw підтримує контейнери компонентів Discord -## Нативні команди й авторизація команд +## Нативні команди та авторизація команд -- `commands.native` за замовчуванням має значення `"auto"` і ввімкнене для Discord. -- Перевизначення для каналу: `channels.discord.commands.native`. +- `commands.native` за замовчуванням має значення `"auto"` і ввімкнено для Discord. +- Перевизначення для окремого каналу: `channels.discord.commands.native`. - `commands.native=false` явно очищає раніше зареєстровані нативні команди Discord. - Авторизація нативних команд використовує ті самі списки дозволених і політики Discord, що й звичайна обробка повідомлень. -- Команди все ще можуть бути видимими в інтерфейсі Discord для користувачів, які не мають авторизації; виконання все одно застосовує авторизацію OpenClaw і повертає "not authorized". +- Команди все одно можуть бути видимими в інтерфейсі Discord для користувачів без авторизації; виконання все одно застосовує авторизацію OpenClaw і повертає "not authorized". -Див. [Slash commands](/uk/tools/slash-commands) для каталогу команд і поведінки. +Див. [Slash-команди](/uk/tools/slash-commands) для каталогу команд і поведінки. -Стандартні налаштування слеш-команд: +Налаштування slash-команд за замовчуванням: - `ephemeral: true` -## Деталі функцій +## Деталі можливостей @@ -579,49 +579,28 @@ OpenClaw підтримує контейнери компонентів Discord - `[[reply_to_current]]` - `[[reply_to:]]` - Керується через `channels.discord.replyToMode`: + Це керується через `channels.discord.replyToMode`: - `off` (за замовчуванням) - `first` - `all` - `batched` - Примітка: `off` вимикає неявне гілкування відповідей. Явні теги `[[reply_to_*]]` усе одно враховуються. - `first` завжди прикріплює неявне посилання нативної відповіді до першого вихідного повідомлення Discord у межах ходу. - `batched` прикріплює неявне посилання нативної відповіді Discord лише тоді, коли - вхідний хід був пакетною вибіркою кількох повідомлень із дебаунсом. Це корисно, - коли нативні відповіді потрібні переважно для неоднозначних чатів зі сплесками, а не для кожного - окремого ходу з одним повідомленням. + Примітка: `off` вимикає неявне вкладення відповідей. Явні теги `[[reply_to_*]]` усе одно враховуються. + `first` завжди додає неявне посилання нативної відповіді до першого вихідного повідомлення Discord за цей хід. + `batched` додає неявне посилання нативної відповіді Discord лише тоді, коли + вхідний хід був відкладеним пакетом із кількох повідомлень. Це корисно, + коли вам потрібні нативні відповіді переважно для неоднозначних чатів із + серією повідомлень, а не для кожного окремого повідомлення. - ID повідомлень відображаються в контексті/історії, тому агенти можуть націлюватися на конкретні повідомлення. + ID повідомлень відображаються в контексті/історії, щоб агенти могли націлюватися на конкретні повідомлення. - - OpenClaw може потоково передавати чернетки відповідей, надсилаючи тимчасове повідомлення та редагуючи його в міру надходження тексту. + + OpenClaw може передавати чернетки відповідей потоком, надсилаючи тимчасове повідомлення та редагуючи його в міру надходження тексту. `channels.discord.streaming` приймає `off` (за замовчуванням) | `partial` | `block` | `progress`. `progress` у Discord відповідає `partial`; `streamMode` є застарілим псевдонімом і автоматично мігрується. - - `channels.discord.streaming` керує потоковим попереднім переглядом (`off` | `partial` | `block` | `progress`, за замовчуванням: `off`). - - Стандартним значенням залишається `off`, тому що редагування попереднього перегляду в Discord може швидко досягати обмежень швидкості, особливо коли кілька ботів або шлюзів використовують один обліковий запис чи трафік сервера. - - `progress` приймається для узгодженості між каналами й у Discord відображається як `partial`. - - `channels.discord.streamMode` є застарілим псевдонімом і мігрує автоматично. - - `partial` редагує одне повідомлення попереднього перегляду в міру надходження токенів. - - `block` надсилає фрагменти розміру чернетки (використовуйте `draftChunk`, щоб налаштувати розмір і точки розбиття). - - Остаточні повідомлення з медіа, помилками та явними відповідями скасовують відкладені редагування попереднього перегляду без виведення тимчасової чернетки перед звичайною доставкою. - - `streaming.preview.toolProgress` керує тим, чи оновлення інструментів/прогресу використовують те саме чернеткове повідомлення попереднього перегляду (за замовчуванням: `true`). Установіть `false`, щоб зберігати окремі повідомлення інструментів/прогресу. - - Приклад: - -```json5 -{ - channels: { - discord: { - streaming: "partial", - }, - }, -} -``` - - Стандартні параметри фрагментації в режимі `block` (обмежуються до `channels.discord.textChunkLimit`): + Значенням за замовчуванням лишається `off`, оскільки редагування попереднього перегляду в Discord швидко впирається в обмеження частоти, коли кілька ботів або gateway спільно використовують один обліковий запис. ```json5 { @@ -638,50 +617,47 @@ OpenClaw підтримує контейнери компонентів Discord } ``` - Потоковий попередній перегляд працює лише для тексту; відповіді з медіа повертаються до звичайної доставки. + - `partial` редагує одне повідомлення попереднього перегляду в міру надходження токенів. + - `block` виводить фрагменти розміру чернетки (використовуйте `draftChunk` для налаштування розміру й точок розриву, обмежених `textChunkLimit`). + - Фінальні повідомлення з медіа, помилками та явними відповідями скасовують незавершені редагування попереднього перегляду. + - `streaming.preview.toolProgress` (за замовчуванням `true`) керує тим, чи повторно використовують оновлення інструментів/прогресу повідомлення попереднього перегляду. - Примітка: потоковий попередній перегляд відокремлений від блокового потоку. Коли для Discord явно - ввімкнено блоковий потік, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного потокового передавання. + Потоковий попередній перегляд підтримує лише текст; відповіді з медіа повертаються до звичайної доставки. Коли `block` streaming явно ввімкнено, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного потокового виводу. - - Контекст історії сервера: + + Контекст історії гільдії: - - `channels.discord.historyLimit` стандартно `20` - - резервне значення: `messages.groupChat.historyLimit` + - `channels.discord.historyLimit` за замовчуванням `20` + - резервно: `messages.groupChat.historyLimit` - `0` вимикає - Керування історією DM: + Керування історією приватних повідомлень: - `channels.discord.dmHistoryLimit` - `channels.discord.dms[""].historyLimit` - Поведінка гілок: + Поведінка обговорень: - - Гілки Discord маршрутизуються як сесії каналів - - метадані батьківської гілки можуть використовуватися для прив’язки до батьківської сесії - - конфігурація гілки успадковує конфігурацію батьківського каналу, якщо немає окремого запису для гілки - - успадкування транскрипту батьківського каналу в новостворені автоматичні гілки вмикається через `channels.discord.thread.inheritParent` (за замовчуванням `false`). Коли `false`, новостворені сесії гілок Discord починаються ізольовано від транскрипту батьківського каналу; коли `true`, історія батьківського каналу ініціалізує нову сесію гілки - - перевизначення для кожного облікового запису розміщені в `channels.discord.accounts..thread.inheritParent` - - реакції інструмента повідомлень можуть визначати цілі DM `user:` на додачу до цілей каналів - - `channels.discord.guilds..channels..requireMention: false` зберігається під час резервної активації на етапі reply, тож канали, налаштовані як always-on, залишаються always-on навіть коли виконується резервний механізм на етапі reply + - Обговорення Discord маршрутизуються як сесії каналів і успадковують конфігурацію батьківського каналу, якщо не перевизначено. + - `channels.discord.thread.inheritParent` (за замовчуванням `false`) вмикає для нових автообговорень початкове заповнення з батьківського транскрипту. Перевизначення для окремих облікових записів розміщуються в `channels.discord.accounts..thread.inheritParent`. + - Реакції інструмента повідомлень можуть визначати цілі приватних повідомлень `user:`. + - `guilds..channels..requireMention: false` зберігається під час резервної активації на етапі відповіді. - Теми каналів впроваджуються як **ненадійний** контекст (а не як system prompt). - Контекст відповіді та цитованих повідомлень наразі залишається таким, як отримано. - Списки дозволених Discord насамперед обмежують, хто може активувати агента, а не є повною межею редагування додаткового контексту. + Теми каналів упроваджуються як **ненадійний** контекст. Списки дозволених обмежують, хто може запускати агента, але не є повною межею редагування додаткового контексту. - - Discord може прив’язати гілку до цілі сесії, щоб подальші повідомлення в цій гілці й надалі маршрутизувалися до тієї самої сесії (зокрема до сесій субагентів). + + Discord може прив’язати обговорення до цілі сесії, щоб подальші повідомлення в цьому обговоренні продовжували маршрутизуватися до тієї самої сесії (включно із сесіями субагентів). Команди: - - `/focus ` прив’язати поточну/нову гілку до цілі субагента/сесії - - `/unfocus` видалити поточну прив’язку гілки - - `/agents` показати активні запуски та стан прив’язки - - `/session idle ` переглянути/оновити автозняття фокуса через неактивність для сфокусованих прив’язок + - `/focus ` прив’язати поточне/нове обговорення до цілі субагента/сесії + - `/unfocus` видалити поточну прив’язку обговорення + - `/agents` показати активні запуски й стан прив’язки + - `/session idle ` переглянути/оновити автоматичне скасування фокуса через неактивність для сфокусованих прив’язок - `/session max-age ` переглянути/оновити жорсткий максимальний вік для сфокусованих прив’язок Конфігурація: @@ -712,16 +688,16 @@ OpenClaw підтримує контейнери компонентів Discord - `session.threadBindings.*` задає глобальні значення за замовчуванням. - `channels.discord.threadBindings.*` перевизначає поведінку Discord. - - `spawnSubagentSessions` має бути true, щоб автоматично створювати/прив’язувати гілки для `sessions_spawn({ thread: true })`. - - `spawnAcpSessions` має бути true, щоб автоматично створювати/прив’язувати гілки для ACP (`/acp spawn ... --thread ...` або `sessions_spawn({ runtime: "acp", thread: true })`). - - Якщо прив’язки гілок вимкнені для облікового запису, `/focus` і пов’язані операції прив’язки гілок недоступні. + - `spawnSubagentSessions` має бути `true`, щоб автоматично створювати/прив’язувати обговорення для `sessions_spawn({ thread: true })`. + - `spawnAcpSessions` має бути `true`, щоб автоматично створювати/прив’язувати обговорення для ACP (`/acp spawn ... --thread ...` або `sessions_spawn({ runtime: "acp", thread: true })`). + - Якщо прив’язки обговорень вимкнено для облікового запису, `/focus` та пов’язані операції прив’язки обговорень недоступні. - Див. [Sub-agents](/uk/tools/subagents), [ACP Agents](/uk/tools/acp-agents) і [Configuration Reference](/uk/gateway/configuration-reference). + Див. [Субагенти](/uk/tools/subagents), [ACP Agents](/uk/tools/acp-agents) і [Довідник із конфігурації](/uk/gateway/configuration-reference). - - Для стабільних ACP робочих просторів у режимі "always-on" налаштуйте типізовані ACP-прив’язки верхнього рівня, націлені на розмови Discord. + + Для стабільних «завжди активних» робочих просторів ACP налаштуйте типізовані ACP-прив’язки верхнього рівня, націлені на розмови Discord. Шлях конфігурації: @@ -777,20 +753,16 @@ OpenClaw підтримує контейнери компонентів Discord Примітки: - - `/acp spawn codex --bind here` прив’язує поточний канал або гілку Discord на місці та зберігає маршрутизацію майбутніх повідомлень до тієї самої ACP-сесії. - - Це все ще може означати "запустити нову ACP-сесію Codex", але саме по собі не створює нову гілку Discord. Наявний канал залишається поверхнею чату. - - Codex усе ще може працювати у власному `cwd` або робочому просторі бекенда на диску. Цей робочий простір є станом runtime, а не гілкою Discord. - - Повідомлення гілок можуть успадковувати ACP-прив’язку батьківського каналу. - - У прив’язаному каналі або гілці `/new` і `/reset` скидають ту саму ACP-сесію на місці. - - Тимчасові прив’язки гілок також працюють і можуть перевизначати визначення цілі, поки вони активні. - - `spawnAcpSessions` потрібен лише тоді, коли OpenClaw має створити/прив’язати дочірню гілку через `--thread auto|here`. Він не потрібен для `/acp spawn ... --bind here` у поточному каналі. + - `/acp spawn codex --bind here` прив’язує поточний канал або обговорення на місці й зберігає майбутні повідомлення в тій самій сесії ACP. Повідомлення в обговореннях успадковують прив’язку батьківського каналу. + - У прив’язаному каналі або обговоренні `/new` і `/reset` скидають ту саму сесію ACP на місці. Тимчасові прив’язки обговорень можуть перевизначати визначення цілі, поки вони активні. + - `spawnAcpSessions` потрібен лише тоді, коли OpenClaw має створити/прив’язати дочірнє обговорення через `--thread auto|here`. - Див. [ACP Agents](/uk/tools/acp-agents), щоб дізнатися подробиці поведінки прив’язок. + Див. [ACP Agents](/uk/tools/acp-agents) для подробиць про поведінку прив’язок. - Режим сповіщень про реакції для кожного сервера: + Режим сповіщень про реакції для кожної гільдії: - `off` - `own` (за замовчуванням) @@ -809,19 +781,19 @@ OpenClaw підтримує контейнери компонентів Discord - `channels.discord.accounts..ackReaction` - `channels.discord.ackReaction` - `messages.ackReaction` - - резервне значення емодзі ідентичності агента (`agents.list[].identity.emoji`, інакше "👀") + - резервне емодзі ідентичності агента (`agents.list[].identity.emoji`, інакше "👀") Примітки: - - Discord приймає emoji Unicode або назви користувацьких emoji. + - Discord приймає Unicode-емодзі або назви користувацьких емодзі. - Використовуйте `""`, щоб вимкнути реакцію для каналу або облікового запису. - - Записи конфігурації, ініційовані з каналу, ввімкнені за замовчуванням. + + Записи конфігурації, ініційовані каналом, за замовчуванням увімкнені. - Це впливає на потоки `/config set|unset` (коли функції команд увімкнені). + Це впливає на сценарії `/config set|unset` (коли ввімкнено функції команд). Вимкнення: @@ -837,8 +809,8 @@ OpenClaw підтримує контейнери компонентів Discord - - Маршрутизуйте трафік WebSocket шлюзу Discord і стартові REST-запити (ID застосунку + визначення списку дозволених) через HTTP(S)-проксі за допомогою `channels.discord.proxy`. + + Маршрутизуйте трафік WebSocket gateway Discord і початкові REST-запити (ID застосунку + визначення списку дозволених) через HTTP(S)-проксі за допомогою `channels.discord.proxy`. ```json5 { @@ -887,14 +859,14 @@ OpenClaw підтримує контейнери компонентів Discord Примітки: - списки дозволених можуть використовувати `pk:` - - відображувані імена учасників зіставляються за іменем/slug лише коли `channels.discord.dangerouslyAllowNameMatching: true` - - пошук використовує ID початкового повідомлення й обмежується часовим вікном + - відображувані імена учасників зіставляються за назвою/slug лише коли `channels.discord.dangerouslyAllowNameMatching: true` + - пошук використовує оригінальний ID повідомлення й обмежується часовим вікном - якщо пошук не вдається, проксійовані повідомлення вважаються повідомленнями бота й відкидаються, якщо не задано `allowBots=true` - - Оновлення статусу присутності застосовуються, коли ви задаєте поле status або activity, або коли вмикаєте автоматичний статус присутності. + + Оновлення статусу присутності застосовуються, коли ви задаєте поле статусу або активності, або коли вмикаєте автоматичний статус присутності. Приклад лише зі статусом: @@ -908,7 +880,7 @@ OpenClaw підтримує контейнери компонентів Discord } ``` - Приклад активності (користувацький статус — це стандартний тип активності): + Приклад активності (користувацький статус — тип активності за замовчуванням): ```json5 { @@ -938,13 +910,13 @@ OpenClaw підтримує контейнери компонентів Discord Відповідність типів активності: - 0: Playing - - 1: Streaming (потребує `activityUrl`) + - 1: Streaming (потрібен `activityUrl`) - 2: Listening - 3: Watching - - 4: Custom (використовує текст активності як стан статусу; emoji необов’язковий) + - 4: Custom (використовує текст активності як стан статусу; емодзі необов’язкове) - 5: Competing - Приклад автоматичного статусу присутності (сигнал здоров’я runtime): + Приклад автоматичного статусу присутності (сигнал стану runtime): ```json5 { @@ -970,54 +942,38 @@ OpenClaw підтримує контейнери компонентів Discord - Discord підтримує обробку погоджень через кнопки в DMs і може за потреби публікувати запити на погодження у вихідному каналі. + Discord підтримує обробку погоджень за допомогою кнопок у приватних повідомленнях і може за потреби публікувати запити на погодження в каналі, де вони виникли. Шлях конфігурації: - `channels.discord.execApprovals.enabled` - - `channels.discord.execApprovals.approvers` (необов’язково; за можливості використовує резервне значення `commands.ownerAllowFrom`) + - `channels.discord.execApprovals.approvers` (необов’язково; за можливості використовується резервно `commands.ownerAllowFrom`) - `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, за замовчуванням: `dm`) - `agentFilter`, `sessionFilter`, `cleanupAfterResolve` - Discord автоматично вмикає нативні exec-погодження, коли `enabled` не задано або дорівнює `"auto"` і можна визначити принаймні одного погоджувача, або з `execApprovals.approvers`, або з `commands.ownerAllowFrom`. Discord не визначає exec-погоджувачів із channel `allowFrom`, застарілого `dm.allowFrom` або `defaultTo` для прямих повідомлень. Установіть `enabled: false`, щоб явно вимкнути Discord як нативний клієнт погоджень. + Discord автоматично вмикає нативні exec-погодження, коли `enabled` не задано або має значення `"auto"` і можна визначити принаймні одного погоджувача — або з `execApprovals.approvers`, або з `commands.ownerAllowFrom`. Discord не визначає exec-погоджувачів із `allowFrom` каналу, застарілого `dm.allowFrom` або `defaultTo` для прямих повідомлень. Задайте `enabled: false`, щоб явно вимкнути Discord як нативний клієнт погодження. - Коли `target` має значення `channel` або `both`, запит на погодження видно в каналі. Лише визначені погоджувачі можуть використовувати кнопки; інші користувачі отримують епізодичну відмову. Запити на погодження включають текст команди, тому вмикайте доставку в канал лише в довірених каналах. Якщо ID каналу неможливо вивести з ключа сесії, OpenClaw повертається до доставки через DM. + Коли `target` має значення `channel` або `both`, запит на погодження видимий у каналі. Лише визначені погоджувачі можуть використовувати кнопки; інші користувачі отримують ефемерну відмову. Запити на погодження містять текст команди, тому вмикайте доставку в канал лише в довірених каналах. Якщо ID каналу неможливо визначити з ключа сесії, OpenClaw повертається до доставки через приватні повідомлення. - Discord також відображає спільні кнопки погодження, які використовуються іншими чат-каналами. Нативний адаптер Discord головним чином додає маршрутизацію DM погоджувачів і fanout у каналі. + Discord також відображає спільні кнопки погодження, які використовуються іншими чат-каналами. Нативний адаптер Discord головним чином додає маршрутизацію приватних повідомлень погоджувачам і розсилання в канал. Коли ці кнопки присутні, вони є основним UX погодження; OpenClaw має включати ручну команду `/approve` лише тоді, коли результат інструмента вказує, - що погодження в чаті недоступні або ручне погодження — єдиний шлях. + що погодження через чат недоступні або ручне погодження — єдиний шлях. - Автентифікація Gateway для цього обробника використовує той самий спільний контракт визначення облікових даних, що й інші клієнти Gateway: + Авторизація gateway і визначення погоджень дотримуються спільного клієнтського контракту Gateway (`plugin:` ID визначаються через `plugin.approval.resolve`; інші ID — через `exec.approval.resolve`). Термін дії погоджень за замовчуванням спливає через 30 хвилин. - - локальна автентифікація з пріоритетом env (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`, потім `gateway.auth.*`) - - у локальному режимі `gateway.remote.*` може використовуватися як резервне значення лише коли `gateway.auth.*` не задано; налаштовані, але не визначені локальні SecretRef закриваються без резервного варіанта - - підтримка віддаленого режиму через `gateway.remote.*`, коли це застосовно - - перевизначення URL безпечні щодо перевизначень: перевизначення CLI не повторно використовують неявні облікові дані, а перевизначення env використовують лише облікові дані env - - Поведінка визначення погоджень: - - - ID з префіксом `plugin:` визначаються через `plugin.approval.resolve`. - - Інші ID визначаються через `exec.approval.resolve`. - - Discord тут не робить додаткового резервного переходу exec-to-plugin; префікс - id визначає, який метод шлюзу він викликає. - - Термін дії exec-погоджень за замовчуванням спливає через 30 хвилин. Якщо погодження завершуються помилкою з - невідомими ID погоджень, перевірте визначення погоджувачів, увімкнення функції та - те, що тип доставленого ID погодження відповідає очікуваному запиту. - - Пов’язана документація: [Exec approvals](/uk/tools/exec-approvals) + Див. [Exec approvals](/uk/tools/exec-approvals). -## Інструменти й обмеження дій +## Інструменти та обмеження дій -Дії з повідомленнями Discord включають обмін повідомленнями, адміністрування каналу, модерацію, статус присутності та дії з метаданими. +Дії повідомлень Discord включають обмін повідомленнями, адміністрування каналів, модерацію, статус присутності та дії з метаданими. Основні приклади: -- обмін повідомленнями: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply` +- повідомлення: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply` - реакції: `react`, `reactions`, `emojiList` - модерація: `timeout`, `kick`, `ban` - статус присутності: `setPresence` @@ -1026,21 +982,21 @@ OpenClaw підтримує контейнери компонентів Discord Обмеження дій розміщені в `channels.discord.actions.*`. -Стандартна поведінка обмежень: +Поведінка обмежень за замовчуванням: -| Група дій | Стандартно | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | -| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | увімкнено | -| roles | вимкнено | -| moderation | вимкнено | -| presence | вимкнено | +| Група дій | За замовчуванням | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | увімкнено | +| roles | вимкнено | +| moderation | вимкнено | +| presence | вимкнено | -## Інтерфейс Components v2 +## UI components v2 -OpenClaw використовує Discord components v2 для exec-погоджень і маркерів між контекстами. Дії з повідомленнями Discord також можуть приймати `components` для користувацького інтерфейсу (розширено; потребує побудови корисного навантаження компонентів через інструмент discord), тоді як застарілі `embeds` і далі доступні, але не рекомендовані. +OpenClaw використовує Discord components v2 для exec-погоджень і міжконтекстних маркерів. Дії повідомлень Discord також можуть приймати `components` для користувацького UI (розширений сценарій; потребує побудови корисного навантаження компонентів через інструмент discord), тоді як застарілі `embeds` усе ще доступні, але не рекомендовані. - `channels.discord.ui.components.accentColor` задає акцентний колір, який використовується контейнерами компонентів Discord (hex). -- Задайте для окремого облікового запису через `channels.discord.accounts..ui.components.accentColor`. +- Задається для окремого облікового запису через `channels.discord.accounts..ui.components.accentColor`. - `embeds` ігноруються, коли присутні components v2. Приклад: @@ -1059,9 +1015,11 @@ OpenClaw використовує Discord components v2 для exec-погодж } ``` -## Голосові канали +## Голос -OpenClaw може приєднуватися до голосових каналів Discord для розмов у реальному часі та безперервного спілкування. Це окрема функція від вкладень голосових повідомлень. +У Discord є дві окремі голосові поверхні: realtime **voice channels** (безперервні розмови) і **voice message attachments** (формат попереднього перегляду хвильової форми). gateway підтримує обидві. + +### Voice channels Вимоги: @@ -1069,7 +1027,7 @@ OpenClaw може приєднуватися до голосових канал - Налаштуйте `channels.discord.voice`. - Бот має мати дозволи Connect + Speak у цільовому голосовому каналі. -Використовуйте нативну команду лише для Discord `/vc join|leave|status`, щоб керувати сесіями. Команда використовує стандартного агента облікового запису та дотримується тих самих правил списку дозволених і групової політики, що й інші команди Discord. +Використовуйте `/vc join|leave|status` для керування сесіями. Команда використовує агента за замовчуванням для облікового запису й дотримується тих самих правил списку дозволених і групової політики, що й інші команди Discord. Приклад автоматичного приєднання: @@ -1100,24 +1058,20 @@ OpenClaw може приєднуватися до голосових канал Примітки: - `voice.tts` перевизначає `messages.tts` лише для голосового відтворення. -- Ходи голосової транскрипції визначають статус власника з `allowFrom` Discord (або `dm.allowFrom`); мовці, які не є власниками, не можуть отримати доступ до інструментів лише для власника (наприклад, `gateway` і `cron`). -- Голос увімкнено за замовчуванням; установіть `channels.discord.voice.enabled=false`, щоб вимкнути його. -- `voice.daveEncryption` і `voice.decryptionFailureTolerance` напряму передаються до параметрів приєднання `@discordjs/voice`. -- Типові значення `@discordjs/voice` — `daveEncryption=true` і `decryptionFailureTolerance=24`, якщо їх не задано. -- OpenClaw також відстежує помилки дешифрування під час отримання й автоматично відновлюється, виходячи з голосового каналу та знову приєднуючись після повторних помилок за короткий проміжок часу. -- Якщо журнали отримання постійно показують `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`, це може бути помилка отримання в upstream `@discordjs/voice`, відстежувана в [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419). +- Ходи голосових транскриптів визначають статус власника з `allowFrom` Discord (або `dm.allowFrom`); мовці, які не є власниками, не можуть отримувати доступ до інструментів лише для власника (наприклад, `gateway` і `cron`). +- Голос увімкнено за замовчуванням; задайте `channels.discord.voice.enabled=false`, щоб вимкнути його. +- `voice.daveEncryption` і `voice.decryptionFailureTolerance` передаються в параметри приєднання `@discordjs/voice`. +- Якщо не задано, значення за замовчуванням для `@discordjs/voice` — `daveEncryption=true` і `decryptionFailureTolerance=24`. +- OpenClaw також відстежує збої розшифрування при отриманні й автоматично відновлюється, виходячи та повторно приєднуючись до голосового каналу після повторних збоїв за короткий проміжок часу. +- Якщо в логах отримання постійно з’являється `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`, це може бути помилка отримання у `@discordjs/voice`, що відстежується в [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419). -## Голосові повідомлення +### Голосові повідомлення -Голосові повідомлення Discord показують попередній перегляд форми хвилі та вимагають аудіо OGG/Opus разом із метаданими. OpenClaw генерує форму хвилі автоматично, але для перевірки та конвертації аудіофайлів на хості Gateway мають бути доступні `ffmpeg` і `ffprobe`. +Голосові повідомлення Discord показують попередній перегляд хвильової форми й потребують аудіо OGG/Opus. OpenClaw автоматично генерує хвильову форму, але на хості gateway потрібні `ffmpeg` і `ffprobe` для перевірки та конвертації. -Вимоги та обмеження: - -- Надайте **локальний шлях до файлу** (URL відхиляються). -- Не додавайте текстовий вміст (Discord не дозволяє текст + голосове повідомлення в одному корисному навантаженні). -- Приймається будь-який аудіоформат; OpenClaw за потреби конвертує його в OGG/Opus. - -Приклад: +- Укажіть **локальний шлях до файлу** (URL відхиляються). +- Не додавайте текстовий вміст (Discord відхиляє текст + голосове повідомлення в одному корисному навантаженні). +- Підтримується будь-який аудіоформат; OpenClaw за потреби конвертує його в OGG/Opus. ```bash message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true) @@ -1126,19 +1080,19 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a ## Усунення проблем - + - увімкніть Message Content Intent - - увімкніть Server Members Intent, якщо ви залежите від визначення користувача/учасника + - увімкніть Server Members Intent, якщо ви залежите від визначення користувачів/учасників - перезапустіть gateway після зміни intents - + - перевірте `groupPolicy` - - перевірте список дозволених серверів у `channels.discord.guilds` - - якщо існує мапа `channels` сервера, дозволяються лише перелічені канали + - перевірте список дозволених гільдій у `channels.discord.guilds` + - якщо існує мапа `channels` гільдії, дозволені лише канали зі списку - перевірте поведінку `requireMention` і шаблони згадок Корисні перевірки: @@ -1154,15 +1108,15 @@ openclaw logs --follow Поширені причини: - - `groupPolicy="allowlist"` без відповідного списку дозволених серверів/каналів - - `requireMention` налаштовано не в тому місці (має бути в `channels.discord.guilds` або записі каналу) - - відправник заблокований списком дозволених `users` сервера/каналу + - `groupPolicy="allowlist"` без відповідного списку дозволених гільдій/каналів + - `requireMention` налаштовано не в тому місці (має бути в `channels.discord.guilds` або в записі каналу) + - відправник заблокований списком дозволених `users` для гільдії/каналу - + - Типові журнали: + Типові логи: - `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE` - `Slow listener detected ...` @@ -1177,9 +1131,9 @@ openclaw logs --follow - один обліковий запис: `channels.discord.inboundWorker.runTimeoutMs` - кілька облікових записів: `channels.discord.accounts..inboundWorker.runTimeoutMs` - - стандартно: `1800000` (30 хвилин); установіть `0`, щоб вимкнути + - за замовчуванням: `1800000` (30 хвилин); задайте `0`, щоб вимкнути - Рекомендоване базове значення: + Рекомендована базова конфігурація: ```json5 { @@ -1200,82 +1154,82 @@ openclaw logs --follow } ``` - Використовуйте `eventQueue.listenerTimeout` для повільного налаштування listener і `inboundWorker.runTimeoutMs` - лише якщо вам потрібен окремий запобіжний механізм для поставлених у чергу ходів агента. + Використовуйте `eventQueue.listenerTimeout` для повільного налаштування listener, а `inboundWorker.runTimeoutMs` + лише якщо вам потрібен окремий запобіжник для агентських ходів у черзі. - + Перевірки дозволів `channels status --probe` працюють лише для числових ID каналів. - Якщо ви використовуєте ключі slug, зіставлення в runtime все одно може працювати, але probe не може повністю перевірити дозволи. + Якщо ви використовуєте ключі slug, зіставлення в runtime все одно може працювати, але probe не зможе повністю перевірити дозволи. - + - - DM вимкнено: `channels.discord.dm.enabled=false` - - політику DM вимкнено: `channels.discord.dmPolicy="disabled"` (застаріле: `channels.discord.dm.policy`) - - очікується підтвердження сполучення в режимі `pairing` + - приватні повідомлення вимкнено: `channels.discord.dm.enabled=false` + - політику приватних повідомлень вимкнено: `channels.discord.dmPolicy="disabled"` (застаріле: `channels.discord.dm.policy`) + - очікується підтвердження підключення в режимі `pairing` За замовчуванням повідомлення, створені ботом, ігноруються. - Якщо ви задали `channels.discord.allowBots=true`, використовуйте суворі правила згадок і списку дозволених, щоб уникнути циклічної поведінки. + Якщо ви задали `channels.discord.allowBots=true`, використовуйте суворі правила згадок і списків дозволених, щоб уникнути циклічної поведінки. Віддавайте перевагу `channels.discord.allowBots="mentions"`, щоб приймати лише повідомлення ботів, які згадують бота. - + - - підтримуйте актуальність OpenClaw (`openclaw update`), щоб була присутня логіка відновлення отримання голосу Discord - - підтвердьте `channels.discord.voice.daveEncryption=true` (стандартно) - - почніть із `channels.discord.voice.decryptionFailureTolerance=24` (стандартне значення upstream) і налаштовуйте лише за потреби - - відстежуйте журнали на наявність: + - підтримуйте актуальність OpenClaw (`openclaw update`), щоб була наявна логіка відновлення прийому голосу Discord + - підтвердьте `channels.discord.voice.daveEncryption=true` (за замовчуванням) + - починайте з `channels.discord.voice.decryptionFailureTolerance=24` (значення upstream за замовчуванням) і налаштовуйте лише за потреби + - відстежуйте логи на наявність: - `discord voice: DAVE decrypt failures detected` - `discord voice: repeated decrypt failures; attempting rejoin` - - якщо збої тривають після автоматичного повторного приєднання, зберіть журнали та порівняйте з [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) + - якщо збої тривають після автоматичного повторного приєднання, зберіть логи й порівняйте з [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) -## Вказівники на довідник конфігурації +## Вказівники на довідник із конфігурації Основний довідник: -- [Configuration reference - Discord](/uk/gateway/configuration-reference#discord) +- [Довідник із конфігурації - Discord](/uk/gateway/configuration-reference#discord) Ключові поля Discord: -- запуск/автентифікація: `enabled`, `token`, `accounts.*`, `allowBots` +- запуск/авторизація: `enabled`, `token`, `accounts.*`, `allowBots` - політика: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*` - команда: `commands.native`, `commands.useAccessGroups`, `configWrites`, `slashCommand.*` - черга подій: `eventQueue.listenerTimeout` (бюджет listener), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency` -- вхідний worker: `inboundWorker.runTimeoutMs` +- inbound worker: `inboundWorker.runTimeoutMs` - відповідь/історія: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` - доставка: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage` -- потоковий режим: `streaming` (застарілий псевдонім: `streamMode`), `streaming.preview.toolProgress`, `draftChunk`, `blockStreaming`, `blockStreamingCoalesce` +- streaming: `streaming` (застарілий псевдонім: `streamMode`), `streaming.preview.toolProgress`, `draftChunk`, `blockStreaming`, `blockStreamingCoalesce` - медіа/повторні спроби: `mediaMaxMb`, `retry` - - `mediaMaxMb` обмежує вихідні завантаження в Discord (стандартно: `100MB`) + - `mediaMaxMb` обмежує вихідні завантаження в Discord (за замовчуванням: `100MB`) - дії: `actions.*` - статус присутності: `activity`, `status`, `activityType`, `activityUrl` - UI: `ui.components.accentColor` -- функції: `threadBindings`, верхньорівневий `bindings[]` (`type: "acp"`), `pluralkit`, `execApprovals`, `intents`, `agentComponents`, `heartbeat`, `responsePrefix` +- можливості: `threadBindings`, верхньорівневий `bindings[]` (`type: "acp"`), `pluralkit`, `execApprovals`, `intents`, `agentComponents`, `heartbeat`, `responsePrefix` -## Безпека та експлуатація +## Безпека та операції -- Вважайте токени бота секретами (`DISCORD_BOT_TOKEN` є бажаним у контрольованих середовищах). -- Надавайте Discord дозволи за принципом найменших привілеїв. +- Ставтеся до токенів ботів як до секретів (`DISCORD_BOT_TOKEN` є бажаним варіантом у керованих середовищах). +- Надавайте Discord лише мінімально необхідні дозволи. - Якщо стан розгортання/стан команд застарів, перезапустіть gateway і повторно перевірте через `openclaw channels status --probe`. ## Пов’язане -- [Pairing](/uk/channels/pairing) -- [Groups](/uk/channels/groups) -- [Channel routing](/uk/channels/channel-routing) -- [Security](/uk/gateway/security) -- [Multi-agent routing](/uk/concepts/multi-agent) -- [Troubleshooting](/uk/channels/troubleshooting) -- [Slash commands](/uk/tools/slash-commands) +- [Підключення](/uk/channels/pairing) +- [Групи](/uk/channels/groups) +- [Маршрутизація каналів](/uk/channels/channel-routing) +- [Безпека](/uk/gateway/security) +- [Маршрутизація кількох агентів](/uk/concepts/multi-agent) +- [Усунення проблем](/uk/channels/troubleshooting) +- [Slash-команди](/uk/tools/slash-commands) diff --git a/docs/uk/gateway/configuration.md b/docs/uk/gateway/configuration.md index b1bd04a6b..22b25cc14 100644 --- a/docs/uk/gateway/configuration.md +++ b/docs/uk/gateway/configuration.md @@ -1,38 +1,37 @@ --- read_when: - Перше налаштування OpenClaw - - Пошук поширених шаблонів конфігурації + - Поширені шаблони конфігурації - Перехід до конкретних розділів конфігурації summary: 'Огляд конфігурації: поширені завдання, швидке налаштування та посилання на повний довідник' title: Конфігурація x-i18n: - generated_at: "2026-04-23T08:14:09Z" + generated_at: "2026-04-23T08:25:11Z" model: gpt-5.4 provider: openai - source_hash: a674bbc73f3a501ffd47ef9396d55d6087806921cfb24ef576398022dd0248c3 + source_hash: d76b40c25f98de791e0d8012b2bc5b80e3e38dde99bb9105539e800ddac3f362 source_path: gateway/configuration.md workflow: 15 --- # Конфігурація -OpenClaw читає необов’язковий конфігураційний файл **JSON5** з `~/.openclaw/openclaw.json`. -Активний шлях конфігурації має вказувати на звичайний файл. Схеми -`openclaw.json` із символьними посиланнями не підтримуються для записів, -якими керує OpenClaw; атомарний запис може замінити шлях замість збереження -символьного посилання. Якщо ви зберігаєте конфігурацію поза типовим -каталогом стану, вкажіть `OPENCLAW_CONFIG_PATH` безпосередньо на реальний файл. +OpenClaw зчитує необов’язкову конфігурацію **JSON5** з `~/.openclaw/openclaw.json`. +Активний шлях до конфігурації має вказувати на звичайний файл. Макети +`openclaw.json` із символьними посиланнями не підтримуються для записів, які виконує OpenClaw; атомарний запис може замінити +шлях замість збереження символьного посилання. Якщо ви зберігаєте конфігурацію поза +стандартним каталогом стану, спрямуйте `OPENCLAW_CONFIG_PATH` безпосередньо на реальний файл. Якщо файл відсутній, OpenClaw використовує безпечні значення за замовчуванням. Типові причини додати конфігурацію: - Підключити канали та керувати тим, хто може надсилати повідомлення боту -- Налаштувати моделі, інструменти, ізоляцію або автоматизацію (Cron, хуки) +- Налаштувати моделі, інструменти, ізоляцію або автоматизацію (cron, hooks) - Налаштувати сесії, медіа, мережу або UI -Перегляньте [повний довідник](/uk/gateway/configuration-reference), щоб побачити всі доступні поля. +Див. [повний довідник](/uk/gateway/configuration-reference) для всіх доступних полів. -**Вперше працюєте з конфігурацією?** Почніть з `openclaw onboard` для інтерактивного налаштування або перегляньте посібник [Приклади конфігурації](/uk/gateway/configuration-examples) для готових конфігурацій, які можна повністю скопіювати й вставити. +**Вперше працюєте з конфігурацією?** Почніть із `openclaw onboard` для інтерактивного налаштування або перегляньте посібник [Приклади конфігурації](/uk/gateway/configuration-examples) із готовими повними конфігураціями для копіювання й вставлення. ## Мінімальна конфігурація @@ -50,8 +49,8 @@ OpenClaw читає необов’язковий конфігураційний ```bash - openclaw onboard # повний процес початкового налаштування - openclaw configure # майстер конфігурації + openclaw onboard # full onboarding flow + openclaw configure # config wizard ``` @@ -63,31 +62,29 @@ OpenClaw читає необов’язковий конфігураційний Відкрийте [http://127.0.0.1:18789](http://127.0.0.1:18789) і використайте вкладку **Config**. - Control UI відображає форму з живої схеми конфігурації, включно з метаданими документації полів - `title` / `description`, а також схемами plugin і каналів, коли вони - доступні, з редактором **Raw JSON** як запасним варіантом. Для інтерфейсів - деталізації та інших інструментів gateway також надає `config.schema.lookup`, - щоб отримати один вузол схеми для певного шляху разом із короткими - відомостями про безпосередні дочірні елементи. + Control UI візуалізує форму на основі живої схеми конфігурації, включно з метаданими документації + полів `title` / `description`, а також схемами plugin і каналів, коли вони + доступні, із редактором **Raw JSON** як запасним варіантом. Для деталізованих + UI та інших інструментів gateway також надає `config.schema.lookup`, щоб + отримати один вузол схеми для конкретного шляху разом із підсумками безпосередніх дочірніх елементів. - Відредагуйте `~/.openclaw/openclaw.json` напряму. Gateway відстежує файл і автоматично застосовує зміни (див. [гаряче перезавантаження](#config-hot-reload)). + Відредагуйте `~/.openclaw/openclaw.json` безпосередньо. Gateway стежить за файлом і автоматично застосовує зміни (див. [гаряче перезавантаження](#config-hot-reload)). ## Сувора валідація -OpenClaw приймає лише конфігурації, що повністю відповідають схемі. Невідомі ключі, некоректні типи або недійсні значення призводять до того, що Gateway **відмовляється запускатися**. Єдиний виняток на кореневому рівні — `$schema` (рядок), щоб редактори могли підключати метадані JSON Schema. +OpenClaw приймає лише конфігурації, які повністю відповідають схемі. Невідомі ключі, некоректні типи або недійсні значення призводять до того, що Gateway **відмовляється запускатися**. Єдиний виняток на рівні кореня — `$schema` (рядок), щоб редактори могли підключати метадані JSON Schema. `openclaw config schema` виводить канонічну JSON Schema, яку використовують Control UI -та валідація. `config.schema.lookup` отримує один вузол для певного шляху разом -із короткими відомостями про дочірні елементи для інструментів деталізації. -Метадані документації полів `title`/`description` поширюються на вкладені об’єкти, -підстановочні символи (`*`), елементи масиву (`[]`) та гілки `anyOf`/ -`oneOf`/`allOf`. Схеми runtime plugin і каналів додаються під час завантаження -реєстру маніфестів. +і валідація. `config.schema.lookup` отримує один вузол для конкретного шляху разом +із підсумками дочірніх елементів для інструментів із деталізованою навігацією. Метадані документації полів `title`/`description` +поширюються на вкладені об’єкти, wildcard (`*`), елементи масиву (`[]`) і гілки `anyOf`/ +`oneOf`/`allOf`. Схеми plugin і каналів під час виконання додаються, коли +завантажено реєстр маніфестів. Коли валідація не проходить: @@ -96,21 +93,19 @@ OpenClaw приймає лише конфігурації, що повністю - Запустіть `openclaw doctor`, щоб побачити точні проблеми - Запустіть `openclaw doctor --fix` (або `--yes`), щоб застосувати виправлення -Після кожного успішного запуску Gateway зберігає довірену останню коректну копію. -Якщо пізніше `openclaw.json` не проходить валідацію (або втрачає `gateway.mode`, -різко зменшується, або на початку з’являється сторонній рядок журналу), -OpenClaw зберігає пошкоджений файл як `.clobbered.*`, відновлює останню коректну -копію та записує причину відновлення в журнал. Під час наступного ходу агента -також надходить попередження про системну подію, щоб основний агент не -перезаписав відновлену конфігурацію без перевірки. Підвищення до статусу -останньої коректної копії пропускається, якщо кандидат містить замасковані -заповнювачі секретів, такі як `***`. +Gateway зберігає довірену останню відому коректну копію після кожного успішного запуску. +Якщо `openclaw.json` згодом не проходить валідацію (або втрачає `gateway.mode`, різко +зменшується, чи до нього випадково додається рядок журналу на початку), OpenClaw зберігає зламаний файл +як `.clobbered.*`, відновлює останню відому коректну копію та записує в журнал причину +відновлення. Наступний хід агента також отримує попередження про системну подію, щоб основний +агент не перезаписав відновлену конфігурацію бездумно. Підвищення до статусу останньої відомої коректної копії +пропускається, якщо кандидат містить замасковані заповнювачі секретів, наприклад `***`. ## Поширені завдання - - Кожен канал має власний розділ конфігурації в `channels.`. Кроки налаштування дивіться на окремій сторінці каналу: + + Кожен канал має власний розділ конфігурації в `channels.`. Див. окрему сторінку каналу для кроків налаштування: - [WhatsApp](/uk/channels/whatsapp) — `channels.whatsapp` - [Telegram](/uk/channels/telegram) — `channels.telegram` @@ -140,7 +135,7 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, - + Задайте основну модель і необов’язкові резервні варіанти: ```json5 @@ -161,30 +156,30 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, ``` - `agents.defaults.models` визначає каталог моделей і виконує роль списку дозволених значень для `/model`. - - Використовуйте `openclaw config set agents.defaults.models '' --strict-json --merge`, щоб додати записи до списку дозволених без видалення наявних моделей. Звичайні заміни, які видалили б записи, відхиляються, якщо ви не передасте `--replace`. + - Використовуйте `openclaw config set agents.defaults.models '' --strict-json --merge`, щоб додати записи до списку дозволених значень без видалення наявних моделей. Звичайні заміни, які видалили б записи, відхиляються, якщо не передати `--replace`. - Посилання на моделі використовують формат `provider/model` (наприклад, `anthropic/claude-opus-4-6`). - - `agents.defaults.imageMaxDimensionPx` керує зменшенням розміру зображень у транскрипті/інструментах (типове значення `1200`); менші значення зазвичай зменшують використання vision-токенів у запусках із великою кількістю знімків екрана. - - Див. [Models CLI](/uk/concepts/models), щоб перемикати моделі в чаті, і [Model Failover](/uk/concepts/model-failover) щодо ротації авторизації та поведінки резервних моделей. - - Для користувацьких/самостійно розміщених провайдерів див. [Custom providers](/uk/gateway/configuration-reference#custom-providers-and-base-urls) у довіднику. + - `agents.defaults.imageMaxDimensionPx` керує зменшенням розміру зображень у транскрипті/інструментах (типове значення `1200`); нижчі значення зазвичай зменшують використання vision-токенів у запусках із великою кількістю знімків екрана. + - Див. [Models CLI](/uk/concepts/models) для перемикання моделей у чаті та [Model Failover](/uk/concepts/model-failover) для ротації автентифікації та поведінки резервного перемикання. + - Для користувацьких/self-hosted провайдерів див. [Custom providers](/uk/gateway/configuration-reference#custom-providers-and-base-urls) у довіднику. - - Доступ до DM керується окремо для кожного каналу через `dmPolicy`: + + Доступ до DM контролюється окремо для кожного каналу через `dmPolicy`: - - `"pairing"` (типово): невідомі відправники отримують одноразовий код сполучення для підтвердження - - `"allowlist"`: лише відправники з `allowFrom` (або зі сховища парного списку дозволених) + - `"pairing"` (типово): невідомі відправники отримують одноразовий код спаровування для підтвердження + - `"allowlist"`: лише відправники з `allowFrom` (або зі сховища дозволених спарених користувачів) - `"open"`: дозволити всі вхідні DM (потрібно `allowFrom: ["*"]`) - `"disabled"`: ігнорувати всі DM - Для груп використовуйте `groupPolicy` + `groupAllowFrom` або списки дозволених, специфічні для каналу. + Для груп використовуйте `groupPolicy` + `groupAllowFrom` або списки дозволених значень, специфічні для каналу. - Див. [повний довідник](/uk/gateway/configuration-reference#dm-and-group-access) для подробиць щодо кожного каналу. + Див. [повний довідник](/uk/gateway/configuration-reference#dm-and-group-access) для подробиць по кожному каналу. - - За замовчуванням для групових повідомлень **потрібна згадка**. Налаштуйте шаблони для кожного агента: + + Повідомлення в групах типово **вимагають згадки**. Налаштуйте шаблони для кожного агента: ```json5 { @@ -207,12 +202,12 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, ``` - **Згадки в метаданих**: нативні @-згадки (WhatsApp tap-to-mention, Telegram @bot тощо) - - **Текстові шаблони**: безпечні шаблони regex у `mentionPatterns` - - Див. [повний довідник](/uk/gateway/configuration-reference#group-chat-mention-gating) для перевизначень на рівні каналів і режиму self-chat. + - **Текстові шаблони**: безпечні regex-шаблони в `mentionPatterns` + - Див. [повний довідник](/uk/gateway/configuration-reference#group-chat-mention-gating) для перевизначень по каналах і режиму self-chat. - + Використовуйте `agents.defaults.skills` для спільної базової конфігурації, а потім перевизначайте конкретних агентів через `agents.list[].skills`: @@ -231,16 +226,16 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, } ``` - - Не вказуйте `agents.defaults.skills`, якщо за замовчуванням Skills не мають бути обмежені. - - Не вказуйте `agents.list[].skills`, щоб успадкувати типові значення. - - Установіть `agents.list[].skills: []`, щоб не дозволяти жодних Skills. - - Див. [Skills](/uk/tools/skills), [Skills config](/uk/tools/skills-config) і - [Configuration Reference](/uk/gateway/configuration-reference#agents-defaults-skills). + - Не задавайте `agents.defaults.skills`, якщо типово Skills не мають обмежуватися. + - Не задавайте `agents.list[].skills`, щоб успадкувати значення за замовчуванням. + - Встановіть `agents.list[].skills: []`, щоб не дозволити жодних Skills. + - Див. [Skills](/uk/tools/skills), [конфігурацію Skills](/uk/tools/skills-config) і + [довідник конфігурації](/uk/gateway/configuration-reference#agents-defaults-skills). - - Керуйте тим, наскільки агресивно gateway перезапускає канали, що виглядають застарілими: + + Керуйте тим, наскільки агресивно gateway перезапускає канали, які виглядають неактивними: ```json5 { @@ -262,15 +257,15 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, } ``` - - Установіть `gateway.channelHealthCheckMinutes: 0`, щоб глобально вимкнути перезапуски через моніторинг стану. - - `channelStaleEventThresholdMinutes` має бути більшим або дорівнювати інтервалу перевірки. - - Використовуйте `channels..healthMonitor.enabled` або `channels..accounts..healthMonitor.enabled`, щоб вимкнути автоперезапуск для одного каналу чи облікового запису без вимкнення глобального моніторингу. - - Див. [Health Checks](/uk/gateway/health) для операційної діагностики та [повний довідник](/uk/gateway/configuration-reference#gateway) для всіх полів. + - Встановіть `gateway.channelHealthCheckMinutes: 0`, щоб глобально вимкнути перезапуски через моніторинг стану. + - `channelStaleEventThresholdMinutes` має бути більшим або рівним інтервалу перевірки. + - Використовуйте `channels..healthMonitor.enabled` або `channels..accounts..healthMonitor.enabled`, щоб вимкнути автоперезапуски для одного каналу чи облікового запису без вимкнення глобального монітора. + - Див. [Health Checks](/uk/gateway/health) для операційного налагодження та [повний довідник](/uk/gateway/configuration-reference#gateway) для всіх полів. - - Сесії керують безперервністю та ізоляцією розмов: + + Сесії керують безперервністю розмови та ізоляцією: ```json5 { @@ -291,14 +286,14 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, ``` - `dmScope`: `main` (спільна) | `per-peer` | `per-channel-peer` | `per-account-channel-peer` - - `threadBindings`: глобальні типові значення для маршрутизації сесій, прив’язаних до потоків (Discord підтримує `/focus`, `/unfocus`, `/agents`, `/session idle` і `/session max-age`). - - Див. [Session Management](/uk/concepts/session) щодо області видимості, зв’язків ідентичностей і політики надсилання. + - `threadBindings`: глобальні значення за замовчуванням для маршрутизації сесій, прив’язаних до гілок (Discord підтримує `/focus`, `/unfocus`, `/agents`, `/session idle` і `/session max-age`). + - Див. [Керування сесіями](/uk/concepts/session) для області дії, зв’язків ідентичностей і політики надсилання. - Див. [повний довідник](/uk/gateway/configuration-reference#session) для всіх полів. - - Запускайте сесії агентів в ізольованих sandbox runtime: + + Запускайте сесії агентів в ізольованих середовищах ізоляції: ```json5 { @@ -315,11 +310,11 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, Спочатку зберіть образ: `scripts/sandbox-setup.sh` - Див. [Sandboxing](/uk/gateway/sandboxing) для повного посібника та [повний довідник](/uk/gateway/configuration-reference#agentsdefaultssandbox) для всіх параметрів. + Див. [Ізоляція](/uk/gateway/sandboxing) для повного посібника та [повний довідник](/uk/gateway/configuration-reference#agentsdefaultssandbox) для всіх параметрів. - + Relay-backed push налаштовується в `openclaw.json`. Додайте це в конфігурацію gateway: @@ -348,35 +343,35 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, Що це робить: - - Дає змогу gateway надсилати `push.test`, сигнали пробудження та сигнали повторного підключення через зовнішній relay. + - Дає змогу gateway надсилати `push.test`, сигнали пробудження та пробудження для повторного підключення через зовнішній relay. - Використовує дозвіл на надсилання в межах реєстрації, який пересилає спарений застосунок iOS. Gateway не потребує relay-токена для всього розгортання. - - Прив’язує кожну реєстрацію з relay-підтримкою до ідентичності gateway, з якою було спарено застосунок iOS, тому інший gateway не зможе повторно використати збережену реєстрацію. - - Залишає локальні/ручні збірки iOS на прямому APNs. Надсилання з relay-підтримкою застосовується лише до офіційних розповсюджуваних збірок, які зареєстровано через relay. - - Має збігатися з базовим URL relay, вбудованим в офіційну/TestFlight збірку iOS, щоб трафік реєстрації й надсилання потрапляв до одного й того самого розгортання relay. + - Прив’язує кожну relay-backed реєстрацію до ідентичності gateway, з якою був спарений застосунок iOS, тому інший gateway не може повторно використати збережену реєстрацію. + - Залишає локальні/ручні збірки iOS на прямому APNs. Relay-backed надсилання застосовується лише до офіційних розповсюджених збірок, які зареєструвалися через relay. + - Має збігатися з базовим URL relay, вбудованим в офіційну/TestFlight збірку iOS, щоб трафік реєстрації та надсилання потрапляв до того самого розгортання relay. - Наскрізний процес: + Наскрізний потік: 1. Установіть офіційну/TestFlight збірку iOS, скомпільовану з тим самим базовим URL relay. - 2. Налаштуйте `gateway.push.apns.relay.baseUrl` у gateway. - 3. Спарте застосунок iOS із gateway і дозвольте підключитися як сесії node, так і сесії оператора. - 4. Застосунок iOS отримує ідентичність gateway, реєструється в relay за допомогою App Attest та квитанції застосунку, а потім публікує payload `push.apns.register` з relay-підтримкою у спарений gateway. - 5. Gateway зберігає relay handle і дозвіл на надсилання, а потім використовує їх для `push.test`, сигналів пробудження та сигналів повторного підключення. + 2. Налаштуйте `gateway.push.apns.relay.baseUrl` на gateway. + 3. Спаріть застосунок iOS із gateway і дозвольте підключитися сеансам node та оператора. + 4. Застосунок iOS отримує ідентичність gateway, реєструється в relay за допомогою App Attest і квитанції застосунку, а потім публікує relay-backed корисне навантаження `push.apns.register` у спарений gateway. + 5. Gateway зберігає relay handle і дозвіл на надсилання, а потім використовує їх для `push.test`, сигналів пробудження та пробуджень для повторного підключення. Операційні примітки: - Якщо ви перемикаєте застосунок iOS на інший gateway, перепідключіть застосунок, щоб він міг опублікувати нову relay-реєстрацію, прив’язану до цього gateway. - - Якщо ви випускаєте нову збірку iOS, яка вказує на інше розгортання relay, застосунок оновлює кешовану relay-реєстрацію замість повторного використання старого джерела relay. + - Якщо ви випускаєте нову збірку iOS, що вказує на інше розгортання relay, застосунок оновлює кешовану relay-реєстрацію замість повторного використання старого джерела relay. Примітка щодо сумісності: - `OPENCLAW_APNS_RELAY_BASE_URL` і `OPENCLAW_APNS_RELAY_TIMEOUT_MS` усе ще працюють як тимчасові перевизначення через env. - - `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true` залишається аварійним варіантом для розробки лише в loopback; не зберігайте HTTP URL relay у конфігурації. + - `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true` залишається аварійним варіантом для розробки лише на loopback; не зберігайте HTTP URL relay у конфігурації. - Див. [iOS App](/uk/platforms/ios#relay-backed-push-for-official-builds) для повного наскрізного процесу та [Authentication and trust flow](/uk/platforms/ios#authentication-and-trust-flow) для моделі безпеки relay. + Див. [iOS App](/uk/platforms/ios#relay-backed-push-for-official-builds) для наскрізного потоку та [Authentication and trust flow](/uk/platforms/ios#authentication-and-trust-flow) для моделі безпеки relay. - + ```json5 { agents: { @@ -397,7 +392,7 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, - + ```json5 { cron: { @@ -412,14 +407,14 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, } ``` - - `sessionRetention`: видаляти завершені ізольовані сесії запуску з `sessions.json` (типово `24h`; установіть `false`, щоб вимкнути). - - `runLog`: очищати `cron/runs/.jsonl` за розміром і кількістю збережених рядків. + - `sessionRetention`: очищати завершені ізольовані сеанси запусків із `sessions.json` (типово `24h`; установіть `false`, щоб вимкнути). + - `runLog`: очищати `cron/runs/.jsonl` за розміром і кількістю рядків, які слід зберегти. - Див. [Cron jobs](/uk/automation/cron-jobs) для огляду можливостей і прикладів CLI. - - Увімкніть HTTP-ендпоїнти Webhook у Gateway: + + Увімкніть HTTP-ендпоїнти Webhook на Gateway: ```json5 { @@ -443,20 +438,20 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, ``` Примітка щодо безпеки: - - Уважайте весь вміст payload hook/Webhook недовіреним введенням. + - Розглядайте весь вміст корисного навантаження hook/Webhook як недовірене введення. - Використовуйте окремий `hooks.token`; не використовуйте повторно спільний токен Gateway. - Автентифікація hook виконується лише через заголовки (`Authorization: Bearer ...` або `x-openclaw-token`); токени в рядку запиту відхиляються. - - `hooks.path` не може бути `/`; використовуйте для вхідних Webhook окремий підшлях, наприклад `/hooks`. - - Залишайте прапорці обходу небезпечного вмісту вимкненими (`hooks.gmail.allowUnsafeExternalContent`, `hooks.mappings[].allowUnsafeExternalContent`), якщо не виконуєте чітко обмежене налагодження. - - Якщо ви вмикаєте `hooks.allowRequestSessionKey`, також установіть `hooks.allowedSessionKeyPrefixes`, щоб обмежити ключі сесій, які може вибирати викликач. - - Для агентів, керованих через hook, віддавайте перевагу сильним сучасним рівням моделей і суворій політиці інструментів (наприклад, лише обмін повідомленнями плюс sandboxing, де це можливо). + - `hooks.path` не може бути `/`; використовуйте для вхідних Webhook-ів окремий підшлях, наприклад `/hooks`. + - Залишайте прапорці обходу небезпечного вмісту вимкненими (`hooks.gmail.allowUnsafeExternalContent`, `hooks.mappings[].allowUnsafeExternalContent`), якщо тільки не виконуєте суворо обмежене налагодження. + - Якщо ви вмикаєте `hooks.allowRequestSessionKey`, також задайте `hooks.allowedSessionKeyPrefixes`, щоб обмежити ключі сесій, які вибирає викликач. + - Для агентів, керованих hook-ами, віддавайте перевагу потужним сучасним рівням моделей і суворій політиці інструментів (наприклад, лише обмін повідомленнями плюс ізоляція, де це можливо). - Див. [повний довідник](/uk/gateway/configuration-reference#hooks) для всіх параметрів mapping і інтеграції Gmail. + Див. [повний довідник](/uk/gateway/configuration-reference#hooks) для всіх параметрів зіставлення та інтеграції з Gmail. - - Запускайте кілька ізольованих агентів з окремими робочими просторами та сесіями: + + Запускайте кількох ізольованих агентів з окремими робочими просторами й сесіями: ```json5 { @@ -473,12 +468,12 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, } ``` - Див. [Multi-Agent](/uk/concepts/multi-agent) і [повний довідник](/uk/gateway/configuration-reference#multi-agent-routing) щодо правил прив’язки та профілів доступу для кожного агента. + Див. [Multi-Agent](/uk/concepts/multi-agent) і [повний довідник](/uk/gateway/configuration-reference#multi-agent-routing) для правил прив’язки й профілів доступу для кожного агента. - - Використовуйте `$include`, щоб упорядкувати великі конфігурації: + + Використовуйте `$include`, щоб упорядковувати великі конфігурації: ```json5 // ~/.openclaw/openclaw.json @@ -491,47 +486,48 @@ OpenClaw зберігає пошкоджений файл як `.clobbered.*`, } ``` - - **Один файл**: замінює об’єкт, у якому міститься - - **Масив файлів**: глибоко об’єднується за порядком (пізніші мають пріоритет) - - **Сусідні ключі**: об’єднуються після include (перевизначають включені значення) - - **Вкладені include**: підтримуються до 10 рівнів вкладеності - - **Відносні шляхи**: обчислюються відносно файлу, який включає - - **Записи, якими керує OpenClaw**: коли запис змінює лише один розділ верхнього рівня, - що підкріплений include одного файлу, наприклад `plugins: { $include: "./plugins.json5" }`, + - **Один файл**: замінює об’єкт, який його містить + - **Масив файлів**: глибоко зливається по порядку (пізніший має пріоритет) + - **Сусідні ключі**: зливаються після include-ів (перевизначають включені значення) + - **Вкладені include-и**: підтримуються до 10 рівнів вкладеності + - **Відносні шляхи**: обчислюються відносно файла, який виконує включення + - **Записи, які виконує OpenClaw**: коли запис змінює лише один розділ верхнього рівня, + що підтримується include-ом одного файла, як-от `plugins: { $include: "./plugins.json5" }`, OpenClaw оновлює цей включений файл і залишає `openclaw.json` без змін - - **Непідтримуваний наскрізний запис**: кореневі include, масиви include та include - із сусідніми перевизначеннями завершуються без змін для записів, якими керує OpenClaw, замість - сплощення конфігурації - - **Обробка помилок**: зрозумілі помилки для відсутніх файлів, помилок розбору та циклічних include + - **Непідтримуваний запис через include**: root include-и, масиви include-ів і include-и + із сусідніми перевизначеннями завершуються безпечною відмовою для записів, які виконує OpenClaw, замість + сплющення конфігурації + - **Обробка помилок**: зрозумілі помилки для відсутніх файлів, помилок розбору й циклічних include-ів ## Гаряче перезавантаження конфігурації -Gateway відстежує `~/.openclaw/openclaw.json` і застосовує зміни автоматично — для більшості параметрів ручний перезапуск не потрібен. +Gateway стежить за `~/.openclaw/openclaw.json` і автоматично застосовує зміни — для більшості параметрів ручний перезапуск не потрібен. -Прямі редагування файлу вважаються недовіреними, доки не пройдуть валідацію. Спостерігач -чекає, поки вщухнуть тимчасові записи/перейменування редактора, читає фінальний файл -і відхиляє некоректні зовнішні зміни, відновлюючи останню коректну конфігурацію. Записи конфігурації, -якими керує OpenClaw, використовують ту саму перевірку схемою перед записом; руйнівні пошкодження, такі -як видалення `gateway.mode` або зменшення файлу більш ніж наполовину, відхиляються -та зберігаються як `.rejected.*` для перевірки. +Прямі редагування файла вважаються недовіреними, доки не пройдуть валідацію. Спостерігач +чекає, поки вщухне активність тимчасових записів/перейменувань редактора, +зчитує фінальний файл і відхиляє недійсні зовнішні редагування, відновлюючи +останню відому коректну конфігурацію. Записи конфігурації, які виконує OpenClaw, +використовують той самий бар’єр схеми перед записом; руйнівні перезаписи, такі +як видалення `gateway.mode` або зменшення файла більш ніж наполовину, відхиляються +й зберігаються як `.rejected.*` для перевірки. -Якщо ви бачите `Config auto-restored from last-known-good` або -`config reload restored last-known-good config` у журналах, перевірте відповідний -файл `.clobbered.*` поруч із `openclaw.json`, виправте відхилений payload, а потім запустіть -`openclaw config validate`. Див. [Gateway troubleshooting](/uk/gateway/troubleshooting#gateway-restored-last-known-good-config) +Якщо в журналах ви бачите `Config auto-restored from last-known-good` або +`config reload restored last-known-good config`, перевірте відповідний +файл `.clobbered.*` поруч із `openclaw.json`, виправте відхилене корисне навантаження, а потім запустіть +`openclaw config validate`. Див. [усунення несправностей Gateway](/uk/gateway/troubleshooting#gateway-restored-last-known-good-config) для контрольного списку відновлення. ### Режими перезавантаження -| Режим | Поведінка | -| ---------------------- | ---------------------------------------------------------------------------------------- | -| **`hybrid`** (типово) | Безпечно застосовує зміни одразу. Для критичних змін автоматично виконує перезапуск. | -| **`hot`** | Застосовує лише безпечні зміни без перезапуску. Записує попередження, коли потрібен перезапуск — ви виконуєте його самі. | +| Режим | Поведінка | +| ---------------------- | --------------------------------------------------------------------------------------- | +| **`hybrid`** (типово) | Миттєво гаряче застосовує безпечні зміни. Для критичних автоматично перезапускає. | +| **`hot`** | Гаряче застосовує лише безпечні зміни. Пише попередження, коли потрібен перезапуск — ви виконуєте його самі. | | **`restart`** | Перезапускає Gateway за будь-якої зміни конфігурації, безпечної чи ні. | -| **`off`** | Вимикає відстеження файлу. Зміни набудуть чинності під час наступного ручного перезапуску. | +| **`off`** | Вимикає спостереження за файлами. Зміни набувають чинності під час наступного ручного перезапуску. | ```json5 { @@ -541,53 +537,53 @@ Gateway відстежує `~/.openclaw/openclaw.json` і застосовує } ``` -### Що застосовується без перезапуску, а що потребує перезапуску +### Що застосовується гаряче, а що потребує перезапуску -Більшість полів застосовуються без перезапуску та без простою. У режимі `hybrid` зміни, що потребують перезапуску, обробляються автоматично. +Більшість полів застосовуються гаряче без простою. У режимі `hybrid` зміни, що потребують перезапуску, обробляються автоматично. -| Категорія | Поля | Потрібен перезапуск? | -| ------------------- | ----------------------------------------------------------------- | -------------------- | -| Канали | `channels.*`, `web` (WhatsApp) — усі вбудовані канали та канали plugin | Ні | -| Агент і моделі | `agent`, `agents`, `models`, `routing` | Ні | -| Автоматизація | `hooks`, `cron`, `agent.heartbeat` | Ні | -| Сесії та повідомлення | `session`, `messages` | Ні | -| Інструменти та медіа | `tools`, `browser`, `skills`, `audio`, `talk` | Ні | -| UI та інше | `ui`, `logging`, `identity`, `bindings` | Ні | -| Сервер Gateway | `gateway.*` (port, bind, auth, tailscale, TLS, HTTP) | **Так** | -| Інфраструктура | `discovery`, `canvasHost`, `plugins` | **Так** | +| Категорія | Поля | Потрібен перезапуск? | +| -------------------- | ----------------------------------------------------------------- | -------------------- | +| Канали | `channels.*`, `web` (WhatsApp) — усі вбудовані канали й канали plugin | Ні | +| Агент і моделі | `agent`, `agents`, `models`, `routing` | Ні | +| Автоматизація | `hooks`, `cron`, `agent.heartbeat` | Ні | +| Сесії та повідомлення| `session`, `messages` | Ні | +| Інструменти й медіа | `tools`, `browser`, `skills`, `audio`, `talk` | Ні | +| UI та інше | `ui`, `logging`, `identity`, `bindings` | Ні | +| Сервер Gateway | `gateway.*` (port, bind, auth, tailscale, TLS, HTTP) | **Так** | +| Інфраструктура | `discovery`, `canvasHost`, `plugins` | **Так** | -`gateway.reload` і `gateway.remote` — винятки: їх зміна **не** призводить до перезапуску. +`gateway.reload` і `gateway.remote` — винятки: їх зміна **не** спричиняє перезапуск. ### Планування перезавантаження Коли ви редагуєте вихідний файл, на який є посилання через `$include`, OpenClaw планує -перезавантаження на основі структури, визначеної у вихідних файлах, а не сплощеного представлення в пам’яті. -Це робить рішення для гарячого перезавантаження (застосувати без перезапуску чи перезапустити) передбачуваними навіть тоді, коли -один розділ верхнього рівня розміщено у власному включеному файлі, наприклад -`plugins: { $include: "./plugins.json5" }`. Планування перезавантаження завершується без змін, якщо -структура джерела неоднозначна. +перезавантаження на основі макета, заданого у вихідних файлах, а не сплющеного представлення в пам’яті. +Це робить рішення гарячого перезавантаження (гаряче застосування чи перезапуск) передбачуваними, навіть коли +один розділ верхнього рівня живе у власному включеному файлі, наприклад +`plugins: { $include: "./plugins.json5" }`. Планування перезавантаження завершується безпечною відмовою, якщо +вихідний макет неоднозначний. -## RPC конфігурації (програмні оновлення) +## Config RPC (програмні оновлення) -Для інструментів, які записують конфігурацію через API gateway, віддавайте перевагу такому процесу: +Для інструментів, які записують конфігурацію через API gateway, використовуйте такий потік: -- `config.schema.lookup`, щоб перевірити одне піддерево (поверхневий вузол схеми + короткі - відомості про дочірні елементи) -- `config.get`, щоб отримати поточний знімок разом із `hash` -- `config.patch` для часткових оновлень (JSON merge patch: об’єкти об’єднуються, `null` +- `config.schema.lookup`, щоб перевірити одне піддерево (неглибокий вузол схеми + підсумки + дочірніх елементів) +- `config.get`, щоб отримати поточний знімок і `hash` +- `config.patch` для часткових оновлень (JSON merge patch: об’єкти зливаються, `null` видаляє, масиви замінюються) -- `config.apply` лише тоді, коли ви справді хочете замінити всю конфігурацію -- `update.run` для явного самостійного оновлення з подальшим перезапуском +- `config.apply` лише якщо ви справді хочете замінити всю конфігурацію +- `update.run` для явного самооновлення й перезапуску -Записи контрольної площини (`config.apply`, `config.patch`, `update.run`) обмежуються -до 3 запитів на 60 секунд для кожної пари `deviceId+clientIp`. Запити на перезапуск -об’єднуються, а потім між циклами перезапуску застосовується затримка 30 секунд. +Записи control-plane (`config.apply`, `config.patch`, `update.run`) +обмежуються до 3 запитів за 60 секунд на `deviceId+clientIp`. Запити на перезапуск +об’єднуються, а потім примусово застосовують 30-секундний cooldown між циклами перезапуску. -Приклад часткового patch: +Приклад часткового патча: ```bash openclaw gateway call config.get --params '{}' # capture payload.hash @@ -598,17 +594,17 @@ openclaw gateway call config.patch --params '{ ``` І `config.apply`, і `config.patch` приймають `raw`, `baseHash`, `sessionKey`, -`note` і `restartDelayMs`. `baseHash` є обов’язковим для `config.patch` і -рекомендованим для `config.apply`, коли конфігурація вже існує. +`note` і `restartDelayMs`. `baseHash` є обов’язковим для обох методів, якщо +конфігурація вже існує. ## Змінні середовища -OpenClaw читає змінні середовища з батьківського процесу, а також з: +OpenClaw зчитує env vars із батьківського процесу, а також із: - `.env` у поточному робочому каталозі (якщо є) - `~/.openclaw/.env` (глобальний запасний варіант) -Жоден із цих файлів не перевизначає вже наявні змінні середовища. Ви також можете задавати вбудовані змінні середовища в конфігурації: +Жоден із цих файлів не перевизначає вже наявні env vars. Ви також можете задавати inline env vars у конфігурації: ```json5 { @@ -619,8 +615,8 @@ OpenClaw читає змінні середовища з батьківсько } ``` - - Якщо ввімкнено і очікувані ключі не задано, OpenClaw запускає вашу login shell і імпортує лише відсутні ключі: + + Якщо це ввімкнено й очікувані ключі не задано, OpenClaw запускає вашу login shell і імпортує лише відсутні ключі: ```json5 { @@ -630,11 +626,11 @@ OpenClaw читає змінні середовища з батьківсько } ``` -Еквівалентна змінна середовища: `OPENCLAW_LOAD_SHELL_ENV=1` +Еквівалент env var: `OPENCLAW_LOAD_SHELL_ENV=1` - - Посилайтеся на змінні середовища в будь-якому рядковому значенні конфігурації за допомогою `${VAR_NAME}`: + + Посилайтеся на env vars у будь-якому рядковому значенні конфігурації через `${VAR_NAME}`: ```json5 { @@ -645,15 +641,15 @@ OpenClaw читає змінні середовища з батьківсько Правила: -- Зіставляються лише імена у верхньому регістрі: `[A-Z_][A-Z0-9_]*` +- Зіставляються лише назви у верхньому регістрі: `[A-Z_][A-Z0-9_]*` - Відсутні/порожні змінні спричиняють помилку під час завантаження -- Використовуйте `$${VAR}` для буквального виводу +- Екрануйте через `$${VAR}` для виведення буквального значення - Працює всередині файлів `$include` - Вбудована підстановка: `"${BASE}/v1"` → `"https://api.example.com/v1"` - + Для полів, які підтримують об’єкти SecretRef, можна використовувати: ```json5 @@ -686,16 +682,16 @@ OpenClaw читає змінні середовища з батьківсько } ``` -Подробиці про SecretRef (зокрема `secrets.providers` для `env`/`file`/`exec`) наведено в [Secrets Management](/uk/gateway/secrets). -Підтримувані шляхи облікових даних перелічено в [SecretRef Credential Surface](/uk/reference/secretref-credential-surface). +Подробиці про SecretRef (зокрема `secrets.providers` для `env`/`file`/`exec`) наведено в [Керуванні секретами](/uk/gateway/secrets). +Підтримувані шляхи облікових даних перелічено в [Поверхня облікових даних SecretRef](/uk/reference/secretref-credential-surface). -Див. [Environment](/uk/help/environment) для повного опису пріоритетів і джерел. +Див. [Environment](/uk/help/environment) для повного порядку пріоритетів і джерел. ## Повний довідник -Повний довідник по полях див. в **[Configuration Reference](/uk/gateway/configuration-reference)**. +Повний довідник по кожному полю дивіться в **[Довіднику конфігурації](/uk/gateway/configuration-reference)**. --- -_Пов’язане: [Configuration Examples](/uk/gateway/configuration-examples) · [Configuration Reference](/uk/gateway/configuration-reference) · [Doctor](/uk/gateway/doctor)_ +_Пов’язане: [Приклади конфігурації](/uk/gateway/configuration-examples) · [Довідник конфігурації](/uk/gateway/configuration-reference) · [Doctor](/uk/gateway/doctor)_ diff --git a/docs/uk/plugins/architecture.md b/docs/uk/plugins/architecture.md index 5a9fc9e6c..0adbf82a2 100644 --- a/docs/uk/plugins/architecture.md +++ b/docs/uk/plugins/architecture.md @@ -1,110 +1,111 @@ --- read_when: - - Створення або налагодження native Plugin для OpenClaw - - Розуміння моделі можливостей Plugin або меж володіння - - Робота над конвеєром завантаження Plugin або реєстром - - Реалізація хуків часу виконання провайдера або Plugin каналів + - Створення або налагодження нативних plugin OpenClaw + - Розуміння моделі можливостей plugin або меж володіння + - Робота над конвеєром завантаження plugin або реєстром + - Реалізація хуків середовища виконання провайдера або channel plugin sidebarTitle: Internals -summary: 'Внутрішня будова Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби часу виконання' -title: Внутрішня будова Plugin +summary: 'Внутрішні компоненти Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби середовища виконання' +title: Внутрішні компоненти Plugin x-i18n: - generated_at: "2026-04-23T08:14:12Z" + generated_at: "2026-04-23T08:25:14Z" model: gpt-5.4 provider: openai - source_hash: d3d5e4b9c48c2a0fc8116733e38a745bac5dfdbe65fdea8e9be6563b4051d805 + source_hash: b5a766c267b2618140c744cbebd28f2b206568f26ce50095b898520f4663e21d source_path: plugins/architecture.md workflow: 15 --- -# Внутрішня будова Plugin +# Внутрішні компоненти Plugin - Це **довідник із глибокої архітектури**. Практичні посібники див. тут: - - [Встановлення та використання Plugin](/uk/tools/plugin) — посібник для користувача - - [Початок роботи](/uk/plugins/building-plugins) — перший навчальний посібник зі створення Plugin - - [Plugin каналів](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями - - [Plugin провайдерів](/uk/plugins/sdk-provider-plugins) — створення провайдера моделей + Це **довідник із глибокої архітектури**. Практичні посібники дивіться тут: + - [Встановлення та використання plugin](/uk/tools/plugin) — посібник користувача + - [Початок роботи](/uk/plugins/building-plugins) — перший підручник зі створення plugin + - [Channel Plugins](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями + - [Provider Plugins](/uk/plugins/sdk-provider-plugins) — створення провайдера моделей - [Огляд SDK](/uk/plugins/sdk-overview) — карта імпорту та API реєстрації -На цій сторінці описано внутрішню архітектуру системи Plugin в OpenClaw. +Ця сторінка описує внутрішню архітектуру системи plugin в OpenClaw. ## Публічна модель можливостей -Можливості — це публічна модель **native Plugin** всередині OpenClaw. Кожен -native Plugin OpenClaw реєструється для одного або кількох типів можливостей: +Можливості — це публічна модель **нативних plugin** всередині OpenClaw. Кожен +нативний plugin OpenClaw реєструється для одного або кількох типів можливостей: -| Можливість | Метод реєстрації | Приклади Plugin | -| ---------------------- | --------------------------------------------- | ----------------------------------- | -| Текстовий inference | `api.registerProvider(...)` | `openai`, `anthropic` | -| CLI-бекенд inference | `api.registerCliBackend(...)` | `openai`, `anthropic` | -| Мовлення | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | -| Транскрипція в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | -| Голос у реальному часі | `api.registerRealtimeVoiceProvider(...)` | `openai` | -| Розуміння медіа | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | -| Генерація зображень | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | -| Генерація музики | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | -| Генерація відео | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Отримання вебвмісту | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Вебпошук | `api.registerWebSearchProvider(...)` | `google` | -| Канал / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | +| Можливість | Метод реєстрації | Приклади plugin | +| --------------------- | ----------------------------------------------- | ----------------------------------- | +| Текстовий inference | `api.registerProvider(...)` | `openai`, `anthropic` | +| Бекенд CLI inference | `api.registerCliBackend(...)` | `openai`, `anthropic` | +| Мовлення | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | +| Транскрипція в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | +| Голос у реальному часі | `api.registerRealtimeVoiceProvider(...)` | `openai` | +| Розуміння медіа | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | +| Генерація зображень | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | +| Генерація музики | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | +| Генерація відео | `api.registerVideoGenerationProvider(...)` | `qwen` | +| Отримання вебданих | `api.registerWebFetchProvider(...)` | `firecrawl` | +| Вебпошук | `api.registerWebSearchProvider(...)` | `google` | +| Channel / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | -Plugin, який реєструє нуль можливостей, але надає хуки, інструменти або -сервіси, є **застарілим Plugin лише з хуками**. Цей шаблон усе ще повністю підтримується. +Plugin, який не реєструє жодної можливості, але надає hooks, tools або +services, є **застарілим plugin лише з hooks**. Цей шаблон усе ще повністю підтримується. ### Позиція щодо зовнішньої сумісності Модель можливостей уже реалізована в core і сьогодні використовується -вбудованими/native Plugin, але сумісність із зовнішніми Plugin усе ще потребує -чіткішої межі, ніж «це експортується, отже це незмінний контракт». +вбудованими/нативними plugin, але сумісність із зовнішніми plugin усе ще +потребує вищої планки, ніж «це експортується, отже це зафіксовано». Поточні рекомендації: -- **наявні зовнішні Plugin:** зберігайте працездатність інтеграцій на основі хуків; вважайте +- **наявні зовнішні plugin:** забезпечуйте працездатність інтеграцій на основі hooks; вважайте це базовим рівнем сумісності -- **нові вбудовані/native Plugin:** надавайте перевагу явній реєстрації можливостей замість - vendor-specific доступу до внутрішніх механізмів або нових дизайнів лише з хуками -- **зовнішні Plugin, які переходять на реєстрацію можливостей:** це дозволено, але - вважайте допоміжні поверхні, специфічні для можливостей, такими, що еволюціонують, якщо в документації контракт явно не позначено як стабільний +- **нові вбудовані/нативні plugin:** віддавайте перевагу явній реєстрації можливостей замість + vendor-specific доступу до внутрішніх компонентів або нових дизайнів лише з hooks +- **зовнішні plugin, що переходять на реєстрацію можливостей:** це дозволено, але + вважайте допоміжні surface, специфічні для можливостей, такими, що еволюціонують, + якщо docs явно не позначають контракт як стабільний Практичне правило: -- API реєстрації можливостей — це рекомендований напрям -- застарілі хуки залишаються найбезпечнішим шляхом без ламання сумісності для зовнішніх Plugin під час +- API реєстрації можливостей — це бажаний напрямок +- застарілі hooks залишаються найбезпечнішим шляхом без ризику поломок для зовнішніх plugin під час переходу -- не всі експортовані допоміжні підшляхи однаково важливі; надавайте перевагу вузькому документованому +- не всі експортовані допоміжні subpath однакові; віддавайте перевагу вузькому задокументованому контракту, а не випадковим допоміжним експортам -### Форми Plugin +### Форми plugin -OpenClaw класифікує кожен завантажений Plugin за формою на основі його фактичної -поведінки реєстрації (а не лише статичних метаданих): +OpenClaw класифікує кожен завантажений plugin за формою на основі його фактичної +поведінки під час реєстрації, а не лише статичних метаданих: -- **plain-capability** -- реєструє рівно один тип можливостей (наприклад, - Plugin лише провайдера, як-от `mistral`) +- **plain-capability** -- реєструє рівно один тип можливості (наприклад, + plugin лише для провайдера, як-от `mistral`) - **hybrid-capability** -- реєструє кілька типів можливостей (наприклад, - `openai` відповідає за текстовий inference, мовлення, розуміння медіа та - генерацію зображень) -- **hook-only** -- реєструє лише хуки (типізовані або користувацькі), без можливостей, - інструментів, команд або сервісів -- **non-capability** -- реєструє інструменти, команди, сервіси або маршрути, але не - можливості + `openai` володіє текстовим inference, мовленням, розумінням медіа та + генерацією зображень) +- **hook-only** -- реєструє лише hooks (типізовані або користувацькі), без можливостей, + tools, commands або services +- **non-capability** -- реєструє tools, commands, services або routes, але без + можливостей -Використовуйте `openclaw plugins inspect `, щоб побачити форму Plugin і розподіл -можливостей. Докладніше див. у [довіднику CLI](/uk/cli/plugins#inspect). +Використовуйте `openclaw plugins inspect `, щоб побачити форму plugin і +розподіл можливостей. Докладніше див. у [довіднику CLI](/uk/cli/plugins#inspect). -### Застарілі хуки +### Застарілі hooks -Хук `before_agent_start` залишається підтримуваним як сумісний шлях для -Plugin лише з хуками. Реальні застарілі Plugin досі від нього залежать. +Hook `before_agent_start` залишається підтримуваним як шлях сумісності для +plugin лише з hooks. Від нього все ще залежать реальні застарілі plugin. -Напрям: +Напрямок: - зберігати його працездатність - документувати його як застарілий - для роботи з перевизначенням моделі/провайдера надавати перевагу `before_model_resolve` - для зміни prompt надавати перевагу `before_prompt_build` -- видаляти лише після зменшення реального використання та підтвердження безпечної міграції через покриття фікстурами +- видаляти лише після зниження реального використання та підтвердження безпечності міграції покриттям через fixtures ### Сигнали сумісності @@ -113,82 +114,82 @@ Plugin лише з хуками. Реальні застарілі Plugin дос | Сигнал | Значення | | -------------------------- | ------------------------------------------------------------ | -| **config valid** | Конфігурація коректно розбирається, і Plugin успішно визначаються | +| **config valid** | Config успішно парситься, і plugin коректно визначаються | | **compatibility advisory** | Plugin використовує підтримуваний, але старіший шаблон (наприклад, `hook-only`) | | **legacy warning** | Plugin використовує `before_agent_start`, який є застарілим | -| **hard error** | Конфігурація некоректна або Plugin не вдалося завантажити | +| **hard error** | Config недійсний або plugin не вдалося завантажити | -Ні `hook-only`, ні `before_agent_start` не зламають ваш Plugin сьогодні -- +Ні `hook-only`, ні `before_agent_start` не зламають ваш plugin сьогодні -- `hook-only` є рекомендаційним сигналом, а `before_agent_start` лише викликає попередження. Ці сигнали також з’являються в `openclaw status --all` і `openclaw plugins doctor`. ## Огляд архітектури -Система Plugin в OpenClaw має чотири шари: +Система plugin OpenClaw має чотири шари: 1. **Маніфест + виявлення** - OpenClaw знаходить потенційні Plugin із налаштованих шляхів, коренів робочих просторів, - глобальних коренів Plugin і вбудованих Plugin. Під час виявлення спочатку читаються native - маніфести `openclaw.plugin.json` і підтримувані маніфести пакетів. + OpenClaw знаходить кандидатів у plugin за налаштованими шляхами, коренями workspace, + глобальними коренями plugin і вбудованими plugin. Виявлення спочатку читає нативні + маніфести `openclaw.plugin.json`, а також підтримувані маніфести bundle. 2. **Увімкнення + валідація** - Core визначає, чи виявлений Plugin увімкнено, вимкнено, заблоковано чи - вибрано для ексклюзивного слота, такого як пам’ять. -3. **Завантаження під час виконання** - Native Plugin OpenClaw завантажуються в процесі через jiti і реєструють - можливості в центральному реєстрі. Сумісні пакети нормалізуються в записи - реєстру без імпорту коду часу виконання. -4. **Споживання поверхонь** - Решта OpenClaw читає реєстр, щоб надавати інструменти, канали, налаштування - провайдерів, хуки, HTTP-маршрути, CLI-команди та сервіси. + Core вирішує, чи є виявлений plugin увімкненим, вимкненим, заблокованим або + вибраним для ексклюзивного слота, такого як memory. +3. **Завантаження середовища виконання** + Нативні plugin OpenClaw завантажуються в межах процесу через jiti та реєструють + можливості в центральному реєстрі. Сумісні bundles нормалізуються в записи + реєстру без імпорту коду середовища виконання. +4. **Споживання surface** + Решта OpenClaw читає реєстр, щоб надавати tools, channels, налаштування + провайдера, hooks, HTTP routes, CLI commands і services. -Спеціально для CLI Plugin виявлення кореневих команд поділено на дві фази: +Зокрема для CLI plugin, виявлення кореневих команд поділено на дві фази: -- метадані на етапі розбору надходять із `registerCli(..., { descriptors: [...] })` -- реальний CLI-модуль Plugin може залишатися лінивим і реєструватися при першому виклику +- метадані на етапі парсингу надходять із `registerCli(..., { descriptors: [...] })` +- справжній модуль CLI plugin може залишатися lazy і реєструватися при першому виклику -Це дає змогу зберігати CLI-код, що належить Plugin, усередині самого Plugin і водночас дозволяє OpenClaw -резервувати назви кореневих команд до розбору. +Це дозволяє залишати код CLI, що належить plugin, усередині plugin, але при цьому +OpenClaw може зарезервувати імена кореневих команд до початку парсингу. -Важлива межа проєктування: +Важлива межа дизайну: -- виявлення + валідація конфігурації мають працювати з **метаданих маніфесту/схеми** - без виконання коду Plugin -- native поведінка під час виконання походить із шляху `register(api)` модуля Plugin +- виявлення + валідація config мають працювати на основі **метаданих маніфесту/схеми** + без виконання коду plugin +- нативна поведінка середовища виконання походить із шляху `register(api)` модуля plugin -Це розділення дає OpenClaw змогу перевіряти конфігурацію, пояснювати відсутні/вимкнені Plugin і -створювати підказки для UI/схеми до повної активації часу виконання. +Цей поділ дозволяє OpenClaw валідовувати config, пояснювати відсутні/вимкнені plugin і +будувати підказки для UI/схем до того, як повне середовище виконання стане активним. -### Plugin каналів і спільний інструмент повідомлень +### Channel plugin і спільний tool повідомлень -Plugin каналів не потрібно реєструвати окремий інструмент send/edit/react для -звичайних дій у чаті. OpenClaw зберігає один спільний інструмент `message` у core, а -Plugin каналів відповідають за специфічне для каналу виявлення та виконання за ним. +Channel plugin не потрібно реєструвати окремий tool для надсилання/редагування/реакцій для +звичайних дій чату. OpenClaw зберігає один спільний tool `message` у core, а +channel plugin володіють виявленням і виконанням, специфічними для каналу, за ним. Поточна межа така: -- core відповідає за хост спільного інструмента `message`, підключення prompt, - облік сесій/гілок і диспетчеризацію виконання -- Plugin каналів відповідають за виявлення дій в обмеженому контексті, виявлення - можливостей і будь-які специфічні для каналу фрагменти схеми -- Plugin каналів відповідають за специфічну для провайдера граматику розмов у сесії, наприклад - як ідентифікатори розмов кодують ідентифікатори гілок або успадковуються від батьківських розмов -- Plugin каналів виконують фінальну дію через свій адаптер дій +- core володіє хостом спільного tool `message`, логікою prompt, веденням обліку + session/thread і диспетчеризацією виконання +- channel plugin володіють виявленням дій у межах області, виявленням можливостей + і будь-якими фрагментами схеми, специфічними для каналу +- channel plugin володіють граматикою розмов session, специфічною для провайдера, наприклад + тим, як id розмов кодують id потоків або успадковують їх від батьківських розмов +- channel plugin виконують фінальну дію через свій адаптер дій -Для Plugin каналів поверхнею SDK є +Для channel plugin surface SDK — це `ChannelMessageActionAdapter.describeMessageTool(...)`. Цей уніфікований виклик -виявлення дає змогу Plugin повертати видимі дії, можливості та внески у схему -разом, щоб ці частини не розходилися між собою. +виявлення дозволяє plugin повертати видимі дії, можливості та внески у схему +разом, щоб ці частини не розходилися. -Коли параметр інструмента повідомлень, специфічний для каналу, містить джерело медіа, наприклад -локальний шлях або віддалений URL медіа, Plugin також має повертати +Коли параметр tool повідомлень, специфічний для каналу, містить джерело медіа, наприклад +локальний шлях або URL віддаленого медіа, plugin також має повертати `mediaSourceParams` із `describeMessageTool(...)`. Core використовує цей явний -список, щоб застосовувати нормалізацію шляхів пісочниці та підказки щодо -вихідного доступу до медіа без жорсткого кодування назв параметрів, що належать Plugin. -Тут слід надавати перевагу картам із прив’язкою до дій, а не одному плоскому списку для всього каналу, щоб -параметр медіа лише для профілю не нормалізувався в не пов’язаних діях, як-от +список, щоб застосовувати нормалізацію шляхів sandbox і підказки доступу до +вихідних медіа без жорстко закодованих назв параметрів, що належать plugin. +Тут краще використовувати карти в межах дій, а не один плаский список на весь канал, щоб +параметр медіа лише для профілю не нормалізувався для не пов’язаних дій, таких як `send`. -Core передає область часу виконання в цей крок виявлення. Серед важливих полів: +Core передає область середовища виконання на цей етап виявлення. Важливі поля включають: - `accountId` - `currentChannelId` @@ -199,125 +200,125 @@ Core передає область часу виконання в цей кро - `agentId` - довірений вхідний `requesterSenderId` -Це важливо для Plugin, чутливих до контексту. Канал може приховувати або показувати -дії з повідомленнями залежно від активного облікового запису, поточної кімнати/гілки/повідомлення або -довіреної ідентичності запитувача без жорстко закодованих специфічних для каналу гілок у -core-інструменті `message`. +Це важливо для plugin, чутливих до контексту. Канал може приховувати або показувати +дії повідомлень залежно від активного облікового запису, поточної кімнати/потоку/повідомлення або +довіреної ідентичності запитувача без жорстко закодованих гілок, специфічних для каналу, +у core tool `message`. -Саме тому зміни маршрутизації embedded-runner усе ще є роботою Plugin: runner -відповідає за передавання поточної ідентичності чату/сесії в межу виявлення Plugin, щоб -спільний інструмент `message` показував правильну поверхню, що належить каналу, -для поточного кроку. +Ось чому зміни маршрутизації embedded-runner усе ще належать до роботи plugin: runner +відповідає за передавання поточної ідентичності чату/session до межі виявлення plugin, щоб +спільний tool `message` відкривав правильний surface, що належить каналу, для +поточного кроку. -Для допоміжних засобів виконання, що належать каналу, вбудовані Plugin мають зберігати середовище -виконання всередині власних модулів extension. Core більше не володіє середовищами -виконання дій із повідомленнями для Discord, Slack, Telegram чи WhatsApp у `src/agents/tools`. -Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, і вбудовані -Plugin мають імпортувати власний локальний код часу виконання безпосередньо зі своїх -модулів, що належать extension. +Для допоміжних засобів виконання, що належать каналу, вбудовані plugin мають зберігати runtime +виконання у власних модулях extension. Core більше не володіє runtime дій повідомлень +Discord, Slack, Telegram або WhatsApp у `src/agents/tools`. +Ми не публікуємо окремі subpath `plugin-sdk/*-action-runtime`, і вбудовані +plugin мають імпортувати власний локальний код runtime безпосередньо зі своїх +модулів extension. -Та сама межа застосовується і до специфічних для провайдерів поверхонь SDK загалом: core не має -імпортувати зручні barrel-модулі, специфічні для каналів Slack, Discord, Signal, -WhatsApp чи подібних extension. Якщо core потрібна певна поведінка, слід або -використати власний barrel `api.ts` / `runtime-api.ts` вбудованого Plugin, або -перенести цю потребу у вузьку загальну можливість у спільному SDK. +Та сама межа застосовується загалом до швів SDK із назвами провайдерів: core не має +імпортувати зручні barrel-модулі, специфічні для каналів, для Slack, Discord, Signal, +WhatsApp або подібних extensions. Якщо core потрібна певна поведінка, він має або +споживати власний barrel `api.ts` / `runtime-api.ts` вбудованого plugin, або +підняти цю потребу до вузької узагальненої можливості в спільному SDK. -Спеціально для опитувань є два шляхи виконання: +Зокрема для опитувань, є два шляхи виконання: -- `outbound.sendPoll` — це спільна базова можливість для каналів, які відповідають загальній +- `outbound.sendPoll` — це спільна базова лінія для каналів, які відповідають загальній моделі опитувань -- `actions.handleAction("poll")` — це бажаний шлях для специфічної для каналу семантики - опитувань або додаткових параметрів опитувань +- `actions.handleAction("poll")` — це бажаний шлях для семантики опитувань, специфічної для каналу, + або додаткових параметрів опитування -Тепер core відкладає спільний розбір опитувань до моменту, коли диспетчеризація -опитувань Plugin відхилить дію, щоб обробники опитувань, що належать Plugin, могли приймати -специфічні для каналу поля опитувань, не блокуючись спочатку загальним парсером опитувань. +Тепер Core відкладає спільний парсинг опитувань до моменту, коли диспетчеризація опитувань plugin +відхиляє дію, щоб обробники опитувань, що належать plugin, могли приймати +поля опитувань, специфічні для каналу, без блокування спочатку узагальненим парсером опитувань. Повну послідовність запуску див. у [Конвеєр завантаження](#load-pipeline). ## Модель володіння можливостями -OpenClaw розглядає native Plugin як межу володіння для **компанії** або +OpenClaw розглядає нативний plugin як межу володіння для **компанії** або **функції**, а не як набір не пов’язаних інтеграцій. Це означає: -- Plugin компанії зазвичай має володіти всіма поверхнями OpenClaw, що стосуються цієї компанії -- Plugin функції зазвичай має володіти повною поверхнею функції, яку він додає -- канали мають використовувати спільні можливості core замість того, щоб імпровізовано повторно - реалізовувати поведінку провайдера +- plugin компанії зазвичай має володіти всіма surface OpenClaw, що стосуються цієї компанії +- plugin функції зазвичай має володіти повним surface функції, яку він вводить +- channels мають споживати спільні можливості core замість спеціальної повторної реалізації + поведінки провайдера Приклади: -- вбудований Plugin `openai` відповідає за поведінку провайдера моделей OpenAI та за поведінку OpenAI для +- вбудований plugin `openai` володіє поведінкою провайдера моделей OpenAI та поведінкою OpenAI для мовлення + голосу в реальному часі + розуміння медіа + генерації зображень -- вбудований Plugin `elevenlabs` відповідає за поведінку мовлення ElevenLabs -- вбудований Plugin `microsoft` відповідає за поведінку мовлення Microsoft -- вбудований Plugin `google` відповідає за поведінку провайдера моделей Google, а також за поведінку Google для +- вбудований plugin `elevenlabs` володіє поведінкою мовлення ElevenLabs +- вбудований plugin `microsoft` володіє поведінкою мовлення Microsoft +- вбудований plugin `google` володіє поведінкою провайдера моделей Google, а також поведінкою Google для розуміння медіа + генерації зображень + вебпошуку -- вбудований Plugin `firecrawl` відповідає за поведінку Firecrawl для отримання вебвмісту -- вбудовані Plugin `minimax`, `mistral`, `moonshot` і `zai` відповідають за свої - бекенди розуміння медіа -- вбудований Plugin `qwen` відповідає за поведінку текстового провайдера Qwen, а також за - поведінку розуміння медіа та генерації відео -- Plugin `voice-call` є Plugin функції: він відповідає за транспорт викликів, інструменти, - CLI, маршрути та міст Twilio для медіапотоку, але використовує спільні можливості мовлення, +- вбудований plugin `firecrawl` володіє поведінкою Firecrawl для отримання вебданих +- вбудовані plugin `minimax`, `mistral`, `moonshot` і `zai` володіють своїми + бекендами розуміння медіа +- вбудований plugin `qwen` володіє поведінкою текстового провайдера Qwen, а також + поведінкою розуміння медіа та генерації відео +- plugin `voice-call` є plugin функції: він володіє транспортом викликів, tools, + CLI, routes і мостом медіапотоку Twilio, але споживає спільні можливості мовлення, а також транскрипції в реальному часі й голосу в реальному часі замість - прямого імпорту vendor Plugin + прямого імпорту plugin постачальників Бажаний кінцевий стан такий: -- OpenAI живе в одному Plugin, навіть якщо охоплює текстові моделі, мовлення, зображення та +- OpenAI живе в одному plugin, навіть якщо він охоплює текстові моделі, мовлення, зображення та майбутнє відео -- інший вендор може зробити те саме для власної поверхні -- канали не мають зважати, який vendor Plugin володіє провайдером; вони використовують +- інший постачальник може робити те саме для власної області surface +- channels не хвилює, який plugin постачальника володіє провайдером; вони споживають спільний контракт можливостей, який надає core -Ось ключова відмінність: +Це ключове розрізнення: - **plugin** = межа володіння -- **capability** = контракт core, який можуть реалізовувати або використовувати кілька Plugin +- **capability** = контракт core, який можуть реалізовувати або споживати кілька plugin -Тому, якщо OpenClaw додає нову доменну область, наприклад відео, перше запитання не таке: -«який провайдер має жорстко закодувати обробку відео?» Перше запитання таке: «який -контракт core для можливості відео?» Щойно такий контракт з’явиться, vendor Plugin -зможуть реєструватися для нього, а Plugin каналів/функцій зможуть його використовувати. +Отже, якщо OpenClaw додає нову область, наприклад відео, перше запитання не +«який провайдер має жорстко закодувати обробку відео?» Перше запитання — «яким є +контракт core для можливості відео?» Щойно цей контракт існує, plugin постачальників +можуть реєструватися для нього, а plugin каналів/функцій можуть його споживати. -Якщо можливість ще не існує, правильний крок зазвичай такий: +Якщо можливість ще не існує, зазвичай правильний крок такий: 1. визначити відсутню можливість у core -2. типізовано відкрити її через API/час виконання Plugin -3. під’єднати канали/функції до цієї можливості -4. дозволити vendor Plugin реєструвати реалізації +2. надати її через API/runtime plugin у типізований спосіб +3. під’єднати channels/functions до цієї можливості +4. дати plugin постачальників зареєструвати реалізації -Це зберігає явність володіння та водночас уникає поведінки core, яка залежить від -одного вендора або разового шляху коду, специфічного для Plugin. +Це зберігає явне володіння й водночас дозволяє уникати поведінки core, яка залежить +від одного постачальника або одноразового code path, специфічного для plugin. -### Шарування можливостей +### Нашарування можливостей -Використовуйте таку ментальну модель, коли вирішуєте, де має бути код: +Використовуйте таку ментальну модель, вирішуючи, де має бути код: -- **шар можливостей core**: спільна оркестрація, політика, fallback, - правила об’єднання config, семантика доставлення та типізовані контракти -- **шар vendor Plugin**: vendor-specific API, автентифікація, каталоги моделей, мовленнєвий - синтез, генерація зображень, майбутні бекенди відео, кінцеві точки використання -- **шар Plugin каналів/функцій**: інтеграція Slack/Discord/voice-call/etc., - яка використовує можливості core і подає їх на поверхню +- **шар можливостей core**: спільна оркестрація, політика, fallback, правила + злиття config, семантика доставки та типізовані контракти +- **шар plugin постачальника**: API, auth, каталоги моделей, мовлення, + синтез, генерація зображень, майбутні бекенди відео, endpoints використання, специфічні для постачальника +- **шар plugin каналу/функції**: інтеграція Slack/Discord/voice-call/etc., + яка споживає можливості core та подає їх через певний surface Наприклад, TTS має таку форму: -- core відповідає за політику TTS під час відповіді, порядок fallback, налаштування та доставлення в канали -- `openai`, `elevenlabs` і `microsoft` відповідають за реалізації синтезу -- `voice-call` використовує допоміжний засіб часу виконання TTS для телефонії +- core володіє політикою TTS під час відповіді, порядком fallback, prefs і доставкою в channel +- `openai`, `elevenlabs` і `microsoft` володіють реалізаціями синтезу +- `voice-call` споживає допоміжний засіб runtime TTS для телефонії -Цьому самому шаблону слід надавати перевагу й для майбутніх можливостей. +Той самий шаблон варто використовувати й для майбутніх можливостей. -### Приклад Plugin компанії з кількома можливостями +### Приклад plugin компанії з кількома можливостями -Plugin компанії має виглядати цілісним ззовні. Якщо OpenClaw має спільні -контракти для моделей, мовлення, транскрипції в реальному часі, голосу в реальному часі, розуміння -медіа, генерації зображень, генерації відео, отримання вебвмісту та вебпошуку, -вендор може володіти всіма своїми поверхнями в одному місці: +Plugin компанії має виглядати цілісним зовні. Якщо OpenClaw має спільні +контракти для моделей, мовлення, транскрипції в реальному часі, голосу в реальному часі, розуміння медіа, +генерації зображень, генерації відео, отримання вебданих і вебпошуку, +постачальник може володіти всіма своїми surface в одному місці: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -373,192 +374,193 @@ export default plugin; Важливі не точні назви допоміжних засобів. Важлива форма: -- один Plugin володіє поверхнею вендора -- core усе ще володіє контрактами можливостей -- канали та Plugin функцій використовують допоміжні засоби `api.runtime.*`, а не код вендора -- контрактні тести можуть перевіряти, що Plugin зареєстрував можливості, якими - він заявляє, що володіє +- один plugin володіє surface постачальника +- core, як і раніше, володіє контрактами можливостей +- channels і plugin функцій споживають допоміжні засоби `api.runtime.*`, а не код постачальника +- тести контрактів можуть перевіряти, що plugin зареєстрував можливості, якими, + за його твердженням, володіє ### Приклад можливості: розуміння відео OpenClaw уже розглядає розуміння зображень/аудіо/відео як одну спільну -можливість. Та сама модель володіння застосовується й тут: +можливість. Тут застосовується та сама модель володіння: 1. core визначає контракт розуміння медіа -2. vendor Plugin реєструють `describeImage`, `transcribeAudio` і - `describeVideo` там, де це доречно -3. канали та Plugin функцій використовують спільну поведінку core замість - прямого підключення до коду вендора +2. plugin постачальників реєструють `describeImage`, `transcribeAudio` і + `describeVideo`, де це доречно +3. channels і plugin функцій споживають спільну поведінку core замість + прямого підключення до коду постачальника -Це запобігає вбудовуванню припущень одного провайдера про відео в core. Plugin володіє -поверхнею вендора; core володіє контрактом можливості та поведінкою fallback. +Це запобігає вбудовуванню припущень одного провайдера щодо відео в core. Plugin володіє +surface постачальника; core володіє контрактом можливості та поведінкою fallback. Генерація відео вже використовує ту саму послідовність: core володіє типізованим -контрактом можливості та допоміжним засобом часу виконання, а vendor Plugin реєструють +контрактом можливості та допоміжним засобом runtime, а plugin постачальників реєструють реалізації `api.registerVideoGenerationProvider(...)` для цього контракту. -Потрібен конкретний контрольний список для впровадження? Див. -[Кулінарна книга можливостей](/uk/plugins/architecture). +Потрібен конкретний контрольний список розгортання? Див. +[Збірник рецептів можливостей](/uk/plugins/architecture). -## Контракти та примусове дотримання +## Контракти та примусове забезпечення -Поверхня API Plugin навмисно типізована та централізована в +Surface API plugin навмисно типізований і централізований у `OpenClawPluginApi`. Цей контракт визначає підтримувані точки реєстрації та -допоміжні засоби часу виконання, на які може покладатися Plugin. +допоміжні засоби runtime, на які plugin може покладатися. Чому це важливо: -- автори Plugin отримують один стабільний внутрішній стандарт -- core може відхиляти дубльоване володіння, наприклад коли два Plugin реєструють той самий +- автори plugin отримують один стабільний внутрішній стандарт +- core може відхиляти дублювання володіння, наприклад коли два plugin реєструють один і той самий id провайдера -- під час запуску можна показувати діагностику з практичними підказками для некоректної реєстрації -- контрактні тести можуть контролювати володіння вбудованими Plugin і запобігати тихому дрейфу +- під час запуску можна показувати придатну до дій діагностику для некоректної реєстрації +- тести контрактів можуть забезпечувати володіння вбудованих plugin і запобігати тихому дрейфу -Є два шари примусового дотримання: +Є два шари примусового забезпечення: -1. **примусове дотримання реєстрації під час виконання** - Реєстр Plugin перевіряє реєстрації під час завантаження Plugin. Приклади: +1. **примусове забезпечення під час реєстрації runtime** + Реєстр plugin валідовує реєстрації під час завантаження plugin. Приклади: дубльовані id провайдерів, дубльовані id провайдерів мовлення та некоректні - реєстрації створюють діагностику Plugin замість невизначеної поведінки. -2. **контрактні тести** - Вбудовані Plugin фіксуються в контрактних реєстрах під час прогонів тестів, щоб - OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для моделей - провайдерів, провайдерів мовлення, провайдерів вебпошуку та володіння реєстраціями - вбудованих Plugin. + реєстрації породжують діагностику plugin замість невизначеної поведінки. +2. **тести контрактів** + Вбудовані plugin фіксуються в реєстрах контрактів під час запуску тестів, щоб + OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для + провайдерів моделей, провайдерів мовлення, провайдерів вебпошуку та володіння + реєстрацією вбудованих plugin. -Практичний ефект такий: OpenClaw заздалегідь знає, який Plugin володіє якою -поверхнею. Це дає core і каналам змогу безшовно компонуватися, тому що володіння -оголошене, типізоване та тестоване, а не неявне. +Практичний ефект полягає в тому, що OpenClaw заздалегідь знає, який plugin яким +surface володіє. Це дозволяє core і channels безшовно компонуватися, оскільки володіння +оголошене, типізоване та придатне для тестування, а не неявне. -### Що має входити в контракт +### Що має входити до контракту -Хороші контракти Plugin є: +Хороші контракти plugin: -- типізованими -- невеликими -- специфічними для можливості -- такими, що належать core -- придатними до повторного використання кількома Plugin -- придатними для використання каналами/функціями без знання про вендора +- типізовані +- невеликі +- специфічні для можливості +- належать core +- придатні для повторного використання кількома plugin +- можуть споживатися channels/functions без знань про постачальника -Погані контракти Plugin — це: +Погані контракти plugin: -- vendor-specific політика, прихована в core -- разові аварійні шляхи для Plugin, які оминають реєстр -- код каналу, що напряму звертається до реалізації вендора -- спеціальні runtime-об’єкти, які не є частиною `OpenClawPluginApi` або +- політика, специфічна для постачальника, прихована в core +- одноразові обхідні шляхи plugin, які обходять реєстр +- код каналу, що напряму звертається до реалізації постачальника +- ad hoc об’єкти runtime, які не є частиною `OpenClawPluginApi` або `api.runtime` -Якщо сумніваєтеся, піднімайте рівень абстракції: спочатку визначте можливість, а вже потім -дозвольте Plugin підключатися до неї. +Якщо сумніваєтеся, підніміть рівень абстракції: спочатку визначте можливість, а +потім дозвольте plugin підключитися до неї. ## Модель виконання -Native Plugin OpenClaw працюють **у процесі** разом із Gateway. Вони не -ізольовані. Завантажений native Plugin має ту саму межу довіри на рівні процесу, що й +Нативні plugin OpenClaw працюють **у межах процесу** разом із Gateway. Вони не +ізольовані. Завантажений нативний plugin має ту саму межу довіри на рівні процесу, що й код core. Наслідки: -- native Plugin може реєструвати інструменти, мережеві обробники, хуки та сервіси -- помилка native Plugin може призвести до збою або дестабілізації gateway -- зловмисний native Plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw +- нативний plugin може реєструвати tools, обробники мережі, hooks і services +- помилка нативного plugin може аварійно завершити роботу gateway або дестабілізувати його +- зловмисний нативний plugin еквівалентний довільному виконанню коду всередині + процесу OpenClaw -Сумісні пакети безпечніші за замовчуванням, тому що OpenClaw наразі розглядає їх -як пакети метаданих/вмісту. У поточних випусках це переважно означає вбудовані +Сумісні bundles за замовчуванням безпечніші, оскільки OpenClaw наразі розглядає їх +як пакети метаданих/вмісту. У поточних релізах це здебільшого означає вбудовані Skills. -Використовуйте allowlist і явні шляхи встановлення/завантаження для невбудованих Plugin. Розглядайте -Plugin робочого простору як код для часу розробки, а не як типові значення для production. +Для невбудованих plugin використовуйте allowlist і явні шляхи встановлення/завантаження. Ставтеся до +workspace plugin як до коду для часу розробки, а не як до стандартного варіанта для production. -Для назв пакетів вбудованого робочого простору зберігайте id Plugin, прив’язаний до npm-імені: -`@openclaw/` за замовчуванням або погоджений типізований суфікс, як-от +Для назв пакетів bundled workspace зберігайте id plugin прив’язаним до назви npm: +`@openclaw/` за замовчуванням або з погодженим типізованим суфіксом, таким як `-provider`, `-plugin`, `-speech`, `-sandbox` або `-media-understanding`, коли -пакет навмисно надає вужчу роль Plugin. +пакет навмисно відкриває вужчу роль plugin. Важлива примітка щодо довіри: -- `plugins.allow` довіряє **id Plugin**, а не походженню джерела. -- Plugin робочого простору з тим самим id, що й у вбудованого Plugin, навмисно затінює - вбудовану копію, коли цей Plugin робочого простору увімкнено/додано до allowlist. +- `plugins.allow` довіряє **id plugin**, а не походженню джерела. +- Workspace plugin з тим самим id, що й вбудований plugin, навмисно затіняє + вбудовану копію, коли цей workspace plugin увімкнено/додано до allowlist. - Це нормально й корисно для локальної розробки, тестування патчів і hotfix. -- Довіра до вбудованого Plugin визначається зі знімка джерела — маніфесту та +- Довіра до вбудованого plugin визначається зі знімка джерела — маніфесту та коду на диску під час завантаження — а не з метаданих встановлення. Пошкоджений - або підмінений запис встановлення не може непомітно розширити поверхню довіри - вбудованого Plugin понад те, що заявляє фактичне джерело. + або підмінений запис встановлення не може непомітно розширити surface довіри + вбудованого plugin понад те, що фактично заявляє джерело. ## Межа експорту -OpenClaw експортує можливості, а не зручність реалізації. +OpenClaw експортує можливості, а не зручні реалізації. -Зберігайте публічність реєстрації можливостей. Скорочуйте допоміжні експорти, які не є контрактом: +Зберігайте публічною реєстрацію можливостей. Скорочуйте допоміжні експорти, що не є частиною контракту: -- допоміжні підшляхи, специфічні для вбудованих Plugin -- підшляхи runtime plumbing, які не призначені як публічний API -- vendor-specific допоміжні засоби для зручності +- subpath допоміжних засобів, специфічних для вбудованих plugin +- subpath plumbing runtime, які не призначені бути публічним API +- зручні допоміжні засоби, специфічні для постачальника - допоміжні засоби setup/onboarding, які є деталями реалізації -Деякі допоміжні підшляхи вбудованих Plugin усе ще залишаються у згенерованій карті експорту SDK -заради сумісності та підтримки вбудованих Plugin. Поточні приклади включають +Деякі subpath допоміжних засобів вбудованих plugin усе ще залишаються в згенерованій +карті експорту SDK для сумісності та підтримки вбудованих plugin. Поточні приклади включають `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, -`plugin-sdk/zalo-setup` і кілька поверхонь `plugin-sdk/matrix*`. Розглядайте їх як -зарезервовані експорти деталей реалізації, а не як рекомендований шаблон SDK для -нових сторонніх Plugin. +`plugin-sdk/zalo-setup` і кілька швів `plugin-sdk/matrix*`. Ставтеся до них як до +зарезервованих експортів деталей реалізації, а не як до рекомендованого шаблону SDK для +нових сторонніх plugin. ## Конвеєр завантаження -Під час запуску OpenClaw приблизно робить таке: +Під час запуску OpenClaw приблизно виконує таке: -1. виявляє корені потенційних Plugin -2. читає маніфести native або сумісних пакетів і метадані пакетів +1. виявляє корені кандидатів у plugin +2. читає нативні маніфести або маніфести сумісних bundle і метадані package 3. відхиляє небезпечних кандидатів -4. нормалізує config Plugin (`plugins.enabled`, `allow`, `deny`, `entries`, +4. нормалізує config plugin (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. вирішує, чи увімкнено кожного кандидата -6. завантажує увімкнені native модулі: зібрані вбудовані модулі використовують native loader; - незібрані native Plugin використовують jiti -7. викликає native хуки `register(api)` і збирає реєстрації в реєстр Plugin -8. відкриває реєстр для команд/поверхонь часу виконання +5. вирішує, чи вмикати кожного кандидата +6. завантажує увімкнені нативні модулі: зібрані вбудовані модулі використовують нативний loader; + незібрані нативні plugin використовують jiti +7. викликає нативні hooks `register(api)` і збирає реєстрації в реєстр plugin +8. відкриває реєстр для commands/surface runtime -`activate` — це застарілий псевдонім для `register` — loader визначає, що з них присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані Plugin використовують `register`; для нових Plugin надавайте перевагу `register`. +`activate` — це застарілий псевдонім для `register` — loader визначає, що саме присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані plugin використовують `register`; для нових plugin віддавайте перевагу `register`. -Перевірки безпеки відбуваються **до** виконання під час виконання. Кандидати блокуються, -коли точка входу виходить за межі кореня Plugin, шлях доступний на запис для всіх або -володіння шляхом виглядає підозріло для невбудованих Plugin. +Захисні перевірки відбуваються **до** виконання runtime. Кандидати блокуються, +коли entry виходить за межі кореня plugin, шлях доступний на запис для всіх, або +володіння шляхом виглядає підозріло для невбудованих plugin. ### Поведінка з пріоритетом маніфесту -Маніфест — це джерело істини для control plane. OpenClaw використовує його, щоб: +Маніфест є джерелом істини для control plane. OpenClaw використовує його, щоб: -- ідентифікувати Plugin -- виявляти оголошені канали/Skills/схему config або можливості пакетів -- перевіряти `plugins.entries..config` -- доповнювати мітки/placeholder-и Control UI +- ідентифікувати plugin +- виявляти оголошені channels/Skills/schema config або можливості bundle +- валідовувати `plugins.entries..config` +- доповнювати підписи/placeholders в Control UI - показувати метадані встановлення/каталогу -- зберігати дешеві дескриптори активації та setup без завантаження runtime Plugin +- зберігати дешеві дескриптори activation і setup без завантаження runtime plugin -Для native Plugin runtime-модуль є частиною data plane. Він реєструє -фактичну поведінку, таку як хуки, інструменти, команди або потоки провайдера. +Для нативних plugin модуль runtime — це частина data plane. Він реєструє +фактичну поведінку, таку як hooks, tools, commands або потоки провайдера. -Необов’язкові блоки маніфесту `activation` і `setup` залишаються в control plane. -Це лише дескриптори метаданих для планування активації та виявлення setup; -вони не замінюють реєстрацію під час виконання, `register(...)` або `setupEntry`. -Перші живі споживачі активації тепер використовують підказки маніфесту для команд, каналів і провайдерів, -щоб звузити завантаження Plugin перед ширшою матеріалізацією реєстру: +Необов’язкові блоки `activation` і `setup` в маніфесті залишаються в control plane. +Це лише метадані-дескриптори для планування activation і виявлення setup; +вони не замінюють реєстрацію runtime, `register(...)` або `setupEntry`. +Перші живі споживачі activation тепер використовують підказки маніфесту для commands, channels і providers, +щоб звузити завантаження plugin до ширшої матеріалізації реєстру: -- Завантаження CLI звужується до Plugin, які володіють запитаною основною командою -- налаштування каналу/визначення Plugin звужується до Plugin, які володіють запитаним - id каналу -- явне налаштування провайдера/визначення під час виконання звужується до Plugin, які володіють +- Завантаження CLI звужується до plugin, які володіють запитаною основною командою +- визначення setup/plugin для channel звужується до plugin, які володіють запитаним + id channel +- явне визначення setup/runtime провайдера звужується до plugin, які володіють запитаним id провайдера -Виявлення setup тепер надає перевагу id, що належать дескрипторам, таким як `setup.providers` і -`setup.cliBackends`, щоб звузити перелік кандидатів Plugin, перш ніж перейти до -`setup-api` для Plugin, яким усе ще потрібні runtime-хуки на етапі setup. Якщо більше -ніж один виявлений Plugin заявляє той самий нормалізований id провайдера setup або CLI-бекенда, -пошук setup відмовляє через неоднозначного власника замість покладання на порядок виявлення. +Виявлення setup тепер віддає перевагу id, що належать дескрипторам, таким як `setup.providers` і +`setup.cliBackends`, щоб звузити коло кандидатів plugin, перш ніж повертатися до +`setup-api` для plugin, яким усе ще потрібні hooks runtime на етапі setup. Якщо більше +ніж один виявлений plugin заявляє той самий нормалізований id провайдера setup або CLI backend, +пошук setup відхиляє неоднозначного власника замість того, щоб покладатися на порядок виявлення. ### Що кешує loader @@ -566,10 +568,10 @@ OpenClaw зберігає короткоживучі кеші в межах пр - результатів виявлення - даних реєстру маніфестів -- завантажених реєстрів Plugin +- завантажених реєстрів plugin -Ці кеші зменшують стрибкоподібні витрати під час запуску та повторних викликів команд. Їх безпечно -розглядати як короткоживучі кеші продуктивності, а не як постійне зберігання. +Ці кеші зменшують вибухове навантаження під час запуску та витрати на повторні команди. Їх безпечно +сприймати як короткоживучі кеші продуктивності, а не як постійне зберігання. Примітка щодо продуктивності: @@ -580,37 +582,37 @@ OpenClaw зберігає короткоживучі кеші в межах пр ## Модель реєстру -Завантажені Plugin не змінюють безпосередньо довільні глобальні змінні core. Вони -реєструються в центральному реєстрі Plugin. +Завантажені plugin не змінюють безпосередньо довільні глобальні об’єкти core. Вони реєструються +в центральному реєстрі plugin. Реєстр відстежує: -- записи Plugin (ідентичність, джерело, походження, статус, діагностика) -- інструменти -- застарілі хуки та типізовані хуки -- канали -- провайдери +- записи plugin (ідентичність, джерело, походження, статус, діагностика) +- tools +- застарілі hooks і типізовані hooks +- channels +- providers - обробники Gateway RPC -- HTTP-маршрути +- HTTP routes - реєстратори CLI -- фонові сервіси -- команди, що належать Plugin +- фонові services +- commands, що належать plugin -Потім можливості core читають із цього реєстру замість прямої взаємодії з модулями Plugin. +Потім функції core читають із цього реєстру замість прямої взаємодії з модулями plugin. Це зберігає односпрямованість завантаження: -- модуль Plugin -> реєстрація в реєстрі +- модуль plugin -> реєстрація в реєстрі - runtime core -> споживання реєстру -Це розділення важливе для супроводу. Воно означає, що більшості поверхонь core -потрібна лише одна точка інтеграції: «прочитати реєстр», а не «створювати спеціальний випадок для кожного модуля Plugin». +Це розділення важливе для підтримуваності. Воно означає, що більшості surface core +потрібна лише одна точка інтеграції: «прочитати реєстр», а не «додати спеціальний випадок для кожного модуля plugin». -## Зворотні виклики прив’язки розмов +## Зворотні виклики прив’язки розмови -Plugin, які прив’язують розмову, можуть реагувати, коли схвалення буде завершено. +Plugin, які прив’язують розмову, можуть реагувати, коли схвалення вирішено. -Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати зворотний виклик після схвалення -або відхилення запиту на прив’язку: +Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати зворотний виклик після того, +як запит на прив’язку схвалено або відхилено: ```ts export default { @@ -634,24 +636,24 @@ export default { - `status`: `"approved"` або `"denied"` - `decision`: `"allow-once"`, `"allow-always"` або `"deny"` -- `binding`: визначена прив’язка для схвалених запитів -- `request`: оригінальний підсумок запиту, підказка від’єднання, id відправника та +- `binding`: вирішена прив’язка для схвалених запитів +- `request`: підсумок початкового запиту, підказка від’єднання, id відправника та метадані розмови -Цей зворотний виклик є лише сповіщенням. Він не змінює, кому дозволено прив’язувати -розмову, і запускається після завершення обробки схвалення в core. +Цей зворотний виклик призначений лише для сповіщення. Він не змінює того, кому дозволено прив’язувати +розмову, і виконується після завершення обробки схвалення в core. -## Runtime-хуки провайдера +## Хуки runtime провайдера Plugin провайдерів тепер мають два шари: -- метадані маніфесту: `providerAuthEnvVars` для дешевого пошуку env-автентифікації провайдера - до завантаження runtime, `providerAuthAliases` для варіантів провайдера, які спільно використовують - автентифікацію, `channelEnvVars` для дешевого пошуку env/setup каналу до - завантаження runtime, а також `providerAuthChoices` для дешевих міток onboarding/вибору автентифікації та - метаданих CLI-прапорців до завантаження runtime -- хуки часу config: `catalog` / застарілий `discovery` плюс `applyConfigDefaults` -- runtime-хуки: `normalizeModelId`, `normalizeTransport`, +- метадані маніфесту: `providerAuthEnvVars` для дешевого пошуку env-auth провайдера + до завантаження runtime, `providerAuthAliases` для варіантів провайдера, які мають спільний + auth, `channelEnvVars` для дешевого пошуку env/setup channel до завантаження runtime, + а також `providerAuthChoices` для дешевих міток onboarding/auth-choice і + метаданих прапорців CLI до завантаження runtime +- hooks часу config: `catalog` / застарілий `discovery`, а також `applyConfigDefaults` +- hooks runtime: `normalizeModelId`, `normalizeTransport`, `normalizeConfig`, `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, `resolveSyntheticAuth`, `resolveExternalAuthProfiles`, @@ -671,88 +673,88 @@ Plugin провайдерів тепер мають два шари: `buildReplayPolicy`, `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` -OpenClaw усе ще володіє загальним циклом агента, failover, обробкою transcript і -політикою інструментів. Ці хуки є поверхнею розширення для поведінки, специфічної для провайдера, без -потреби в цілком окремому транспорті inference. +OpenClaw, як і раніше, володіє узагальненим циклом агента, failover, обробкою transcript і +політикою tools. Ці hooks є surface розширення для поведінки, специфічної для провайдера, без +необхідності мати повністю власний транспорт inference. -Використовуйте маніфест `providerAuthEnvVars`, коли провайдер має облікові дані на основі env, -які загальні шляхи auth/status/model-picker мають бачити без завантаження runtime Plugin. -Використовуйте маніфест `providerAuthAliases`, коли один id провайдера має повторно використовувати -env-змінні, профілі автентифікації, автентифікацію на основі config та варіант onboarding із API-ключем -іншого id провайдера. Використовуйте маніфест `providerAuthChoices`, коли поверхні CLI для onboarding/вибору автентифікації +Використовуйте `providerAuthEnvVars` у маніфесті, коли провайдер має облікові дані на основі env, +які загальні шляхи auth/status/model-picker повинні бачити без завантаження runtime plugin. +Використовуйте `providerAuthAliases` у маніфесті, коли один id провайдера має повторно використовувати +env vars, профілі auth, auth на основі config і варіант onboarding з API-key іншого id провайдера. +Використовуйте `providerAuthChoices` у маніфесті, коли surface CLI onboarding/auth-choice мають знати id варіанта провайдера, мітки груп і просту схему auth з одним прапорцем -без завантаження runtime провайдера. Зберігайте runtime `envVars` провайдера для -операторських підказок, таких як мітки onboarding або змінні setup для OAuth +без завантаження runtime провайдера. Зберігайте `envVars` runtime провайдера для підказок, +орієнтованих на операторів, таких як мітки onboarding або змінні setup для OAuth client-id/client-secret. -Використовуйте маніфест `channelEnvVars`, коли канал має auth або setup на основі env, які -загальний fallback до shell-env, перевірки config/status або запити setup мають бачити -без завантаження runtime каналу. +Використовуйте `channelEnvVars` у маніфесті, коли channel має auth або setup на основі env, які +загальний fallback shell-env, перевірки config/status або підказки setup повинні бачити +без завантаження runtime channel. -### Порядок хуків і використання +### Порядок hooks і використання -Для Plugin моделей/провайдерів OpenClaw викликає хуки приблизно в такому порядку. -Стовпець «Коли використовувати» — це короткий посібник для прийняття рішення. +Для plugin моделей/провайдерів OpenClaw викликає hooks приблизно в такому порядку. +Стовпець «Коли використовувати» — це короткий посібник для прийняття рішень. -| # | Хук | Що він робить | Коли використовувати | +| # | Hook | Що він робить | Коли використовувати | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | Публікує config провайдера в `models.providers` під час генерації `models.json` | Провайдер володіє каталогом або базовими значеннями `base URL` | -| 2 | `applyConfigDefaults` | Застосовує глобальні значення config за замовчуванням, що належать провайдеру, під час матеріалізації config | Значення за замовчуванням залежать від режиму auth, env або семантики сімейства моделей провайдера | -| -- | _(вбудований пошук моделі)_ | OpenClaw спочатку намагається використати звичайний шлях реєстру/каталогу | _(це не хук Plugin)_ | -| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми model-id перед пошуком | Провайдер володіє очищенням псевдонімів перед визначенням канонічної моделі | -| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства провайдера перед загальним складанням моделі | Провайдер володіє очищенням транспорту для користувацьких id провайдерів у тому самому сімействі транспорту | -| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед визначенням runtime/провайдера | Провайдеру потрібне очищення config, яке має жити разом із Plugin; допоміжні засоби вбудованого сімейства Google також підстраховують підтримувані записи config Google | -| 6 | `applyNativeStreamingUsageCompat` | Застосовує сумісні переписування використання native streaming до config провайдерів | Провайдеру потрібні виправлення метаданих використання native streaming, що залежать від кінцевої точки | -| 7 | `resolveConfigApiKey` | Визначає auth через env-marker для config провайдерів до завантаження runtime auth | Провайдер має власне визначення API-ключа через env-marker; `amazon-bedrock` також має тут вбудований розв’язувач env-marker AWS | -| 8 | `resolveSyntheticAuth` | Показує локальну/self-hosted або config-based auth без збереження відкритого тексту | Провайдер може працювати із синтетичним/локальним маркером облікових даних | -| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні auth-профілі, що належать провайдеру; значення `persistence` за замовчуванням — `runtime-only` для облікових даних, що належать CLI/app | Провайдер повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token; оголосіть `contracts.externalAuthProviders` у маніфесті | -| 10 | `shouldDeferSyntheticProfileAuth` | Знижує пріоритет збережених синтетичних заповнювачів профілю порівняно з auth на основі env/config | Провайдер зберігає синтетичні профілі-заповнювачі, які не повинні мати вищий пріоритет | -| 11 | `resolveDynamicModel` | Синхронний fallback для model id, що належать провайдеру, але ще відсутні в локальному реєстрі | Провайдер приймає довільні upstream model id | -| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` запускається знову | Провайдеру потрібні мережеві метадані до визначення невідомих id | -| 13 | `normalizeResolvedModel` | Фінальне переписування перед тим, як embedded runner використовує визначену модель | Провайдеру потрібні переписування транспорту, але він усе ще використовує транспорт core | -| 14 | `contributeResolvedModelCompat` | Додає прапорці сумісності для моделей вендора за іншим сумісним транспортом | Провайдер розпізнає власні моделі на proxy-транспортах, не перебираючи на себе самого провайдера | -| 15 | `capabilities` | Метадані transcript/інструментів, що належать провайдеру й використовуються спільною логікою core | Провайдеру потрібні особливості transcript/сімейства провайдера | -| 16 | `normalizeToolSchemas` | Нормалізує схеми інструментів до того, як їх побачить embedded runner | Провайдеру потрібне очищення схем для сімейства транспорту | -| 17 | `inspectToolSchemas` | Показує діагностику схем, що належить провайдеру, після нормалізації | Провайдер хоче попередження щодо ключових слів без навчання core правилам, специфічним для провайдера | -| 18 | `resolveReasoningOutputMode` | Вибирає native чи позначений контракт виводу reasoning | Провайдеру потрібен позначений reasoning/фінальний вивід замість native полів | -| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед загальними обгортками опцій потоку | Провайдеру потрібні параметри запиту за замовчуванням або очищення параметрів для конкретного провайдера | -| 20 | `createStreamFn` | Повністю замінює звичайний шлях потоку користувацьким транспортом | Провайдеру потрібен користувацький wire protocol, а не просто обгортка | -| 21 | `wrapStreamFn` | Обгортка потоку після застосування загальних обгорток | Провайдеру потрібні обгортки сумісності для заголовків/тіла запиту/моделі без користувацького транспорту | -| 22 | `resolveTransportTurnState` | Прикріплює native заголовки транспорту або метадані для кожного кроку | Провайдер хоче, щоб загальні транспорти надсилали native ідентичність кроку провайдера | -| 23 | `resolveWebSocketSessionPolicy` | Прикріплює native заголовки WebSocket або політику охолодження сесії | Провайдер хоче, щоб загальні WS-транспорти налаштовували заголовки сесії або політику fallback | -| 24 | `formatApiKey` | Форматувач auth-профілю: збережений профіль стає рядком runtime `apiKey` | Провайдер зберігає додаткові метадані auth і потребує користувацької форми runtime-токена | -| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для користувацьких кінцевих точок оновлення або політики помилок оновлення | Провайдер не відповідає спільним механізмам оновлення `pi-ai` | -| 26 | `buildAuthDoctorHint` | Підказка з виправлення, що додається, коли оновлення OAuth завершується помилкою | Провайдеру потрібні власні рекомендації з відновлення auth після помилки оновлення | -| 27 | `matchesContextOverflowError` | Засіб зіставлення переповнення вікна контексту, що належить провайдеру | Провайдер має сирі помилки переповнення, які загальні евристики не побачать | -| 28 | `classifyFailoverReason` | Класифікація причини failover, що належить провайдеру | Провайдер може зіставляти сирі помилки API/транспорту з rate-limit/overload тощо | -| 29 | `isCacheTtlEligible` | Політика prompt-cache для proxy/backhaul-провайдерів | Провайдеру потрібне керування TTL кешу, специфічне для proxy | -| 30 | `buildMissingAuthMessage` | Замінює загальне повідомлення відновлення при відсутній auth | Провайдеру потрібна підказка відновлення при відсутній auth, специфічна для провайдера | -| 31 | `suppressBuiltInModel` | Приховування застарілих upstream-моделей плюс необов’язкова підказка про помилку для користувача | Провайдеру потрібно приховати застарілі upstream-рядки або замінити їх підказкою від вендора | -| 32 | `augmentModelCatalog` | Додає синтетичні/фінальні рядки каталогу після виявлення | Провайдеру потрібні синтетичні рядки для прямої сумісності в `models list` і засобах вибору | -| 33 | `resolveThinkingProfile` | Установлює рівень `/think`, мітки відображення та значення за замовчуванням для конкретної моделі | Провайдер надає користувацьку шкалу thinking або бінарну мітку для вибраних моделей | -| 34 | `isBinaryThinking` | Хук сумісності для перемикача reasoning увімкнено/вимкнено | Провайдер надає лише бінарний режим thinking увімкнено/вимкнено | -| 35 | `supportsXHighThinking` | Хук сумісності для підтримки reasoning `xhigh` | Провайдер хоче `xhigh` лише для підмножини моделей | -| 36 | `resolveDefaultThinkingLevel` | Хук сумісності для рівня `/think` за замовчуванням | Провайдер володіє політикою `/think` за замовчуванням для сімейства моделей | -| 37 | `isModernModelRef` | Засіб зіставлення modern-model для фільтрів live-профілів і вибору smoke | Провайдер володіє зіставленням бажаних моделей для live/smoke | -| 38 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний runtime-токен/ключ безпосередньо перед inference | Провайдеру потрібен обмін токена або короткоживучі облікові дані запиту | -| 39 | `resolveUsageAuth` | Визначає облікові дані використання/білінгу для `/usage` та пов’язаних поверхонь статусу | Провайдеру потрібен користувацький розбір токена використання/квоти або інші облікові дані використання | -| 40 | `fetchUsageSnapshot` | Отримує та нормалізує специфічні для провайдера знімки використання/квоти після визначення auth | Провайдеру потрібна специфічна для провайдера кінцева точка використання або парсер корисного навантаження | -| 41 | `createEmbeddingProvider` | Створює адаптер embedding, що належить провайдеру, для пам’яті/пошуку | Поведінка embedding для пам’яті має належати Plugin провайдера | -| 42 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою transcript для провайдера | Провайдеру потрібна користувацька політика transcript (наприклад, видалення блоків thinking) | -| 43 | `sanitizeReplayHistory` | Переписує історію replay після загального очищення transcript | Провайдеру потрібні переписування replay, специфічні для провайдера, поза межами спільних допоміжних засобів Compaction | -| 44 | `validateReplayTurns` | Фінальна перевірка або переформатування кроків replay перед embedded runner | Транспорту провайдера потрібна суворіша перевірка кроків після загальної санітизації | -| 45 | `onModelSelected` | Виконує побічні ефекти після вибору моделі, що належать провайдеру | Провайдеру потрібна телеметрія або стан, що належить провайдеру, коли модель стає активною | +| 1 | `catalog` | Публікує config провайдера в `models.providers` під час генерації `models.json` | Провайдер володіє каталогом або типовими значеннями `base URL` | +| 2 | `applyConfigDefaults` | Застосовує типові глобальні значення config, що належать провайдеру, під час матеріалізації config | Типові значення залежать від режиму auth, env або семантики сімейства моделей провайдера | +| -- | _(built-in model lookup)_ | OpenClaw спочатку намагається використати звичайний шлях реєстру/каталогу | _(не є hook plugin)_ | +| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми model-id перед пошуком | Провайдер володіє очищенням псевдонімів перед канонічним визначенням моделі | +| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства провайдера перед узагальненим збиранням моделі | Провайдер володіє очищенням transport для користувацьких id провайдера в тому самому сімействі transport | +| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед визначенням runtime/провайдера | Провайдеру потрібне очищення config, яке має жити разом із plugin; вбудовані допоміжні засоби сімейства Google також страхують підтримувані записи Google config | +| 6 | `applyNativeStreamingUsageCompat` | Застосовує переписування сумісності використання нативного streaming до провайдерів config | Провайдеру потрібні виправлення метаданих використання нативного streaming, що залежать від endpoint | +| 7 | `resolveConfigApiKey` | Визначає auth з env-marker для провайдерів config до завантаження auth runtime | Провайдер має власне визначення API-key з env-marker; `amazon-bedrock` також має тут вбудований resolver AWS env-marker | +| 8 | `resolveSyntheticAuth` | Показує локальний/self-hosted або auth на основі config без збереження відкритого тексту | Провайдер може працювати із синтетичним/локальним маркером облікових даних | +| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі auth, що належать провайдеру; типове значення `persistence` — `runtime-only` для облікових даних CLI/app | Провайдер повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token; оголосіть `contracts.externalAuthProviders` у маніфесті | +| 10 | `shouldDeferSyntheticProfileAuth` | Опускає збережені синтетичні заповнювачі профілів нижче auth на основі env/config | Провайдер зберігає синтетичні профілі-заповнювачі, які не мають мати вищий пріоритет | +| 11 | `resolveDynamicModel` | Синхронний fallback для model id, що належать провайдеру, але ще відсутні в локальному реєстрі | Провайдер приймає довільні upstream model id | +| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` запускається знову | Провайдеру потрібні мережеві метадані перед визначенням невідомих id | +| 13 | `normalizeResolvedModel` | Остаточне переписування перед тим, як embedded runner використає визначену модель | Провайдеру потрібні переписування transport, але він усе ще використовує transport core | +| 14 | `contributeResolvedModelCompat` | Додає прапорці compat для моделей постачальника за іншим сумісним transport | Провайдер розпізнає власні моделі на proxy transport без перехоплення ролі провайдера | +| 15 | `capabilities` | Метадані transcript/tooling, що належать провайдеру та використовуються спільною логікою core | Провайдеру потрібні особливості transcript/сімейства провайдера | +| 16 | `normalizeToolSchemas` | Нормалізує схеми tools до того, як їх побачить embedded runner | Провайдеру потрібне очищення схем для сімейства transport | +| 17 | `inspectToolSchemas` | Показує діагностику схем, що належить провайдеру, після нормалізації | Провайдер хоче попередження щодо ключових слів без навчання core правилам, специфічним для провайдера | +| 18 | `resolveReasoningOutputMode` | Вибирає нативний чи тегований контракт виводу reasoning | Провайдеру потрібен тегований вивід reasoning/final замість нативних полів | +| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед узагальненими обгортками параметрів stream | Провайдеру потрібні типові параметри запиту або очищення параметрів для конкретного провайдера | +| 20 | `createStreamFn` | Повністю замінює звичайний шлях stream на користувацький transport | Провайдеру потрібен користувацький wire protocol, а не просто обгортка | +| 21 | `wrapStreamFn` | Обгортка stream після застосування узагальнених обгорток | Провайдеру потрібні обгортки сумісності заголовків/тіла/моделі запиту без користувацького transport | +| 22 | `resolveTransportTurnState` | Додає нативні заголовки або метадані transport для кожного кроку | Провайдер хоче, щоб узагальнені transport надсилали нативну для провайдера ідентичність кроку | +| 23 | `resolveWebSocketSessionPolicy` | Додає нативні заголовки WebSocket або політику cooldown сесії | Провайдер хоче, щоб узагальнені transport WS налаштовували заголовки сесії або політику fallback | +| 24 | `formatApiKey` | Форматувач auth-profile: збережений профіль стає рядком `apiKey` для runtime | Провайдер зберігає додаткові метадані auth і потребує користувацьку форму токена для runtime | +| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для користувацьких endpoint оновлення або політики помилки оновлення | Провайдер не відповідає спільним засобам оновлення `pi-ai` | +| 26 | `buildAuthDoctorHint` | Підказка виправлення, що додається, коли оновлення OAuth завершується помилкою | Провайдеру потрібні власні рекомендації з відновлення auth після помилки оновлення | +| 27 | `matchesContextOverflowError` | Matcher переповнення вікна контексту, що належить провайдеру | Провайдер має сирі помилки переповнення, які узагальнені евристики не розпізнають | +| 28 | `classifyFailoverReason` | Класифікація причин failover, що належить провайдеру | Провайдер може зіставляти сирі помилки API/transport з rate-limit/overload тощо | +| 29 | `isCacheTtlEligible` | Політика prompt-cache для proxy/backhaul-провайдерів | Провайдеру потрібне керування TTL кешу, специфічне для proxy | +| 30 | `buildMissingAuthMessage` | Заміна узагальненого повідомлення відновлення при відсутності auth | Провайдеру потрібна власна підказка відновлення для відсутньої auth | +| 31 | `suppressBuiltInModel` | Пригнічення застарілої upstream-моделі плюс необов’язкова орієнтована на користувача підказка про помилку | Провайдеру потрібно приховати застарілі upstream-рядки або замінити їх підказкою постачальника | +| 32 | `augmentModelCatalog` | Синтетичні/фінальні рядки каталогу, додані після виявлення | Провайдеру потрібні синтетичні рядки прямої сумісності в `models list` і засобах вибору | +| 33 | `resolveThinkingProfile` | Задання рівня `/think`, міток відображення та типового значення для конкретної моделі | Провайдер відкриває користувацьку шкалу thinking або двійкову мітку для вибраних моделей | +| 34 | `isBinaryThinking` | Hook сумісності перемикача reasoning увімкнено/вимкнено | Провайдер відкриває лише двійковий режим thinking увімкнено/вимкнено | +| 35 | `supportsXHighThinking` | Hook сумісності підтримки reasoning `xhigh` | Провайдер хоче `xhigh` лише для підмножини моделей | +| 36 | `resolveDefaultThinkingLevel` | Hook сумісності типового рівня `/think` | Провайдер володіє типовою політикою `/think` для сімейства моделей | +| 37 | `isModernModelRef` | Matcher сучасних моделей для фільтрів live profiles і вибору smoke | Провайдер володіє зіставленням бажаних моделей для live/smoke | +| 38 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний токен/ключ runtime безпосередньо перед inference | Провайдеру потрібен обмін токенів або короткоживучі облікові дані запиту | +| 39 | `resolveUsageAuth` | Визначає облікові дані usage/billing для `/usage` і пов’язаних surface статусу | Провайдеру потрібен користувацький парсинг токена usage/quota або інші облікові дані usage | +| 40 | `fetchUsageSnapshot` | Отримує та нормалізує знімки usage/quota, специфічні для провайдера, після визначення auth | Провайдеру потрібен endpoint usage, специфічний для провайдера, або parser корисного навантаження | +| 41 | `createEmbeddingProvider` | Створює адаптер embedding, що належить провайдеру, для memory/search | Поведінка embedding для memory має належати plugin провайдера | +| 42 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою transcript для провайдера | Провайдеру потрібна користувацька політика transcript, наприклад видалення блоків thinking | +| 43 | `sanitizeReplayHistory` | Переписує історію replay після узагальненого очищення transcript | Провайдеру потрібні переписування replay, специфічні для провайдера, понад спільні допоміжні засоби Compaction | +| 44 | `validateReplayTurns` | Остаточна валідація або переформування кроків replay перед embedded runner | Transport провайдера потребує суворішої валідації кроків після узагальненої санації | +| 45 | `onModelSelected` | Виконує побічні ефекти після вибору, що належать провайдеру | Провайдеру потрібна телеметрія або стан, що належить провайдеру, коли модель стає активною | `normalizeModelId`, `normalizeTransport` і `normalizeConfig` спочатку перевіряють -зіставлений Plugin провайдера, а потім переходять до інших Plugin провайдерів, здатних до хуків, -доки один із них фактично не змінить id моделі або transport/config. Це зберігає -працездатність shim-адаптерів псевдонімів/сумісності провайдерів без потреби для викликача знати, -який вбудований Plugin володіє переписуванням. Якщо жоден хук провайдера не перепише -підтримуваний запис config сімейства Google, вбудований нормалізатор config Google все одно -застосує це очищення сумісності. +відповідний plugin провайдера, а потім переходять до інших plugin провайдерів із підтримкою hooks, +доки один із них фактично не змінить id моделі або transport/config. Це дозволяє +shim для псевдонімів/сумісності провайдерів працювати без необхідності, щоб викликач знав, +який саме вбудований plugin володіє цим переписуванням. Якщо жоден hook провайдера не переписує +підтримуваний запис config сімейства Google, вбудований нормалізатор Google config усе одно +застосовує це очищення сумісності. Якщо провайдеру потрібен повністю користувацький wire protocol або користувацький виконавець запитів, -це вже інший клас розширення. Ці хуки призначені для поведінки провайдера, яка +це вже інший клас розширення. Ці hooks призначені для поведінки провайдера, яка все ще працює в межах звичайного циклу inference OpenClaw. ### Приклад провайдера @@ -811,35 +813,35 @@ api.registerProvider({ ### Вбудовані приклади -Вбудовані Plugin провайдерів використовують наведені вище хуки в комбінаціях, адаптованих до -потреб кожного вендора щодо каталогу, auth, thinking, replay і відстеження використання. Точний -набір хуків для кожного провайдера міститься разом із вихідним кодом Plugin у `extensions/`; вважайте -це авторитетним списком замість дублювання тут. +Вбудовані plugin провайдерів використовують наведені вище hooks у поєднаннях, адаптованих до +потреб кожного постачальника щодо каталогу, auth, thinking, replay і відстеження usage. Точний +набір hooks для кожного провайдера розміщено разом із вихідним кодом plugin у `extensions/`; вважайте +це авторитетним списком, а не дублюйте його тут. Показові шаблони: -- **Провайдери каталогу з pass-through** (OpenRouter, Kilocode, Z.AI, xAI) реєструють +- **Провайдери каталогу з наскрізною передачею** (OpenRouter, Kilocode, Z.AI, xAI) реєструють `catalog` разом із `resolveDynamicModel`/`prepareDynamicModel`, щоб вони могли показувати - upstream model id раніше за статичний каталог OpenClaw. -- **Провайдери з OAuth + кінцевою точкою використання** (GitHub Copilot, Gemini CLI, ChatGPT + upstream model id раніше, ніж статичний каталог OpenClaw. +- **Провайдери з OAuth + endpoint usage** (GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi, z.ai) поєднують `prepareRuntimeAuth` або `formatApiKey` - з `resolveUsageAuth` + `fetchUsageSnapshot`, щоб володіти обміном токенів і + із `resolveUsageAuth` + `fetchUsageSnapshot`, щоб керувати обміном токенів і інтеграцією `/usage`. - **Очищення replay / transcript** спільно використовується через іменовані сімейства: `google-gemini`, `passthrough-gemini`, `anthropic-by-model`, `hybrid-anthropic-openai`. Провайдери підключаються через `buildReplayPolicy`, - замість того щоб кожен окремо реалізовував очищення transcript. -- **Лише каталогові** вбудовані провайдери (`byteplus`, `cloudflare-ai-gateway`, + а не реалізують очищення transcript кожен окремо. +- **Лише каталог** вбудовані провайдери (`byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, `synthetic`, `together`, - `venice`, `vercel-ai-gateway`, `volcengine`) реєструють лише `catalog` і працюють - на спільному циклі inference. -- **Специфічні для Anthropic допоміжні засоби потоку** (beta-заголовки, `/fast`/`serviceTier`, - `context1m`) розміщено всередині публічної поверхні `api.ts` / - `contract-api.ts` вбудованого Plugin Anthropic (`wrapAnthropicProviderStream`, `resolveAnthropicBetas`, + `venice`, `vercel-ai-gateway`, `volcengine`) реєструють лише `catalog` і + працюють на спільному циклі inference. +- **Допоміжні засоби stream, специфічні для Anthropic** (beta headers, `/fast`/`serviceTier`, + `context1m`) розміщені всередині публічного шва `api.ts` / + `contract-api.ts` вбудованого plugin Anthropic (`wrapAnthropicProviderStream`, `resolveAnthropicBetas`, `resolveAnthropicFastMode`, `resolveAnthropicServiceTier`), а не в - загальному SDK. + узагальненому SDK. -## Допоміжні засоби часу виконання +## Допоміжні засоби runtime Plugin можуть отримувати доступ до вибраних допоміжних засобів core через `api.runtime`. Для TTS: @@ -862,11 +864,11 @@ const voices = await api.runtime.tts.listVoices({ Примітки: -- `textToSpeech` повертає звичайне корисне навантаження виводу TTS із core для поверхонь файлів/голосових повідомлень. -- Використовує config `messages.tts` і вибір провайдера з core. -- Повертає PCM audio buffer + sample rate. Plugin мають виконувати ресемплінг/кодування для провайдерів. -- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для засобів вибору голосу або потоків setup, що належать вендору. -- Списки голосів можуть містити багатші метадані, як-от locale, стать і теги особистості для засобів вибору, обізнаних про провайдера. +- `textToSpeech` повертає звичайне корисне навантаження виводу TTS core для surface файлів/голосових нотаток. +- Використовує config core `messages.tts` і вибір провайдера. +- Повертає PCM audio buffer + частоту дискретизації. Plugin мають виконувати ресемплінг/кодування для провайдерів. +- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для засобів вибору голосу або потоків setup, що належать постачальнику. +- Списки голосів можуть включати багатші метадані, як-от мова, стать і теги особистості для засобів вибору, обізнаних про провайдера. - OpenAI і ElevenLabs сьогодні підтримують телефонію. Microsoft — ні. Plugin також можуть реєструвати провайдерів мовлення через `api.registerSpeechProvider(...)`. @@ -889,15 +891,15 @@ api.registerSpeechProvider({ Примітки: -- Зберігайте політику TTS, fallback і доставлення відповідей у core. -- Використовуйте провайдерів мовлення для поведінки синтезу, що належить вендору. +- Зберігайте політику TTS, fallback і доставку відповідей у core. +- Використовуйте провайдерів мовлення для поведінки синтезу, що належить постачальнику. - Застарілий вхід Microsoft `edge` нормалізується до id провайдера `microsoft`. -- Рекомендована модель володіння — орієнтована на компанію: один vendor Plugin може - володіти текстовими, мовленнєвими, графічними та майбутніми медіапровайдерами, коли OpenClaw додає ці - контракти можливостей. +- Бажана модель володіння є орієнтованою на компанію: один plugin постачальника може володіти + текстовими, мовленнєвими, графічними та майбутніми медіапровайдерами, коли OpenClaw додає + відповідні контракти можливостей. -Для розуміння зображень/аудіо/відео Plugin реєструють один типізований -провайдер media-understanding замість загального key/value-масиву: +Для розуміння зображень/аудіо/відео plugin реєструють один типізований +провайдер media-understanding замість узагальненого набору key/value: ```ts api.registerMediaUnderstandingProvider({ @@ -911,16 +913,16 @@ api.registerMediaUnderstandingProvider({ Примітки: -- Зберігайте оркестрацію, fallback, config і підключення каналів у core. -- Зберігайте поведінку вендора в Plugin провайдера. +- Зберігайте оркестрацію, fallback, config і підключення до channel у core. +- Зберігайте поведінку постачальника в plugin провайдера. - Адитивне розширення має залишатися типізованим: нові необов’язкові методи, нові необов’язкові поля результату, нові необов’язкові можливості. -- Генерація відео вже наслідує той самий шаблон: - - core володіє контрактом можливості та допоміжним засобом часу виконання - - vendor Plugin реєструють `api.registerVideoGenerationProvider(...)` - - Plugin функцій/каналів використовують `api.runtime.videoGeneration.*` +- Генерація відео вже дотримується того самого шаблону: + - core володіє контрактом можливості та допоміжним засобом runtime + - plugin постачальників реєструють `api.registerVideoGenerationProvider(...)` + - plugin функцій/channel споживають `api.runtime.videoGeneration.*` -Для runtime-допоміжних засобів media-understanding Plugin можуть викликати: +Для допоміжних засобів runtime media-understanding plugin можуть викликати: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -935,7 +937,7 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -Для транскрипції аудіо Plugin можуть використовувати або runtime media-understanding, +Для транскрипції аудіо plugin можуть використовувати або runtime media-understanding, або старіший псевдонім STT: ```ts @@ -949,13 +951,13 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ Примітки: -- `api.runtime.mediaUnderstanding.*` — це рекомендована спільна поверхня для +- `api.runtime.mediaUnderstanding.*` — це бажаний спільний surface для розуміння зображень/аудіо/відео. -- Використовує config аудіо розуміння медіа з core (`tools.media.audio`) і порядок fallback провайдерів. -- Повертає `{ text: undefined }`, коли вихід транскрипції не створено (наприклад, для пропущеного/непідтримуваного вводу). -- `api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом для сумісності. +- Використовує core media-understanding audio config (`tools.media.audio`) і порядок fallback провайдерів. +- Повертає `{ text: undefined }`, коли вихід транскрипції не створюється (наприклад, для пропущеного/непідтримуваного вводу). +- `api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом сумісності. -Plugin також можуть запускати фонові прогони subagent через `api.runtime.subagent`: +Plugin також можуть запускати фонові підзапуски subagent через `api.runtime.subagent`: ```ts const result = await api.runtime.subagent.run({ @@ -969,14 +971,14 @@ const result = await api.runtime.subagent.run({ Примітки: -- `provider` і `model` — це необов’язкові перевизначення для окремого прогону, а не постійні зміни сесії. +- `provider` і `model` — це необов’язкові перевизначення для окремого запуску, а не постійні зміни session. - OpenClaw враховує ці поля перевизначення лише для довірених викликачів. -- Для прогонів fallback, що належать Plugin, оператори мають явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. -- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені Plugin конкретними канонічними цілями `provider/model`, або `"*"` для явного дозволу будь-якої цілі. -- Прогони subagent для недовірених Plugin теж працюють, але запити на перевизначення відхиляються замість тихого переходу на fallback. +- Для fallback-запусків, що належать plugin, оператори мають явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. +- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені plugin конкретними канонічними цілями `provider/model`, або `"*"`, щоб явно дозволити будь-яку ціль. +- Недовірені запуски subagent від plugin теж працюють, але запити на перевизначення відхиляються замість тихого fallback. -Для вебпошуку Plugin можуть використовувати спільний runtime-допоміжний засіб замість -прямого доступу до підключення інструмента агента: +Для вебпошуку plugin можуть споживати спільний допоміжний засіб runtime замість +звернення до підключення tool агента: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -997,9 +999,9 @@ Plugin також можуть реєструвати провайдерів в Примітки: -- Зберігайте вибір провайдера, визначення облікових даних і спільну семантику запиту в core. -- Використовуйте провайдерів вебпошуку для vendor-specific транспортів пошуку. -- `api.runtime.webSearch.*` — це рекомендована спільна поверхня для Plugin функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструмента агента. +- Зберігайте вибір провайдера, визначення облікових даних і спільну семантику запитів у core. +- Використовуйте провайдерів вебпошуку для транспортів пошуку, специфічних для постачальника. +- `api.runtime.webSearch.*` — це бажаний спільний surface для plugin функцій/channel, яким потрібна поведінка пошуку без залежності від обгортки tool агента. ### `api.runtime.imageGeneration` @@ -1014,12 +1016,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`: генерує зображення, використовуючи налаштований ланцюжок провайдерів генерації зображень. -- `listProviders(...)`: показує доступних провайдерів генерації зображень та їхні можливості. +- `generate(...)`: генерує зображення за допомогою налаштованого ланцюжка провайдерів генерації зображень. +- `listProviders(...)`: перелічує доступних провайдерів генерації зображень та їхні можливості. -## Gateway HTTP-маршрути +## HTTP routes Gateway -Plugin можуть відкривати HTTP-ендпоїнти через `api.registerHttpRoute(...)`. +Plugin можуть відкривати HTTP endpoints за допомогою `api.registerHttpRoute(...)`. ```ts api.registerHttpRoute({ @@ -1034,137 +1036,138 @@ api.registerHttpRoute({ }); ``` -Поля маршруту: +Поля route: -- `path`: шлях маршруту під HTTP-сервером Gateway. -- `auth`: обов’язкове. Використовуйте `"gateway"`, щоб вимагати звичайну auth Gateway, або `"plugin"` для auth/перевірки Webhook, якими керує Plugin. -- `match`: необов’язкове. `"exact"` (типово) або `"prefix"`. -- `replaceExisting`: необов’язкове. Дозволяє тому самому Plugin замінити власну наявну реєстрацію маршруту. -- `handler`: повертайте `true`, коли маршрут обробив запит. +- `path`: шлях route під HTTP-сервером gateway. +- `auth`: обов’язкове поле. Використовуйте `"gateway"`, щоб вимагати звичайний auth gateway, або `"plugin"` для auth/webhook verification, якими керує plugin. +- `match`: необов’язкове поле. `"exact"` (типово) або `"prefix"`. +- `replaceExisting`: необов’язкове поле. Дозволяє тому самому plugin замінити власну наявну реєстрацію route. +- `handler`: повертайте `true`, коли route обробив запит. Примітки: -- `api.registerHttpHandler(...)` видалено, і він спричинить помилку завантаження Plugin. Натомість використовуйте `api.registerHttpRoute(...)`. -- Маршрути Plugin мають явно оголошувати `auth`. -- Конфлікти точного `path + match` відхиляються, якщо не задано `replaceExisting: true`, і один Plugin не може замінити маршрут іншого Plugin. -- Маршрути, що перекриваються, з різними рівнями `auth` відхиляються. Ланцюжки fallthrough `exact`/`prefix` мають бути лише в межах одного рівня auth. -- Маршрути `auth: "plugin"` **не** отримують автоматично області runtime оператора. Вони призначені для Webhook або перевірки підпису, якими керує Plugin, а не для привілейованих допоміжних викликів Gateway. -- Маршрути `auth: "gateway"` виконуються в межах області runtime запиту Gateway, але ця область навмисно консервативна: - - bearer-auth зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) залишає області runtime маршрутів Plugin прив’язаними до `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` - - довірені HTTP-режими з ідентичністю (наприклад, `trusted-proxy` або `gateway.auth.mode = "none"` у приватному ingress) враховують `x-openclaw-scopes` лише тоді, коли цей заголовок явно присутній - - якщо в таких запитах маршруту Plugin з ідентичністю `x-openclaw-scopes` відсутній, область runtime повертається до `operator.write` -- Практичне правило: не вважайте маршрут Plugin з auth Gateway неявною поверхнею адміністратора. Якщо вашому маршруту потрібна поведінка лише для адміністратора, вимагайте режим auth з ідентичністю та документуйте явний контракт заголовка `x-openclaw-scopes`. +- `api.registerHttpHandler(...)` видалено, і він викличе помилку завантаження plugin. Використовуйте натомість `api.registerHttpRoute(...)`. +- Route plugin повинні явно оголошувати `auth`. +- Конфлікти точних `path + match` відхиляються, якщо не вказано `replaceExisting: true`, і один plugin не може замінити route іншого plugin. +- Route, що перекриваються та мають різні рівні `auth`, відхиляються. Зберігайте ланцюжки fallthrough `exact`/`prefix` лише в межах одного рівня auth. +- Route з `auth: "plugin"` **не** отримують автоматично scopes runtime оператора. Вони призначені для webhook/signature verification, якими керує plugin, а не для привілейованих допоміжних викликів Gateway. +- Route з `auth: "gateway"` виконуються в межах scope runtime запиту Gateway, але цей scope навмисно консервативний: + - bearer auth зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) утримує scopes runtime route plugin на рівні `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` + - довірені HTTP-режими з ідентичністю виклику (наприклад, `trusted-proxy` або `gateway.auth.mode = "none"` на приватному ingress) враховують `x-openclaw-scopes` лише тоді, коли цей заголовок явно присутній + - якщо `x-openclaw-scopes` відсутній у таких запитах plugin-route з ідентичністю, scope runtime повертається до `operator.write` +- Практичне правило: не припускайте, що route plugin з gateway-auth є неявним admin surface. Якщо вашому route потрібна поведінка лише для admin, вимагайте режим auth з ідентичністю виклику й документуйте явний контракт заголовка `x-openclaw-scopes`. ## Шляхи імпорту Plugin SDK -Під час створення нових Plugin використовуйте вузькі підшляхи SDK замість монолітного кореневого -barrel `openclaw/plugin-sdk`. Основні підшляхи: +Під час створення нових plugin використовуйте вузькі subpath SDK замість монолітного +кореневого barrel `openclaw/plugin-sdk`. Основні subpath: -| Підшлях | Призначення | -| ----------------------------------- | -------------------------------------------------- | -| `openclaw/plugin-sdk/plugin-entry` | Примітиви реєстрації Plugin | -| `openclaw/plugin-sdk/core` | Загальний спільний контракт для Plugin | -| `openclaw/plugin-sdk/config-schema` | Коренева Zod-схема `openclaw.json` (`OpenClawSchema`) | +| Subpath | Призначення | +| ----------------------------------- | ------------------------------------------------- | +| `openclaw/plugin-sdk/plugin-entry` | Примітиви реєстрації plugin | +| `openclaw/plugin-sdk/channel-core` | Допоміжні засоби входу/побудови channel | +| `openclaw/plugin-sdk/core` | Узагальнені спільні допоміжні засоби та зонтичний контракт | +| `openclaw/plugin-sdk/config-schema` | Коренева схема Zod для `openclaw.json` (`OpenClawSchema`) | -Plugin каналів вибирають із сімейства вузьких поверхонь — `channel-setup`, +Channel plugin вибирають із сімейства вузьких швів — `channel-setup`, `setup-runtime`, `setup-adapter-runtime`, `setup-tools`, `channel-pairing`, `channel-contract`, `channel-feedback`, `channel-inbound`, `channel-lifecycle`, `channel-reply-pipeline`, `command-auth`, `secret-input`, `webhook-ingress`, -`channel-targets` і `channel-actions`. Поведінку схвалення слід консолідувати -навколо одного контракту `approvalCapability`, а не змішувати між не пов’язаними -полями Plugin. Див. [Plugin каналів](/uk/plugins/sdk-channel-plugins). +`channel-targets` і `channel-actions`. Поведінку схвалення слід зводити +до одного контракту `approvalCapability`, а не змішувати між не пов’язаними +полями plugin. Див. [Channel plugin](/uk/plugins/sdk-channel-plugins). -Допоміжні засоби runtime і config розміщені у відповідних підшляхах `*-runtime` +Допоміжні засоби runtime і config розміщені у відповідних subpath `*-runtime` (`approval-runtime`, `config-runtime`, `infra-runtime`, `agent-runtime`, `lazy-runtime`, `directory-runtime`, `text-runtime`, `runtime-store` тощо). `openclaw/plugin-sdk/channel-runtime` є застарілим — це shim сумісності для -старіших Plugin. Новий код має імпортувати натомість вужчі загальні примітиви. +старіших plugin. Новий код має імпортувати натомість вужчі узагальнені примітиви. -Внутрішні точки входу репозиторію (для кореня пакета кожного вбудованого Plugin): +Внутрішні точки входу репозиторію (для кореня кожного package вбудованого plugin): -- `index.js` — точка входу вбудованого Plugin +- `index.js` — точка входу вбудованого plugin - `api.js` — barrel допоміжних засобів/типів - `runtime-api.js` — barrel лише для runtime -- `setup-entry.js` — точка входу setup Plugin +- `setup-entry.js` — точка входу plugin setup -Зовнішні Plugin мають імпортувати лише підшляхи `openclaw/plugin-sdk/*`. Ніколи -не імпортуйте `src/*` іншого пакета Plugin із core або з іншого Plugin. -Точки входу, завантажені через facade, надають перевагу активному знімку runtime config, якщо він +Зовнішні plugin мають імпортувати лише subpath `openclaw/plugin-sdk/*`. Ніколи +не імпортуйте `src/*` іншого package plugin з core або з іншого plugin. +Точки входу, завантажені через facade, віддають перевагу активному знімку config runtime, якщо він існує, а потім повертаються до визначеного файла config на диску. -Підшляхи, специфічні для можливостей, як-от `image-generation`, `media-understanding` -і `speech`, існують, оскільки вбудовані Plugin уже використовують їх сьогодні. Вони не є -автоматично зовнішніми контрактами, замороженими на довгий строк — перевіряйте відповідну -довідкову сторінку SDK, коли покладаєтеся на них. +Subpath, специфічні для можливостей, такі як `image-generation`, `media-understanding` +і `speech`, існують, бо вбудовані plugin використовують їх уже сьогодні. Вони не є +автоматично замороженими зовнішніми контрактами на довгий строк — перевіряйте відповідну +сторінку довідки SDK, коли покладаєтеся на них. -## Схеми інструмента повідомлень +## Схеми tool повідомлень -Plugin мають володіти внесками в схему `describeMessageTool(...)`, специфічними для каналу, -для примітивів, що не є повідомленнями, таких як реакції, позначення прочитаного та опитування. -Спільне подання надсилання має використовувати загальний контракт `MessagePresentation` -замість native полів кнопок, компонентів, блоків або карток, специфічних для провайдера. -Див. [Message Presentation](/uk/plugins/message-presentation), де описано контракт, -правила fallback, зіставлення провайдерів і контрольний список для авторів Plugin. +Plugin мають володіти внесками до схеми channel-specific `describeMessageTool(...)` +для примітивів, що не є повідомленнями, таких як реакції, прочитання й опитування. +Спільне подання надсилання має використовувати узагальнений контракт `MessagePresentation`, +а не нативні для провайдера поля кнопок, компонентів, блоків або карток. +Див. [Message Presentation](/uk/plugins/message-presentation) щодо контракту, +правил fallback, зіставлення провайдерів і контрольного списку для авторів plugin. -Plugin, здатні надсилати, оголошують, що саме вони можуть відтворювати, через можливості повідомлень: +Plugin із підтримкою надсилання оголошують, що саме вони можуть відображати, через можливості повідомлень: - `presentation` для блоків семантичного подання (`text`, `context`, `divider`, `buttons`, `select`) -- `delivery-pin` для запитів на доставлення із закріпленням +- `delivery-pin` для запитів доставки із закріпленням -Core вирішує, чи відтворювати подання нативно, чи деградувати його до тексту. -Не відкривайте аварійні шляхи до native UI, специфічного для провайдера, із загального інструмента повідомлень. -Застарілі допоміжні засоби SDK для старих native-схем залишаються експортованими для наявних -сторонніх Plugin, але нові Plugin не повинні їх використовувати. +Core вирішує, чи відображати подання нативно, чи деградувати його до тексту. +Не відкривайте нативні для провайдера обхідні шляхи UI через узагальнений tool повідомлень. +Застарілі допоміжні засоби SDK для старих нативних схем залишаються експортованими для наявних +сторонніх plugin, але нові plugin не повинні їх використовувати. -## Визначення цілі каналу +## Визначення цілей channel -Plugin каналів мають володіти семантикою цілей, специфічною для каналу. Залишайте спільний -хост outbound загальним і використовуйте поверхню адаптера повідомлень для правил провайдера: +Channel plugin мають володіти семантикою цілей, специфічною для channel. Зберігайте спільний +хост outbound узагальненим і використовуйте surface адаптера повідомлень для правил провайдера: - `messaging.inferTargetChatType({ to })` вирішує, чи нормалізовану ціль - слід трактувати як `direct`, `group` або `channel` до пошуку в директорії. + слід трактувати як `direct`, `group` або `channel` до пошуку в directory. - `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє core, чи - слід одразу перейти до визначення за id-подібним значенням замість пошуку в директорії. -- `messaging.targetResolver.resolveTarget(...)` — це fallback Plugin, коли - core потребує фінального визначення, що належить провайдеру, після нормалізації або - після відсутності збігу в директорії. -- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту сесії, специфічного для провайдера, + має вхід одразу перейти до визначення за id-подібним значенням замість пошуку в directory. +- `messaging.targetResolver.resolveTarget(...)` — це fallback plugin, коли + core потрібне остаточне визначення, що належить провайдеру, після нормалізації або + після промаху в directory. +- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту session, специфічною для провайдера, після того як ціль визначено. Рекомендований поділ: -- Використовуйте `inferTargetChatType` для рішень про категорію, які мають відбуватися до - пошуку серед peers/groups. -- Використовуйте `looksLikeId` для перевірок на кшталт «сприймати це як явний/native id цілі». +- Використовуйте `inferTargetChatType` для рішень щодо категорій, які мають прийматися до + пошуку peers/groups. +- Використовуйте `looksLikeId` для перевірок типу «трактувати це як явний/нативний id цілі». - Використовуйте `resolveTarget` для fallback-нормалізації, специфічної для провайдера, а не для - широкого пошуку в директорії. -- Зберігайте provider-native id, як-от id чату, id гілки, JID, handles і id кімнат, - усередині значень `target` або параметрів, специфічних для провайдера, а не в загальних полях SDK. + широкого пошуку в directory. +- Зберігайте нативні для провайдера id, як-от chat id, thread id, JID, handles і room + id, усередині значень `target` або параметрів, специфічних для провайдера, а не в узагальнених полях SDK. -## Директорії на основі config +## Directory на основі config -Plugin, які формують записи директорії з config, мають зберігати цю логіку в -Plugin і повторно використовувати спільні допоміжні засоби з +Plugin, які виводять записи directory з config, мають зберігати цю логіку в +plugin і повторно використовувати спільні допоміжні засоби з `openclaw/plugin-sdk/directory-runtime`. -Використовуйте це, коли каналу потрібні peers/groups на основі config, наприклад: +Використовуйте це, коли channel потребує peers/groups на основі config, наприклад: -- DM peers, керовані allowlist -- налаштовані мапи каналів/груп -- статичні fallback директорії з областю видимості облікового запису +- DM peers на основі allowlist +- налаштовані карти channel/group +- статичні fallback directory в межах облікового запису -Спільні допоміжні засоби в `directory-runtime` обробляють лише загальні операції: +Спільні допоміжні засоби в `directory-runtime` обробляють лише узагальнені операції: - фільтрацію запитів -- застосування ліміту -- допоміжні засоби дедуплікації/нормалізації +- застосування обмежень +- дедуплікацію/нормалізацію - побудову `ChannelDirectoryEntry[]` -Специфічні для каналу перевірка облікового запису та нормалізація id мають залишатися в -реалізації Plugin. +Інспекція облікового запису й нормалізація id, специфічні для channel, мають залишатися +в реалізації plugin. ## Каталоги провайдерів @@ -1175,62 +1178,59 @@ Plugin провайдерів можуть визначати каталоги `models.providers`: - `{ provider }` для одного запису провайдера -- `{ providers }` для кількох записів провайдерів +- `{ providers }` для кількох записів провайдера -Використовуйте `catalog`, коли Plugin володіє model id, специфічними для провайдера, значеннями `base URL` -за замовчуванням або метаданими моделей, захищеними auth. +Використовуйте `catalog`, коли plugin володіє model id, типовими значеннями base URL або +метаданими моделі, захищеними auth, специфічними для провайдера. -`catalog.order` керує тим, коли каталог Plugin об’єднується відносно -вбудованих неявних провайдерів OpenClaw: +`catalog.order` керує тим, коли каталог plugin зливається відносно вбудованих +неявних провайдерів OpenClaw: -- `simple`: провайдери з простим API-ключем або керовані env +- `simple`: звичайні провайдери на основі API-key або env - `profile`: провайдери, які з’являються, коли існують профілі auth - `paired`: провайдери, які синтезують кілька пов’язаних записів провайдера -- `late`: останній прохід після інших неявних провайдерів +- `late`: останній прохід, після інших неявних провайдерів -Пізніші провайдери перемагають при конфлікті ключів, тому Plugin можуть навмисно перевизначати -вбудований запис провайдера з тим самим id провайдера. +Пізніші провайдери перемагають у разі колізії ключів, тому plugin можуть навмисно +перевизначати вбудований запис провайдера з тим самим id провайдера. Сумісність: - `discovery` усе ще працює як застарілий псевдонім - якщо зареєстровано і `catalog`, і `discovery`, OpenClaw використовує `catalog` -## Лише для читання: перевірка каналу +## Канальна інспекція лише для читання -Якщо ваш Plugin реєструє канал, надавайте перевагу реалізації +Якщо ваш plugin реєструє channel, віддавайте перевагу реалізації `plugin.config.inspectAccount(cfg, accountId)` разом із `resolveAccount(...)`. Чому: -- `resolveAccount(...)` — це runtime-шлях. Він може припускати, що облікові дані - повністю матеріалізовані, і може швидко завершуватися з помилкою, коли потрібні секрети відсутні. +- `resolveAccount(...)` — це шлях runtime. Йому дозволено припускати, що облікові дані + повністю матеріалізовані, і він може швидко завершуватися з помилкою, якщо потрібні secrets відсутні. - Шляхи команд лише для читання, такі як `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve`, а також потоки doctor/відновлення config, - не повинні потребувати матеріалізації runtime-облікових даних лише для того, щоб - описати конфігурацію. + `openclaw channels status`, `openclaw channels resolve` і потоки doctor/config + repair, не повинні матеріалізовувати облікові дані runtime лише для + опису конфігурації. Рекомендована поведінка `inspectAccount(...)`: - Повертайте лише описовий стан облікового запису. - Зберігайте `enabled` і `configured`. -- За потреби включайте поля джерела/стану облікових даних, такі як: +- Додавайте поля джерела/стану облікових даних, коли це доречно, наприклад: - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Не потрібно повертати сирі значення токенів лише для звітування про доступність у режимі лише читання. - Достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела) - для команд на кшталт status. +- Вам не потрібно повертати сирі значення токенів лише для повідомлення про доступність у режимі лише для читання. Достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела). - Використовуйте `configured_unavailable`, коли облікові дані налаштовано через SecretRef, але вони недоступні в поточному шляху команди. -Це дає змогу командам лише для читання повідомляти «налаштовано, але недоступно в цьому -шляху команди» замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштовано. +Це дає змогу командам лише для читання повідомляти «налаштовано, але недоступно в цьому шляху команди» замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштовано. ## Package packs -Каталог Plugin може містити `package.json` з `openclaw.extensions`: +Каталог plugin може містити `package.json` з `openclaw.extensions`: ```json { @@ -1242,64 +1242,65 @@ Plugin провайдерів можуть визначати каталоги } ``` -Кожен запис стає Plugin. Якщо pack перелічує кілька extension, id Plugin +Кожен запис стає plugin. Якщо pack містить кілька extensions, id plugin стає `name/`. -Якщо ваш Plugin імпортує залежності npm, установіть їх у цьому каталозі, щоб +Якщо ваш plugin імпортує залежності npm, установіть їх у цьому каталозі, щоб `node_modules` був доступний (`npm install` / `pnpm install`). -Захисне обмеження безпеки: кожен запис `openclaw.extensions` має залишатися в межах каталогу Plugin -після визначення symlink. Записи, які виходять за межі каталогу пакета, відхиляються. +Захисне обмеження безпеки: кожен запис `openclaw.extensions` має залишатися в межах каталогу plugin +після визначення symlink. Записи, які виходять за межі каталогу package, відхиляються. -Примітка щодо безпеки: `openclaw plugins install` встановлює залежності Plugin через -`npm install --omit=dev --ignore-scripts` (без lifecycle-скриптів, без dev-залежностей під час runtime). Зберігайте дерево залежностей Plugin -«чистим JS/TS» і уникайте пакетів, які потребують збирання через `postinstall`. +Примітка щодо безпеки: `openclaw plugins install` встановлює залежності plugin за допомогою +`npm install --omit=dev --ignore-scripts` (без lifecycle scripts і без dev dependencies у runtime). Підтримуйте дерева залежностей plugin +у форматі «чистий JS/TS» і уникайте package, які потребують збірок `postinstall`. -Необов’язково: `openclaw.setupEntry` може вказувати на легкий модуль лише для setup. -Коли OpenClaw потребує поверхонь setup для вимкненого Plugin каналу або -коли Plugin каналу увімкнено, але ще не налаштовано, він завантажує `setupEntry` -замість повної точки входу Plugin. Це робить запуск і setup легшими, -коли основна точка входу Plugin також підключає інструменти, хуки або інший код лише для runtime. +Необов’язково: `openclaw.setupEntry` може вказувати на полегшений модуль лише для setup. +Коли OpenClaw потребує surface setup для вимкненого channel plugin або +коли channel plugin увімкнений, але ще не налаштований, він завантажує `setupEntry` +замість повної точки входу plugin. Це робить запуск і setup легшими, +коли основна точка входу plugin також підключає tools, hooks або інший код +лише для runtime. Необов’язково: `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -може підключити Plugin каналу до того самого шляху `setupEntry` під час -фази запуску gateway до початку прослуховування, навіть якщо канал уже налаштовано. +може підключити channel plugin до того самого шляху `setupEntry` під час фази +запуску gateway до початку прослуховування, навіть коли channel уже налаштований. -Використовуйте це лише тоді, коли `setupEntry` повністю покриває поверхню запуску, яка має існувати +Використовуйте це лише тоді, коли `setupEntry` повністю покриває surface запуску, який має існувати до того, як gateway почне прослуховування. На практиці це означає, що точка входу setup -має реєструвати кожну можливість, що належить каналу й від якої залежить запуск, наприклад: +має зареєструвати кожну можливість, що належить channel, від якої залежить запуск, наприклад: -- саму реєстрацію каналу -- будь-які HTTP-маршрути, які мають бути доступні до того, як gateway почне прослуховування -- будь-які методи Gateway, інструменти або сервіси, які мають існувати в той самий проміжок часу +- саму реєстрацію channel +- будь-які HTTP routes, які мають бути доступні до початку прослуховування gateway +- будь-які методи gateway, tools або services, які мають існувати в той самий проміжок часу -Якщо ваша повна точка входу все ще володіє будь-якою обов’язковою можливістю запуску, не вмикайте -цей прапорець. Залишайте Plugin у типовому режимі й дозвольте OpenClaw завантажити +Якщо ваша повна точка входу все ще володіє будь-якою потрібною можливістю запуску, не вмикайте +цей прапорець. Залиште для plugin типову поведінку й дозвольте OpenClaw завантажити повну точку входу під час запуску. -Вбудовані канали також можуть публікувати допоміжні засоби поверхні контракту лише для setup, з якими core -може консультуватися до завантаження повного runtime каналу. Поточна поверхня -просування setup така: +Вбудовані channels також можуть публікувати допоміжні засоби surface контракту лише для setup, які core +може використовувати до завантаження повного runtime channel. Поточний surface +підвищення setup такий: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -Core використовує цю поверхню, коли йому потрібно просунути застарілий config каналу з одним обліковим записом -у `channels..accounts.*` без завантаження повної точки входу Plugin. -Поточний вбудований приклад — Matrix: він переносить лише ключі auth/bootstrap у -іменований просунутий обліковий запис, коли іменовані облікові записи вже існують, і може зберігати -налаштований неканонічний ключ облікового запису за замовчуванням замість того, щоб завжди створювати +Core використовує цей surface, коли йому потрібно підвищити застарілий config channel +з одним обліковим записом до `channels..accounts.*` без завантаження повної точки входу plugin. +Поточний вбудований приклад — Matrix: він переносить лише ключі auth/bootstrap до +іменованого підвищеного облікового запису, коли іменовані облікові записи вже існують, і може +зберігати налаштований неканонічний ключ default-account замість того, щоб завжди створювати `accounts.default`. -Ці адаптери патчів setup зберігають відкладеним виявлення поверхні контракту вбудованих пакетів. Час імпорту залишається легким; поверхня -просування завантажується лише під час першого використання, а не через повторний вхід у запуск -вбудованого каналу під час імпорту модуля. +Ці адаптери патчів setup зберігають lazy-виявлення surface контракту вбудованих plugin. +Час імпорту залишається невеликим; surface підвищення завантажується лише під час першого використання +замість повторного входу в запуск вбудованого channel під час імпорту модуля. -Коли ці поверхні запуску включають Gateway RPC methods, зберігайте їх на -префіксі, специфічному для Plugin. Простори імен адміністратора core (`config.*`, +Коли ці surface запуску включають методи Gateway RPC, зберігайте їх під +префіксом, специфічним для plugin. Простори імен admin core (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди визначаються -як `operator.admin`, навіть якщо Plugin запитує вужчу область. +як `operator.admin`, навіть якщо plugin запитує вужчий scope. Приклад: @@ -1316,10 +1317,10 @@ Core використовує цю поверхню, коли йому потр } ``` -### Метадані каталогу каналу +### Метадані каталогу channel -Plugin каналів можуть оголошувати метадані setup/виявлення через `openclaw.channel` і -підказки встановлення через `openclaw.install`. Це дозволяє core не містити даних каталогу. +Channel plugin можуть оголошувати метадані setup/discovery через `openclaw.channel` і +підказки встановлення через `openclaw.install`. Це дозволяє зберігати дані каталогу core порожніми. Приклад: @@ -1349,39 +1350,39 @@ Plugin каналів можуть оголошувати метадані setup Корисні поля `openclaw.channel`, окрім мінімального прикладу: -- `detailLabel`: вторинна мітка для багатших поверхонь каталогу/статусу -- `docsLabel`: перевизначає текст посилання для посилання на документацію -- `preferOver`: id Plugin/каналів нижчого пріоритету, які цей запис каталогу має випереджати -- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: елементи керування текстом поверхні вибору -- `markdownCapable`: позначає канал як здатний до Markdown для рішень щодо outbound-форматування -- `exposure.configured`: приховує канал із поверхонь списку налаштованих каналів, коли встановлено `false` -- `exposure.setup`: приховує канал з інтерактивних засобів вибору setup/configure, коли встановлено `false` -- `exposure.docs`: позначає канал як внутрішній/приватний для поверхонь навігації документації -- `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; надавайте перевагу `exposure` -- `quickstartAllowFrom`: підключає канал до стандартного потоку quickstart `allowFrom` +- `detailLabel`: вторинна мітка для багатших surface каталогу/статусу +- `docsLabel`: перевизначення тексту посилання для посилання на docs +- `preferOver`: id plugin/channel нижчого пріоритету, які цей запис каталогу має перевершувати +- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: елементи керування текстом для surface вибору +- `markdownCapable`: позначає channel як здатний працювати з Markdown для рішень щодо форматування outbound +- `exposure.configured`: приховує channel із surface списків налаштованих channel, якщо встановлено `false` +- `exposure.setup`: приховує channel з інтерактивних засобів вибору setup/configure, якщо встановлено `false` +- `exposure.docs`: позначає channel як внутрішній/приватний для surface навігації docs +- `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; віддавайте перевагу `exposure` +- `quickstartAllowFrom`: підключає channel до стандартного потоку quickstart `allowFrom` - `forceAccountBinding`: вимагає явної прив’язки облікового запису, навіть якщо існує лише один обліковий запис -- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення цілей оголошень +- `preferSessionLookupForAnnounceTarget`: віддає перевагу пошуку session під час визначення цілей announce -OpenClaw також може об’єднувати **зовнішні каталоги каналів** (наприклад, експорт -реєстру MPM). Помістіть JSON-файл в одне з місць: +OpenClaw також може зливати **зовнішні каталоги channel** (наприклад, експорт +реєстру MPM). Помістіть файл JSON в одне з таких місць: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -Або вкажіть у `OPENCLAW_PLUGIN_CATALOG_PATHS` (або `OPENCLAW_MPM_CATALOG_PATHS`) -один чи кілька JSON-файлів (розділених комами/крапками з комою/як у `PATH`). Кожен файл має +Або вкажіть `OPENCLAW_PLUGIN_CATALOG_PATHS` (або `OPENCLAW_MPM_CATALOG_PATHS`) на +один або кілька файлів JSON (розділених комами/крапками з комою/форматом `PATH`). Кожен файл має містити `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. Парсер також приймає `"packages"` або `"plugins"` як застарілі псевдоніми для ключа `"entries"`. -## Plugin механізму контексту +## Plugin рушія контексту -Plugin механізму контексту володіють оркестрацією контексту сесії для ingеst, assembly -та Compaction. Реєструйте їх у своєму Plugin через -`api.registerContextEngine(id, factory)`, а потім вибирайте активний механізм через +Plugin рушія контексту володіють оркестрацією контексту session для ingestion, assembly +і Compaction. Реєструйте їх зі свого plugin за допомогою +`api.registerContextEngine(id, factory)`, а потім вибирайте активний рушій через `plugins.slots.contextEngine`. -Використовуйте це, коли вашому Plugin потрібно замінити або розширити типовий конвеєр -контексту, а не просто додати пошук у пам’яті або хуки. +Використовуйте це, коли вашому plugin потрібно замінити або розширити типовий конвеєр +контексту, а не просто додати пошук у memory або hooks. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -1409,7 +1410,7 @@ export default function (api) { } ``` -Якщо ваш механізм **не** володіє алгоритмом Compaction, зберігайте `compact()` +Якщо ваш рушій **не** володіє алгоритмом Compaction, залиште `compact()` реалізованим і явно делегуйте його: ```ts @@ -1447,45 +1448,45 @@ export default function (api) { ## Додавання нової можливості -Коли Plugin потребує поведінки, яка не вписується в поточний API, не обходьте -систему Plugin через приватний доступ до внутрішніх механізмів. Додайте відсутню можливість. +Коли plugin потрібна поведінка, яка не вписується в поточний API, не обходьте +систему plugin приватним зверненням до внутрішніх компонентів. Додайте відсутню можливість. Рекомендована послідовність: 1. визначте контракт core - Вирішіть, якою спільною поведінкою має володіти core: політикою, fallback, об’єднанням config, - життєвим циклом, семантикою для каналів і формою runtime-допоміжного засобу. -2. додайте типізовані поверхні реєстрації/runtime Plugin - Розширте `OpenClawPluginApi` і/або `api.runtime` найменшою корисною - типізованою поверхнею можливості. -3. під’єднайте споживачів core + каналів/функцій - Канали й Plugin функцій мають використовувати нову можливість через core, - а не через прямий імпорт реалізації вендора. -4. зареєструйте реалізації вендорів - Потім vendor Plugin реєструють свої бекенди для цієї можливості. -5. додайте контрактне покриття - Додайте тести, щоб володіння й форма реєстрації залишалися явними з часом. + Вирішіть, якою спільною поведінкою має володіти core: політика, fallback, злиття config, + життєвий цикл, семантика для channel і форма допоміжних засобів runtime. +2. додайте типізовані surface реєстрації/runtime plugin + Розширте `OpenClawPluginApi` і/або `api.runtime` найменшим корисним + типізованим surface можливості. +3. підключіть споживачів core + channel/feature + Channels і plugin функцій мають споживати нову можливість через core, + а не шляхом прямого імпорту реалізації постачальника. +4. зареєструйте реалізації постачальників + Потім plugin постачальників реєструють свої бекенди для цієї можливості. +5. додайте покриття контракту + Додайте тести, щоб володіння й форма реєстрації з часом залишалися явними. -Так OpenClaw зберігає свою чітку архітектурну позицію, не стаючи жорстко прив’язаним до -уявлень одного провайдера. Див. [Кулінарну книгу можливостей](/uk/plugins/architecture), -де наведено конкретний контрольний список файлів і приклад. +Саме так OpenClaw зберігає чітку позицію, не стаючи при цьому жорстко прив’язаним до +світогляду одного провайдера. Див. [Збірник рецептів можливостей](/uk/plugins/architecture) +для конкретного контрольного списку файлів і опрацьованого прикладу. ### Контрольний список можливості -Коли ви додаєте нову можливість, реалізація зазвичай має одночасно торкатися -таких поверхонь: +Коли ви додаєте нову можливість, реалізація зазвичай має торкатися цих +surface разом: - типів контракту core в `src//types.ts` -- runner/runtime-допоміжного засобу core в `src//runtime.ts` -- поверхні реєстрації API Plugin в `src/plugins/types.ts` -- підключення реєстру Plugin в `src/plugins/registry.ts` -- відкриття runtime Plugin у `src/plugins/runtime/*`, коли Plugin функцій/каналів - мають це використовувати -- допоміжних засобів capture/test у `src/test-utils/plugin-registration.ts` +- runner/допоміжного засобу runtime core в `src//runtime.ts` +- surface реєстрації API plugin в `src/plugins/types.ts` +- підключення реєстру plugin в `src/plugins/registry.ts` +- відкриття runtime plugin в `src/plugins/runtime/*`, коли plugin функцій/channel + мають це споживати +- захоплення/допоміжних засобів тестування в `src/test-utils/plugin-registration.ts` - перевірок володіння/контракту в `src/plugins/contracts/registry.ts` -- документації для операторів/Plugin у `docs/` +- docs для операторів/plugin у `docs/` -Якщо одна з цих поверхонь відсутня, це зазвичай ознака того, що можливість +Якщо одна з цих surface відсутня, це зазвичай ознака того, що можливість ще не повністю інтегрована. ### Шаблон можливості @@ -1516,7 +1517,7 @@ const clip = await api.runtime.videoGeneration.generate({ }); ``` -Шаблон контрактного тесту: +Шаблон тесту контракту: ```ts expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); @@ -1525,6 +1526,6 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Це зберігає правило простим: - core володіє контрактом можливості + оркестрацією -- vendor Plugin володіють реалізаціями вендорів -- Plugin функцій/каналів використовують runtime-допоміжні засоби -- контрактні тести зберігають явність володіння +- plugin постачальників володіють реалізаціями постачальників +- plugin функцій/channel споживають допоміжні засоби runtime +- тести контрактів зберігають володіння явним