From ec2e40b1a67aa6005602a139647ab7e7087faaff Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Thu, 23 Apr 2026 08:18:47 +0000 Subject: [PATCH] chore(i18n): refresh uk translations --- docs/uk/gateway/configuration.md | 446 ++++----- docs/uk/plugins/architecture.md | 1544 ++++++++++++++---------------- 2 files changed, 895 insertions(+), 1095 deletions(-) diff --git a/docs/uk/gateway/configuration.md b/docs/uk/gateway/configuration.md index 7bd8be682..b1bd04a6b 100644 --- a/docs/uk/gateway/configuration.md +++ b/docs/uk/gateway/configuration.md @@ -1,38 +1,38 @@ --- read_when: - Перше налаштування OpenClaw - - Шукаєте поширені шаблони конфігурації - - Перехід до певних розділів конфігурації + - Пошук поширених шаблонів конфігурації + - Перехід до конкретних розділів конфігурації summary: 'Огляд конфігурації: поширені завдання, швидке налаштування та посилання на повний довідник' title: Конфігурація x-i18n: - generated_at: "2026-04-23T07:25:03Z" + generated_at: "2026-04-23T08:14:09Z" model: gpt-5.4 provider: openai - source_hash: 6a68c5e4d375e0910b65fa4da2bcfc6fa560cbcba750778605420dc1b83eeb15 + source_hash: a674bbc73f3a501ffd47ef9396d55d6087806921cfb24ef576398022dd0248c3 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 використовує безпечні типові значення. Поширені причини додати конфігурацію: +Якщо файл відсутній, OpenClaw використовує безпечні значення за замовчуванням. Типові причини додати конфігурацію: - Підключити канали та керувати тим, хто може надсилати повідомлення боту -- Налаштувати моделі, інструменти, ізоляцію або автоматизацію (cron, hooks) -- Тонко налаштувати сесії, медіа, мережу або UI +- Налаштувати моделі, інструменти, ізоляцію або автоматизацію (Cron, хуки) +- Налаштувати сесії, медіа, мережу або UI Перегляньте [повний довідник](/uk/gateway/configuration-reference), щоб побачити всі доступні поля. -**Вперше налаштовуєте конфігурацію?** Почніть із `openclaw onboard` для інтерактивного налаштування або перегляньте посібник [Приклади конфігурації](/uk/gateway/configuration-examples) для повних готових конфігурацій, які можна скопіювати й вставити. +**Вперше працюєте з конфігурацією?** Почніть з `openclaw onboard` для інтерактивного налаштування або перегляньте посібник [Приклади конфігурації](/uk/gateway/configuration-examples) для готових конфігурацій, які можна повністю скопіювати й вставити. ## Мінімальна конфігурація @@ -62,44 +62,32 @@ OpenClaw читає необов’язкову конфігурацію - Відкрийте [http://127.0.0.1:18789](http://127.0.0.1:18789) і використовуйте вкладку **Config**. - Control UI відображає форму на основі живої схеми конфігурації, зокрема метадані документації полів - `title` / `description`, а також схеми plugin і каналів, коли вони - доступні, із редактором **Raw JSON** як запасним варіантом. Для деталізованих - UI та інших інструментів gateway також надає `config.schema.lookup`, щоб - отримати один вузол схеми з прив’язкою до шляху разом із короткими описами безпосередніх дочірніх елементів. + Відкрийте [http://127.0.0.1:18789](http://127.0.0.1:18789) і використайте вкладку **Config**. + Control UI відображає форму з живої схеми конфігурації, включно з метаданими документації полів + `title` / `description`, а також схемами plugin і каналів, коли вони + доступні, з редактором **Raw JSON** як запасним варіантом. Для інтерфейсів + деталізації та інших інструментів 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 - і валідація конфігурації. -- Вважайте цей вивід схеми канонічним машинозчитуваним контрактом для - `openclaw.json`; цей огляд і довідник конфігурації його підсумовують. -- Значення полів `title` і `description` переносяться у вивід схеми для - редакторів та інструментів форм. -- Вкладені об’єкти, записи з шаблоном (`*`) і елементи масивів (`[]`) успадковують ті самі - метадані документації там, де існує відповідна документація поля. -- Гілки композиції `anyOf` / `oneOf` / `allOf` також успадковують ті самі метадані - документації, тому варіанти union/intersection зберігають ту саму довідку полів. -- `config.schema.lookup` повертає один нормалізований шлях конфігурації з неглибоким - вузлом схеми (`title`, `description`, `type`, `enum`, `const`, типові межі - та подібні поля валідації), відповідними метаданими підказок UI та короткими описами безпосередніх дочірніх елементів - для інструментів деталізованого перегляду. -- Схеми runtime plugin/каналів об’єднуються, коли gateway може завантажити - поточний реєстр маніфестів. -- `pnpm config:docs:check` виявляє розбіжності між артефактами базового рівня конфігурації для документації - та поточною поверхнею схеми. +`openclaw config schema` виводить канонічну JSON Schema, яку використовують Control UI +та валідація. `config.schema.lookup` отримує один вузол для певного шляху разом +із короткими відомостями про дочірні елементи для інструментів деталізації. +Метадані документації полів `title`/`description` поширюються на вкладені об’єкти, +підстановочні символи (`*`), елементи масиву (`[]`) та гілки `anyOf`/ +`oneOf`/`allOf`. Схеми runtime plugin і каналів додаються під час завантаження +реєстру маніфестів. Коли валідація не проходить: @@ -108,29 +96,21 @@ OpenClaw приймає лише конфігурації, які повніст - Запустіть `openclaw doctor`, щоб побачити точні проблеми - Запустіть `openclaw doctor --fix` (або `--yes`), щоб застосувати виправлення -Gateway також зберігає довірену останню відому справну копію після успішного запуску. Якщо -`openclaw.json` пізніше змінено поза OpenClaw і він більше не проходить валідацію, запуск -і гаряче перезавантаження збережуть зіпсований файл як часовий знімок `.clobbered.*`, -відновлять останню відому справну копію та запишуть помітне попередження з причиною відновлення. -Відновлення під час читання на запуску також розглядає різке зменшення розміру, відсутність метаданих конфігурації та -відсутній `gateway.mode` як критичні ознаки пошкодження, якщо остання відома справна -копія мала ці поля. -Якщо перед інакше дійсною конфігурацією JSON випадково додано рядок статусу/журналу, -запуск gateway і `openclaw doctor --fix` можуть прибрати цей префікс, -зберегти забруднений файл як `.clobbered.*` і продовжити роботу з відновленим -JSON. -Наступний хід основного агента також отримує попередження про системну подію, яке повідомляє, що -конфігурацію було відновлено і її не можна бездумно перезаписувати. Підвищення статусу останньої відомої справної копії -оновлюється після перевіреного запуску та після прийнятих гарячих перезавантажень, зокрема -записів конфігурації, якими керує OpenClaw, якщо хеш збереженого файлу все ще збігається з прийнятим -записом. Підвищення пропускається, коли кандидат містить замасковані -заповнювачі секретів, такі як `***` або скорочені значення токенів. +Після кожного успішного запуску Gateway зберігає довірену останню коректну копію. +Якщо пізніше `openclaw.json` не проходить валідацію (або втрачає `gateway.mode`, +різко зменшується, або на початку з’являється сторонній рядок журналу), +OpenClaw зберігає пошкоджений файл як `.clobbered.*`, відновлює останню коректну +копію та записує причину відновлення в журнал. Під час наступного ходу агента +також надходить попередження про системну подію, щоб основний агент не +перезаписав відновлену конфігурацію без перевірки. Підвищення до статусу +останньої коректної копії пропускається, якщо кандидат містить замасковані +заповнювачі секретів, такі як `***`. ## Поширені завдання - - Кожен канал має власний розділ конфігурації в `channels.`. Дивіться окрему сторінку каналу для кроків налаштування: + + Кожен канал має власний розділ конфігурації в `channels.`. Кроки налаштування дивіться на окремій сторінці каналу: - [WhatsApp](/uk/channels/whatsapp) — `channels.whatsapp` - [Telegram](/uk/channels/telegram) — `channels.telegram` @@ -143,7 +123,7 @@ JSON. - [iMessage](/uk/channels/imessage) — `channels.imessage` - [Mattermost](/uk/channels/mattermost) — `channels.mattermost` - Усі канали використовують однаковий шаблон політики особистих повідомлень: + Усі канали використовують однаковий шаблон політики DM: ```json5 { @@ -160,8 +140,8 @@ JSON. - - Налаштуйте основну модель і необов’язкові резервні варіанти: + + Задайте основну модель і необов’язкові резервні варіанти: ```json5 { @@ -180,31 +160,31 @@ JSON. } ``` - - `agents.defaults.models` визначає каталог моделей і слугує списком дозволених значень для `/model`. - - Використовуйте `openclaw config set agents.defaults.models '' --strict-json --merge`, щоб додавати записи до списку дозволених без видалення наявних моделей. Звичайні заміни, які видалили б записи, відхиляються, якщо не передати `--replace`. + - `agents.defaults.models` визначає каталог моделей і виконує роль списку дозволених значень для `/model`. + - Використовуйте `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) для ротації автентифікації та поведінки резервних варіантів. - - Для користувацьких/self-hosted providers дивіться [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) щодо ротації авторизації та поведінки резервних моделей. + - Для користувацьких/самостійно розміщених провайдерів див. [Custom providers](/uk/gateway/configuration-reference#custom-providers-and-base-urls) у довіднику. - - Доступ до особистих повідомлень керується для кожного каналу через `dmPolicy`: + + Доступ до DM керується окремо для кожного каналу через `dmPolicy`: - `"pairing"` (типово): невідомі відправники отримують одноразовий код сполучення для підтвердження - - `"allowlist"`: лише відправники з `allowFrom` (або зі сховища дозволених сполучених відправників) - - `"open"`: дозволити всі вхідні особисті повідомлення (потрібно `allowFrom: ["*"]`) - - `"disabled"`: ігнорувати всі особисті повідомлення + - `"allowlist"`: лише відправники з `allowFrom` (або зі сховища парного списку дозволених) + - `"open"`: дозволити всі вхідні DM (потрібно `allowFrom: ["*"]`) + - `"disabled"`: ігнорувати всі DM Для груп використовуйте `groupPolicy` + `groupAllowFrom` або списки дозволених, специфічні для каналу. - Дивіться [повний довідник](/uk/gateway/configuration-reference#dm-and-group-access) для деталей по кожному каналу. + Див. [повний довідник](/uk/gateway/configuration-reference#dm-and-group-access) для подробиць щодо кожного каналу. - - Для групових повідомлень типовим значенням є **обов’язкова згадка**. Налаштуйте шаблони для кожного агента: + + За замовчуванням для групових повідомлень **потрібна згадка**. Налаштуйте шаблони для кожного агента: ```json5 { @@ -226,14 +206,14 @@ JSON. } ``` - - **Metadata mentions**: нативні @-згадки (WhatsApp tap-to-mention, Telegram @bot тощо) - - **Text patterns**: безпечні шаблони regex у `mentionPatterns` - - Дивіться [повний довідник](/uk/gateway/configuration-reference#group-chat-mention-gating) для перевизначень по каналах і режиму чату з самим собою. + - **Згадки в метаданих**: нативні @-згадки (WhatsApp tap-to-mention, Telegram @bot тощо) + - **Текстові шаблони**: безпечні шаблони regex у `mentionPatterns` + - Див. [повний довідник](/uk/gateway/configuration-reference#group-chat-mention-gating) для перевизначень на рівні каналів і режиму self-chat. - - Використовуйте `agents.defaults.skills` для спільного базового набору, а потім перевизначайте конкретних + + Використовуйте `agents.defaults.skills` для спільної базової конфігурації, а потім перевизначайте конкретних агентів через `agents.list[].skills`: ```json5 @@ -251,16 +231,16 @@ JSON. } ``` - - Не вказуйте `agents.defaults.skills`, щоб типово не обмежувати 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). + - Установіть `agents.list[].skills: []`, щоб не дозволяти жодних Skills. + - Див. [Skills](/uk/tools/skills), [Skills config](/uk/tools/skills-config) і + [Configuration Reference](/uk/gateway/configuration-reference#agents-defaults-skills). - - Керуйте тим, наскільки агресивно gateway перезапускає канали, які виглядають застарілими: + + Керуйте тим, наскільки агресивно gateway перезапускає канали, що виглядають застарілими: ```json5 { @@ -282,15 +262,15 @@ JSON. } ``` - - Встановіть `gateway.channelHealthCheckMinutes: 0`, щоб глобально вимкнути перезапуски моніторингу стану. + - Установіть `gateway.channelHealthCheckMinutes: 0`, щоб глобально вимкнути перезапуски через моніторинг стану. - `channelStaleEventThresholdMinutes` має бути більшим або дорівнювати інтервалу перевірки. - - Використовуйте `channels..healthMonitor.enabled` або `channels..accounts..healthMonitor.enabled`, щоб вимкнути автоматичні перезапуски для одного каналу чи облікового запису без вимкнення глобального монітора. - - Дивіться [Health Checks](/uk/gateway/health) для операційного налагодження та [повний довідник](/uk/gateway/configuration-reference#gateway) для всіх полів. + - Використовуйте `channels..healthMonitor.enabled` або `channels..accounts..healthMonitor.enabled`, щоб вимкнути автоперезапуск для одного каналу чи облікового запису без вимкнення глобального моніторингу. + - Див. [Health Checks](/uk/gateway/health) для операційної діагностики та [повний довідник](/uk/gateway/configuration-reference#gateway) для всіх полів. - - Сесії керують безперервністю розмови та ізоляцією: + + Сесії керують безперервністю та ізоляцією розмов: ```json5 { @@ -312,13 +292,13 @@ JSON. - `dmScope`: `main` (спільна) | `per-peer` | `per-channel-peer` | `per-account-channel-peer` - `threadBindings`: глобальні типові значення для маршрутизації сесій, прив’язаних до потоків (Discord підтримує `/focus`, `/unfocus`, `/agents`, `/session idle` і `/session max-age`). - - Дивіться [Керування сесіями](/uk/concepts/session) для охоплення, зв’язків ідентичності та політики надсилання. - - Дивіться [повний довідник](/uk/gateway/configuration-reference#session) для всіх полів. + - Див. [Session Management](/uk/concepts/session) щодо області видимості, зв’язків ідентичностей і політики надсилання. + - Див. [повний довідник](/uk/gateway/configuration-reference#session) для всіх полів. - - Запускайте сесії агентів в ізольованих середовищах ізоляції: + + Запускайте сесії агентів в ізольованих sandbox runtime: ```json5 { @@ -335,14 +315,14 @@ JSON. Спочатку зберіть образ: `scripts/sandbox-setup.sh` - Дивіться [Ізоляція](/uk/gateway/sandboxing) для повного посібника та [повний довідник](/uk/gateway/configuration-reference#agentsdefaultssandbox) для всіх параметрів. + Див. [Sandboxing](/uk/gateway/sandboxing) для повного посібника та [повний довідник](/uk/gateway/configuration-reference#agentsdefaultssandbox) для всіх параметрів. - + Relay-backed push налаштовується в `openclaw.json`. - Встановіть це в конфігурації gateway: + Додайте це в конфігурацію gateway: ```json5 { @@ -351,7 +331,7 @@ JSON. apns: { relay: { baseUrl: "https://relay.example.com", - // Необов’язково. Типове значення: 10000 + // Optional. Default: 10000 timeoutMs: 10000, }, }, @@ -360,7 +340,7 @@ JSON. } ``` - Еквівалент CLI: + Еквівалент у CLI: ```bash openclaw config set gateway.push.apns.relay.baseUrl https://relay.example.com @@ -368,35 +348,35 @@ JSON. Що це робить: - - Дозволяє gateway надсилати `push.test`, сигнали пробудження та сигнали повторного підключення через зовнішній relay. - - Використовує право надсилання з областю реєстрації, яке пересилає спарений застосунок iOS. Gateway не потрібен relay-токен для всього розгортання. - - Прив’язує кожну relay-backed реєстрацію до ідентичності gateway, з якою був спарений застосунок iOS, тому інший gateway не може повторно використати збережену реєстрацію. - - Залишає локальні/ручні збірки iOS на прямому APNs. Relay-backed надсилання застосовуються лише до офіційно поширюваних збірок, які зареєструвалися через relay. - - Має збігатися з базовим URL relay, вбудованим в офіційну/TestFlight збірку iOS, щоб трафік реєстрації та надсилання потрапляв до того самого розгортання relay. + - Дає змогу gateway надсилати `push.test`, сигнали пробудження та сигнали повторного підключення через зовнішній relay. + - Використовує дозвіл на надсилання в межах реєстрації, який пересилає спарений застосунок iOS. Gateway не потребує relay-токена для всього розгортання. + - Прив’язує кожну реєстрацію з relay-підтримкою до ідентичності gateway, з якою було спарено застосунок iOS, тому інший gateway не зможе повторно використати збережену реєстрацію. + - Залишає локальні/ручні збірки iOS на прямому APNs. Надсилання з relay-підтримкою застосовується лише до офіційних розповсюджуваних збірок, які зареєстровано через 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 і квитанції застосунку, а потім публікує relay-backed payload `push.apns.register` до спареного gateway. - 5. Gateway зберігає relay handle і право надсилання, а потім використовує їх для `push.test`, сигналів пробудження та сигналів повторного підключення. + 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`, сигналів пробудження та сигналів повторного підключення. Операційні примітки: - - Якщо ви перемикаєте застосунок iOS на інший gateway, повторно підключіть застосунок, щоб він міг опублікувати нову relay-реєстрацію, прив’язану до цього gateway. + - Якщо ви перемикаєте застосунок iOS на інший gateway, перепідключіть застосунок, щоб він міг опублікувати нову relay-реєстрацію, прив’язану до цього gateway. - Якщо ви випускаєте нову збірку 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_BASE_URL` і `OPENCLAW_APNS_RELAY_TIMEOUT_MS` усе ще працюють як тимчасові перевизначення через env. + - `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: { @@ -410,14 +390,14 @@ JSON. } ``` - - `every`: рядок тривалості (`30m`, `2h`). Встановіть `0m`, щоб вимкнути. + - `every`: рядок тривалості (`30m`, `2h`). Установіть `0m`, щоб вимкнути. - `target`: `last` | `none` | `` (наприклад, `discord`, `matrix`, `telegram` або `whatsapp`) - - `directPolicy`: `allow` (типово) або `block` для цілей Heartbeat у стилі особистих повідомлень - - Дивіться [Heartbeat](/uk/gateway/heartbeat) для повного посібника. + - `directPolicy`: `allow` (типово) або `block` для цілей Heartbeat у стилі DM + - Див. [Heartbeat](/uk/gateway/heartbeat) для повного посібника. - + ```json5 { cron: { @@ -432,14 +412,14 @@ JSON. } ``` - - `sessionRetention`: очищати завершені ізольовані сесії запуску з `sessions.json` (типово `24h`; встановіть `false`, щоб вимкнути). + - `sessionRetention`: видаляти завершені ізольовані сесії запуску з `sessions.json` (типово `24h`; установіть `false`, щоб вимкнути). - `runLog`: очищати `cron/runs/.jsonl` за розміром і кількістю збережених рядків. - - Дивіться [завдання Cron](/uk/automation/cron-jobs) для огляду функціональності та прикладів CLI. + - Див. [Cron jobs](/uk/automation/cron-jobs) для огляду можливостей і прикладів CLI. - - Увімкніть HTTP-ендпойнти Webhook на Gateway: + + Увімкніть HTTP-ендпоїнти Webhook у Gateway: ```json5 { @@ -463,20 +443,20 @@ JSON. ``` Примітка щодо безпеки: - - Розглядайте весь вміст payload hook/webhook як ненадійне введення. + - Уважайте весь вміст payload 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, віддавайте перевагу сильним сучасним рівням моделей і суворій політиці інструментів (наприклад, лише надсилання повідомлень плюс ізоляція, де це можливо). + - `hooks.path` не може бути `/`; використовуйте для вхідних Webhook окремий підшлях, наприклад `/hooks`. + - Залишайте прапорці обходу небезпечного вмісту вимкненими (`hooks.gmail.allowUnsafeExternalContent`, `hooks.mappings[].allowUnsafeExternalContent`), якщо не виконуєте чітко обмежене налагодження. + - Якщо ви вмикаєте `hooks.allowRequestSessionKey`, також установіть `hooks.allowedSessionKeyPrefixes`, щоб обмежити ключі сесій, які може вибирати викликач. + - Для агентів, керованих через hook, віддавайте перевагу сильним сучасним рівням моделей і суворій політиці інструментів (наприклад, лише обмін повідомленнями плюс sandboxing, де це можливо). - Дивіться [повний довідник](/uk/gateway/configuration-reference#hooks) для всіх параметрів зіставлення та інтеграції Gmail. + Див. [повний довідник](/uk/gateway/configuration-reference#hooks) для всіх параметрів mapping і інтеграції Gmail. - - Запускайте кількох ізольованих агентів з окремими робочими просторами та сесіями: + + Запускайте кілька ізольованих агентів з окремими робочими просторами та сесіями: ```json5 { @@ -493,11 +473,11 @@ JSON. } ``` - Дивіться [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`, щоб упорядкувати великі конфігурації: ```json5 @@ -511,47 +491,47 @@ JSON. } ``` - - **Один файл**: замінює об’єкт-контейнер + - **Один файл**: замінює об’єкт, у якому міститься - **Масив файлів**: глибоко об’єднується за порядком (пізніші мають пріоритет) - - **Сусідні ключі**: об’єднуються після includes (перевизначають включені значення) - - **Вкладені includes**: підтримуються до 10 рівнів вкладеності + - **Сусідні ключі**: об’єднуються після include (перевизначають включені значення) + - **Вкладені include**: підтримуються до 10 рівнів вкладеності - **Відносні шляхи**: обчислюються відносно файлу, який включає - **Записи, якими керує OpenClaw**: коли запис змінює лише один розділ верхнього рівня, - підкріплений include одного файлу, наприклад `plugins: { $include: "./plugins.json5" }`, - OpenClaw оновлює цей включений файл і залишає `openclaw.json` недоторканим - - **Непідтримуваний запис наскрізь**: кореневі includes, масиви include і includes - із сусідніми перевизначеннями аварійно завершуються для записів, якими керує OpenClaw, замість + що підкріплений include одного файлу, наприклад `plugins: { $include: "./plugins.json5" }`, + OpenClaw оновлює цей включений файл і залишає `openclaw.json` без змін + - **Непідтримуваний наскрізний запис**: кореневі include, масиви include та include + із сусідніми перевизначеннями завершуються без змін для записів, якими керує OpenClaw, замість сплощення конфігурації - - **Обробка помилок**: зрозумілі помилки для відсутніх файлів, помилок розбору та циклічних includes + - **Обробка помилок**: зрозумілі помилки для відсутніх файлів, помилок розбору та циклічних 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](/uk/gateway/troubleshooting#gateway-restored-last-known-good-config) +файл `.clobbered.*` поруч із `openclaw.json`, виправте відхилений payload, а потім запустіть +`openclaw config validate`. Див. [Gateway troubleshooting](/uk/gateway/troubleshooting#gateway-restored-last-known-good-config) для контрольного списку відновлення. ### Режими перезавантаження -| Режим | Поведінка | -| ---------------------- | -------------------------------------------------------------------------------------- | -| **`hybrid`** (типово) | Миттєво гаряче застосовує безпечні зміни. Автоматично перезапускає для критичних. | -| **`hot`** | Гаряче застосовує лише безпечні зміни. Пише попередження, коли потрібен перезапуск — ви обробляєте це самі. | -| **`restart`** | Перезапускає Gateway за будь-якої зміни конфігурації, безпечної чи ні. | -| **`off`** | Вимикає відстеження файлів. Зміни набувають чинності під час наступного ручного перезапуску. | +| Режим | Поведінка | +| ---------------------- | ---------------------------------------------------------------------------------------- | +| **`hybrid`** (типово) | Безпечно застосовує зміни одразу. Для критичних змін автоматично виконує перезапуск. | +| **`hot`** | Застосовує лише безпечні зміни без перезапуску. Записує попередження, коли потрібен перезапуск — ви виконуєте його самі. | +| **`restart`** | Перезапускає Gateway за будь-якої зміни конфігурації, безпечної чи ні. | +| **`off`** | Вимикає відстеження файлу. Зміни набудуть чинності під час наступного ручного перезапуску. | ```json5 { @@ -561,114 +541,74 @@ 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 конфігурації (програмні оновлення) +Для інструментів, які записують конфігурацію через API gateway, віддавайте перевагу такому процесу: + +- `config.schema.lookup`, щоб перевірити одне піддерево (поверхневий вузол схеми + короткі + відомості про дочірні елементи) +- `config.get`, щоб отримати поточний знімок разом із `hash` +- `config.patch` для часткових оновлень (JSON merge patch: об’єкти об’єднуються, `null` + видаляє, масиви замінюються) +- `config.apply` лише тоді, коли ви справді хочете замінити всю конфігурацію +- `update.run` для явного самостійного оновлення з подальшим перезапуском + -RPC запису control-plane (`config.apply`, `config.patch`, `update.run`) мають обмеження частоти: **3 запити на 60 секунд** для кожного `deviceId+clientIp`. У разі спрацювання обмеження RPC повертає `UNAVAILABLE` з `retryAfterMs`. +Записи контрольної площини (`config.apply`, `config.patch`, `update.run`) обмежуються +до 3 запитів на 60 секунд для кожної пари `deviceId+clientIp`. Запити на перезапуск +об’єднуються, а потім між циклами перезапуску застосовується затримка 30 секунд. -Безпечний/типовий процес: +Приклад часткового patch: -- `config.schema.lookup`: переглянути одне піддерево конфігурації з прив’язкою до шляху з неглибоким - вузлом схеми, відповідними метаданими підказок і короткими описами безпосередніх дочірніх елементів -- `config.get`: отримати поточний знімок + хеш -- `config.patch`: бажаний шлях часткового оновлення -- `config.apply`: лише повна заміна конфігурації -- `update.run`: явне самооновлення + перезапуск +```bash +openclaw gateway call config.get --params '{}' # capture payload.hash +openclaw gateway call config.patch --params '{ + "raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }", + "baseHash": "" +}' +``` -Коли ви не замінюєте всю конфігурацію, віддавайте перевагу `config.schema.lookup`, -а потім `config.patch`. - - - - Перевіряє + записує повну конфігурацію і перезапускає Gateway за один крок. - - - `config.apply` замінює **всю конфігурацію**. Використовуйте `config.patch` для часткових оновлень або `openclaw config set` для окремих ключів. - - - Параметри: - - - `raw` (string) — payload JSON5 для всієї конфігурації - - `baseHash` (optional) — хеш конфігурації з `config.get` (обов’язковий, коли конфігурація існує) - - `sessionKey` (optional) — ключ сесії для ping пробудження після перезапуску - - `note` (optional) — примітка для sentinel перезапуску - - `restartDelayMs` (optional) — затримка перед перезапуском (типово 2000) - - Запити на перезапуск об’єднуються, якщо один уже очікує/виконується, і між циклами перезапуску діє 30-секундний період охолодження. - - ```bash - openclaw gateway call config.get --params '{}' # capture payload.hash - openclaw gateway call config.apply --params '{ - "raw": "{ agents: { defaults: { workspace: \"~/.openclaw/workspace\" } } }", - "baseHash": "", - "sessionKey": "agent:main:whatsapp:direct:+15555550123" - }' - ``` - - - - - Об’єднує часткове оновлення з наявною конфігурацією (семантика JSON merge patch): - - - Об’єкти об’єднуються рекурсивно - - `null` видаляє ключ - - Масиви замінюються - - Параметри: - - - `raw` (string) — JSON5 лише з тими ключами, які потрібно змінити - - `baseHash` (required) — хеш конфігурації з `config.get` - - `sessionKey`, `note`, `restartDelayMs` — ті самі, що й у `config.apply` - - Поведінка перезапуску збігається з `config.apply`: об’єднання відкладених перезапусків плюс 30-секундний період охолодження між циклами перезапуску. - - ```bash - openclaw gateway call config.patch --params '{ - "raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }", - "baseHash": "" - }' - ``` - - - +І `config.apply`, і `config.patch` приймають `raw`, `baseHash`, `sessionKey`, +`note` і `restartDelayMs`. `baseHash` є обов’язковим для `config.patch` і +рекомендованим для `config.apply`, коли конфігурація вже існує. ## Змінні середовища -OpenClaw читає змінні середовища з батьківського процесу, а також із: +OpenClaw читає змінні середовища з батьківського процесу, а також з: - `.env` у поточному робочому каталозі (якщо є) -- `~/.openclaw/.env` (глобальний резервний варіант) +- `~/.openclaw/.env` (глобальний запасний варіант) -Жоден із цих файлів не перевизначає наявні змінні середовища. Ви також можете задавати вбудовані змінні середовища в конфігурації: +Жоден із цих файлів не перевизначає вже наявні змінні середовища. Ви також можете задавати вбудовані змінні середовища в конфігурації: ```json5 { @@ -679,8 +619,8 @@ OpenClaw читає змінні середовища з батьківсько } ``` - - Якщо цю функцію ввімкнено, а очікувані ключі не задано, OpenClaw запускає вашу login shell і імпортує лише відсутні ключі: + + Якщо ввімкнено і очікувані ключі не задано, OpenClaw запускає вашу login shell і імпортує лише відсутні ключі: ```json5 { @@ -690,7 +630,7 @@ OpenClaw читає змінні середовища з батьківсько } ``` -Еквівалент змінної середовища: `OPENCLAW_LOAD_SHELL_ENV=1` +Еквівалентна змінна середовища: `OPENCLAW_LOAD_SHELL_ENV=1` @@ -705,9 +645,9 @@ OpenClaw читає змінні середовища з батьківсько Правила: -- Зіставляються лише назви у верхньому регістрі: `[A-Z_][A-Z0-9_]*` +- Зіставляються лише імена у верхньому регістрі: `[A-Z_][A-Z0-9_]*` - Відсутні/порожні змінні спричиняють помилку під час завантаження -- Екранування через `$${VAR}` для буквального виводу +- Використовуйте `$${VAR}` для буквального виводу - Працює всередині файлів `$include` - Вбудована підстановка: `"${BASE}/v1"` → `"https://api.example.com/v1"` @@ -746,16 +686,16 @@ OpenClaw читає змінні середовища з батьківсько } ``` -Подробиці про SecretRef (зокрема `secrets.providers` для `env`/`file`/`exec`) наведено в [Керування секретами](/uk/gateway/secrets). -Підтримувані шляхи облікових даних перелічено в [Поверхня облікових даних SecretRef](/uk/reference/secretref-credential-surface). +Подробиці про SecretRef (зокрема `secrets.providers` для `env`/`file`/`exec`) наведено в [Secrets Management](/uk/gateway/secrets). +Підтримувані шляхи облікових даних перелічено в [SecretRef Credential Surface](/uk/reference/secretref-credential-surface). -Дивіться [Середовище](/uk/help/environment) для повного порядку пріоритету та джерел. +Див. [Environment](/uk/help/environment) для повного опису пріоритетів і джерел. ## Повний довідник -Повний довідник по полях дивіться в **[Довіднику конфігурації](/uk/gateway/configuration-reference)**. +Повний довідник по полях див. в **[Configuration Reference](/uk/gateway/configuration-reference)**. --- -_Пов’язане: [Приклади конфігурації](/uk/gateway/configuration-examples) · [Довідник конфігурації](/uk/gateway/configuration-reference) · [Doctor](/uk/gateway/doctor)_ +_Пов’язане: [Configuration Examples](/uk/gateway/configuration-examples) · [Configuration Reference](/uk/gateway/configuration-reference) · [Doctor](/uk/gateway/doctor)_ diff --git a/docs/uk/plugins/architecture.md b/docs/uk/plugins/architecture.md index a50ccc301..5a9fc9e6c 100644 --- a/docs/uk/plugins/architecture.md +++ b/docs/uk/plugins/architecture.md @@ -1,17 +1,17 @@ --- read_when: - - Збирання або налагодження нативних plugins OpenClaw + - Створення або налагодження native Plugin для OpenClaw - Розуміння моделі можливостей Plugin або меж володіння - Робота над конвеєром завантаження Plugin або реєстром - - Реалізація runtime hooks provider або plugins каналів + - Реалізація хуків часу виконання провайдера або Plugin каналів sidebarTitle: Internals -summary: 'Внутрішня будова Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та runtime helpers' +summary: 'Внутрішня будова Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби часу виконання' title: Внутрішня будова Plugin x-i18n: - generated_at: "2026-04-23T07:25:43Z" + generated_at: "2026-04-23T08:14:12Z" model: gpt-5.4 provider: openai - source_hash: e7500ddc49feb828c65b0ec856aafdd53d52c965c32232bb518eb218f686ebf0 + source_hash: d3d5e4b9c48c2a0fc8116733e38a745bac5dfdbe65fdea8e9be6563b4051d805 source_path: plugins/architecture.md workflow: 15 --- @@ -19,177 +19,176 @@ x-i18n: # Внутрішня будова Plugin - Це **поглиблений довідник з архітектури**. Практичні посібники див. тут: - - [Встановлення та використання plugins](/uk/tools/plugin) — посібник для користувачів - - [Початок роботи](/uk/plugins/building-plugins) — перший посібник зі створення plugin - - [Plugins каналів](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями - - [Plugins providers](/uk/plugins/sdk-provider-plugins) — створення provider моделей + Це **довідник із глибокої архітектури**. Практичні посібники див. тут: + - [Встановлення та використання Plugin](/uk/tools/plugin) — посібник для користувача + - [Початок роботи](/uk/plugins/building-plugins) — перший навчальний посібник зі створення Plugin + - [Plugin каналів](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями + - [Plugin провайдерів](/uk/plugins/sdk-provider-plugins) — створення провайдера моделей - [Огляд SDK](/uk/plugins/sdk-overview) — карта імпорту та API реєстрації -На цій сторінці описано внутрішню архітектуру системи plugins OpenClaw. +На цій сторінці описано внутрішню архітектуру системи Plugin в OpenClaw. ## Публічна модель можливостей -Можливості — це публічна модель **нативних plugins** всередині OpenClaw. Кожен -нативний plugin OpenClaw реєструється для одного або кількох типів можливостей: +Можливості — це публічна модель **native Plugin** всередині OpenClaw. Кожен +native Plugin OpenClaw реєструється для одного або кількох типів можливостей: -| Capability | Registration method | Приклади plugins | -| ---------------------- | ------------------------------------------------ | ------------------------------------ | -| Виведення тексту | `api.registerProvider(...)` | `openai`, `anthropic` | -| Бекенд CLI для виведення | `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` | +| Канал / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | -Plugin, який реєструє нуль можливостей, але надає hooks, tools або -services, є **застарілим plugin лише з hooks**. Такий шаблон і далі повністю підтримується. +Plugin, який реєструє нуль можливостей, але надає хуки, інструменти або +сервіси, є **застарілим Plugin лише з хуками**. Цей шаблон усе ще повністю підтримується. ### Позиція щодо зовнішньої сумісності Модель можливостей уже реалізована в core і сьогодні використовується -вбудованими/нативними plugins, але сумісність зовнішніх plugins усе ще потребує -чіткішої межі, ніж «це експортується, отже це заморожено». +вбудованими/native Plugin, але сумісність із зовнішніми Plugin усе ще потребує +чіткішої межі, ніж «це експортується, отже це незмінний контракт». Поточні рекомендації: -- **наявні зовнішні plugins:** зберігайте працездатність інтеграцій на основі hooks; вважайте +- **наявні зовнішні Plugin:** зберігайте працездатність інтеграцій на основі хуків; вважайте це базовим рівнем сумісності -- **нові вбудовані/нативні plugins:** віддавайте перевагу явній реєстрації можливостей замість - vendor-specific доступу всередину або нових конструкцій лише з hooks -- **зовнішні plugins, що переходять на реєстрацію можливостей:** це дозволено, але - вважайте surfaces допоміжних засобів, прив’язані до конкретних можливостей, такими, що розвиваються, - якщо документація явно не позначає контракт як стабільний +- **нові вбудовані/native Plugin:** надавайте перевагу явній реєстрації можливостей замість + vendor-specific доступу до внутрішніх механізмів або нових дизайнів лише з хуками +- **зовнішні Plugin, які переходять на реєстрацію можливостей:** це дозволено, але + вважайте допоміжні поверхні, специфічні для можливостей, такими, що еволюціонують, якщо в документації контракт явно не позначено як стабільний Практичне правило: -- API реєстрації можливостей — це бажаний напрямок -- застарілі hooks залишаються найбезпечнішим шляхом без порушення сумісності для зовнішніх plugins під час +- API реєстрації можливостей — це рекомендований напрям +- застарілі хуки залишаються найбезпечнішим шляхом без ламання сумісності для зовнішніх Plugin під час переходу -- не всі експортовані допоміжні subpaths однакові; віддавайте перевагу вузькому задокументованому - контракту, а не побічним експортам допоміжних засобів +- не всі експортовані допоміжні підшляхи однаково важливі; надавайте перевагу вузькому документованому + контракту, а не випадковим допоміжним експортам -### Форми plugins +### Форми Plugin -OpenClaw класифікує кожен завантажений plugin за формою на основі його фактичної -поведінки реєстрації, а не лише статичних метаданих: +OpenClaw класифікує кожен завантажений Plugin за формою на основі його фактичної +поведінки реєстрації (а не лише статичних метаданих): -- **plain-capability** — реєструє рівно один тип можливостей (наприклад, - plugin лише для provider, як-от `mistral`) -- **hybrid-capability** — реєструє кілька типів можливостей (наприклад, - `openai` володіє виведенням тексту, мовленням, розумінням медіа та - генерацією зображень) -- **hook-only** — реєструє лише hooks (типізовані або користувацькі), без capabilities, - tools, commands чи services -- **non-capability** — реєструє tools, commands, services або routes, але без - capabilities +- **plain-capability** -- реєструє рівно один тип можливостей (наприклад, + Plugin лише провайдера, як-от `mistral`) +- **hybrid-capability** -- реєструє кілька типів можливостей (наприклад, + `openai` відповідає за текстовий inference, мовлення, розуміння медіа та + генерацію зображень) +- **hook-only** -- реєструє лише хуки (типізовані або користувацькі), без можливостей, + інструментів, команд або сервісів +- **non-capability** -- реєструє інструменти, команди, сервіси або маршрути, але не + можливості -Використовуйте `openclaw plugins inspect `, щоб побачити форму plugin і розподіл +Використовуйте `openclaw plugins inspect `, щоб побачити форму Plugin і розподіл можливостей. Докладніше див. у [довіднику CLI](/uk/cli/plugins#inspect). -### Застарілі hooks +### Застарілі хуки -Hook `before_agent_start` залишається підтримуваним як шлях сумісності для -plugins лише з hooks. Реальні застарілі plugins усе ще залежать від нього. +Хук `before_agent_start` залишається підтримуваним як сумісний шлях для +Plugin лише з хуками. Реальні застарілі Plugin досі від нього залежать. -Напрямок: +Напрям: -- зберігати його працездатним +- зберігати його працездатність - документувати його як застарілий -- для роботи з перевизначенням model/provider віддавати перевагу `before_model_resolve` -- для змін prompts віддавати перевагу `before_prompt_build` -- видаляти лише після зниження реального використання і коли покриття fixtures доведе безпечність міграції +- для роботи з перевизначенням моделі/провайдера надавати перевагу `before_model_resolve` +- для зміни prompt надавати перевагу `before_prompt_build` +- видаляти лише після зменшення реального використання та підтвердження безпечної міграції через покриття фікстурами ### Сигнали сумісності -Під час запуску `openclaw doctor` або `openclaw plugins inspect ` ви можете побачити -один із таких ярликів: +Коли ви запускаєте `openclaw doctor` або `openclaw plugins inspect `, ви можете побачити +одну з таких міток: -| Signal | Значення | -| -------------------------- | ----------------------------------------------------------- | -| **config valid** | Config успішно розбирається, plugins коректно визначаються | +| Сигнал | Значення | +| -------------------------- | ------------------------------------------------------------ | +| **config valid** | Конфігурація коректно розбирається, і Plugin успішно визначаються | | **compatibility advisory** | Plugin використовує підтримуваний, але старіший шаблон (наприклад, `hook-only`) | -| **legacy warning** | Plugin використовує `before_agent_start`, який є застарілим | -| **hard error** | Config некоректний або plugin не вдалося завантажити | +| **legacy warning** | Plugin використовує `before_agent_start`, який є застарілим | +| **hard error** | Конфігурація некоректна або Plugin не вдалося завантажити | -Ні `hook-only`, ні `before_agent_start` не зламають ваш plugin сьогодні -- +Ні `hook-only`, ні `before_agent_start` не зламають ваш Plugin сьогодні -- `hook-only` є рекомендаційним сигналом, а `before_agent_start` лише викликає попередження. Ці сигнали також з’являються в `openclaw status --all` і `openclaw plugins doctor`. ## Огляд архітектури -Система plugins OpenClaw має чотири рівні: +Система Plugin в OpenClaw має чотири шари: 1. **Маніфест + виявлення** - OpenClaw знаходить кандидатів у plugins із налаштованих шляхів, коренів workspace, - глобальних коренів plugins і вбудованих plugins. Виявлення спочатку читає нативні - маніфести `openclaw.plugin.json` та маніфести підтримуваних bundle. + OpenClaw знаходить потенційні Plugin із налаштованих шляхів, коренів робочих просторів, + глобальних коренів Plugin і вбудованих Plugin. Під час виявлення спочатку читаються native + маніфести `openclaw.plugin.json` і підтримувані маніфести пакетів. 2. **Увімкнення + валідація** - Core визначає, чи є виявлений plugin увімкненим, вимкненим, заблокованим або - вибраним для ексклюзивного слота, наприклад пам’яті. -3. **Завантаження runtime** - Нативні plugins OpenClaw завантажуються в процесі через jiti і реєструють - можливості в центральному реєстрі. Сумісні bundles нормалізуються в записи - реєстру без імпорту коду runtime. -4. **Використання surfaces** - Решта OpenClaw читає реєстр, щоб надавати tools, канали, налаштування provider, - hooks, HTTP routes, CLI commands і services. + Core визначає, чи виявлений Plugin увімкнено, вимкнено, заблоковано чи + вибрано для ексклюзивного слота, такого як пам’ять. +3. **Завантаження під час виконання** + Native Plugin OpenClaw завантажуються в процесі через jiti і реєструють + можливості в центральному реєстрі. Сумісні пакети нормалізуються в записи + реєстру без імпорту коду часу виконання. +4. **Споживання поверхонь** + Решта OpenClaw читає реєстр, щоб надавати інструменти, канали, налаштування + провайдерів, хуки, HTTP-маршрути, CLI-команди та сервіси. -Зокрема для CLI plugin виявлення кореневих commands розділено на дві фази: +Спеціально для CLI Plugin виявлення кореневих команд поділено на дві фази: -- метадані часу розбору надходять із `registerCli(..., { descriptors: [...] })` -- реальний модуль CLI plugin може залишатися лінивим і реєструватися під час першого виклику +- метадані на етапі розбору надходять із `registerCli(..., { descriptors: [...] })` +- реальний CLI-модуль Plugin може залишатися лінивим і реєструватися при першому виклику -Це дозволяє залишати код CLI, що належить plugin, всередині plugin, і водночас дає OpenClaw -можливість резервувати імена кореневих commands до розбору. +Це дає змогу зберігати CLI-код, що належить Plugin, усередині самого Plugin і водночас дозволяє OpenClaw +резервувати назви кореневих команд до розбору. Важлива межа проєктування: -- виявлення + валідація config мають працювати на основі **метаданих маніфесту/схеми** - без виконання коду plugin -- нативна поведінка runtime надходить зі шляху `register(api)` модуля plugin +- виявлення + валідація конфігурації мають працювати з **метаданих маніфесту/схеми** + без виконання коду Plugin +- native поведінка під час виконання походить із шляху `register(api)` модуля Plugin -Такий поділ дозволяє OpenClaw валідовувати config, пояснювати відсутні/вимкнені plugins і -будувати підказки UI/схеми ще до повної активації runtime. +Це розділення дає OpenClaw змогу перевіряти конфігурацію, пояснювати відсутні/вимкнені Plugin і +створювати підказки для UI/схеми до повної активації часу виконання. -### Plugins каналів і спільний tool повідомлень +### Plugin каналів і спільний інструмент повідомлень -Plugins каналів не повинні реєструвати окремий tool для надсилання/редагування/реакцій для -звичайних дій у чаті. OpenClaw зберігає один спільний tool `message` у core, а -plugins каналів володіють специфічним для каналу виявленням і виконанням за ним. +Plugin каналів не потрібно реєструвати окремий інструмент send/edit/react для +звичайних дій у чаті. OpenClaw зберігає один спільний інструмент `message` у core, а +Plugin каналів відповідають за специфічне для каналу виявлення та виконання за ним. Поточна межа така: -- core володіє хостом спільного tool `message`, підключенням prompts, веденням обліку сесій/гілок - і диспетчеризацією виконання -- plugins каналів володіють виявленням дій у межах scope, виявленням можливостей і будь-якими - специфічними для каналу фрагментами схеми -- plugins каналів володіють специфічною для provider граматикою розмов сесії, наприклад - тим, як ідентифікатори conversation кодують thread ids або успадковуються від батьківських conversations -- plugins каналів виконують остаточну дію через свій адаптер дій +- core відповідає за хост спільного інструмента `message`, підключення prompt, + облік сесій/гілок і диспетчеризацію виконання +- Plugin каналів відповідають за виявлення дій в обмеженому контексті, виявлення + можливостей і будь-які специфічні для каналу фрагменти схеми +- Plugin каналів відповідають за специфічну для провайдера граматику розмов у сесії, наприклад + як ідентифікатори розмов кодують ідентифікатори гілок або успадковуються від батьківських розмов +- Plugin каналів виконують фінальну дію через свій адаптер дій -Для plugins каналів surface SDK — це +Для Plugin каналів поверхнею SDK є `ChannelMessageActionAdapter.describeMessageTool(...)`. Цей уніфікований виклик -виявлення дозволяє plugin повертати видимі дії, можливості та внески до схеми -разом, щоб ці частини не розходилися. +виявлення дає змогу Plugin повертати видимі дії, можливості та внески у схему +разом, щоб ці частини не розходилися між собою. -Коли специфічний для каналу параметр tool повідомлень містить джерело медіа, наприклад -локальний шлях або URL віддаленого медіа, plugin також має повертати -`mediaSourceParams` з `describeMessageTool(...)`. Core використовує цей явний -список, щоб застосовувати нормалізацію шляхів пісочниці й підказки доступу до вихідних медіа -без жорстко закодованих імен параметрів plugin. -Тут віддавайте перевагу maps у межах дії, а не одному плоскому списку для всього каналу, -щоб параметр медіа лише для профілю не нормалізувався для не пов’язаних дій, таких як +Коли параметр інструмента повідомлень, специфічний для каналу, містить джерело медіа, наприклад +локальний шлях або віддалений URL медіа, Plugin також має повертати +`mediaSourceParams` із `describeMessageTool(...)`. Core використовує цей явний +список, щоб застосовувати нормалізацію шляхів пісочниці та підказки щодо +вихідного доступу до медіа без жорсткого кодування назв параметрів, що належать Plugin. +Тут слід надавати перевагу картам із прив’язкою до дій, а не одному плоскому списку для всього каналу, щоб +параметр медіа лише для профілю не нормалізувався в не пов’язаних діях, як-от `send`. -Core передає scope runtime у цей крок виявлення. Важливі поля включають: +Core передає область часу виконання в цей крок виявлення. Серед важливих полів: - `accountId` - `currentChannelId` @@ -200,124 +199,125 @@ Core передає scope runtime у цей крок виявлення. Важ - `agentId` - довірений вхідний `requesterSenderId` -Це важливо для context-sensitive plugins. Канал може приховувати або показувати -дії повідомлень залежно від активного облікового запису, поточної кімнати/гілки/повідомлення або +Це важливо для Plugin, чутливих до контексту. Канал може приховувати або показувати +дії з повідомленнями залежно від активного облікового запису, поточної кімнати/гілки/повідомлення або довіреної ідентичності запитувача без жорстко закодованих специфічних для каналу гілок у -core tool `message`. +core-інструменті `message`. -Саме тому зміни маршрутизації embedded-runner усе ще є роботою plugin: runner -відповідає за передавання поточної ідентичності чату/сесії в межу виявлення plugin, щоб -спільний tool `message` відкривав правильний surface, що належить каналу, для поточного ходу. +Саме тому зміни маршрутизації embedded-runner усе ще є роботою Plugin: runner +відповідає за передавання поточної ідентичності чату/сесії в межу виявлення Plugin, щоб +спільний інструмент `message` показував правильну поверхню, що належить каналу, +для поточного кроку. -Для допоміжних засобів виконання, що належать каналу, вбудовані plugins мають зберігати runtime виконання -всередині власних модулів extension. Core більше не володіє runtime дій повідомлень Discord, -Slack, Telegram або WhatsApp у `src/agents/tools`. -Ми не публікуємо окремі subpaths `plugin-sdk/*-action-runtime`, і вбудовані -plugins мають імпортувати свій власний локальний код runtime безпосередньо зі своїх -модулів extension. +Для допоміжних засобів виконання, що належать каналу, вбудовані Plugin мають зберігати середовище +виконання всередині власних модулів extension. Core більше не володіє середовищами +виконання дій із повідомленнями для Discord, Slack, Telegram чи WhatsApp у `src/agents/tools`. +Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, і вбудовані +Plugin мають імпортувати власний локальний код часу виконання безпосередньо зі своїх +модулів, що належать extension. -Та сама межа застосовується до загалом SDK seams із назвами providers: core не повинен -імпортувати зручні barrels, специфічні для каналів Slack, Discord, Signal, -WhatsApp або подібних extensions. Якщо core потребує певної поведінки, або використовуйте -власний barrel `api.ts` / `runtime-api.ts` вбудованого plugin, або підніміть цю потребу -до вузької загальної можливості в спільному SDK. +Та сама межа застосовується і до специфічних для провайдерів поверхонь SDK загалом: core не має +імпортувати зручні barrel-модулі, специфічні для каналів Slack, Discord, Signal, +WhatsApp чи подібних extension. Якщо core потрібна певна поведінка, слід або +використати власний barrel `api.ts` / `runtime-api.ts` вбудованого Plugin, або +перенести цю потребу у вузьку загальну можливість у спільному SDK. -Зокрема для опитувань існує два шляхи виконання: +Спеціально для опитувань є два шляхи виконання: -- `outbound.sendPoll` — спільна базова реалізація для каналів, що відповідають загальній моделі - опитувань -- `actions.handleAction("poll")` — бажаний шлях для специфічної для каналу семантики +- `outbound.sendPoll` — це спільна базова можливість для каналів, які відповідають загальній + моделі опитувань +- `actions.handleAction("poll")` — це бажаний шлях для специфічної для каналу семантики опитувань або додаткових параметрів опитувань -Тепер core відкладає спільний розбір опитувань до моменту, коли диспетчеризація опитування plugin -відхиляє дію, тож обробники опитувань, що належать plugin, можуть приймати специфічні для каналу поля -опитувань без блокування загальним парсером опитувань на попередньому етапі. +Тепер core відкладає спільний розбір опитувань до моменту, коли диспетчеризація +опитувань Plugin відхилить дію, щоб обробники опитувань, що належать Plugin, могли приймати +специфічні для каналу поля опитувань, не блокуючись спочатку загальним парсером опитувань. -Повну послідовність запуску див. у розділі [Конвеєр завантаження](#load-pipeline). +Повну послідовність запуску див. у [Конвеєр завантаження](#load-pipeline). ## Модель володіння можливостями -OpenClaw розглядає нативний plugin як межу володіння для **компанії** або +OpenClaw розглядає native Plugin як межу володіння для **компанії** або **функції**, а не як набір не пов’язаних інтеграцій. Це означає: -- plugin компанії зазвичай має володіти всіма surfaces OpenClaw, пов’язаними з цією компанією -- plugin функції зазвичай має володіти повним surface функції, яку він додає -- канали мають використовувати спільні можливості core замість того, щоб повторно реалізовувати - поведінку provider ad hoc +- Plugin компанії зазвичай має володіти всіма поверхнями OpenClaw, що стосуються цієї компанії +- Plugin функції зазвичай має володіти повною поверхнею функції, яку він додає +- канали мають використовувати спільні можливості core замість того, щоб імпровізовано повторно + реалізовувати поведінку провайдера Приклади: -- вбудований plugin `openai` володіє поведінкою provider моделей OpenAI, а також поведінкою OpenAI для +- вбудований Plugin `openai` відповідає за поведінку провайдера моделей OpenAI та за поведінку OpenAI для мовлення + голосу в реальному часі + розуміння медіа + генерації зображень -- вбудований plugin `elevenlabs` володіє поведінкою мовлення ElevenLabs -- вбудований plugin `microsoft` володіє поведінкою мовлення Microsoft -- вбудований plugin `google` володіє поведінкою provider моделей Google, а також поведінкою Google для +- вбудований Plugin `elevenlabs` відповідає за поведінку мовлення ElevenLabs +- вбудований Plugin `microsoft` відповідає за поведінку мовлення Microsoft +- вбудований Plugin `google` відповідає за поведінку провайдера моделей Google, а також за поведінку Google для розуміння медіа + генерації зображень + вебпошуку -- вбудований plugin `firecrawl` володіє поведінкою отримання вебданих Firecrawl -- вбудовані plugins `minimax`, `mistral`, `moonshot` і `zai` володіють своїми - бекендами розуміння медіа -- вбудований plugin `qwen` володіє поведінкою text-provider Qwen, а також - поведінкою розуміння медіа і генерації відео -- plugin `voice-call` — це plugin функції: він володіє транспортом дзвінків, tools, - CLI, routes і мостом медіапотоків Twilio, але використовує спільні можливості мовлення, +- вбудований Plugin `firecrawl` відповідає за поведінку Firecrawl для отримання вебвмісту +- вбудовані Plugin `minimax`, `mistral`, `moonshot` і `zai` відповідають за свої + бекенди розуміння медіа +- вбудований Plugin `qwen` відповідає за поведінку текстового провайдера Qwen, а також за + поведінку розуміння медіа та генерації відео +- Plugin `voice-call` є Plugin функції: він відповідає за транспорт викликів, інструменти, + CLI, маршрути та міст Twilio для медіапотоку, але використовує спільні можливості мовлення, а також транскрипції в реальному часі й голосу в реальному часі замість - прямого імпорту plugins vendor + прямого імпорту vendor Plugin -Бажаний кінцевий стан: +Бажаний кінцевий стан такий: -- OpenAI знаходиться в одному plugin, навіть якщо охоплює текстові моделі, мовлення, зображення та +- OpenAI живе в одному Plugin, навіть якщо охоплює текстові моделі, мовлення, зображення та майбутнє відео -- інший vendor може зробити так само для власного surface -- канали не залежать від того, який plugin vendor володіє provider; вони використовують +- інший вендор може зробити те саме для власної поверхні +- канали не мають зважати, який vendor Plugin володіє провайдером; вони використовують спільний контракт можливостей, який надає core Ось ключова відмінність: - **plugin** = межа володіння -- **capability** = контракт core, який можуть реалізовувати або використовувати кілька plugins +- **capability** = контракт core, який можуть реалізовувати або використовувати кілька Plugin -Тому, якщо OpenClaw додає нову область, наприклад відео, перше питання не таке: -«який provider повинен жорстко закодувати обробку відео?» Перше питання таке: «яким є -контракт core для можливостей відео?» Щойно такий контракт з’являється, plugins vendor -можуть реєструватися для нього, а plugins каналів/функцій можуть його використовувати. +Тому, якщо OpenClaw додає нову доменну область, наприклад відео, перше запитання не таке: +«який провайдер має жорстко закодувати обробку відео?» Перше запитання таке: «який +контракт core для можливості відео?» Щойно такий контракт з’явиться, vendor Plugin +зможуть реєструватися для нього, а Plugin каналів/функцій зможуть його використовувати. -Якщо можливість ще не існує, зазвичай правильний крок такий: +Якщо можливість ще не існує, правильний крок зазвичай такий: 1. визначити відсутню можливість у core -2. відкрити її через API/runtime plugin у типізований спосіб -3. підключити канали/функції до цієї можливості -4. дозволити plugins vendor реєструвати реалізації +2. типізовано відкрити її через API/час виконання Plugin +3. під’єднати канали/функції до цієї можливості +4. дозволити vendor Plugin реєструвати реалізації -Це робить володіння явним і водночас уникає поведінки core, яка залежить від -одного vendor або одноразового специфічного для plugin шляху коду. +Це зберігає явність володіння та водночас уникає поведінки core, яка залежить від +одного вендора або разового шляху коду, специфічного для Plugin. ### Шарування можливостей -Використовуйте таку ментальну модель, коли вирішуєте, де має знаходитися код: +Використовуйте таку ментальну модель, коли вирішуєте, де має бути код: -- **шар можливостей core**: спільна оркестрація, policy, fallback, правила - злиття config, семантика доставки та типізовані контракти -- **шар plugin vendor**: специфічні для vendor API, автентифікація, каталоги моделей, синтез мовлення, - генерація зображень, майбутні бекенди відео, endpoints використання -- **шар plugin каналу/функції**: інтеграція Slack/Discord/voice-call тощо, - яка використовує можливості core і представляє їх на певному surface +- **шар можливостей core**: спільна оркестрація, політика, fallback, + правила об’єднання config, семантика доставлення та типізовані контракти +- **шар vendor Plugin**: vendor-specific API, автентифікація, каталоги моделей, мовленнєвий + синтез, генерація зображень, майбутні бекенди відео, кінцеві точки використання +- **шар Plugin каналів/функцій**: інтеграція Slack/Discord/voice-call/etc., + яка використовує можливості core і подає їх на поверхню Наприклад, TTS має таку форму: -- core володіє policy TTS під час відповіді, порядком fallback, prefs і доставкою через канали -- `openai`, `elevenlabs` і `microsoft` володіють реалізаціями синтезу -- `voice-call` використовує допоміжний засіб runtime телекомунікаційного TTS +- core відповідає за політику TTS під час відповіді, порядок fallback, налаштування та доставлення в канали +- `openai`, `elevenlabs` і `microsoft` відповідають за реалізації синтезу +- `voice-call` використовує допоміжний засіб часу виконання TTS для телефонії -Тому для майбутніх можливостей слід віддавати перевагу такому самому шаблону. +Цьому самому шаблону слід надавати перевагу й для майбутніх можливостей. -### Приклад plugin компанії з кількома можливостями +### Приклад Plugin компанії з кількома можливостями -Plugin компанії має виглядати цілісно ззовні. Якщо OpenClaw має спільні -контракти для моделей, мовлення, транскрипції в реальному часі, голосу в реальному часі, розуміння медіа, -генерації зображень, генерації відео, отримання вебданих і вебпошуку, -vendor може володіти всіма своїми surfaces в одному місці: +Plugin компанії має виглядати цілісним ззовні. Якщо OpenClaw має спільні +контракти для моделей, мовлення, транскрипції в реальному часі, голосу в реальному часі, розуміння +медіа, генерації зображень, генерації відео, отримання вебвмісту та вебпошуку, +вендор може володіти всіма своїми поверхнями в одному місці: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -371,245 +371,246 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -Важливі не точні назви helper. Важлива форма: +Важливі не точні назви допоміжних засобів. Важлива форма: -- один plugin володіє surface vendor -- core, як і раніше, володіє контрактами можливостей -- канали та plugins функцій використовують helpers `api.runtime.*`, а не код vendor -- contract tests можуть перевіряти, що plugin зареєстрував ті можливості, - якими він заявляє, що володіє +- один Plugin володіє поверхнею вендора +- core усе ще володіє контрактами можливостей +- канали та Plugin функцій використовують допоміжні засоби `api.runtime.*`, а не код вендора +- контрактні тести можуть перевіряти, що Plugin зареєстрував можливості, якими + він заявляє, що володіє ### Приклад можливості: розуміння відео OpenClaw уже розглядає розуміння зображень/аудіо/відео як одну спільну -можливість. Та сама модель володіння застосовується і тут: +можливість. Та сама модель володіння застосовується й тут: 1. core визначає контракт розуміння медіа -2. plugins vendor реєструють `describeImage`, `transcribeAudio` і - `describeVideo`, де це застосовно -3. канали та plugins функцій використовують спільну поведінку core замість - прямого підключення до коду vendor +2. vendor Plugin реєструють `describeImage`, `transcribeAudio` і + `describeVideo` там, де це доречно +3. канали та Plugin функцій використовують спільну поведінку core замість + прямого підключення до коду вендора -Це дозволяє не вшивати припущення про відео одного provider у core. Plugin володіє -surface vendor; core володіє контрактом можливостей і поведінкою fallback. +Це запобігає вбудовуванню припущень одного провайдера про відео в core. Plugin володіє +поверхнею вендора; core володіє контрактом можливості та поведінкою fallback. Генерація відео вже використовує ту саму послідовність: core володіє типізованим -контрактом можливостей і helper runtime, а plugins vendor реєструють -реалізації `api.registerVideoGenerationProvider(...)` для нього. +контрактом можливості та допоміжним засобом часу виконання, а vendor Plugin реєструють +реалізації `api.registerVideoGenerationProvider(...)` для цього контракту. -Потрібен конкретний контрольний список впровадження? Див. -[Capability Cookbook](/uk/plugins/architecture). +Потрібен конкретний контрольний список для впровадження? Див. +[Кулінарна книга можливостей](/uk/plugins/architecture). -## Контракти та забезпечення виконання +## Контракти та примусове дотримання -Surface API plugin навмисно типізований і централізований у +Поверхня API Plugin навмисно типізована та централізована в `OpenClawPluginApi`. Цей контракт визначає підтримувані точки реєстрації та -helpers runtime, на які може покладатися plugin. +допоміжні засоби часу виконання, на які може покладатися Plugin. Чому це важливо: -- автори plugins отримують один стабільний внутрішній стандарт -- core може відхилити дубльоване володіння, наприклад коли два plugins реєструють той самий - id provider -- під час запуску можна показувати діагностику з конкретними діями для некоректної реєстрації -- contract tests можуть забезпечувати володіння вбудованими plugins і запобігати тихому дрейфу +- автори Plugin отримують один стабільний внутрішній стандарт +- core може відхиляти дубльоване володіння, наприклад коли два Plugin реєструють той самий + id провайдера +- під час запуску можна показувати діагностику з практичними підказками для некоректної реєстрації +- контрактні тести можуть контролювати володіння вбудованими Plugin і запобігати тихому дрейфу -Є два шари забезпечення виконання: +Є два шари примусового дотримання: -1. **забезпечення виконання реєстрації під час runtime** - Реєстр plugins перевіряє реєстрації під час завантаження plugins. Приклади: - дубльовані id provider, дубльовані id providers мовлення та некоректні - реєстрації спричиняють діагностику plugin замість невизначеної поведінки. -2. **contract tests** - Вбудовані plugins фіксуються в реєстрах контрактів під час тестових запусків, щоб - OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для model - providers, providers мовлення, providers вебпошуку та володіння реєстрацією вбудованих plugins. +1. **примусове дотримання реєстрації під час виконання** + Реєстр Plugin перевіряє реєстрації під час завантаження Plugin. Приклади: + дубльовані id провайдерів, дубльовані id провайдерів мовлення та некоректні + реєстрації створюють діагностику Plugin замість невизначеної поведінки. +2. **контрактні тести** + Вбудовані Plugin фіксуються в контрактних реєстрах під час прогонів тестів, щоб + OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для моделей + провайдерів, провайдерів мовлення, провайдерів вебпошуку та володіння реєстраціями + вбудованих Plugin. -Практичний ефект полягає в тому, що OpenClaw заздалегідь знає, який plugin яким -surface володіє. Це дає змогу core і каналам безперешкодно компонуватися, оскільки володіння -задеклароване, типізоване й тестоване, а не неявне. +Практичний ефект такий: OpenClaw заздалегідь знає, який Plugin володіє якою +поверхнею. Це дає core і каналам змогу безшовно компонуватися, тому що володіння +оголошене, типізоване та тестоване, а не неявне. ### Що має входити в контракт -Хороші контракти plugin: +Хороші контракти Plugin є: -- типізовані -- невеликі -- специфічні для можливості -- належать core -- придатні до повторного використання кількома plugins -- можуть використовуватися каналами/функціями без знання vendor +- типізованими +- невеликими +- специфічними для можливості +- такими, що належать core +- придатними до повторного використання кількома Plugin +- придатними для використання каналами/функціями без знання про вендора -Погані контракти plugin: +Погані контракти Plugin — це: -- специфічна для vendor policy, прихована в core -- одноразові аварійні шляхи plugin, які обходять реєстр -- код каналу, який напряму звертається до реалізації vendor -- ad hoc об’єкти runtime, які не є частиною `OpenClawPluginApi` або +- vendor-specific політика, прихована в core +- разові аварійні шляхи для Plugin, які оминають реєстр +- код каналу, що напряму звертається до реалізації вендора +- спеціальні runtime-об’єкти, які не є частиною `OpenClawPluginApi` або `api.runtime` -Якщо є сумніви, підніміть рівень абстракції: спочатку визначте можливість, а вже потім -дозвольте plugins підключатися до неї. +Якщо сумніваєтеся, піднімайте рівень абстракції: спочатку визначте можливість, а вже потім +дозвольте Plugin підключатися до неї. ## Модель виконання -Нативні plugins OpenClaw працюють **у межах процесу** разом із Gateway. Вони не -ізольовані пісочницею. Завантажений нативний plugin має той самий межовий рівень довіри процесу, що й +Native Plugin OpenClaw працюють **у процесі** разом із Gateway. Вони не +ізольовані. Завантажений native Plugin має ту саму межу довіри на рівні процесу, що й код core. Наслідки: -- нативний plugin може реєструвати tools, network handlers, hooks і services -- помилка нативного plugin може призвести до збою або дестабілізації gateway -- зловмисний нативний plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw +- native Plugin може реєструвати інструменти, мережеві обробники, хуки та сервіси +- помилка native Plugin може призвести до збою або дестабілізації gateway +- зловмисний native Plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw -Сумісні bundles безпечніші за замовчуванням, оскільки OpenClaw наразі розглядає їх -як пакети метаданих/контенту. У поточних релізах це здебільшого означає вбудовані +Сумісні пакети безпечніші за замовчуванням, тому що OpenClaw наразі розглядає їх +як пакети метаданих/вмісту. У поточних випусках це переважно означає вбудовані Skills. -Для невбудованих plugins використовуйте allowlists і явні шляхи встановлення/завантаження. Ставтеся до -workspace plugins як до коду для часу розробки, а не як до стандартних налаштувань production. +Використовуйте allowlist і явні шляхи встановлення/завантаження для невбудованих Plugin. Розглядайте +Plugin робочого простору як код для часу розробки, а не як типові значення для production. -Для імен пакетів вбудованих workspace зберігайте id plugin прив’язаним до імені npm: -`@openclaw/` за замовчуванням або схвалений типізований суфікс, наприклад +Для назв пакетів вбудованого робочого простору зберігайте id Plugin, прив’язаний до npm-імені: +`@openclaw/` за замовчуванням або погоджений типізований суфікс, як-от `-provider`, `-plugin`, `-speech`, `-sandbox` або `-media-understanding`, коли -пакет навмисно відкриває вужчу роль plugin. +пакет навмисно надає вужчу роль Plugin. -Важлива примітка про довіру: +Важлива примітка щодо довіри: -- `plugins.allow` довіряє **ids plugins**, а не походженню джерела. -- Workspace plugin з тим самим id, що й вбудований plugin, навмисно затіняє - вбудовану копію, коли цей workspace plugin увімкнено/додано до allowlist. -- Це нормально і корисно для локальної розробки, тестування патчів і hotfix. -- Довіра до вбудованого plugin визначається зі snapshot джерела — маніфесту та +- `plugins.allow` довіряє **id Plugin**, а не походженню джерела. +- Plugin робочого простору з тим самим id, що й у вбудованого Plugin, навмисно затінює + вбудовану копію, коли цей Plugin робочого простору увімкнено/додано до allowlist. +- Це нормально й корисно для локальної розробки, тестування патчів і hotfix. +- Довіра до вбудованого Plugin визначається зі знімка джерела — маніфесту та коду на диску під час завантаження — а не з метаданих встановлення. Пошкоджений - або підмінений запис встановлення не може непомітно розширити surface довіри вбудованого plugin - понад те, що заявляє фактичне джерело. + або підмінений запис встановлення не може непомітно розширити поверхню довіри + вбудованого Plugin понад те, що заявляє фактичне джерело. ## Межа експорту OpenClaw експортує можливості, а не зручність реалізації. -Зберігайте реєстрацію можливостей публічною. Скорочуйте експорти helper, що не є контрактами: +Зберігайте публічність реєстрації можливостей. Скорочуйте допоміжні експорти, які не є контрактом: -- subpaths helper, специфічні для вбудованих plugins -- subpaths внутрішньої інфраструктури runtime, не призначені як публічний API -- helpers зручності, специфічні для vendor -- helpers налаштування/онбордингу, які є деталями реалізації +- допоміжні підшляхи, специфічні для вбудованих Plugin +- підшляхи runtime plumbing, які не призначені як публічний API +- vendor-specific допоміжні засоби для зручності +- допоміжні засоби setup/onboarding, які є деталями реалізації -Деякі subpaths helper вбудованих plugins досі залишаються в згенерованій карті експорту SDK -заради сумісності та супроводу вбудованих plugins. Поточні приклади включають +Деякі допоміжні підшляхи вбудованих Plugin усе ще залишаються у згенерованій карті експорту SDK +заради сумісності та підтримки вбудованих Plugin. Поточні приклади включають `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, -`plugin-sdk/zalo-setup` і кілька seams `plugin-sdk/matrix*`. Ставтеся до них як до -зарезервованих експортів деталей реалізації, а не як до рекомендованого шаблону SDK для -нових сторонніх plugins. +`plugin-sdk/zalo-setup` і кілька поверхонь `plugin-sdk/matrix*`. Розглядайте їх як +зарезервовані експорти деталей реалізації, а не як рекомендований шаблон SDK для +нових сторонніх Plugin. ## Конвеєр завантаження -Під час запуску OpenClaw приблизно виконує таке: +Під час запуску OpenClaw приблизно робить таке: -1. виявляє корені кандидатів plugins -2. читає нативні або сумісні маніфести bundle та метадані пакетів +1. виявляє корені потенційних Plugin +2. читає маніфести native або сумісних пакетів і метадані пакетів 3. відхиляє небезпечних кандидатів -4. нормалізує config plugins (`plugins.enabled`, `allow`, `deny`, `entries`, +4. нормалізує config Plugin (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. визначає стан увімкнення для кожного кандидата -6. завантажує увімкнені нативні модулі: зібрані вбудовані модулі використовують нативний завантажувач; - незібрані нативні plugins використовують jiti -7. викликає hooks нативного `register(api)` і збирає реєстрації в реєстр plugins -8. відкриває реєстр для surfaces commands/runtime +5. вирішує, чи увімкнено кожного кандидата +6. завантажує увімкнені native модулі: зібрані вбудовані модулі використовують native loader; + незібрані native Plugin використовують jiti +7. викликає native хуки `register(api)` і збирає реєстрації в реєстр Plugin +8. відкриває реєстр для команд/поверхонь часу виконання -`activate` — це застарілий псевдонім для `register` — завантажувач визначає, що саме присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані plugins використовують `register`; для нових plugins віддавайте перевагу `register`. +`activate` — це застарілий псевдонім для `register` — loader визначає, що з них присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані Plugin використовують `register`; для нових Plugin надавайте перевагу `register`. -Перевірки безпеки відбуваються **до** виконання runtime. Кандидати блокуються, -коли entry виходить за межі кореня plugin, шлях є world-writable або -володіння шляхом виглядає підозріло для невбудованих plugins. +Перевірки безпеки відбуваються **до** виконання під час виконання. Кандидати блокуються, +коли точка входу виходить за межі кореня Plugin, шлях доступний на запис для всіх або +володіння шляхом виглядає підозріло для невбудованих Plugin. -### Поведінка manifest-first +### Поведінка з пріоритетом маніфесту Маніфест — це джерело істини для control plane. OpenClaw використовує його, щоб: -- ідентифікувати plugin -- виявляти оголошені канали/Skills/схему config або можливості bundle -- валідовувати `plugins.entries..config` -- доповнювати labels/placeholders Control UI +- ідентифікувати Plugin +- виявляти оголошені канали/Skills/схему config або можливості пакетів +- перевіряти `plugins.entries..config` +- доповнювати мітки/placeholder-и Control UI - показувати метадані встановлення/каталогу -- зберігати дешеві дескриптори активації та налаштування без завантаження runtime plugin +- зберігати дешеві дескриптори активації та setup без завантаження runtime Plugin -Для нативних plugins модуль runtime — це частина data plane. Він реєструє -фактичну поведінку, наприклад hooks, tools, commands або потоки provider. +Для native Plugin runtime-модуль є частиною data plane. Він реєструє +фактичну поведінку, таку як хуки, інструменти, команди або потоки провайдера. Необов’язкові блоки маніфесту `activation` і `setup` залишаються в control plane. -Це лише дескриптори метаданих для планування активації й виявлення налаштування; -вони не замінюють реєстрацію runtime, `register(...)` або `setupEntry`. -Перші живі споживачі активації тепер використовують підказки маніфесту для commands, каналів і providers, -щоб звузити завантаження plugins до ширшої матеріалізації реєстру: +Це лише дескриптори метаданих для планування активації та виявлення setup; +вони не замінюють реєстрацію під час виконання, `register(...)` або `setupEntry`. +Перші живі споживачі активації тепер використовують підказки маніфесту для команд, каналів і провайдерів, +щоб звузити завантаження Plugin перед ширшою матеріалізацією реєстру: -- Завантаження CLI звужується до plugins, які володіють запитаною основною command -- визначення налаштування каналу/plugin звужується до plugins, які володіють запитаним +- Завантаження CLI звужується до Plugin, які володіють запитаною основною командою +- налаштування каналу/визначення Plugin звужується до Plugin, які володіють запитаним id каналу -- явне визначення налаштування/runtime provider звужується до plugins, які володіють - запитаним id provider +- явне налаштування провайдера/визначення під час виконання звужується до Plugin, які володіють + запитаним id провайдера -Виявлення налаштування тепер надає перевагу ids, що належать дескрипторам, таким як `setup.providers` і -`setup.cliBackends`, щоб звузити коло кандидатів plugins перед переходом до -`setup-api` для plugins, яким усе ще потрібні hooks runtime під час налаштування. Якщо більше -ніж один виявлений plugin заявляє той самий нормалізований id provider налаштування або CLI backend, -пошук налаштування відхиляє неоднозначного власника замість того, щоб покладатися на -порядок виявлення. +Виявлення setup тепер надає перевагу id, що належать дескрипторам, таким як `setup.providers` і +`setup.cliBackends`, щоб звузити перелік кандидатів Plugin, перш ніж перейти до +`setup-api` для Plugin, яким усе ще потрібні runtime-хуки на етапі setup. Якщо більше +ніж один виявлений Plugin заявляє той самий нормалізований id провайдера setup або CLI-бекенда, +пошук setup відмовляє через неоднозначного власника замість покладання на порядок виявлення. -### Що кешує завантажувач +### Що кешує loader -OpenClaw зберігає короткочасні кеші в межах процесу для: +OpenClaw зберігає короткоживучі кеші в межах процесу для: - результатів виявлення - даних реєстру маніфестів -- завантажених реєстрів plugins +- завантажених реєстрів Plugin -Ці кеші зменшують стрибкоподібне навантаження під час запуску та повторних commands. Їх безпечно -сприймати як короткочасні кеші продуктивності, а не як постійне зберігання. +Ці кеші зменшують стрибкоподібні витрати під час запуску та повторних викликів команд. Їх безпечно +розглядати як короткоживучі кеші продуктивності, а не як постійне зберігання. Примітка щодо продуктивності: -- Встановіть `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` або +- Установіть `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` або `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1`, щоб вимкнути ці кеші. - Налаштовуйте вікна кешу за допомогою `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` і `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS`. ## Модель реєстру -Завантажені plugins не змінюють напряму довільні глобальні об’єкти core. Вони реєструються в -центральному реєстрі plugins. +Завантажені Plugin не змінюють безпосередньо довільні глобальні змінні core. Вони +реєструються в центральному реєстрі Plugin. Реєстр відстежує: -- записи plugins (ідентичність, джерело, походження, статус, діагностика) -- tools -- застарілі hooks і типізовані hooks +- записи Plugin (ідентичність, джерело, походження, статус, діагностика) +- інструменти +- застарілі хуки та типізовані хуки - канали -- providers -- handlers Gateway RPC -- HTTP routes +- провайдери +- обробники Gateway RPC +- HTTP-маршрути - реєстратори CLI -- фонові services -- commands, що належать plugins +- фонові сервіси +- команди, що належать Plugin -Потім можливості core читають із цього реєстру замість прямої взаємодії з модулями plugin. -Це зберігає одностороннє завантаження: +Потім можливості core читають із цього реєстру замість прямої взаємодії з модулями Plugin. +Це зберігає односпрямованість завантаження: -- модуль plugin -> реєстрація в реєстрі -- runtime core -> використання реєстру +- модуль Plugin -> реєстрація в реєстрі +- runtime core -> споживання реєстру -Це розділення важливе для супроводу. Воно означає, що більшості surfaces core потрібна -лише одна точка інтеграції: «прочитати реєстр», а не «робити special-case для кожного модуля plugin». +Це розділення важливе для супроводу. Воно означає, що більшості поверхонь core +потрібна лише одна точка інтеграції: «прочитати реєстр», а не «створювати спеціальний випадок для кожного модуля Plugin». -## Зворотні виклики прив’язки conversation +## Зворотні виклики прив’язки розмов -Plugins, які прив’язують conversation, можуть реагувати, коли схвалення визначено. +Plugin, які прив’язують розмову, можуть реагувати, коли схвалення буде завершено. -Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати зворотний виклик після того, як запит на прив’язку буде схвалено або відхилено: +Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати зворотний виклик після схвалення +або відхилення запиту на прив’язку: ```ts export default { @@ -634,23 +635,23 @@ export default { - `status`: `"approved"` або `"denied"` - `decision`: `"allow-once"`, `"allow-always"` або `"deny"` - `binding`: визначена прив’язка для схвалених запитів -- `request`: початкове зведення запиту, підказка від’єднання, id відправника та - метадані conversation +- `request`: оригінальний підсумок запиту, підказка від’єднання, id відправника та + метадані розмови -Цей зворотний виклик призначений лише для сповіщення. Він не змінює того, кому дозволено прив’язувати -conversation, і виконується після завершення обробки схвалення в core. +Цей зворотний виклик є лише сповіщенням. Він не змінює, кому дозволено прив’язувати +розмову, і запускається після завершення обробки схвалення в core. -## Runtime hooks provider +## Runtime-хуки провайдера -Plugins provider тепер мають два шари: +Plugin провайдерів тепер мають два шари: -- метадані маніфесту: `providerAuthEnvVars` для дешевого пошуку env-auth provider - до завантаження runtime, `providerAuthAliases` для варіантів provider, які спільно використовують - auth, `channelEnvVars` для дешевого пошуку env/setup каналу до - завантаження runtime, а також `providerAuthChoices` для дешевих labels онбордингу/вибору auth та - метаданих прапорців CLI до завантаження runtime -- hooks часу config: `catalog` / застарілий `discovery` плюс `applyConfigDefaults` -- hooks runtime: `normalizeModelId`, `normalizeTransport`, +- метадані маніфесту: `providerAuthEnvVars` для дешевого пошуку env-автентифікації провайдера + до завантаження runtime, `providerAuthAliases` для варіантів провайдера, які спільно використовують + автентифікацію, `channelEnvVars` для дешевого пошуку env/setup каналу до + завантаження runtime, а також `providerAuthChoices` для дешевих міток onboarding/вибору автентифікації та + метаданих CLI-прапорців до завантаження runtime +- хуки часу config: `catalog` / застарілий `discovery` плюс `applyConfigDefaults` +- runtime-хуки: `normalizeModelId`, `normalizeTransport`, `normalizeConfig`, `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, `resolveSyntheticAuth`, `resolveExternalAuthProfiles`, @@ -670,90 +671,91 @@ Plugins provider тепер мають два шари: `buildReplayPolicy`, `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` -OpenClaw, як і раніше, володіє загальним циклом агента, failover, обробкою transcript і -policy tools. Ці hooks — це surface розширення для специфічної для provider поведінки без -потреби в повністю користувацькому транспорті виведення. +OpenClaw усе ще володіє загальним циклом агента, failover, обробкою transcript і +політикою інструментів. Ці хуки є поверхнею розширення для поведінки, специфічної для провайдера, без +потреби в цілком окремому транспорті inference. -Використовуйте маніфест `providerAuthEnvVars`, коли provider має облікові дані на основі env, -які загальні шляхи auth/status/model-picker повинні бачити без завантаження runtime plugin. Використовуйте маніфест -`providerAuthAliases`, коли один id provider повинен повторно використовувати env vars, профілі auth, -auth на основі config і варіант онбордингу API-key іншого id provider. Використовуйте маніфест -`providerAuthChoices`, коли surfaces CLI для онбордингу/вибору auth повинні знати id вибору provider, -labels груп і просте підключення auth через один прапорець без завантаження runtime provider. Залишайте runtime provider -`envVars` для операторських підказок, таких як labels онбордингу або змінні налаштування -client-id/client-secret OAuth. +Використовуйте маніфест `providerAuthEnvVars`, коли провайдер має облікові дані на основі env, +які загальні шляхи auth/status/model-picker мають бачити без завантаження runtime Plugin. +Використовуйте маніфест `providerAuthAliases`, коли один id провайдера має повторно використовувати +env-змінні, профілі автентифікації, автентифікацію на основі config та варіант onboarding із API-ключем +іншого id провайдера. Використовуйте маніфест `providerAuthChoices`, коли поверхні CLI для onboarding/вибору автентифікації +мають знати id варіанта провайдера, мітки груп і просту схему auth з одним прапорцем +без завантаження runtime провайдера. Зберігайте runtime `envVars` провайдера для +операторських підказок, таких як мітки onboarding або змінні setup для OAuth +client-id/client-secret. Використовуйте маніфест `channelEnvVars`, коли канал має auth або setup на основі env, які -загальний shell-env fallback, перевірки config/status або prompts налаштування повинні бачити +загальний fallback до shell-env, перевірки config/status або запити setup мають бачити без завантаження runtime каналу. -### Порядок hooks і їх використання +### Порядок хуків і використання -Для plugins model/provider OpenClaw викликає hooks приблизно в такому порядку. -Стовпець «Коли використовувати» — це короткий посібник для вибору. +Для Plugin моделей/провайдерів OpenClaw викликає хуки приблизно в такому порядку. +Стовпець «Коли використовувати» — це короткий посібник для прийняття рішення. -| # | Hook | Що він робить | Коли використовувати | +| # | Хук | Що він робить | Коли використовувати | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | Публікує config provider у `models.providers` під час генерації `models.json` | Provider володіє каталогом або базовими значеннями `base URL` | -| 2 | `applyConfigDefaults` | Застосовує глобальні значення config за замовчуванням, що належать provider, під час матеріалізації config | Значення за замовчуванням залежать від режиму auth, env або семантики сімейства моделей provider | -| -- | _(built-in model lookup)_ | OpenClaw спочатку намагається використати звичайний шлях реєстру/каталогу | _(не є hook plugin)_ | -| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми model-id перед пошуком | Provider володіє очищенням псевдонімів до канонічного визначення моделі | -| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства provider перед загальним складанням моделі | Provider володіє очищенням транспорту для користувацьких ids provider у тому самому сімействі транспорту | -| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед визначенням runtime/provider | Provider потребує очищення config, яке має жити разом із plugin; вбудовані helpers сімейства Google також страхують підтримувані записи config Google | -| 6 | `applyNativeStreamingUsageCompat` | Застосовує переписування сумісності native streaming-usage до config providers | Provider потребує виправлень метаданих native streaming usage, зумовлених endpoint | -| 7 | `resolveConfigApiKey` | Визначає auth через env-marker для config providers до завантаження auth runtime | Provider має власне визначення API-key через env-marker; `amazon-bedrock` також має тут вбудований resolver AWS env-marker | -| 8 | `resolveSyntheticAuth` | Відкриває локальний/self-hosted або auth на основі config без збереження відкритого тексту | Provider може працювати із synthetic/local маркером облікових даних | -| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі auth, що належать provider; типове `persistence` — `runtime-only` для облікових даних CLI/app | Provider повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token; оголосіть `contracts.externalAuthProviders` у маніфесті | -| 10 | `shouldDeferSyntheticProfileAuth` | Знижує пріоритет збережених synthetic-заповнювачів профілю порівняно з auth на основі env/config | Provider зберігає synthetic-профілі-заповнювачі, які не повинні мати вищий пріоритет | -| 11 | `resolveDynamicModel` | Синхронний fallback для ids моделей provider, яких ще немає в локальному реєстрі | Provider приймає довільні ids моделей верхнього рівня | -| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` виконується знову | Provider потребує мережевих метаданих до визначення невідомих ids | -| 13 | `normalizeResolvedModel` | Остаточне переписування перед тим, як embedded runner використає визначену модель | Provider потребує переписування транспорту, але все ще використовує транспорт core | -| 14 | `contributeResolvedModelCompat` | Додає прапорці сумісності для моделей vendor за іншим сумісним транспортом | Provider розпізнає власні моделі на проксі-транспортах, не перебираючи на себе роль provider | -| 15 | `capabilities` | Метадані transcript/tooling, що належать provider і використовуються спільною логікою core | Provider потребує особливостей transcript/сімейства provider | -| 16 | `normalizeToolSchemas` | Нормалізує схеми tools до того, як їх побачить embedded runner | Provider потребує очищення схем для сімейства транспорту | -| 17 | `inspectToolSchemas` | Виводить діагностику схем, що належить provider, після нормалізації | Provider хоче попередження щодо ключових слів без навчання core правилам, специфічним для provider | -| 18 | `resolveReasoningOutputMode` | Вибирає контракт виводу reasoning: native або з тегами | Provider потребує reasoning/final output із тегами замість native-полів | -| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед загальними обгортками опцій потоку | Provider потребує параметри запиту за замовчуванням або очищення параметрів для конкретного provider | -| 20 | `createStreamFn` | Повністю замінює звичайний шлях потоку користувацьким транспортом | Provider потребує користувацький дротовий протокол, а не просто обгортку | -| 21 | `wrapStreamFn` | Обгортка потоку після застосування загальних обгорток | Provider потребує обгортки сумісності заголовків/тіла запиту/моделі без користувацького транспорту | -| 22 | `resolveTransportTurnState` | Прикріплює native-заголовки транспорту або метадані для кожного ходу | Provider хоче, щоб загальні транспорти надсилали native-ідентичність ходу provider | -| 23 | `resolveWebSocketSessionPolicy` | Прикріплює native-заголовки WebSocket або policy охолодження сесії | Provider хоче, щоб загальні WS-транспорти налаштовували заголовки сесії або policy fallback | -| 24 | `formatApiKey` | Форматувальник auth-profile: збережений профіль стає рядком `apiKey` runtime | Provider зберігає додаткові метадані auth і потребує користувацьку форму токена runtime | -| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для користувацьких endpoint оновлення або policy помилки оновлення | Provider не відповідає спільним засобам оновлення `pi-ai` | -| 26 | `buildAuthDoctorHint` | Підказка виправлення, що додається, коли оновлення OAuth завершується помилкою | Provider потребує власні рекомендації щодо виправлення auth після помилки оновлення | -| 27 | `matchesContextOverflowError` | Matcher переповнення context-window, що належить provider | Provider має сирі помилки переповнення, які загальні евристики не виявлять | -| 28 | `classifyFailoverReason` | Класифікація причини failover, що належить provider | Provider може зіставляти сирі помилки API/транспорту з rate-limit/overload тощо | -| 29 | `isCacheTtlEligible` | Policy prompt-cache для providers проксі/backhaul | Provider потребує gating TTL кешу, специфічний для проксі | -| 30 | `buildMissingAuthMessage` | Заміна загального повідомлення відновлення при відсутньому auth | Provider потребує специфічну для provider підказку відновлення при відсутньому auth | -| 31 | `suppressBuiltInModel` | Пригнічення застарілої моделі верхнього рівня плюс необов’язкова підказка помилки для користувача | Provider потребує приховати застарілі рядки верхнього рівня або замінити їх підказкою vendor | -| 32 | `augmentModelCatalog` | Synthetic/фінальні рядки каталогу, додані після виявлення | Provider потребує synthetic-рядки прямої сумісності в `models list` і засобах вибору | -| 33 | `resolveThinkingProfile` | Специфічний для моделі рівень `/think`, labels відображення та значення за замовчуванням | Provider відкриває користувацьку шкалу thinking або бінарний label для вибраних моделей | -| 34 | `isBinaryThinking` | Hook сумісності для перемикача reasoning увімкнено/вимкнено | Provider відкриває лише бінарний режим thinking увімкнено/вимкнено | -| 35 | `supportsXHighThinking` | Hook сумісності підтримки reasoning `xhigh` | Provider хоче `xhigh` лише для підмножини моделей | -| 36 | `resolveDefaultThinkingLevel` | Hook сумісності рівня `/think` за замовчуванням | Provider володіє policy `/think` за замовчуванням для сімейства моделей | -| 37 | `isModernModelRef` | Matcher сучасних моделей для фільтрів live profile і вибору smoke | Provider володіє зіставленням бажаних моделей для live/smoke | -| 38 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний токен/ключ runtime безпосередньо перед виведенням | Provider потребує обміну токена або короткоживучих облікових даних запиту | -| 39 | `resolveUsageAuth` | Визначає облікові дані використання/білінгу для `/usage` і пов’язаних surfaces стану | Provider потребує користувацький розбір токена використання/квоти або інші облікові дані використання | -| 40 | `fetchUsageSnapshot` | Отримує та нормалізує специфічні для provider snapshot використання/квоти після визначення auth | Provider потребує специфічний для provider endpoint використання або парсер корисного навантаження | -| 41 | `createEmbeddingProvider` | Будує адаптер embedding, що належить provider, для пам’яті/пошуку | Поведінка embedding для пам’яті має належати plugin provider | -| 42 | `buildReplayPolicy` | Повертає policy replay, яка керує обробкою transcript для provider | Provider потребує користувацьку policy transcript (наприклад, видалення блоків thinking) | -| 43 | `sanitizeReplayHistory` | Переписує історію replay після загального очищення transcript | Provider потребує специфічні для provider переписування replay понад спільні helpers Compaction | -| 44 | `validateReplayTurns` | Остаточна валідація або переформування ходів replay перед embedded runner | Транспорт provider потребує суворішої валідації ходів після загальної санітизації | -| 45 | `onModelSelected` | Виконує побічні ефекти після вибору моделі, що належать provider | Provider потребує телеметрію або стан, що належить provider, коли модель стає активною | +| 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` | Виконує побічні ефекти після вибору моделі, що належать провайдеру | Провайдеру потрібна телеметрія або стан, що належить провайдеру, коли модель стає активною | `normalizeModelId`, `normalizeTransport` і `normalizeConfig` спочатку перевіряють -відповідний plugin provider, а потім переходять до інших plugins provider, які підтримують hooks, -доки один із них справді не змінить id моделі або transport/config. Це дозволяє -псевдонімним/сумісним shim provider працювати без вимоги, щоб викликач знав, який -вбудований plugin володіє цим переписуванням. Якщо жоден hook provider не переписує підтримуваний -запис config сімейства Google, вбудований нормалізатор config Google все одно застосовує -це очищення сумісності. +зіставлений Plugin провайдера, а потім переходять до інших Plugin провайдерів, здатних до хуків, +доки один із них фактично не змінить id моделі або transport/config. Це зберігає +працездатність shim-адаптерів псевдонімів/сумісності провайдерів без потреби для викликача знати, +який вбудований Plugin володіє переписуванням. Якщо жоден хук провайдера не перепише +підтримуваний запис config сімейства Google, вбудований нормалізатор config Google все одно +застосує це очищення сумісності. -Якщо provider потрібен повністю користувацький дротовий протокол або користувацький виконавець запитів, -це вже інший клас розширення. Ці hooks призначені для поведінки provider, яка -все ще працює в межах звичайного циклу виведення OpenClaw. +Якщо провайдеру потрібен повністю користувацький wire protocol або користувацький виконавець запитів, +це вже інший клас розширення. Ці хуки призначені для поведінки провайдера, яка +все ще працює в межах звичайного циклу inference OpenClaw. -### Приклад provider +### Приклад провайдера ```ts api.registerProvider({ @@ -809,118 +811,37 @@ api.registerProvider({ ### Вбудовані приклади -- Anthropic використовує `resolveDynamicModel`, `capabilities`, `buildAuthDoctorHint`, - `resolveUsageAuth`, `fetchUsageSnapshot`, `isCacheTtlEligible`, - `resolveThinkingProfile`, `applyConfigDefaults`, `isModernModelRef` - і `wrapStreamFn`, оскільки володіє прямою сумісністю Claude 4.6, - підказками для сімейства provider, рекомендаціями з відновлення auth, інтеграцією - endpoint використання, придатністю prompt-cache, значеннями config за замовчуванням з урахуванням auth, політикою - thinking Claude за замовчуванням/адаптивною і специфічним для Anthropic формуванням потоку для - beta headers, `/fast` / `serviceTier` та `context1m`. -- Специфічні для Claude потокові helpers Anthropic поки що залишаються у власному - публічному seam `api.ts` / `contract-api.ts` вбудованого plugin. Цей package surface - експортує `wrapAnthropicProviderStream`, `resolveAnthropicBetas`, - `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` і нижчорівневі - засоби побудови обгорток Anthropic замість розширення загального SDK навколо правил - beta-header одного provider. -- OpenAI використовує `resolveDynamicModel`, `normalizeResolvedModel` і - `capabilities`, а також `buildMissingAuthMessage`, `suppressBuiltInModel`, - `augmentModelCatalog`, `resolveThinkingProfile` і `isModernModelRef`, - оскільки володіє прямою сумісністю GPT-5.4, прямою нормалізацією OpenAI - `openai-completions` -> `openai-responses`, підказками auth з урахуванням Codex, - пригніченням Spark, synthetic-рядками списку OpenAI і політикою thinking / - live-model GPT-5; сімейство потоків `openai-responses-defaults` володіє - спільними native-обгортками OpenAI Responses для headers атрибуції, - `/fast`/`serviceTier`, деталізації тексту, native вебпошуку Codex, - формування корисного навантаження reasoning-compat і керування context Responses. -- OpenRouter використовує `catalog`, а також `resolveDynamicModel` і - `prepareDynamicModel`, оскільки provider є наскрізним і може відкривати нові - ids моделей до оновлення статичного каталогу OpenClaw; він також використовує - `capabilities`, `wrapStreamFn` і `isCacheTtlEligible`, щоб тримати - специфічні для provider headers запитів, метадані маршрутизації, патчі reasoning і - policy prompt-cache поза core. Його policy replay походить із - сімейства `passthrough-gemini`, тоді як сімейство потоків `openrouter-thinking` - володіє ін’єкцією reasoning через проксі та пропусками unsupported-model / `auto`. -- GitHub Copilot використовує `catalog`, `auth`, `resolveDynamicModel` і - `capabilities`, а також `prepareRuntimeAuth` і `fetchUsageSnapshot`, оскільки йому - потрібні вхід у систему пристрою, що належить provider, поведінка fallback моделі, особливості - transcript Claude, обмін токена GitHub -> токен Copilot і endpoint використання, - що належить provider. -- OpenAI Codex використовує `catalog`, `resolveDynamicModel`, - `normalizeResolvedModel`, `refreshOAuth` і `augmentModelCatalog`, а також - `prepareExtraParams`, `resolveUsageAuth` і `fetchUsageSnapshot`, оскільки він - усе ще працює на транспорті OpenAI core, але володіє нормалізацією - transport/base URL, fallback policy оновлення OAuth, типовим вибором транспорту, - synthetic-рядками каталогу Codex та інтеграцією endpoint використання ChatGPT; він - ділить те саме сімейство потоків `openai-responses-defaults`, що й прямий OpenAI. -- Google AI Studio і Gemini CLI OAuth використовують `resolveDynamicModel`, - `buildReplayPolicy`, `sanitizeReplayHistory`, - `resolveReasoningOutputMode`, `wrapStreamFn` і `isModernModelRef`, оскільки - сімейство replay `google-gemini` володіє fallback прямої сумісності Gemini 3.1, - native-валідацією replay Gemini, початковою санітизацією replay, режимом - виводу reasoning із тегами та зіставленням сучасних моделей, тоді як - сімейство потоків `google-thinking` володіє нормалізацією корисного навантаження thinking Gemini; - Gemini CLI OAuth також використовує `formatApiKey`, `resolveUsageAuth` і - `fetchUsageSnapshot` для форматування токенів, розбору токенів і підключення - endpoint квот. -- Anthropic Vertex використовує `buildReplayPolicy` через - сімейство replay `anthropic-by-model`, щоб очищення replay, специфічне для Claude, залишалося - обмеженим ids Claude, а не кожним транспортом `anthropic-messages`. -- Amazon Bedrock використовує `buildReplayPolicy`, `matchesContextOverflowError`, - `classifyFailoverReason` і `resolveThinkingProfile`, оскільки володіє - специфічною для Bedrock класифікацією помилок throttle/not-ready/context-overflow - для трафіку Anthropic-on-Bedrock; його policy replay усе ще поділяє той самий - захист `anthropic-by-model`, обмежений Claude. -- OpenRouter, Kilocode, Opencode і Opencode Go використовують `buildReplayPolicy` - через сімейство replay `passthrough-gemini`, оскільки вони проксіюють моделі Gemini - через сумісні з OpenAI транспорти й потребують санітизації - thought-signature Gemini без native-валідації replay Gemini чи - початкових переписувань. -- MiniMax використовує `buildReplayPolicy` через - сімейство replay `hybrid-anthropic-openai`, оскільки один provider володіє семантикою і - Anthropic-message, і OpenAI-compatible; він зберігає видалення - thinking-block лише для Claude на боці Anthropic, водночас перевизначаючи режим - виводу reasoning назад на native, а сімейство потоків `minimax-fast-mode` володіє - переписуванням моделей швидкого режиму на спільному шляху потоку. -- Moonshot використовує `catalog`, `resolveThinkingProfile` і `wrapStreamFn`, оскільки все ще використовує спільний - транспорт OpenAI, але потребує нормалізації корисного навантаження thinking, що належить provider; сімейство - потоків `moonshot-thinking` зіставляє config і стан `/think` зі своїм - native-бінарним корисним навантаженням thinking. -- Kilocode використовує `catalog`, `capabilities`, `wrapStreamFn` і - `isCacheTtlEligible`, оскільки йому потрібні headers запитів, що належать provider, - нормалізація корисного навантаження reasoning, підказки transcript Gemini і - gating cache-TTL Anthropic; сімейство потоків `kilocode-thinking` зберігає ін’єкцію - thinking Kilo на спільному проксі-шляху потоку, водночас пропускаючи `kilo/auto` та - інші ids проксі-моделей, які не підтримують явні корисні навантаження reasoning. -- Z.AI використовує `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`, - `isCacheTtlEligible`, `resolveThinkingProfile`, `isModernModelRef`, - `resolveUsageAuth` і `fetchUsageSnapshot`, оскільки володіє fallback GLM-5, - значеннями `tool_stream` за замовчуванням, бінарним UX thinking, зіставленням сучасних моделей і - як auth використання, так і отриманням квот; сімейство потоків `tool-stream-default-on` тримає - обгортку `tool_stream`, увімкнену за замовчуванням, поза рукописним кодом glue для кожного provider. -- xAI використовує `normalizeResolvedModel`, `normalizeTransport`, - `contributeResolvedModelCompat`, `prepareExtraParams`, `wrapStreamFn`, - `resolveSyntheticAuth`, `resolveDynamicModel` і `isModernModelRef`, - оскільки володіє нормалізацією native-транспорту xAI Responses, переписуванням - псевдонімів швидкого режиму Grok, `tool_stream` за замовчуванням, очищенням - strict-tool / корисного навантаження reasoning, повторним використанням fallback auth для tools, - що належать plugin, прямим визначенням моделей Grok і латками сумісності, що належать provider, - такими як профіль схем tools xAI, непідтримувані ключові слова схем, native `web_search` і декодування - аргументів виклику tools з HTML-сутностями. -- Mistral, OpenCode Zen і OpenCode Go використовують лише `capabilities`, щоб тримати - особливості transcript/tooling поза core. -- Вбудовані providers лише з каталогом, такі як `byteplus`, `cloudflare-ai-gateway`, - `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, - `synthetic`, `together`, `venice`, `vercel-ai-gateway` і `volcengine`, використовують - лише `catalog`. -- Qwen використовує `catalog` для свого text provider, а також спільні реєстрації розуміння медіа і - генерації відео для своїх мультимодальних surfaces. -- MiniMax і Xiaomi використовують `catalog`, а також hooks використання, тому що їхня поведінка `/usage` - належить plugin, навіть попри те, що виведення все ще виконується через спільні транспорти. +Вбудовані Plugin провайдерів використовують наведені вище хуки в комбінаціях, адаптованих до +потреб кожного вендора щодо каталогу, auth, thinking, replay і відстеження використання. Точний +набір хуків для кожного провайдера міститься разом із вихідним кодом Plugin у `extensions/`; вважайте +це авторитетним списком замість дублювання тут. -## Runtime helpers +Показові шаблони: -Plugins можуть отримувати доступ до вибраних helpers core через `api.runtime`. Для TTS: +- **Провайдери каталогу з pass-through** (OpenRouter, Kilocode, Z.AI, xAI) реєструють + `catalog` разом із `resolveDynamicModel`/`prepareDynamicModel`, щоб вони могли показувати + upstream model id раніше за статичний каталог OpenClaw. +- **Провайдери з OAuth + кінцевою точкою використання** (GitHub Copilot, Gemini CLI, ChatGPT + Codex, MiniMax, Xiaomi, z.ai) поєднують `prepareRuntimeAuth` або `formatApiKey` + з `resolveUsageAuth` + `fetchUsageSnapshot`, щоб володіти обміном токенів і + інтеграцією `/usage`. +- **Очищення replay / transcript** спільно використовується через іменовані сімейства: + `google-gemini`, `passthrough-gemini`, `anthropic-by-model`, + `hybrid-anthropic-openai`. Провайдери підключаються через `buildReplayPolicy`, + замість того щоб кожен окремо реалізовував очищення 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`, + `resolveAnthropicFastMode`, `resolveAnthropicServiceTier`), а не в + загальному SDK. + +## Допоміжні засоби часу виконання + +Plugin можуть отримувати доступ до вибраних допоміжних засобів core через `api.runtime`. Для TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -941,14 +862,14 @@ const voices = await api.runtime.tts.listVoices({ Примітки: -- `textToSpeech` повертає звичайне корисне навантаження виводу TTS core для surfaces файлів/голосових нотаток. -- Використовує config core `messages.tts` і вибір provider. -- Повертає буфер аудіо PCM + sample rate. Plugins повинні виконати ресемплінг/кодування для providers. -- `listVoices` є необов’язковим для кожного provider. Використовуйте його для засобів вибору голосу або потоків налаштування, що належать vendor. -- Списки голосів можуть включати багатші метадані, такі як locale, gender і теги personality для засобів вибору з урахуванням provider. +- `textToSpeech` повертає звичайне корисне навантаження виводу TTS із core для поверхонь файлів/голосових повідомлень. +- Використовує config `messages.tts` і вибір провайдера з core. +- Повертає PCM audio buffer + sample rate. Plugin мають виконувати ресемплінг/кодування для провайдерів. +- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для засобів вибору голосу або потоків setup, що належать вендору. +- Списки голосів можуть містити багатші метадані, як-от locale, стать і теги особистості для засобів вибору, обізнаних про провайдера. - OpenAI і ElevenLabs сьогодні підтримують телефонію. Microsoft — ні. -Plugins також можуть реєструвати providers мовлення через `api.registerSpeechProvider(...)`. +Plugin також можуть реєструвати провайдерів мовлення через `api.registerSpeechProvider(...)`. ```ts api.registerSpeechProvider({ @@ -968,15 +889,15 @@ api.registerSpeechProvider({ Примітки: -- Зберігайте policy TTS, fallback і доставку відповідей у core. -- Використовуйте providers мовлення для поведінки синтезу, що належить vendor. -- Застаріле значення вводу Microsoft `edge` нормалізується до id provider `microsoft`. -- Бажана модель володіння орієнтована на компанію: один plugin vendor може володіти - providers тексту, мовлення, зображень і майбутніх медіа, коли OpenClaw додає ці +- Зберігайте політику TTS, fallback і доставлення відповідей у core. +- Використовуйте провайдерів мовлення для поведінки синтезу, що належить вендору. +- Застарілий вхід Microsoft `edge` нормалізується до id провайдера `microsoft`. +- Рекомендована модель володіння — орієнтована на компанію: один vendor Plugin може + володіти текстовими, мовленнєвими, графічними та майбутніми медіапровайдерами, коли OpenClaw додає ці контракти можливостей. -Для розуміння зображень/аудіо/відео plugins реєструють один типізований -provider розуміння медіа замість загального пакета key/value: +Для розуміння зображень/аудіо/відео Plugin реєструють один типізований +провайдер media-understanding замість загального key/value-масиву: ```ts api.registerMediaUnderstandingProvider({ @@ -991,15 +912,15 @@ api.registerMediaUnderstandingProvider({ Примітки: - Зберігайте оркестрацію, fallback, config і підключення каналів у core. -- Зберігайте поведінку vendor у plugin provider. +- Зберігайте поведінку вендора в Plugin провайдера. - Адитивне розширення має залишатися типізованим: нові необов’язкові методи, нові необов’язкові поля результату, нові необов’язкові можливості. -- Генерація відео вже дотримується того самого шаблону: - - core володіє контрактом можливостей і helper runtime - - plugins vendor реєструють `api.registerVideoGenerationProvider(...)` - - plugins функцій/каналів використовують `api.runtime.videoGeneration.*` +- Генерація відео вже наслідує той самий шаблон: + - core володіє контрактом можливості та допоміжним засобом часу виконання + - vendor Plugin реєструють `api.registerVideoGenerationProvider(...)` + - Plugin функцій/каналів використовують `api.runtime.videoGeneration.*` -Для helpers runtime розуміння медіа plugins можуть викликати: +Для runtime-допоміжних засобів media-understanding Plugin можуть викликати: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -1014,8 +935,8 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -Для транскрипції аудіо plugins можуть використовувати або runtime -розуміння медіа, або старіший псевдонім STT: +Для транскрипції аудіо Plugin можуть використовувати або runtime media-understanding, +або старіший псевдонім STT: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -1028,13 +949,13 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ Примітки: -- `api.runtime.mediaUnderstanding.*` — це бажаний спільний surface для +- `api.runtime.mediaUnderstanding.*` — це рекомендована спільна поверхня для розуміння зображень/аудіо/відео. -- Використовує конфігурацію аудіо розуміння медіа core (`tools.media.audio`) і порядок fallback provider. -- Повертає `{ text: undefined }`, коли не створено результат транскрипції (наприклад, для пропущеного/непідтримуваного вводу). -- `api.runtime.stt.transcribeAudioFile(...)` залишається як псевдонім сумісності. +- Використовує config аудіо розуміння медіа з core (`tools.media.audio`) і порядок fallback провайдерів. +- Повертає `{ text: undefined }`, коли вихід транскрипції не створено (наприклад, для пропущеного/непідтримуваного вводу). +- `api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом для сумісності. -Plugins також можуть запускати фонові запуски subagent через `api.runtime.subagent`: +Plugin також можуть запускати фонові прогони subagent через `api.runtime.subagent`: ```ts const result = await api.runtime.subagent.run({ @@ -1048,14 +969,14 @@ const result = await api.runtime.subagent.run({ Примітки: -- `provider` і `model` — це необов’язкові перевизначення для окремого запуску, а не постійні зміни сесії. +- `provider` і `model` — це необов’язкові перевизначення для окремого прогону, а не постійні зміни сесії. - OpenClaw враховує ці поля перевизначення лише для довірених викликачів. -- Для запусків fallback, що належать plugin, оператори повинні явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. -- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені plugins конкретними канонічними цілями `provider/model`, або `"*"`, щоб явно дозволити будь-яку ціль. -- Запуски subagent із недовірених plugins теж працюють, але запити на перевизначення відхиляються замість тихого переходу до fallback. +- Для прогонів fallback, що належать Plugin, оператори мають явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. +- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені Plugin конкретними канонічними цілями `provider/model`, або `"*"` для явного дозволу будь-якої цілі. +- Прогони subagent для недовірених Plugin теж працюють, але запити на перевизначення відхиляються замість тихого переходу на fallback. -Для вебпошуку plugins можуть використовувати спільний helper runtime замість -звернення безпосередньо до підключення tool агента: +Для вебпошуку Plugin можуть використовувати спільний runtime-допоміжний засіб замість +прямого доступу до підключення інструмента агента: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -1071,14 +992,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -Plugins також можуть реєструвати providers вебпошуку через +Plugin також можуть реєструвати провайдерів вебпошуку через `api.registerWebSearchProvider(...)`. Примітки: -- Зберігайте вибір provider, визначення облікових даних і спільну семантику запитів у core. -- Використовуйте providers вебпошуку для транспортів пошуку, специфічних для vendor. -- `api.runtime.webSearch.*` — це бажаний спільний surface для plugins функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки tool агента. +- Зберігайте вибір провайдера, визначення облікових даних і спільну семантику запиту в core. +- Використовуйте провайдерів вебпошуку для vendor-specific транспортів пошуку. +- `api.runtime.webSearch.*` — це рекомендована спільна поверхня для Plugin функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструмента агента. ### `api.runtime.imageGeneration` @@ -1093,12 +1014,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`: генерує зображення за допомогою налаштованого ланцюжка providers генерації зображень. -- `listProviders(...)`: перелічує доступні providers генерації зображень і їхні можливості. +- `generate(...)`: генерує зображення, використовуючи налаштований ланцюжок провайдерів генерації зображень. +- `listProviders(...)`: показує доступних провайдерів генерації зображень та їхні можливості. -## HTTP routes Gateway +## Gateway HTTP-маршрути -Plugins можуть відкривати HTTP endpoints через `api.registerHttpRoute(...)`. +Plugin можуть відкривати HTTP-ендпоїнти через `api.registerHttpRoute(...)`. ```ts api.registerHttpRoute({ @@ -1113,266 +1034,203 @@ api.registerHttpRoute({ }); ``` -Поля route: +Поля маршруту: -- `path`: шлях route під HTTP-сервером gateway. -- `auth`: обов’язкове. Використовуйте `"gateway"`, щоб вимагати звичайну auth gateway, або `"plugin"` для auth/перевірки Webhook, якими керує plugin. +- `path`: шлях маршруту під HTTP-сервером Gateway. +- `auth`: обов’язкове. Використовуйте `"gateway"`, щоб вимагати звичайну auth Gateway, або `"plugin"` для auth/перевірки Webhook, якими керує Plugin. - `match`: необов’язкове. `"exact"` (типово) або `"prefix"`. -- `replaceExisting`: необов’язкове. Дозволяє тому самому plugin замінити власну наявну реєстрацію route. -- `handler`: повертає `true`, коли route обробив запит. +- `replaceExisting`: необов’язкове. Дозволяє тому самому Plugin замінити власну наявну реєстрацію маршруту. +- `handler`: повертайте `true`, коли маршрут обробив запит. Примітки: -- `api.registerHttpHandler(...)` було видалено і спричинить помилку завантаження plugin. Замість нього використовуйте `api.registerHttpRoute(...)`. -- Routes plugin повинні явно оголошувати `auth`. -- Конфлікти точних `path + match` відхиляються, якщо не задано `replaceExisting: true`, і один plugin не може замінити route іншого plugin. -- Перекривні routes з різними рівнями `auth` відхиляються. Зберігайте ланцюжки fallthrough `exact`/`prefix` лише в межах одного рівня auth. -- Routes `auth: "plugin"` **не** отримують runtime scopes оператора автоматично. Вони призначені для Webhooks/перевірки підписів, якими керує plugin, а не для привілейованих helper-викликів Gateway. -- Routes `auth: "gateway"` працюють у межах runtime scope запиту Gateway, але цей scope навмисно консервативний: - - bearer auth зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) утримує runtime scopes route plugin на рівні `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` - - довірені HTTP-режими з носієм ідентичності (наприклад, `trusted-proxy` або `gateway.auth.mode = "none"` у приватному ingress) враховують `x-openclaw-scopes` лише тоді, коли цей заголовок явно присутній - - якщо `x-openclaw-scopes` відсутній у таких запитах route plugin з носієм ідентичності, runtime scope переходить до `operator.write` -- Практичне правило: не припускайте, що route plugin з auth gateway є неявним admin surface. Якщо вашому route потрібна поведінка лише для admin, вимагайте режим auth із носієм ідентичності та документуйте явний контракт заголовка `x-openclaw-scopes`. +- `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`. -## Шляхи імпорту SDK plugin +## Шляхи імпорту Plugin SDK -Під час написання plugins використовуйте subpaths SDK замість монолітного імпорту `openclaw/plugin-sdk`: +Під час створення нових Plugin використовуйте вузькі підшляхи SDK замість монолітного кореневого +barrel `openclaw/plugin-sdk`. Основні підшляхи: -- `openclaw/plugin-sdk/plugin-entry` для примітивів реєстрації plugin. -- `openclaw/plugin-sdk/core` для загального спільного контракту, орієнтованого на plugin. -- `openclaw/plugin-sdk/config-schema` для експорту кореневої Zod-схеми `openclaw.json` - (`OpenClawSchema`). -- Стабільні примітиви каналів, такі як `openclaw/plugin-sdk/channel-setup`, - `openclaw/plugin-sdk/setup-runtime`, - `openclaw/plugin-sdk/setup-adapter-runtime`, - `openclaw/plugin-sdk/setup-tools`, - `openclaw/plugin-sdk/channel-pairing`, - `openclaw/plugin-sdk/channel-contract`, - `openclaw/plugin-sdk/channel-feedback`, - `openclaw/plugin-sdk/channel-inbound`, - `openclaw/plugin-sdk/channel-lifecycle`, - `openclaw/plugin-sdk/channel-reply-pipeline`, - `openclaw/plugin-sdk/command-auth`, - `openclaw/plugin-sdk/secret-input` і - `openclaw/plugin-sdk/webhook-ingress` для спільного підключення setup/auth/reply/webhook. - `channel-inbound` — це спільне місце для debounce, зіставлення згадок, - helpers політики вхідних згадок, форматування envelope вхідних даних і helpers - контексту envelope вхідних даних. - `channel-setup` — це вузький seam налаштування для необов’язкового встановлення. - `setup-runtime` — це безпечний для runtime surface налаштування, який використовується `setupEntry` / - відкладеним запуском, включно з безпечними для імпорту адаптерами латок налаштування. - `setup-adapter-runtime` — це seam адаптера налаштування облікового запису з урахуванням env. - `setup-tools` — це малий seam helpers для CLI/архівів/документації (`formatCliCommand`, - `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, - `CONFIG_DIR`). -- Domain subpaths, такі як `openclaw/plugin-sdk/channel-config-helpers`, - `openclaw/plugin-sdk/allow-from`, - `openclaw/plugin-sdk/channel-config-schema`, - `openclaw/plugin-sdk/telegram-command-config`, - `openclaw/plugin-sdk/channel-policy`, - `openclaw/plugin-sdk/approval-gateway-runtime`, - `openclaw/plugin-sdk/approval-handler-adapter-runtime`, - `openclaw/plugin-sdk/approval-handler-runtime`, - `openclaw/plugin-sdk/approval-runtime`, - `openclaw/plugin-sdk/config-runtime`, - `openclaw/plugin-sdk/infra-runtime`, - `openclaw/plugin-sdk/agent-runtime`, - `openclaw/plugin-sdk/lazy-runtime`, - `openclaw/plugin-sdk/reply-history`, - `openclaw/plugin-sdk/routing`, - `openclaw/plugin-sdk/status-helpers`, - `openclaw/plugin-sdk/text-runtime`, - `openclaw/plugin-sdk/runtime-store` і - `openclaw/plugin-sdk/directory-runtime` для спільних helpers runtime/config. - `telegram-command-config` — це вузький публічний seam для нормалізації/валідації користувацьких - commands Telegram і він залишається доступним, навіть якщо surface контракту вбудованого - Telegram тимчасово недоступний. - `text-runtime` — це спільний seam тексту/markdown/логування, включно з - видаленням assistant-visible-text, helpers рендерингу/фрагментації markdown, helpers - редагування, helpers тегів директив і утилітами безпечного тексту. -- Специфічні для схвалення seams каналів мають надавати перевагу одному контракту `approvalCapability` - у plugin. Потім core читає auth схвалення, доставку, рендеринг, - native-routing і поведінку lazy native-handler через цю єдину можливість - замість змішування поведінки схвалення в непов’язані поля plugin. -- `openclaw/plugin-sdk/channel-runtime` є застарілим і залишається лише як - shim сумісності для старіших plugins. Новий код повинен імпортувати вужчі - загальні примітиви, а код repo не повинен додавати нові імпорти цього - shim. -- Внутрішні частини вбудованих extensions залишаються приватними. Зовнішні plugins повинні використовувати лише subpaths `openclaw/plugin-sdk/*`. Код core/test OpenClaw може використовувати публічні точки входу repo - в корені пакета plugin, такі як `index.js`, `api.js`, - `runtime-api.js`, `setup-entry.js`, і вузькоспеціалізовані файли, такі як - `login-qr-api.js`. Ніколи не імпортуйте `src/*` пакета plugin із core або з - іншого extension. -- Поділ точок входу repo: - `/api.js` — це barrel helpers/types, - `/runtime-api.js` — це barrel лише для runtime, - `/index.js` — це точка входу вбудованого plugin, - а `/setup-entry.js` — це точка входу plugin для setup. -- Поточні приклади вбудованих providers: - - Anthropic використовує `api.js` / `contract-api.js` для helpers потоку Claude, таких - як `wrapAnthropicProviderStream`, helpers beta-header і розбір `service_tier`. - - OpenAI використовує `api.js` для побудовників provider, helpers моделі за замовчуванням і - побудовників provider у реальному часі. - - OpenRouter використовує `api.js` для свого побудовника provider, а також helpers - онбордингу/config, тоді як `register.runtime.js` усе ще може повторно експортувати загальні - helpers `plugin-sdk/provider-stream` для локального використання в repo. -- Публічні точки входу, завантажені через facade, надають перевагу активному snapshot config runtime, - якщо він існує, а потім переходять до визначеного файла config на диску, коли - OpenClaw ще не обслуговує snapshot runtime. -- Загальні спільні примітиви залишаються бажаним публічним контрактом SDK. Невеликий - зарезервований сумісний набір branded helper seams вбудованих каналів усе ще існує. Ставтеся до них як до seams для супроводу вбудованих компонентів/сумісності, а не як до нових цілей імпорту для сторонніх розробників; нові міжканальні контракти, як і раніше, мають з’являтися в загальних subpaths `plugin-sdk/*` або в локальних barrels plugin `api.js` / - `runtime-api.js`. +| Підшлях | Призначення | +| ----------------------------------- | -------------------------------------------------- | +| `openclaw/plugin-sdk/plugin-entry` | Примітиви реєстрації Plugin | +| `openclaw/plugin-sdk/core` | Загальний спільний контракт для Plugin | +| `openclaw/plugin-sdk/config-schema` | Коренева Zod-схема `openclaw.json` (`OpenClawSchema`) | -Примітка щодо сумісності: +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). -- Уникайте кореневого barrel `openclaw/plugin-sdk` у новому коді. -- Спочатку віддавайте перевагу вузьким стабільним примітивам. Новіші subpaths setup/pairing/reply/ - feedback/contract/inbound/threading/command/secret-input/webhook/infra/ - allowlist/status/message-tool — це бажаний контракт для нової роботи з - вбудованими та зовнішніми plugins. - Розбір/зіставлення цілей має належати `openclaw/plugin-sdk/channel-targets`. - Обмеження дій повідомлень і helpers message-id для реакцій мають належати - `openclaw/plugin-sdk/channel-actions`. -- Branded helper barrels, специфічні для вбудованих extensions, за замовчуванням не є стабільними. Якщо - helper потрібен лише вбудованому extension, тримайте його за локальним - seam `api.js` або `runtime-api.js` цього extension замість просування в - `openclaw/plugin-sdk/`. -- Нові спільні helper seams мають бути загальними, а не branded для каналу. Спільний розбір - цілей має належати `openclaw/plugin-sdk/channel-targets`; специфічні для каналу - внутрішні частини мають залишатися за локальним seam `api.js` або `runtime-api.js` - plugin-власника. -- Специфічні для можливостей subpaths, такі як `image-generation`, - `media-understanding` і `speech`, існують, тому що вбудовані/нативні plugins - використовують їх уже сьогодні. Сам факт їх наявності ще не означає, що кожен експортований helper є - довгостроковим замороженим зовнішнім контрактом. +Допоміжні засоби runtime і config розміщені у відповідних підшляхах `*-runtime` +(`approval-runtime`, `config-runtime`, `infra-runtime`, `agent-runtime`, +`lazy-runtime`, `directory-runtime`, `text-runtime`, `runtime-store` тощо). -## Схеми tool повідомлень + +`openclaw/plugin-sdk/channel-runtime` є застарілим — це shim сумісності для +старіших Plugin. Новий код має імпортувати натомість вужчі загальні примітиви. + -Plugins мають володіти внесками до схеми `describeMessageTool(...)`, специфічними для каналу, -для примітивів, що не є повідомленнями, таких як реакції, читання та опитування. -Спільне представлення надсилання має використовувати загальний контракт `MessagePresentation` -замість native-полів button, component, block або card, специфічних для provider. -Контракт, правила fallback, зіставлення providers і контрольний список для автора plugin див. у -[Message Presentation](/uk/plugins/message-presentation). +Внутрішні точки входу репозиторію (для кореня пакета кожного вбудованого Plugin): -Plugins, які підтримують надсилання, оголошують, що вони можуть рендерити, через можливості повідомлень: +- `index.js` — точка входу вбудованого Plugin +- `api.js` — barrel допоміжних засобів/типів +- `runtime-api.js` — barrel лише для runtime +- `setup-entry.js` — точка входу setup Plugin -- `presentation` для блоків семантичного представлення (`text`, `context`, `divider`, `buttons`, `select`) -- `delivery-pin` для запитів доставки із закріпленням +Зовнішні Plugin мають імпортувати лише підшляхи `openclaw/plugin-sdk/*`. Ніколи +не імпортуйте `src/*` іншого пакета Plugin із core або з іншого Plugin. +Точки входу, завантажені через facade, надають перевагу активному знімку runtime config, якщо він +існує, а потім повертаються до визначеного файла config на диску. -Core вирішує, чи рендерити представлення нативно, чи деградувати його до тексту. -Не відкривайте аварійні шляхи до native UI provider із загального tool повідомлень. -Застарілі helpers SDK для старих native-схем залишаються експортованими для наявних -сторонніх plugins, але нові plugins не повинні їх використовувати. +Підшляхи, специфічні для можливостей, як-от `image-generation`, `media-understanding` +і `speech`, існують, оскільки вбудовані Plugin уже використовують їх сьогодні. Вони не є +автоматично зовнішніми контрактами, замороженими на довгий строк — перевіряйте відповідну +довідкову сторінку SDK, коли покладаєтеся на них. + +## Схеми інструмента повідомлень + +Plugin мають володіти внесками в схему `describeMessageTool(...)`, специфічними для каналу, +для примітивів, що не є повідомленнями, таких як реакції, позначення прочитаного та опитування. +Спільне подання надсилання має використовувати загальний контракт `MessagePresentation` +замість native полів кнопок, компонентів, блоків або карток, специфічних для провайдера. +Див. [Message Presentation](/uk/plugins/message-presentation), де описано контракт, +правила fallback, зіставлення провайдерів і контрольний список для авторів Plugin. + +Plugin, здатні надсилати, оголошують, що саме вони можуть відтворювати, через можливості повідомлень: + +- `presentation` для блоків семантичного подання (`text`, `context`, `divider`, `buttons`, `select`) +- `delivery-pin` для запитів на доставлення із закріпленням + +Core вирішує, чи відтворювати подання нативно, чи деградувати його до тексту. +Не відкривайте аварійні шляхи до native UI, специфічного для провайдера, із загального інструмента повідомлень. +Застарілі допоміжні засоби SDK для старих native-схем залишаються експортованими для наявних +сторонніх Plugin, але нові Plugin не повинні їх використовувати. ## Визначення цілі каналу -Plugins каналів мають володіти семантикою цілі, специфічною для каналу. Зберігайте спільний -хост вихідної комунікації загальним і використовуйте surface адаптера повідомлень для правил provider: +Plugin каналів мають володіти семантикою цілей, специфічною для каналу. Залишайте спільний +хост outbound загальним і використовуйте поверхню адаптера повідомлень для правил провайдера: -- `messaging.inferTargetChatType({ to })` визначає, чи нормалізовану ціль - слід трактувати як `direct`, `group` або `channel` до пошуку в каталозі. +- `messaging.inferTargetChatType({ to })` вирішує, чи нормалізовану ціль + слід трактувати як `direct`, `group` або `channel` до пошуку в директорії. - `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє core, чи - слід для введення одразу перейти до визначення як id-подібного значення замість пошуку в каталозі. -- `messaging.targetResolver.resolveTarget(...)` — це fallback plugin, коли - core потребує остаточного визначення, що належить provider, після нормалізації або після - відсутності результату в каталозі. -- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою route сесії, специфічною для provider, - після визначення цілі. + слід одразу перейти до визначення за id-подібним значенням замість пошуку в директорії. +- `messaging.targetResolver.resolveTarget(...)` — це fallback Plugin, коли + core потребує фінального визначення, що належить провайдеру, після нормалізації або + після відсутності збігу в директорії. +- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту сесії, специфічного для провайдера, + після того як ціль визначено. Рекомендований поділ: -- Використовуйте `inferTargetChatType` для рішень щодо категорій, які повинні прийматися до +- Використовуйте `inferTargetChatType` для рішень про категорію, які мають відбуватися до пошуку серед peers/groups. -- Використовуйте `looksLikeId` для перевірок на кшталт «трактувати це як явний/native id цілі». -- Використовуйте `resolveTarget` для fallback нормалізації, специфічного для provider, а не для - широкого пошуку в каталозі. -- Зберігайте native-ids provider, такі як ids chat, ids thread, JID, handles і ids room, - усередині значень `target` або специфічних для provider параметрів, а не в загальних полях SDK. +- Використовуйте `looksLikeId` для перевірок на кшталт «сприймати це як явний/native id цілі». +- Використовуйте `resolveTarget` для fallback-нормалізації, специфічної для провайдера, а не для + широкого пошуку в директорії. +- Зберігайте provider-native id, як-от id чату, id гілки, JID, handles і id кімнат, + усередині значень `target` або параметрів, специфічних для провайдера, а не в загальних полях SDK. -## Каталоги на основі config +## Директорії на основі config -Plugins, які формують записи каталогу з config, повинні зберігати цю логіку в -plugin і повторно використовувати спільні helpers із +Plugin, які формують записи директорії з config, мають зберігати цю логіку в +Plugin і повторно використовувати спільні допоміжні засоби з `openclaw/plugin-sdk/directory-runtime`. Використовуйте це, коли каналу потрібні peers/groups на основі config, наприклад: -- peers DM, керовані allowlist -- налаштовані зіставлення каналів/груп -- статичні fallback каталогу в межах облікового запису +- DM peers, керовані allowlist +- налаштовані мапи каналів/груп +- статичні fallback директорії з областю видимості облікового запису -Спільні helpers у `directory-runtime` обробляють лише загальні операції: +Спільні допоміжні засоби в `directory-runtime` обробляють лише загальні операції: - фільтрацію запитів -- застосування обмежень -- helpers дедуплікації/нормалізації +- застосування ліміту +- допоміжні засоби дедуплікації/нормалізації - побудову `ChannelDirectoryEntry[]` -Специфічна для каналу перевірка облікового запису та нормалізація id мають залишатися в -реалізації plugin. +Специфічні для каналу перевірка облікового запису та нормалізація id мають залишатися в +реалізації Plugin. -## Каталоги provider +## Каталоги провайдерів -Plugins provider можуть визначати каталоги моделей для виведення через +Plugin провайдерів можуть визначати каталоги моделей для inference за допомогою `registerProvider({ catalog: { run(...) { ... } } })`. `catalog.run(...)` повертає ту саму форму, яку OpenClaw записує в `models.providers`: -- `{ provider }` для одного запису provider -- `{ providers }` для кількох записів provider +- `{ provider }` для одного запису провайдера +- `{ providers }` для кількох записів провайдерів -Використовуйте `catalog`, коли plugin володіє model ids, базовими значеннями base URL або метаданими моделей з обмеженням auth, специфічними для provider. +Використовуйте `catalog`, коли Plugin володіє model id, специфічними для провайдера, значеннями `base URL` +за замовчуванням або метаданими моделей, захищеними auth. -`catalog.order` керує тим, коли каталог plugin зливається відносно -вбудованих неявних providers OpenClaw: +`catalog.order` керує тим, коли каталог Plugin об’єднується відносно +вбудованих неявних провайдерів OpenClaw: -- `simple`: прості providers на основі API-key або env -- `profile`: providers, які з’являються, коли існують профілі auth -- `paired`: providers, які синтезують кілька пов’язаних записів provider -- `late`: останній прохід, після інших неявних providers +- `simple`: провайдери з простим API-ключем або керовані env +- `profile`: провайдери, які з’являються, коли існують профілі auth +- `paired`: провайдери, які синтезують кілька пов’язаних записів провайдера +- `late`: останній прохід після інших неявних провайдерів -Пізніші providers перемагають у разі конфлікту ключів, тож plugins можуть навмисно перевизначати -вбудований запис provider з тим самим id provider. +Пізніші провайдери перемагають при конфлікті ключів, тому Plugin можуть навмисно перевизначати +вбудований запис провайдера з тим самим id провайдера. Сумісність: - `discovery` усе ще працює як застарілий псевдонім - якщо зареєстровано і `catalog`, і `discovery`, OpenClaw використовує `catalog` -## Інспекція каналу лише для читання +## Лише для читання: перевірка каналу -Якщо ваш plugin реєструє канал, віддавайте перевагу реалізації +Якщо ваш Plugin реєструє канал, надавайте перевагу реалізації `plugin.config.inspectAccount(cfg, accountId)` разом із `resolveAccount(...)`. Чому: -- `resolveAccount(...)` — це шлях runtime. Він може припускати, що облікові дані - повністю матеріалізовані, і швидко завершуватися помилкою, коли потрібні секрети відсутні. +- `resolveAccount(...)` — це runtime-шлях. Він може припускати, що облікові дані + повністю матеріалізовані, і може швидко завершуватися з помилкою, коли потрібні секрети відсутні. - Шляхи команд лише для читання, такі як `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve`, а також потоки doctor/config - repair, не повинні матеріалізовувати облікові дані runtime лише для того, щоб + `openclaw channels status`, `openclaw channels resolve`, а також потоки doctor/відновлення config, + не повинні потребувати матеріалізації runtime-облікових даних лише для того, щоб описати конфігурацію. Рекомендована поведінка `inspectAccount(...)`: - Повертайте лише описовий стан облікового запису. - Зберігайте `enabled` і `configured`. -- Додавайте поля джерела/стану облікових даних, коли це доречно, наприклад: +- За потреби включайте поля джерела/стану облікових даних, такі як: - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Вам не потрібно повертати сирі значення токенів лише для повідомлення про доступність у режимі лише читання. Достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела) для команд типу status. +- Не потрібно повертати сирі значення токенів лише для звітування про доступність у режимі лише читання. + Достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела) + для команд на кшталт status. - Використовуйте `configured_unavailable`, коли облікові дані налаштовано через SecretRef, але вони недоступні в поточному шляху команди. -Це дозволяє командам лише для читання повідомляти «налаштовано, але недоступно в цьому шляху команди» замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштований. +Це дає змогу командам лише для читання повідомляти «налаштовано, але недоступно в цьому +шляху команди» замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштовано. -## Пакети pack +## Package packs -Каталог plugin може містити `package.json` з `openclaw.extensions`: +Каталог Plugin може містити `package.json` з `openclaw.extensions`: ```json { @@ -1384,63 +1242,64 @@ Plugins provider можуть визначати каталоги моделей } ``` -Кожен запис стає plugin. Якщо pack містить кілька extensions, id plugin +Кожен запис стає Plugin. Якщо pack перелічує кілька extension, id Plugin стає `name/`. -Якщо ваш plugin імпортує залежності npm, встановіть їх у цьому каталозі, щоб +Якщо ваш Plugin імпортує залежності npm, установіть їх у цьому каталозі, щоб `node_modules` був доступний (`npm install` / `pnpm install`). -Захисне обмеження безпеки: кожен запис `openclaw.extensions` повинен залишатися в межах каталогу plugin -після визначення symlink. Записи, що виходять за межі каталогу пакета, -відхиляються. +Захисне обмеження безпеки: кожен запис `openclaw.extensions` має залишатися в межах каталогу Plugin +після визначення symlink. Записи, які виходять за межі каталогу пакета, відхиляються. -Примітка щодо безпеки: `openclaw plugins install` встановлює залежності plugin через -`npm install --omit=dev --ignore-scripts` (без lifecycle scripts, без залежностей dev під час runtime). Зберігайте дерева залежностей plugin «чистими JS/TS» і уникайте пакетів, які потребують збірок через `postinstall`. +Примітка щодо безпеки: `openclaw plugins install` встановлює залежності Plugin через +`npm install --omit=dev --ignore-scripts` (без lifecycle-скриптів, без dev-залежностей під час runtime). Зберігайте дерево залежностей Plugin +«чистим JS/TS» і уникайте пакетів, які потребують збирання через `postinstall`. -Необов’язково: `openclaw.setupEntry` може вказувати на полегшений модуль лише для setup. -Коли OpenClaw потребує surfaces setup для вимкненого plugin каналу або -коли plugin каналу увімкнений, але ще не налаштований, він завантажує `setupEntry` -замість повної точки входу plugin. Це робить запуск і setup легшими, -коли ваша основна точка входу plugin також підключає tools, hooks або інший код -лише для runtime. +Необов’язково: `openclaw.setupEntry` може вказувати на легкий модуль лише для setup. +Коли OpenClaw потребує поверхонь setup для вимкненого Plugin каналу або +коли Plugin каналу увімкнено, але ще не налаштовано, він завантажує `setupEntry` +замість повної точки входу Plugin. Це робить запуск і setup легшими, +коли основна точка входу Plugin також підключає інструменти, хуки або інший код лише для runtime. Необов’язково: `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -може перевести plugin каналу на той самий шлях `setupEntry` під час -передслухового етапу запуску gateway, навіть якщо канал уже налаштовано. +може підключити Plugin каналу до того самого шляху `setupEntry` під час +фази запуску gateway до початку прослуховування, навіть якщо канал уже налаштовано. -Використовуйте це лише тоді, коли `setupEntry` повністю покриває surface запуску, який має існувати -до того, як gateway почне слухати. На практиці це означає, що точка входу setup -повинна реєструвати кожну можливість, що належить каналу і від якої залежить запуск, наприклад: +Використовуйте це лише тоді, коли `setupEntry` повністю покриває поверхню запуску, яка має існувати +до того, як gateway почне прослуховування. На практиці це означає, що точка входу setup +має реєструвати кожну можливість, що належить каналу й від якої залежить запуск, наприклад: - саму реєстрацію каналу -- будь-які HTTP routes, які мають бути доступні до початку прослуховування gateway -- будь-які methods Gateway, tools або services, які повинні існувати в той самий період +- будь-які HTTP-маршрути, які мають бути доступні до того, як gateway почне прослуховування +- будь-які методи Gateway, інструменти або сервіси, які мають існувати в той самий проміжок часу -Якщо ваша повна точка входу все ще володіє будь-якою потрібною можливістю запуску, не вмикайте -цей прапорець. Залишайте plugin у стандартній поведінці й дозвольте OpenClaw завантажувати +Якщо ваша повна точка входу все ще володіє будь-якою обов’язковою можливістю запуску, не вмикайте +цей прапорець. Залишайте Plugin у типовому режимі й дозвольте OpenClaw завантажити повну точку входу під час запуску. -Вбудовані канали також можуть публікувати helpers поверхні контракту лише для setup, до яких core -може звертатися до завантаження повного runtime каналу. Поточний surface -просування setup такий: +Вбудовані канали також можуть публікувати допоміжні засоби поверхні контракту лише для setup, з якими core +може консультуватися до завантаження повного runtime каналу. Поточна поверхня +просування setup така: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -Core використовує цей surface, коли йому потрібно просунути застарілу конфігурацію -каналу з одним обліковим записом у `channels..accounts.*` без завантаження повної точки входу plugin. -Matrix — поточний вбудований приклад: він переміщує лише ключі auth/bootstrap у -іменований просунутий обліковий запис, коли іменовані облікові записи вже існують, і може зберегти -налаштований неканонічний ключ default-account замість того, щоб завжди створювати +Core використовує цю поверхню, коли йому потрібно просунути застарілий config каналу з одним обліковим записом +у `channels..accounts.*` без завантаження повної точки входу Plugin. +Поточний вбудований приклад — Matrix: він переносить лише ключі auth/bootstrap у +іменований просунутий обліковий запис, коли іменовані облікові записи вже існують, і може зберігати +налаштований неканонічний ключ облікового запису за замовчуванням замість того, щоб завжди створювати `accounts.default`. -Ці адаптери латок setup зберігають лінивий характер виявлення поверхні контракту вбудованих компонентів. Час імпорту залишається легким; surface просування завантажується лише під час першого використання замість повторного входу в запуск вбудованого каналу під час імпорту модуля. +Ці адаптери патчів setup зберігають відкладеним виявлення поверхні контракту вбудованих пакетів. Час імпорту залишається легким; поверхня +просування завантажується лише під час першого використання, а не через повторний вхід у запуск +вбудованого каналу під час імпорту модуля. -Коли ці surfaces запуску включають methods Gateway RPC, зберігайте їх на -специфічному для plugin префіксі. Простори імен admin core (`config.*`, +Коли ці поверхні запуску включають Gateway RPC methods, зберігайте їх на +префіксі, специфічному для Plugin. Простори імен адміністратора core (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди визначаються -як `operator.admin`, навіть якщо plugin запитує вужчий scope. +як `operator.admin`, навіть якщо Plugin запитує вужчу область. Приклад: @@ -1459,8 +1318,8 @@ Matrix — поточний вбудований приклад: він пере ### Метадані каталогу каналу -Plugins каналів можуть оголошувати метадані setup/discovery через `openclaw.channel` і -підказки встановлення через `openclaw.install`. Це дозволяє core не містити власних даних каталогу. +Plugin каналів можуть оголошувати метадані setup/виявлення через `openclaw.channel` і +підказки встановлення через `openclaw.install`. Це дозволяє core не містити даних каталогу. Приклад: @@ -1488,41 +1347,41 @@ Plugins каналів можуть оголошувати метадані setu } ``` -Корисні поля `openclaw.channel` понад мінімальний приклад: +Корисні поля `openclaw.channel`, окрім мінімального прикладу: -- `detailLabel`: вторинний label для багатших surfaces каталогу/status -- `docsLabel`: перевизначає текст посилання для посилання на docs -- `preferOver`: ids plugin/channel з нижчим пріоритетом, які цей запис каталогу має випереджати -- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: елементи керування текстом для surface вибору -- `markdownCapable`: позначає канал як здатний до markdown для рішень щодо форматування вихідних даних -- `exposure.configured`: приховує канал із surfaces списку налаштованих каналів, якщо встановлено `false` -- `exposure.setup`: приховує канал з інтерактивних засобів вибору setup/configure, якщо встановлено `false` -- `exposure.docs`: позначає канал як внутрішній/приватний для surfaces навігації docs -- `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; віддавайте перевагу `exposure` +- `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` -- `forceAccountBinding`: вимагає явної прив’язки облікового запису, навіть коли існує лише один обліковий запис -- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення цілей announce +- `forceAccountBinding`: вимагає явної прив’язки облікового запису, навіть якщо існує лише один обліковий запис +- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення цілей оголошень -OpenClaw також може зливати **зовнішні каталоги каналів** (наприклад, експорт -реєстру MPM). Помістіть файл JSON в одне з таких місць: +OpenClaw також може об’єднувати **зовнішні каталоги каналів** (наприклад, експорт +реєстру 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"`. -## Plugins context engine +## Plugin механізму контексту -Plugins context engine володіють оркестрацією контексту сесії для приймання, збирання -та Compaction. Реєструйте їх зі свого plugin через -`api.registerContextEngine(id, factory)`, а потім вибирайте активний engine через +Plugin механізму контексту володіють оркестрацією контексту сесії для ingеst, assembly +та Compaction. Реєструйте їх у своєму Plugin через +`api.registerContextEngine(id, factory)`, а потім вибирайте активний механізм через `plugins.slots.contextEngine`. -Використовуйте це, коли вашому plugin потрібно замінити або розширити типовий -конвеєр контексту, а не просто додати пошук пам’яті або hooks. +Використовуйте це, коли вашому Plugin потрібно замінити або розширити типовий конвеєр +контексту, а не просто додати пошук у пам’яті або хуки. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -1550,7 +1409,7 @@ export default function (api) { } ``` -Якщо ваш engine **не** володіє алгоритмом Compaction, залишайте `compact()` +Якщо ваш механізм **не** володіє алгоритмом Compaction, зберігайте `compact()` реалізованим і явно делегуйте його: ```ts @@ -1588,44 +1447,45 @@ export default function (api) { ## Додавання нової можливості -Коли plugin потребує поведінки, яка не вписується в поточний API, не обходьте -систему plugins через приватний внутрішній доступ. Додайте відсутню можливість. +Коли Plugin потребує поведінки, яка не вписується в поточний API, не обходьте +систему Plugin через приватний доступ до внутрішніх механізмів. Додайте відсутню можливість. Рекомендована послідовність: 1. визначте контракт core - Вирішіть, якою спільною поведінкою має володіти core: policy, fallback, злиття config, - життєвий цикл, семантика для каналів і форма helper runtime. -2. додайте типізовані surfaces реєстрації/runtime plugin - Розширте `OpenClawPluginApi` і/або `api.runtime` найменшим корисним - типізованим surface можливостей. -3. підключіть споживачів core + каналів/функцій - Канали та plugins функцій повинні використовувати нову можливість через core, - а не імпортувати реалізацію vendor напряму. -4. зареєструйте реалізації vendor - Потім plugins vendor реєструють свої бекенди для цієї можливості. -5. додайте покриття контракту - Додайте тести, щоб із часом володіння та форма реєстрації залишалися явними. + Вирішіть, якою спільною поведінкою має володіти core: політикою, fallback, об’єднанням config, + життєвим циклом, семантикою для каналів і формою runtime-допоміжного засобу. +2. додайте типізовані поверхні реєстрації/runtime Plugin + Розширте `OpenClawPluginApi` і/або `api.runtime` найменшою корисною + типізованою поверхнею можливості. +3. під’єднайте споживачів core + каналів/функцій + Канали й Plugin функцій мають використовувати нову можливість через core, + а не через прямий імпорт реалізації вендора. +4. зареєструйте реалізації вендорів + Потім vendor Plugin реєструють свої бекенди для цієї можливості. +5. додайте контрактне покриття + Додайте тести, щоб володіння й форма реєстрації залишалися явними з часом. -Так OpenClaw зберігає чітку позицію, не стаючи жорстко прив’язаним до -світогляду одного provider. Конкретний контрольний список файлів і робочий приклад див. у [Capability Cookbook](/uk/plugins/architecture). +Так OpenClaw зберігає свою чітку архітектурну позицію, не стаючи жорстко прив’язаним до +уявлень одного провайдера. Див. [Кулінарну книгу можливостей](/uk/plugins/architecture), +де наведено конкретний контрольний список файлів і приклад. ### Контрольний список можливості Коли ви додаєте нову можливість, реалізація зазвичай має одночасно торкатися -таких surfaces: +таких поверхонь: -- типи контрактів core у `src//types.ts` -- helper runner/runtime core у `src//runtime.ts` -- surface реєстрації API plugin у `src/plugins/types.ts` -- підключення реєстру plugins у `src/plugins/registry.ts` -- відкриття runtime plugin у `src/plugins/runtime/*`, коли plugins функцій/каналів - повинні це використовувати -- helpers capture/test у `src/test-utils/plugin-registration.ts` -- твердження володіння/контракту в `src/plugins/contracts/registry.ts` -- docs для операторів/plugins у `docs/` +- типів контракту 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` +- перевірок володіння/контракту в `src/plugins/contracts/registry.ts` +- документації для операторів/Plugin у `docs/` -Якщо одного з цих surfaces бракує, це зазвичай ознака того, що можливість +Якщо одна з цих поверхонь відсутня, це зазвичай ознака того, що можливість ще не повністю інтегрована. ### Шаблон можливості @@ -1656,7 +1516,7 @@ const clip = await api.runtime.videoGeneration.generate({ }); ``` -Шаблон contract test: +Шаблон контрактного тесту: ```ts expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); @@ -1664,7 +1524,7 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Це зберігає правило простим: -- core володіє контрактом можливостей + оркестрацією -- plugins vendor володіють реалізаціями vendor -- plugins функцій/каналів використовують helpers runtime -- contract tests зберігають явність володіння +- core володіє контрактом можливості + оркестрацією +- vendor Plugin володіють реалізаціями вендорів +- Plugin функцій/каналів використовують runtime-допоміжні засоби +- контрактні тести зберігають явність володіння