diff --git a/docs/uk/plugins/architecture-internals.md b/docs/uk/plugins/architecture-internals.md index a467d7ab7..52bdaac5e 100644 --- a/docs/uk/plugins/architecture-internals.md +++ b/docs/uk/plugins/architecture-internals.md @@ -1,155 +1,156 @@ --- read_when: - - Реалізація runtime hooks провайдера, життєвого циклу каналу або пакетних pack-ів - - Налагодження порядку завантаження Plugin або стану реєстру - - Додавання нової можливості Plugin або Plugin engine контексту -summary: 'Внутрішня архітектура Plugin: конвеєр завантаження, реєстр, runtime hooks, маршрути HTTP та довідкові таблиці' -title: Внутрішня архітектура Plugin + - Реалізація runtime-хуків провайдера, життєвого циклу каналу або пакунків пакетів + - Налагодження порядку завантаження plugin або стану реєстру + - Додавання нової можливості plugin або plugin рушія контексту +summary: 'Внутрішні механізми архітектури Plugin: конвеєр завантаження, реєстр, runtime-хуки, HTTP-маршрути та довідкові таблиці' +title: Внутрішні механізми архітектури Plugin x-i18n: - generated_at: "2026-04-27T12:52:05Z" + generated_at: "2026-04-27T16:06:47Z" model: gpt-5.4 provider: openai - source_hash: 2c491e72f14cd0cb5673343dd8374e7377f245ac6f0ca94eee954540fd0d7de6 + source_hash: 72aac4073018a61d3731a8de54782c63c9ab6e3d21b3af95198adadf8be582f1 source_path: plugins/architecture-internals.md workflow: 15 --- -Щоб ознайомитися з публічною моделлю можливостей, формами Plugin і контрактами -володіння/виконання, див. [Архітектура Plugin](/uk/plugins/architecture). Ця сторінка — -довідник із внутрішніх механізмів: конвеєр завантаження, реєстр, runtime hooks, -маршрути Gateway HTTP, шляхи імпорту та таблиці схем. +Для публічної моделі можливостей, форм plugin та контрактів +володіння/виконання див. [Архітектура Plugin](/uk/plugins/architecture). Ця сторінка — +довідник із внутрішніх механізмів: конвеєра завантаження, реєстру, runtime-хуків, +HTTP-маршрутів Gateway, шляхів імпорту та таблиць схем. ## Конвеєр завантаження Під час запуску OpenClaw приблизно робить таке: -1. виявляє корені потенційних Plugin -2. зчитує маніфести native або сумісних пакетів і метадані пакета -3. відхиляє небезпечні кандидати -4. нормалізує конфігурацію Plugin (`plugins.enabled`, `allow`, `deny`, `entries`, +1. виявляє кандидатні корені plugin +2. зчитує маніфести native або сумісних пакетів і метадані пакетів +3. відхиляє небезпечних кандидатів +4. нормалізує конфігурацію plugin (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. визначає, чи ввімкнено кожного кандидата -6. завантажує ввімкнені native-модулі: зібрані вбудовані модулі використовують native-loader; - незібрані native Plugin використовують jiti -7. викликає native hooks `register(api)` і збирає реєстрації в реєстр Plugin -8. відкриває реєстр для команд/runtime-поверхонь +5. визначає, чи вмикати кожного кандидата +6. завантажує ввімкнені native-модулі: зібрані вбудовані модулі використовують native-завантажувач; + незібрані native-plugin використовують jiti +7. викликає native-хуки `register(api)` і збирає реєстрації в реєстр plugin +8. відкриває реєстр для поверхонь команд/runtime -`activate` — це застарілий псевдонім для `register` — loader визначає, що саме присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані Plugin використовують `register`; для нових Plugin віддавайте перевагу `register`. +`activate` — це застарілий псевдонім для `register` — завантажувач визначає, що з них присутнє (`def.register ?? def.activate`), і викликає в тій самій точці. Усі вбудовані plugins використовують `register`; для нових plugins надавайте перевагу `register`. Перевірки безпеки відбуваються **до** виконання runtime. Кандидати блокуються, -коли entry виходить за межі кореня Plugin, шлях доступний для запису всім, або -володіння шляхом виглядає підозріло для не вбудованих Plugin. +коли точка входу виходить за межі кореня plugin, шлях має право запису для всіх, +або власник шляху виглядає підозріло для невбудованих plugins. ### Поведінка з пріоритетом маніфесту Маніфест — це джерело істини для control plane. OpenClaw використовує його, щоб: -- ідентифікувати Plugin +- ідентифікувати plugin - виявляти оголошені канали/Skills/схему конфігурації або можливості пакета - перевіряти `plugins.entries..config` -- доповнювати мітки/placeholder-и Control UI +- доповнювати мітки/заповнювачі Control UI - показувати метадані встановлення/каталогу -- зберігати легкі дескриптори активації та налаштування без завантаження runtime Plugin +- зберігати недорогі дескриптори активації та налаштування без завантаження runtime plugin -Для native Plugin runtime-модуль є частиною data plane. Він реєструє -фактичну поведінку, таку як hooks, інструменти, команди або потоки провайдера. +Для native-plugins runtime-модуль є частиною data plane. Він реєструє +фактичну поведінку, таку як хуки, інструменти, команди або потоки провайдера. Необов’язкові блоки маніфесту `activation` і `setup` залишаються в control plane. -Це лише дескриптори метаданих для планування активації та виявлення налаштування; +Це лише метадані-дескриптори для планування активації та виявлення налаштування; вони не замінюють runtime-реєстрацію, `register(...)` або `setupEntry`. -Перші live-споживачі активації тепер використовують підказки маніфесту щодо команд, каналів і провайдерів, -щоб звузити завантаження Plugin до ширшої матеріалізації реєстру: +Перші споживачі живої активації тепер використовують підказки маніфесту щодо команд, каналів і провайдерів, +щоб звузити завантаження plugin до ширшої матеріалізації реєстру: -- завантаження CLI звужується до Plugin, які володіють запитаною основною командою -- налаштування каналу/визначення Plugin звужується до Plugin, які володіють запитаним +- завантаження CLI звужується до plugins, які володіють запитаною основною командою +- налаштування каналу/визначення plugin звужується до plugins, які володіють запитаним id каналу -- явне визначення налаштування/runtime провайдера звужується до Plugin, які володіють +- явне визначення налаштування/runtime провайдера звужується до plugins, які володіють запитаним id провайдера -Планувальник активації надає як API лише з id для наявних викликачів, так і -API плану для нової діагностики. Записи плану повідомляють, чому Plugin було вибрано, -відокремлюючи явні підказки планувальника `activation.*` від резервного варіанта -володіння з маніфесту, такого як `providers`, `channels`, `commandAliases`, `setup.providers`, -`contracts.tools` і hooks. Це розділення причин є межею сумісності: -наявні метадані Plugin продовжують працювати, а новий код може виявляти широкі підказки +Планувальник активації надає і API лише з id для наявних викликів, і +API плану для нової діагностики. Записи плану повідомляють, чому plugin було вибрано, +відокремлюючи явні підказки планувальника `activation.*` від резервного +володіння з маніфесту, такого як `providers`, `channels`, `commandAliases`, +`setup.providers`, `contracts.tools` і хуки. Це розділення причин є межею сумісності: +наявні метадані plugin і далі працюють, а новий код може виявляти широкі підказки або резервну поведінку без зміни семантики завантаження runtime. -Виявлення налаштування тепер віддає перевагу id, якими володіють дескриптори, таким як `setup.providers` і -`setup.cliBackends`, щоб звузити коло кандидатів Plugin, перш ніж повертатися до -`setup-api` для Plugin, яким усе ще потрібні runtime hooks на етапі налаштування. Списки налаштування провайдера -використовують `providerAuthChoices` маніфесту, варіанти налаштування, похідні від дескриптора, -та метадані каталогу встановлення без завантаження runtime провайдера. Явне -`setup.requiresRuntime: false` є межею лише для дескриптора; пропущене -`requiresRuntime` зберігає застарілий резервний варіант `setup-api` для сумісності. Якщо більше -ніж один виявлений Plugin заявляє той самий нормалізований id провайдера налаштування або CLI backend, -пошук налаштування відмовляється від неоднозначного власника замість того, щоб покладатися на -порядок виявлення. Коли runtime налаштування все ж виконується, діагностика реєстру повідомляє про -розходження між `setup.providers` / `setup.cliBackends` і провайдерами або CLI backend-ами, -зареєстрованими `setup-api`, не блокуючи застарілі Plugin. +Виявлення налаштування тепер надає перевагу id, що належать дескриптору, таким як +`setup.providers` і `setup.cliBackends`, щоб звузити кандидатні plugins перед тим, як +повернутися до `setup-api` для plugins, яким і далі потрібні runtime-хуки на етапі налаштування. Списки +налаштування провайдера використовують маніфест `providerAuthChoices`, варіанти налаштування, +похідні від дескриптора, і метадані каталогу встановлення без завантаження runtime провайдера. Явний +`setup.requiresRuntime: false` є межею лише для дескриптора; якщо +`requiresRuntime` пропущено, для сумісності зберігається застарілий резервний шлях `setup-api`. Якщо більше +ніж один виявлений plugin заявляє про той самий нормалізований id провайдера налаштування або CLI-бекенда, +пошук налаштування відхиляє неоднозначного власника замість покладання на +порядок виявлення. Коли runtime налаштування все ж виконується, діагностика реєстру повідомляє +про розбіжності між `setup.providers` / `setup.cliBackends` і провайдерами або CLI-бекендами, +зареєстрованими через setup-api, не блокуючи застарілі plugins. -### Що кешує loader +### Що кешує завантажувач -OpenClaw зберігає короткоживучі кеші в процесі для: +OpenClaw зберігає короткоживучі внутрішньопроцесні кеші для: - результатів виявлення - даних реєстру маніфестів -- завантажених реєстрів Plugin +- завантажених реєстрів plugin -Ці кеші зменшують пікове навантаження під час запуску та повторні накладні витрати команд. Їх безпечно -розглядати як короткоживучі кеші продуктивності, а не як постійне сховище. +Ці кеші зменшують пікове навантаження під час запуску та накладні витрати повторних команд. Їх безпечно +розглядати як короткоживучі кеші продуктивності, а не як постійне зберігання. -Гарячі шляхи Gateway мають віддавати перевагу поточному `PluginLookUpTable` або явному -реєстру маніфестів, переданому через ланцюжок викликів. Для викликачів, які все ще перебудовують -метадані маніфесту зі збереженого індексу встановлених Plugin, OpenClaw також зберігає -невеликий обмежений резервний кеш із ключами за встановленим індексом, формою запиту, -політикою конфігурації, коренями runtime та сигнатурами файлів маніфесту/пакета. Цей кеш — -лише резервний варіант для повторної реконструкції встановленого індексу; це не змінюваний -runtime-реєстр Plugin. +Гарячі шляхи запуску Gateway мають віддавати перевагу поточному `PluginMetadataSnapshot`, +похідному `PluginLookUpTable` або явному реєстру маніфестів, переданому по ланцюжку викликів. Перевірка конфігурації, +автоматичне ввімкнення під час запуску та bootstrap plugin використовують той самий знімок, коли це можливо. +Для викликів, які все ще перебудовують метадані маніфесту зі збереженого індексу встановлених plugin, +OpenClaw також зберігає невеликий обмежений резервний кеш із ключами за встановленим індексом, формою запиту, політикою конфігурації, +runtime-коренями та сигнатурами файлів маніфесту/пакета. Цей кеш є лише +резервом для повторної реконструкції індексу встановлених plugin; це не змінюваний runtime- +реєстр plugin. Примітка щодо продуктивності: -- Установіть `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` або +- Встановіть `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` або `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1`, щоб вимкнути ці кеші. -- Установіть `OPENCLAW_DISABLE_INSTALLED_PLUGIN_MANIFEST_REGISTRY_CACHE=1`, щоб вимкнути - лише резервний кеш manifest-registry для встановленого індексу. +- Встановіть `OPENCLAW_DISABLE_INSTALLED_PLUGIN_MANIFEST_REGISTRY_CACHE=1`, щоб вимкнути + лише резервний кеш реєстру маніфестів для індексу встановлених plugin. - Налаштовуйте вікна кешу через `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` і `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS`. ## Модель реєстру -Завантажені Plugin не змінюють напряму довільні глобальні змінні ядра. Вони реєструються в -центральному реєстрі Plugin. +Завантажені plugins не змінюють напряму довільні глобальні об’єкти ядра. Вони реєструються в +центральному реєстрі plugin. Реєстр відстежує: -- записи Plugin (ідентичність, джерело, походження, статус, діагностика) +- записи plugin (ідентичність, джерело, походження, статус, діагностика) - інструменти -- застарілі hooks і типізовані hooks +- застарілі хуки й типізовані хуки - канали -- провайдери +- провайдерів - обробники Gateway RPC - HTTP-маршрути - реєстратори CLI -- фонові служби -- команди, що належать Plugin +- фонові сервіси +- команди, що належать plugin -Потім функції ядра читають із цього реєстру замість прямої взаємодії з модулями Plugin. +Функції ядра потім читають із цього реєстру замість прямої взаємодії з модулями plugin. Це зберігає односпрямованість завантаження: -- модуль Plugin -> реєстрація в реєстрі +- модуль plugin -> реєстрація в реєстрі - runtime ядра -> споживання реєстру -Це розділення важливе для супроводу. Воно означає, що більшості поверхонь ядра потрібна -лише одна точка інтеграції: "читати реєстр", а не "робити special-case для кожного модуля Plugin". +Це розділення важливе для супроводу. Воно означає, що більшості поверхонь ядра +потрібна лише одна точка інтеграції: «читати реєстр», а не «окремо обробляти кожен модуль plugin». -## Callback-і прив’язки розмов +## Колбеки прив’язки розмови -Plugin, які прив’язують розмову, можуть реагувати, коли схвалення буде вирішено. +Plugins, які прив’язують розмову, можуть реагувати, коли погодження завершено. -Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати callback після того, як запит на прив’язку -буде схвалено або відхилено: +Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати колбек після того, як запит на прив’язку +схвалено або відхилено: ```ts export default { @@ -157,128 +158,128 @@ export default { register(api) { api.onConversationBindingResolved(async (event) => { if (event.status === "approved") { - // A binding now exists for this plugin + conversation. + // Для цього plugin + розмови тепер існує прив’язка. console.log(event.binding?.conversationId); return; } - // The request was denied; clear any local pending state. + // Запит було відхилено; очистьте будь-який локальний стан очікування. console.log(event.request.conversation.conversationId); }); }, }; ``` -Поля payload callback-а: +Поля корисного навантаження колбека: - `status`: `"approved"` або `"denied"` - `decision`: `"allow-once"`, `"allow-always"` або `"deny"` -- `binding`: визначена прив’язка для схвалених запитів -- `request`: підсумок початкового запиту, підказка від’єднання, id відправника та +- `binding`: вирішена прив’язка для схвалених запитів +- `request`: зведення початкового запиту, підказка від’єднання, id відправника та метадані розмови -Цей callback призначений лише для сповіщення. Він не змінює того, кому дозволено прив’язувати -розмову, і запускається після завершення обробки схвалення в ядрі. +Цей колбек призначений лише для сповіщення. Він не змінює, хто має право прив’язувати +розмову, і виконується після завершення обробки погодження ядром. -## Runtime hooks провайдера +## Runtime-хуки провайдера -Plugin провайдера мають три шари: +Plugins провайдера мають три рівні: -- **Метадані маніфесту** для дешевого пошуку до runtime: - `setup.providers[].envVars`, застаріла сумісна форма `providerAuthEnvVars`, +- **Метадані маніфесту** для недорогого передruntime-пошуку: + `setup.providers[].envVars`, застарілий сумісний `providerAuthEnvVars`, `providerAuthAliases`, `providerAuthChoices` і `channelEnvVars`. -- **Hooks часу конфігурації**: `catalog` (застаріле `discovery`) плюс +- **Хуки часу конфігурації**: `catalog` (застарілий `discovery`) плюс `applyConfigDefaults`. -- **Runtime hooks**: понад 40 необов’язкових hooks для автентифікації, визначення моделі, - обгортання потоку, рівнів thinking, політики повтору та кінцевих точок використання. Див. - повний список у розділі [Порядок hooks і використання](#hook-order-and-usage). +- **Runtime-хуки**: понад 40 необов’язкових хуків для auth, визначення моделі, + обгортання потоку, рівнів thinking, політики відтворення та кінцевих точок використання. Див. + повний список у розділі [Порядок і використання хуків](#hook-order-and-usage). -OpenClaw, як і раніше, володіє загальним циклом агента, резервним перемиканням, обробкою транскрипту та -політикою інструментів. Ці hooks є поверхнею розширення для специфічної поведінки провайдера -без потреби в повністю власному транспорті inference. +OpenClaw і далі відповідає за загальний цикл агента, failover, обробку транскриптів і +політику інструментів. Ці хуки — поверхня розширення для специфічної поведінки провайдера +без потреби у повністю власному транспорті інференсу. -Використовуйте `setup.providers[].envVars` маніфесту, коли провайдер має облікові дані на основі env, -які загальні шляхи auth/status/model-picker мають бачити без завантаження runtime Plugin. -Застаріле `providerAuthEnvVars` усе ще зчитується адаптером сумісності під час -перехідного періоду, а не вбудовані Plugin, які його використовують, отримують діагностику маніфесту. Використовуйте маніфест `providerAuthAliases`, -коли один id провайдера має повторно використовувати env vars, профілі автентифікації, -автентифікацію на основі конфігурації та варіант onboarding API-key іншого id провайдера. Використовуйте маніфест -`providerAuthChoices`, коли поверхні CLI onboarding/auth-choice мають знати -id вибору провайдера, мітки груп і просту auth-обв’язку з одним прапорцем без -завантаження runtime провайдера. Залишайте runtime `envVars` провайдера -для операторських підказок, таких як мітки onboarding або змінні налаштування +Використовуйте маніфест `setup.providers[].envVars`, коли провайдер має облікові дані на основі env, +які мають бути видимі загальним шляхам auth/status/вибору моделі без +завантаження runtime plugin. Застарілий `providerAuthEnvVars` і далі читається адаптером сумісності +під час перехідного періоду, а невбудовані plugins, які його використовують, отримують +діагностику маніфесту. Використовуйте маніфест `providerAuthAliases`, коли один id провайдера +має повторно використовувати env vars, профілі auth, auth на основі конфігурації та варіант +онбордингу з API-ключем іншого id провайдера. Використовуйте маніфест +`providerAuthChoices`, коли поверхні CLI онбордингу/вибору auth мають знати +id варіанта провайдера, мітки груп і просту auth-проводку з одним прапорцем без +завантаження runtime провайдера. Залишайте runtime провайдера +`envVars` для операторських підказок, таких як мітки онбордингу або змінні налаштування OAuth client-id/client-secret. Використовуйте маніфест `channelEnvVars`, коли канал має auth або налаштування на основі env, -які загальний резервний варіант shell-env, перевірки config/status або підказки setup мають бачити +які загальний резервний шлях shell-env, перевірки config/status або підказки налаштування мають бачити без завантаження runtime каналу. -### Порядок hooks і використання +### Порядок і використання хуків -Для Plugin моделі/провайдера OpenClaw викликає hooks приблизно в такому порядку. -Стовпець "Коли використовувати" — це короткий посібник для вибору. +Для plugins моделі/провайдера OpenClaw викликає хуки приблизно в такому порядку. +Стовпець «Коли використовувати» — це короткий посібник для вибору. -| # | Hook | Що він робить | Коли використовувати | -| --- | --------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | Публікує конфігурацію провайдера в `models.providers` під час генерації `models.json` | Провайдер володіє каталогом або типовими значеннями `base URL` | -| 2 | `applyConfigDefaults` | Застосовує типові глобальні значення конфігурації провайдера під час матеріалізації конфігурації | Типові значення залежать від режиму автентифікації, env або семантики сімейства моделей провайдера | -| -- | _(вбудований пошук моделі)_ | OpenClaw спочатку пробує звичайний шлях реєстру/каталогу | _(це не hook Plugin)_ | -| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми `model-id` перед пошуком | Провайдер володіє очищенням псевдонімів перед канонічним визначенням моделі | -| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства провайдера перед загальним складанням моделі | Провайдер володіє очищенням транспорту для власних id провайдера в межах того самого сімейства транспорту | -| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед runtime/визначенням провайдера | Провайдеру потрібне очищення конфігурації, яке має жити разом із Plugin; вбудовані помічники сімейства Google також страхують підтримувані записи конфігурації Google | -| 6 | `applyNativeStreamingUsageCompat` | Застосовує compat-переписування використання native streaming до провайдерів у конфігурації | Провайдеру потрібні виправлення метаданих використання native streaming, зумовлені кінцевою точкою | -| 7 | `resolveConfigApiKey` | Визначає автентифікацію env-marker для провайдерів у конфігурації до завантаження runtime-auth | Провайдер має власне визначення API-key env-marker; `amazon-bedrock` також має тут вбудований AWS-resolver для env-marker | -| 8 | `resolveSyntheticAuth` | Показує локальну/self-hosted або конфігураційну автентифікацію без збереження plaintext | Провайдер може працювати із synthetic/local marker облікових даних | -| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі автентифікації провайдера; типове значення `persistence` — `runtime-only` для облікових даних CLI/застосунку | Провайдер повторно використовує зовнішні облікові дані автентифікації без збереження скопійованих refresh-token-ів; оголосіть `contracts.externalAuthProviders` у маніфесті | -| 10 | `shouldDeferSyntheticProfileAuth` | Опускає placeholder-и збережених synthetic-профілів нижче за автентифікацію на основі env/конфігурації | Провайдер зберігає synthetic placeholder-профілі, які не повинні мати вищий пріоритет | -| 11 | `resolveDynamicModel` | Синхронний резервний варіант для власних id моделей провайдера, яких ще немає в локальному реєстрі | Провайдер приймає довільні upstream id моделей | -| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` запускається знову | Провайдеру потрібні мережеві метадані перед визначенням невідомих id | -| 13 | `normalizeResolvedModel` | Фінальне переписування перед тим, як вбудований виконавець використає визначену модель | Провайдеру потрібні переписування транспорту, але він усе ще використовує транспорт ядра | -| 14 | `contributeResolvedModelCompat` | Додає compat-прапорці для моделей вендора за іншим сумісним транспортом | Провайдер розпізнає власні моделі на proxy transport-ах, не перебираючи на себе роль провайдера | -| 15 | `capabilities` | Метадані транскрипту/інструментів провайдера, які використовує спільна логіка ядра | Провайдеру потрібні особливості транскрипту/сімейства провайдера | -| 16 | `normalizeToolSchemas` | Нормалізує схеми інструментів до того, як їх побачить вбудований виконавець | Провайдеру потрібне очищення схем для сімейства транспорту | -| 17 | `inspectToolSchemas` | Показує діагностику схем провайдера після нормалізації | Провайдер хоче попередження щодо ключових слів без навчання ядра правилам, специфічним для провайдера | -| 18 | `resolveReasoningOutputMode` | Вибирає native чи tagged-контракт виходу reasoning | Провайдеру потрібен tagged reasoning/final output замість native-полів | -| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед загальними обгортками параметрів потоку | Провайдеру потрібні типові параметри запиту або очищення параметрів для конкретного провайдера | +| # | Хук | Що він робить | Коли використовувати | +| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | `catalog` | Публікує конфігурацію провайдера в `models.providers` під час генерації `models.json` | Провайдер володіє каталогом або типовими значеннями `base URL` | +| 2 | `applyConfigDefaults` | Застосовує глобальні типові значення конфігурації, що належать провайдеру, під час матеріалізації конфігурації | Типові значення залежать від режиму auth, env або семантики сімейства моделей провайдера | +| -- | _(вбудований пошук моделі)_ | OpenClaw спочатку пробує звичайний шлях через реєстр/каталог | _(не є хуком plugin)_ | +| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми model-id перед пошуком | Провайдер володіє очищенням псевдонімів перед канонічним визначенням моделі | +| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства провайдера перед загальним складанням моделі | Провайдер володіє очищенням транспорту для власних id провайдера в межах того самого сімейства транспорту | +| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед визначенням runtime/провайдера | Провайдеру потрібне очищення конфігурації, яке має жити разом із plugin; вбудовані helper-и сімейства Google також страхують підтримувані записи конфігурації Google | +| 6 | `applyNativeStreamingUsageCompat` | Застосовує сумісні перезаписи native streaming-usage до конфігурованих провайдерів | Провайдеру потрібні виправлення метаданих native streaming usage, що залежать від кінцевої точки | +| 7 | `resolveConfigApiKey` | Визначає auth env-marker для конфігурованих провайдерів перед завантаженням runtime auth | Провайдер має власне визначення API-ключа env-marker; `amazon-bedrock` також має тут вбудований AWS-резолвер env-marker | +| 8 | `resolveSyntheticAuth` | Виводить локальний/self-hosted або auth на основі конфігурації без збереження відкритого тексту | Провайдер може працювати із синтетичним/локальним маркером облікових даних | +| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі auth, що належать провайдеру; типовим `persistence` є `runtime-only` для облікових даних CLI/app | Провайдер повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token-ів; оголосіть `contracts.externalAuthProviders` у маніфесті | +| 10 | `shouldDeferSyntheticProfileAuth` | Опускає збережені заповнювачі синтетичних профілів нижче за auth на основі env/конфігурації | Провайдер зберігає синтетичні профілі-заповнювачі, які не мають отримувати пріоритет | +| 11 | `resolveDynamicModel` | Синхронний резервний шлях для model id провайдера, яких ще немає в локальному реєстрі | Провайдер приймає довільні id моделей із зовнішнього джерела | +| 12 | `prepareDynamicModel` | Асинхронний розігрів, після чого `resolveDynamicModel` запускається знову | Провайдеру потрібні мережеві метадані перед визначенням невідомих id | +| 13 | `normalizeResolvedModel` | Остаточний перезапис перед тим, як вбудований runner використовує визначену модель | Провайдеру потрібні перезаписи транспорту, але він усе ще використовує транспорт ядра | +| 14 | `contributeResolvedModelCompat` | Додає прапорці compat для моделей вендора за іншим сумісним транспортом | Провайдер розпізнає власні моделі на proxy-транспортах, не перебираючи на себе роль провайдера | +| 15 | `capabilities` | Метадані транскрипту/інструментів, що належать провайдеру та використовуються спільною логікою ядра | Провайдеру потрібні особливості транскрипту/сімейства провайдера | +| 16 | `normalizeToolSchemas` | Нормалізує схеми інструментів перед тим, як їх побачить вбудований runner | Провайдеру потрібне очищення схем для сімейства транспорту | +| 17 | `inspectToolSchemas` | Виводить діагностику схем, що належить провайдеру, після нормалізації | Провайдер хоче попередження про ключові слова без додавання в ядро специфічних для провайдера правил | +| 18 | `resolveReasoningOutputMode` | Вибирає native чи tagged-контракт reasoning output | Провайдеру потрібен tagged reasoning/final output замість native-полів | +| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед загальними обгортками параметрів потоку | Провайдеру потрібні типові параметри запиту або очищення параметрів для конкретного провайдера | | 20 | `createStreamFn` | Повністю замінює звичайний шлях потоку власним транспортом | Провайдеру потрібен власний wire protocol, а не просто обгортка | -| 21 | `wrapStreamFn` | Обгортка потоку після застосування загальних обгорток | Провайдеру потрібні обгортки сумісності заголовків/body/моделі запиту без власного транспорту | -| 22 | `resolveTransportTurnState` | Прикріплює native-заголовки або метадані транспорту для кожного ходу | Провайдер хоче, щоб загальні транспорти надсилали native-ідентичність ходу провайдера | -| 23 | `resolveWebSocketSessionPolicy` | Прикріплює native-заголовки WebSocket або політику охолодження сесії | Провайдер хоче, щоб загальні WS-транспорти налаштовували заголовки сесії або політику резервного перемикання | -| 24 | `formatApiKey` | Formatter профілю автентифікації: збережений профіль стає runtime-рядком `apiKey` | Провайдер зберігає додаткові метадані автентифікації й потребує власної форми runtime-токена | -| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для власних кінцевих точок оновлення або політики збоїв оновлення | Провайдер не вписується в спільні refreshers `pi-ai` | -| 26 | `buildAuthDoctorHint` | Підказка для виправлення, що додається, коли оновлення OAuth зазнає невдачі | Провайдеру потрібна власна підказка щодо відновлення автентифікації після збою оновлення | -| 27 | `matchesContextOverflowError` | Власний matcher провайдера для переповнення контекстного вікна | Провайдер має сирі помилки переповнення, які загальні евристики не виявляють | -| 28 | `classifyFailoverReason` | Власна класифікація причин резервного перемикання провайдера | Провайдер може зіставляти сирі помилки API/транспорту з rate-limit/перевантаженням тощо | -| 29 | `isCacheTtlEligible` | Політика prompt-cache для proxy/backhaul-провайдерів | Провайдеру потрібне керування TTL кешу, специфічне для proxy | -| 30 | `buildMissingAuthMessage` | Заміна загального повідомлення про відсутню автентифікацію | Провайдеру потрібна власна підказка щодо відновлення після відсутньої автентифікації | -| 31 | `suppressBuiltInModel` | Приглушення застарілих upstream-моделей плюс необов’язкова підказка помилки для користувача | Провайдеру потрібно приховати застарілі upstream-рядки або замінити їх підказкою вендора | -| 32 | `augmentModelCatalog` | Synthetic/фінальні рядки каталогу, додані після виявлення | Провайдеру потрібні synthetic-рядки для прямої сумісності в майбутньому в `models list` і picker-ах | -| 33 | `resolveThinkingProfile` | Набір рівнів `/think`, мітки відображення та типове значення для конкретної моделі | Провайдер надає власну шкалу thinking або двійкову мітку для вибраних моделей | -| 34 | `isBinaryThinking` | Hook сумісності для перемикача reasoning увімк./вимк. | Провайдер підтримує лише двійковий thinking увімк./вимк. | -| 35 | `supportsXHighThinking` | Hook сумісності для підтримки reasoning `xhigh` | Провайдер хоче підтримку `xhigh` лише для підмножини моделей | -| 36 | `resolveDefaultThinkingLevel` | Hook сумісності для типового рівня `/think` | Провайдер володіє типовою політикою `/think` для сімейства моделей | -| 37 | `isModernModelRef` | Matcher сучасних моделей для live-фільтрів профілю та вибору smoke | Провайдер володіє зіставленням бажаних моделей для live/smoke | +| 21 | `wrapStreamFn` | Обгортка потоку після застосування загальних обгорток | Провайдеру потрібні обгортки сумісності заголовків/тіла запиту/моделі без власного транспорту | +| 22 | `resolveTransportTurnState` | Додає native-заголовки або метадані транспорту для кожного ходу | Провайдер хоче, щоб загальні транспорти надсилали native-ідентичність ходу провайдера | +| 23 | `resolveWebSocketSessionPolicy` | Додає native-заголовки WebSocket або політику cooldown сесії | Провайдер хоче, щоб загальні WS-транспорти налаштовували заголовки сесії або політику резервного шляху | +| 24 | `formatApiKey` | Форматувач auth-профілю: збережений профіль стає рядком runtime `apiKey` | Провайдер зберігає додаткові метадані auth і потребує власну форму runtime-токена | +| 25 | `refreshOAuth` | Перевизначення OAuth refresh для власних кінцевих точок refresh або політики помилки refresh | Провайдер не відповідає спільним механізмам refresh `pi-ai` | +| 26 | `buildAuthDoctorHint` | Підказка виправлення, що додається, коли OAuth refresh завершується помилкою | Провайдеру потрібна власна підказка відновлення auth після помилки refresh | +| 27 | `matchesContextOverflowError` | Власний зіставник переповнення context window для провайдера | Провайдер має сирі помилки переповнення, які загальні евристики не виявлять | +| 28 | `classifyFailoverReason` | Класифікація причин failover, що належить провайдеру | Провайдер може зіставляти сирі помилки API/транспорту з rate-limit/перевантаженням тощо | +| 29 | `isCacheTtlEligible` | Політика prompt-cache для proxy/backhaul-провайдерів | Провайдеру потрібне обмеження TTL кешу, специфічне для proxy | +| 30 | `buildMissingAuthMessage` | Заміна загального повідомлення відновлення при відсутності auth | Провайдеру потрібна специфічна для провайдера підказка відновлення при відсутності auth | +| 31 | `suppressBuiltInModel` | Приховування застарілих моделей із зовнішнього джерела плюс необов’язкова користувацька підказка про помилку | Провайдеру потрібно приховувати застарілі рядки з зовнішнього джерела або замінювати їх підказкою вендора | +| 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 | Провайдер володіє зіставленням preferred-model для live/smoke | | 38 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний runtime-токен/ключ безпосередньо перед inference | Провайдеру потрібен обмін токена або короткоживучі облікові дані запиту | -| 39 | `resolveUsageAuth` | Визначає облікові дані використання/білінгу для `/usage` і пов’язаних поверхонь стану | Провайдеру потрібен власний розбір токена використання/квоти або інші облікові дані використання | -| 40 | `fetchUsageSnapshot` | Отримує та нормалізує snapshots використання/квоти, специфічні для провайдера, після визначення автентифікації | Провайдеру потрібна власна кінцева точка використання або parser payload-у | -| 41 | `createEmbeddingProvider` | Створює embedding-adapter провайдера для memory/search | Поведінка embedding-ів пам’яті має належати Plugin провайдера | -| 42 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою транскрипту для провайдера | Провайдеру потрібна власна політика транскрипту (наприклад, видалення блоків thinking) | -| 43 | `sanitizeReplayHistory` | Переписує історію replay після загального очищення транскрипту | Провайдеру потрібні переписування replay, специфічні для провайдера, понад спільні helper-и Compaction | -| 44 | `validateReplayTurns` | Фінальна перевірка або зміна форми ходів replay перед вбудованим виконавцем | Транспорту провайдера потрібна суворіша перевірка ходів після загальної санітизації | -| 45 | `onModelSelected` | Запускає побічні ефекти провайдера після вибору | Провайдеру потрібна телеметрія або стан провайдера, коли модель стає активною | +| 39 | `resolveUsageAuth` | Визначає облікові дані usage/billing для `/usage` та пов’язаних поверхонь статусу | Провайдеру потрібен власний парсинг токена usage/quota або інші облікові дані для usage | +| 40 | `fetchUsageSnapshot` | Отримує й нормалізує специфічні для провайдера знімки usage/quota після визначення auth | Провайдеру потрібна специфічна для провайдера кінцева точка usage або парсер корисного навантаження | +| 41 | `createEmbeddingProvider` | Створює embedding-адаптер, що належить провайдеру, для пам’яті/пошуку | Поведінка embedding для пам’яті має належати plugin провайдера | +| 42 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою транскрипту для провайдера | Провайдеру потрібна власна політика транскрипту, наприклад видалення блоків thinking | +| 43 | `sanitizeReplayHistory` | Перезаписує історію replay після загального очищення транскрипту | Провайдеру потрібні специфічні для провайдера перезаписи replay понад спільні helper-и Compaction | +| 44 | `validateReplayTurns` | Остаточна перевірка або зміна форми ходів replay перед вбудованим runner | Транспорту провайдера потрібна суворіша перевірка ходів після загальної санації | +| 45 | `onModelSelected` | Виконує побічні ефекти після вибору моделі, що належать провайдеру | Провайдеру потрібна телеметрія або стан, що належить провайдеру, коли модель стає активною | `normalizeModelId`, `normalizeTransport` і `normalizeConfig` спочатку перевіряють -відповідний Plugin провайдера, а потім переходять до інших Plugin провайдерів, -які підтримують hooks, доки один із них фактично не змінить id моделі або -транспорт/конфігурацію. Це дає змогу shim-ам провайдерів для псевдонімів/compat -працювати без вимоги, щоб викликач знав, який саме вбудований Plugin володіє -цим переписуванням. Якщо жоден hook провайдера не переписує підтримуваний запис -конфігурації сімейства Google, вбудований нормалізатор конфігурації Google усе -одно застосовує це виправлення compat. +plugin провайдера, що збігся, а потім переходять до інших plugin провайдерів із підтримкою хуків, +доки один із них фактично не змінить id моделі або transport/config. Це дає змогу +shim-прошаркам alias/compat провайдера працювати без вимоги, щоб виклик знав, який +саме вбудований plugin володіє цим перезаписом. Якщо жоден хук провайдера не перезапише +підтримуваний запис конфігурації сімейства Google, вбудований нормалізатор конфігурації Google +усе одно застосує це очищення сумісності. -Якщо провайдеру потрібен повністю власний wire protocol або власний виконавець -запитів, це інший клас розширення. Ці hooks призначені для поведінки провайдера, -яка все ще виконується в межах звичайного циклу inference OpenClaw. +Якщо провайдеру потрібен повністю власний wire protocol або власний виконавець запитів, +це вже інший клас розширення. Ці хуки призначені для поведінки провайдера, +яка все ще працює в межах звичайного циклу inference OpenClaw. ### Приклад провайдера @@ -336,45 +337,45 @@ api.registerProvider({ ### Вбудовані приклади -Вбудовані Plugin провайдерів поєднують hooks вище, щоб відповідати потребам -кожного вендора щодо каталогу, автентифікації, thinking, replay і використання. Авторитетний -набір hooks живе разом із кожним Plugin у `extensions/`; ця сторінка -ілюструє форми, а не дзеркально повторює список. +Вбудовані plugins провайдерів поєднують наведені вище хуки, щоб відповідати потребам +кожного вендора щодо каталогу, auth, thinking, replay та usage. Авторитетний набір хуків +живе разом із кожним plugin у `extensions/`; ця сторінка ілюструє форми, а не +дзеркально відтворює список. - OpenRouter, Kilocode, Z.AI, xAI реєструють `catalog` плюс - `resolveDynamicModel` / `prepareDynamicModel`, щоб показувати upstream - id моделей раніше за статичний каталог OpenClaw. + OpenRouter, Kilocode, Z.AI, xAI реєструють `catalog` разом із + `resolveDynamicModel` / `prepareDynamicModel`, щоб вони могли показувати id моделей + із зовнішнього джерела раніше за статичний каталог OpenClaw. - + GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi, z.ai поєднують `prepareRuntimeAuth` або `formatApiKey` з `resolveUsageAuth` + `fetchUsageSnapshot`, щоб керувати обміном токенів та інтеграцією `/usage`. - + Спільні іменовані сімейства (`google-gemini`, `passthrough-gemini`, `anthropic-by-model`, `hybrid-anthropic-openai`) дають провайдерам змогу - підключатися до політики транскрипту через `buildReplayPolicy` замість того, - щоб кожен Plugin заново реалізовував очищення. + підключати політику транскриптів через `buildReplayPolicy` замість того, щоб кожен plugin + повторно реалізовував очищення. - + `byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, `synthetic`, `together`, `venice`, `vercel-ai-gateway` і - `volcengine` реєструють лише `catalog` і працюють у спільному циклі inference. + `volcengine` реєструють лише `catalog` і використовують спільний цикл inference. - - Бета-заголовки, `/fast` / `serviceTier` і `context1m` живуть у - публічному seam `api.ts` / `contract-api.ts` Plugin Anthropic + + Бета-заголовки, `/fast` / `serviceTier` і `context1m` розміщено всередині + публічного шва `api.ts` / `contract-api.ts` plugin Anthropic (`wrapAnthropicProviderStream`, `resolveAnthropicBetas`, `resolveAnthropicFastMode`, `resolveAnthropicServiceTier`), а не в загальному SDK. -## Runtime helper-и +## Runtime-helper-и -Plugin можуть отримувати доступ до вибраних helper-ів ядра через `api.runtime`. Для TTS: +Plugins можуть отримувати доступ до вибраних helper-ів ядра через `api.runtime`. Для TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -395,14 +396,14 @@ const voices = await api.runtime.tts.listVoices({ Примітки: -- `textToSpeech` повертає звичайний payload виходу TTS ядра для поверхонь файлів/голосових повідомлень. -- Використовує конфігурацію `messages.tts` ядра та вибір провайдера. -- Повертає буфер аудіо PCM + частоту дискретизації. Plugin мають виконати ресемплінг/кодування для провайдерів. -- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для picker-ів голосу або потоків налаштування, що належать вендору. -- Списки голосів можуть містити багатші метадані, такі як локаль, стать і теги особистості для picker-ів, обізнаних про провайдера. +- `textToSpeech` повертає звичайне корисне навантаження виводу TTS ядра для поверхонь файлів/голосових нотаток. +- Використовує конфігурацію ядра `messages.tts` і вибір провайдера. +- Повертає PCM-аудіобуфер + частоту дискретизації. Plugins мають виконувати ресемплінг/кодування для провайдерів. +- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для засобів вибору голосу або потоків налаштування, що належать вендору. +- Списки голосів можуть містити багатші метадані, як-от locale, стать і теги характеру для засобів вибору, обізнаних про провайдера. - OpenAI і ElevenLabs сьогодні підтримують телефонію. Microsoft — ні. -Plugin також можуть реєструвати провайдерів мовлення через `api.registerSpeechProvider(...)`. +Plugins також можуть реєструвати мовленнєвих провайдерів через `api.registerSpeechProvider(...)`. ```ts api.registerSpeechProvider({ @@ -422,15 +423,15 @@ api.registerSpeechProvider({ Примітки: -- Зберігайте політику TTS, резервне перемикання та доставку відповідей у ядрі. -- Використовуйте провайдерів мовлення для поведінки синтезу, що належить вендору. +- Залишайте політику TTS, резервний шлях і доставлення відповіді в ядрі. +- Використовуйте мовленнєвих провайдерів для поведінки синтезу, що належить вендору. - Застарілий вхід Microsoft `edge` нормалізується до id провайдера `microsoft`. -- Бажана модель володіння є компанієорієнтованою: один Plugin вендора може володіти - провайдерами тексту, мовлення, зображень і майбутніх медіа, коли OpenClaw додаватиме - ці контракти можливостей. +- Бажана модель володіння — орієнтована на компанію: один plugin вендора може володіти + текстовими, мовленнєвими, графічними та майбутніми медіапровайдерами, коли OpenClaw додаватиме ці + контракти можливостей. -Для розуміння зображень/аудіо/відео Plugin реєструють один типізований -провайдер розуміння медіа замість узагальненого набору ключ/значення: +Для розуміння зображень/аудіо/відео plugins реєструють одного типізованого +провайдера розуміння медіа замість узагальненого набору ключ/значення: ```ts api.registerMediaUnderstandingProvider({ @@ -444,16 +445,16 @@ api.registerMediaUnderstandingProvider({ Примітки: -- Зберігайте оркестрацію, резервне перемикання, конфігурацію та wiring каналів у ядрі. -- Зберігайте поведінку вендора в Plugin провайдера. -- Адитивне розширення має залишатися типізованим: нові необов’язкові методи, нові необов’язкові +- Залишайте оркестрацію, резервний шлях, конфігурацію та підключення каналів у ядрі. +- Залишайте поведінку вендора в plugin провайдера. +- Розширення шляхом додавання має залишатися типізованим: нові необов’язкові методи, нові необов’язкові поля результату, нові необов’язкові можливості. -- Генерація відео вже дотримується того самого шаблону: - - ядро володіє контрактом можливості та runtime helper-ом - - Plugin вендорів реєструють `api.registerVideoGenerationProvider(...)` - - Plugin функцій/каналів споживають `api.runtime.videoGeneration.*` +- Генерація відео вже наслідує той самий шаблон: + - ядро володіє контрактом можливості та runtime-helper-ом + - plugins вендорів реєструють `api.registerVideoGenerationProvider(...)` + - plugins функцій/каналів використовують `api.runtime.videoGeneration.*` -Для runtime helper-ів розуміння медіа Plugin можуть викликати: +Для runtime-helper-ів розуміння медіа plugins можуть викликати: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -468,27 +469,27 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -Для транскрипції аудіо Plugin можуть використовувати або runtime розуміння медіа, -або старіший псевдонім STT: +Для транскрибування аудіо plugins можуть використовувати або runtime +розуміння медіа, або старіший псевдонім STT: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, - // Optional when MIME cannot be inferred reliably: + // Необов’язково, коли MIME неможливо надійно визначити: mime: "audio/ogg", }); ``` Примітки: -- `api.runtime.mediaUnderstanding.*` є бажаною спільною поверхнею для +- `api.runtime.mediaUnderstanding.*` — це бажана спільна поверхня для розуміння зображень/аудіо/відео. -- Використовує конфігурацію аудіо розуміння медіа ядра (`tools.media.audio`) і порядок резервного перемикання провайдерів. -- Повертає `{ text: undefined }`, коли вихід транскрипції не створюється (наприклад, вхід пропущено/не підтримується). -- `api.runtime.stt.transcribeAudioFile(...)` лишається псевдонімом сумісності. +- Використовує конфігурацію аудіо розуміння медіа ядра (`tools.media.audio`) і порядок резервних шляхів провайдера. +- Повертає `{ text: undefined }`, коли вихід транскрибування не створюється (наприклад, для пропущеного/непідтримуваного вводу). +- `api.runtime.stt.transcribeAudioFile(...)` залишається як псевдонім сумісності. -Plugin також можуть запускати фонові підзапуски subagent через `api.runtime.subagent`: +Plugins також можуть запускати фонові виконання субагентів через `api.runtime.subagent`: ```ts const result = await api.runtime.subagent.run({ @@ -503,14 +504,14 @@ const result = await api.runtime.subagent.run({ Примітки: - `provider` і `model` — це необов’язкові перевизначення для окремого запуску, а не постійні зміни сесії. -- OpenClaw враховує ці поля перевизначення лише для довірених викликачів. -- Для запусків резервного перемикання, що належать Plugin, оператори мають явно ввімкнути `plugins.entries..subagent.allowModelOverride: true`. -- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені Plugin конкретними канонічними цільовими `provider/model`, або `"*"` для явного дозволу будь-якої цілі. -- Запуски subagent від недовірених Plugin також працюють, але запити перевизначення відхиляються замість тихого переходу до резервного варіанта. -- Сесії subagent, створені Plugin, позначаються id Plugin, який їх створив. Резервний варіант `api.runtime.subagent.deleteSession(...)` може видаляти лише такі сесії-власники; довільне видалення сесій усе ще вимагає запиту Gateway з областю admin. +- OpenClaw враховує ці поля перевизначення лише для довірених викликів. +- Для резервних запусків, що належать plugin, оператори мають явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. +- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені plugins конкретними канонічними цілями `provider/model`, або `"*"`, щоб явно дозволити будь-яку ціль. +- Запуски субагента з недовірених plugin усе ще працюють, але запити на перевизначення відхиляються замість тихого переходу на резервний шлях. +- Сесії субагентів, створені plugin, позначаються id plugin, що їх створив. Резервний шлях `api.runtime.subagent.deleteSession(...)` може видаляти лише ці сесії, що належать plugin; довільне видалення сесій, як і раніше, потребує запиту Gateway з областю дії адміністратора. -Для вебпошуку Plugin можуть споживати спільний runtime helper замість -прямого доступу до wiring інструментів агента: +Для вебпошуку plugins можуть використовувати спільний runtime-helper замість +звернення до підключення інструмента агента: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -526,14 +527,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -Plugin також можуть реєструвати провайдерів вебпошуку через +Plugins також можуть реєструвати провайдерів вебпошуку через `api.registerWebSearchProvider(...)`. Примітки: -- Зберігайте вибір провайдера, визначення облікових даних і спільну семантику запитів у ядрі. -- Використовуйте провайдерів вебпошуку для транспортів пошуку, специфічних для вендора. -- `api.runtime.webSearch.*` є бажаною спільною поверхнею для Plugin функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструмента агента. +- Залишайте вибір провайдера, визначення облікових даних і спільну семантику запитів у ядрі. +- Використовуйте провайдерів вебпошуку для специфічних транспортів пошуку вендора. +- `api.runtime.webSearch.*` — це бажана спільна поверхня для plugins функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструмента агента. ### `api.runtime.imageGeneration` @@ -548,12 +549,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`: створити зображення, використовуючи налаштований ланцюжок провайдерів генерації зображень. -- `listProviders(...)`: показати доступних провайдерів генерації зображень та їхні можливості. +- `generate(...)`: генерує зображення, використовуючи налаштований ланцюжок провайдерів генерації зображень. +- `listProviders(...)`: перелічує доступних провайдерів генерації зображень і їхні можливості. -## Маршрути Gateway HTTP +## HTTP-маршрути Gateway -Plugin можуть відкривати кінцеві точки HTTP через `api.registerHttpRoute(...)`. +Plugins можуть відкривати HTTP-ендпойнти через `api.registerHttpRoute(...)`. ```ts api.registerHttpRoute({ @@ -571,139 +572,140 @@ api.registerHttpRoute({ Поля маршруту: - `path`: шлях маршруту під HTTP-сервером gateway. -- `auth`: обов’язкове поле. Використовуйте `"gateway"`, щоб вимагати звичайну автентифікацію gateway, або `"plugin"` для автентифікації/перевірки Webhook, якими керує Plugin. -- `match`: необов’язкове поле. `"exact"` (типово) або `"prefix"`. -- `replaceExisting`: необов’язкове поле. Дає змогу тому самому Plugin замінити власну наявну реєстрацію маршруту. -- `handler`: повертайте `true`, коли маршрут обробив запит. +- `auth`: обов’язкове. Використовуйте `"gateway"`, щоб вимагати звичайну auth gateway, або `"plugin"` для auth, керованої plugin, / перевірки Webhook. +- `match`: необов’язкове. `"exact"` (типово) або `"prefix"`. +- `replaceExisting`: необов’язкове. Дозволяє тому самому plugin замінити власну наявну реєстрацію маршруту. +- `handler`: повертає `true`, коли маршрут обробив запит. Примітки: -- `api.registerHttpHandler(...)` видалено, і він спричинить помилку завантаження Plugin. Натомість використовуйте `api.registerHttpRoute(...)`. -- Маршрути Plugin мають явно оголошувати `auth`. -- Конфлікти точного `path + match` відхиляються, якщо не вказано `replaceExisting: true`, і один Plugin не може замінити маршрут іншого Plugin. -- Перекривні маршрути з різними рівнями `auth` відхиляються. Ланцюжки переходу `exact`/`prefix` мають бути лише в межах одного рівня auth. -- Маршрути `auth: "plugin"` **не** отримують автоматично runtime-області оператора. Вони призначені для Webhook-ів/перевірки підписів, якими керує Plugin, а не для привілейованих helper-викликів Gateway. -- Маршрути `auth: "gateway"` виконуються в межах runtime-області запиту Gateway, але ця область навмисно консервативна: - - bearer-автентифікація зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) тримає runtime-області маршруту Plugin закріпленими на `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` +- `api.registerHttpHandler(...)` було видалено, і це спричинить помилку завантаження plugin. Натомість використовуйте `api.registerHttpRoute(...)`. +- Маршрути plugin мають явно оголошувати `auth`. +- Конфлікти точного `path + match` відхиляються, якщо не задано `replaceExisting: true`, і один plugin не може замінити маршрут іншого plugin. +- Перекривні маршрути з різними рівнями `auth` відхиляються. Ланцюжки передачі керування `exact`/`prefix` мають залишатися лише в межах одного рівня auth. +- Маршрути `auth: "plugin"` **не** отримують автоматично області runtime оператора. Вони призначені для webhook-ів / перевірки підписів, керованих plugin, а не для привілейованих helper-викликів 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` лише тоді, коли цей заголовок явно присутній - - якщо `x-openclaw-scopes` відсутній у таких запитах маршруту Plugin з ідентичністю, runtime-область повертається до `operator.write` -- Практичне правило: не припускайте, що маршрут Plugin з автентифікацією gateway є неявною поверхнею admin. Якщо вашому маршруту потрібна поведінка лише для admin, вимагайте режим auth з ідентичністю та документуйте явний контракт заголовка `x-openclaw-scopes`. + - якщо `x-openclaw-scopes` відсутній у таких запитах маршрутів plugin з ідентичністю, область runtime повертається до `operator.write` +- Практичне правило: не припускайте, що маршрут plugin з auth gateway є неявною поверхнею адміністратора. Якщо вашому маршруту потрібна поведінка лише для адміністратора, вимагайте режим auth з ідентичністю й задокументуйте явний контракт заголовка `x-openclaw-scopes`. ## Шляхи імпорту Plugin SDK -Під час створення нових Plugin використовуйте вузькі підшляхи SDK замість -монолітного кореневого barrel `openclaw/plugin-sdk`. Основні підшляхи: +Під час створення нових plugins використовуйте вузькі підшляхи SDK замість +монолітного кореневого barrel `openclaw/plugin-sdk`. +Основні підшляхи: -| Підшлях | Призначення | -| ---------------------------------- | ------------------------------------------------ | -| `openclaw/plugin-sdk/plugin-entry` | Примітиви реєстрації Plugin | -| `openclaw/plugin-sdk/channel-core` | Helper-и входу/побудови каналу | -| `openclaw/plugin-sdk/core` | Загальні спільні helper-и та umbrella-контракт | -| `openclaw/plugin-sdk/config-schema`| Коренева схема Zod `openclaw.json` (`OpenClawSchema`) | +| Підшлях | Призначення | +| ---------------------------------- | -------------------------------------------------- | +| `openclaw/plugin-sdk/plugin-entry` | Примітиви реєстрації Plugin | +| `openclaw/plugin-sdk/channel-core` | Helper-и входу/побудови каналу | +| `openclaw/plugin-sdk/core` | Загальні спільні helper-и та umbrella-контракт | +| `openclaw/plugin-sdk/config-schema` | Коренева Zod-схема `openclaw.json` (`OpenClawSchema`) | -Plugin каналів вибирають із сімейства вузьких seam-ів — `channel-setup`, +Plugins каналів вибирають із сімейства вузьких швів — `channel-setup`, `setup-runtime`, `setup-adapter-runtime`, `setup-tools`, `channel-pairing`, `channel-contract`, `channel-feedback`, `channel-inbound`, `channel-lifecycle`, `channel-reply-pipeline`, `command-auth`, `secret-input`, `webhook-ingress`, -`channel-targets` і `channel-actions`. Поведінка схвалення має консолідуватися -навколо одного контракту `approvalCapability`, а не змішуватися через не пов’язані -поля Plugin. Див. [Plugin каналів](/uk/plugins/sdk-channel-plugins). +`channel-targets` і `channel-actions`. Поведінку погодження слід консолідувати +в одному контракті `approvalCapability`, а не змішувати між не пов’язаними +полями plugin. Див. [Plugins каналів](/uk/plugins/sdk-channel-plugins). -Runtime і helper-и конфігурації живуть у відповідних підшляхах `*-runtime` +Runtime- і config-helper-и розміщені у відповідних підшляхах `*-runtime` (`approval-runtime`, `config-runtime`, `infra-runtime`, `agent-runtime`, `lazy-runtime`, `directory-runtime`, `text-runtime`, `runtime-store` тощо). -`openclaw/plugin-sdk/channel-runtime` застарів — це shim сумісності для -старіших Plugin. Новий код має імпортувати вужчі загальні примітиви. +`openclaw/plugin-sdk/channel-runtime` є застарілим — це shim сумісності для +старіших plugins. Новий код має імпортувати натомість вужчі загальні примітиви. -Внутрішні точки входу репозиторію (для кореня пакета кожного вбудованого Plugin): +Внутрішні для репозиторію точки входу (для кореня пакета кожного вбудованого plugin): -- `index.js` — точка входу вбудованого Plugin +- `index.js` — точка входу вбудованого plugin - `api.js` — barrel helper-ів/типів - `runtime-api.js` — barrel лише для runtime -- `setup-entry.js` — точка входу Plugin для setup +- `setup-entry.js` — точка входу plugin для setup -Зовнішні Plugin мають імпортувати лише підшляхи `openclaw/plugin-sdk/*`. Ніколи -не імпортуйте `src/*` іншого пакета Plugin із ядра чи з іншого Plugin. -Точки входу, завантажені через facade, віддають перевагу активному snapshot-у конфігурації runtime, якщо він існує, -а потім переходять до визначеного файла конфігурації на диску. +Зовнішні plugins мають імпортувати лише підшляхи `openclaw/plugin-sdk/*`. Ніколи +не імпортуйте `src/*` іншого пакета plugin з ядра або з іншого plugin. +Точки входу, завантажені через facade, віддають перевагу активному знімку runtime-конфігурації, якщо він існує, +а потім повертаються до визначеного файлу конфігурації на диску. -Підшляхи для конкретних можливостей, такі як `image-generation`, `media-understanding` -і `speech`, існують, оскільки вбудовані Plugin використовують їх уже сьогодні. Вони не є -автоматично назавжди зафіксованими зовнішніми контрактами — перевіряйте відповідну -довідкову сторінку SDK, коли покладаєтеся на них. +Підшляхи, специфічні для можливостей, як-от `image-generation`, `media-understanding` +і `speech`, існують, оскільки вбудовані plugins уже використовують їх сьогодні. Вони не є +автоматично зовнішніми контрактами, замороженими на довгий строк — перевіряйте відповідну сторінку +довідки SDK, коли покладаєтесь на них. ## Схеми інструментів повідомлень -Plugin мають володіти внесками в схеми каналоспецифічного `describeMessageTool(...)` -для примітивів, відмінних від повідомлень, таких як реакції, прочитання та опитування. -Спільне подання надсилання має використовувати загальний контракт `MessagePresentation` -замість native-полів провайдера для кнопок, компонентів, блоків або карток. -Див. [Message Presentation](/uk/plugins/message-presentation), щоб ознайомитися з контрактом, -правилами резервного варіанта, зіставленням провайдерів і контрольним списком автора Plugin. +Plugins мають володіти внесками до схеми канально-специфічного `describeMessageTool(...)` +для немеседжевих примітивів, як-от реакції, прочитання та опитування. +Спільне представлення надсилання має використовувати загальний контракт `MessagePresentation` +замість native-полів кнопок, компонентів, блоків або карток конкретного провайдера. +Див. [Message Presentation](/uk/plugins/message-presentation) для контракту, +правил резервного шляху, мапування провайдерів і контрольного списку автора plugin. -Plugin, здатні надсилати, оголошують те, що вони можуть відтворювати, через можливості повідомлень: +Plugins із підтримкою надсилання оголошують, що саме вони можуть відобразити, через можливості повідомлень: -- `presentation` для семантичних блоків подання (`text`, `context`, `divider`, `buttons`, `select`) -- `delivery-pin` для запитів закріпленої доставки +- `presentation` для блоків семантичного представлення (`text`, `context`, `divider`, `buttons`, `select`) +- `delivery-pin` для запитів закріпленого доставлення -Ядро вирішує, чи відтворювати подання нативно, чи деградувати його до тексту. -Не відкривайте generic message tool через лазівки до native UI провайдера. -Застарілі helper-и SDK для старих native-схем лишаються експортованими для наявних -сторонніх Plugin, але нові Plugin не повинні їх використовувати. +Ядро вирішує, чи відображати представлення native-способом, чи деградувати його до тексту. +Не відкривайте шляхи обходу до native UI провайдера з загального інструмента повідомлень. +Застарілі helper-и SDK для старих native-схем залишаються експортованими для наявних +сторонніх plugins, але нові plugins не мають їх використовувати. -## Визначення цілей каналу +## Визначення цілі каналу -Plugin каналів мають володіти семантикою цілей, специфічною для каналу. Зберігайте спільний +Plugins каналів мають володіти канально-специфічною семантикою цілей. Залишайте спільний вихідний хост узагальненим і використовуйте поверхню messaging adapter для правил провайдера: -- `messaging.inferTargetChatType({ to })` вирішує, чи нормалізовану ціль - слід вважати `direct`, `group` чи `channel` до пошуку в каталозі. -- `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє ядру, чи - вхідні дані мають одразу перейти до визначення, схожого на id, замість пошуку в каталозі. -- `messaging.targetResolver.resolveTarget(...)` є резервним варіантом Plugin, коли - ядру потрібне фінальне визначення, що належить провайдеру, після нормалізації або після - промаху в каталозі. -- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою route сесії, специфічною для провайдера, - після того як ціль визначено. +- `messaging.inferTargetChatType({ to })` визначає, чи слід трактувати нормалізовану ціль + як `direct`, `group` або `channel` до пошуку в директорії. +- `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє ядру, чи має + вхідне значення одразу переходити до визначення id-подібної цілі замість пошуку в директорії. +- `messaging.targetResolver.resolveTarget(...)` — це резервний шлях plugin, коли + ядру потрібне остаточне визначення, що належить провайдеру, після нормалізації або + після промаху по директорії. +- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту вихідної сесії, + специфічною для провайдера, після того як ціль визначено. -Рекомендований розподіл: +Рекомендований поділ: -- Використовуйте `inferTargetChatType` для рішень щодо категорій, які мають прийматися до - пошуку peer/group. -- Використовуйте `looksLikeId` для перевірок на кшталт "вважати це явним/native id цілі". -- Використовуйте `resolveTarget` як резервний варіант нормалізації, специфічний для провайдера, а не для - широкого пошуку в каталозі. -- Зберігайте native-id провайдера, такі як chat id, thread id, JID, handle і room - id, усередині значень `target` або параметрів, специфічних для провайдера, а не в generic-полях SDK. +- Використовуйте `inferTargetChatType` для рішень щодо категорії, які мають ухвалюватися до + пошуку peers/groups. +- Використовуйте `looksLikeId` для перевірок на кшталт «трактувати це як явний/native id цілі». +- Використовуйте `resolveTarget` для резервного шляху нормалізації, специфічного для провайдера, а не для + широкого пошуку в директорії. +- Зберігайте native-id провайдера, як-от id чату, id потоку, JID, handles та room id, + всередині значень `target` або параметрів, специфічних для провайдера, а не в загальних полях SDK. -## Каталоги на основі конфігурації +## Директорії на основі конфігурації -Plugin, які виводять записи каталогу з конфігурації, мають зберігати цю логіку в -Plugin і повторно використовувати спільні helper-и з +Plugins, які отримують записи директорії з конфігурації, мають зберігати цю логіку в +plugin і повторно використовувати спільні helper-и з `openclaw/plugin-sdk/directory-runtime`. -Використовуйте це, коли каналу потрібні peer/group на основі конфігурації, такі як: +Використовуйте це, коли каналу потрібні peers/groups на основі конфігурації, наприклад: -- peer-и DM зі списку дозволених +- DM-peers, керовані allowlist - налаштовані мапи каналів/груп -- статичні резервні варіанти каталогу на рівні облікового запису +- статичні резервні шляхи директорії в межах облікового запису Спільні helper-и в `directory-runtime` обробляють лише загальні операції: - фільтрацію запитів -- застосування лімітів -- видалення дублікатів/helper-и нормалізації +- застосування ліміту +- helper-и дедуплікації/нормалізації - побудову `ChannelDirectoryEntry[]` Перевірка облікового запису та нормалізація id, специфічні для каналу, мають залишатися -в реалізації Plugin. +в реалізації plugin. ## Каталоги провайдерів -Plugin провайдерів можуть визначати каталоги моделей для inference через +Plugins провайдерів можуть визначати каталоги моделей для inference через `registerProvider({ catalog: { run(...) { ... } } })`. `catalog.run(...)` повертає ту саму форму, яку OpenClaw записує в @@ -712,57 +714,58 @@ Plugin провайдерів можуть визначати каталоги - `{ provider }` для одного запису провайдера - `{ providers }` для кількох записів провайдера -Використовуйте `catalog`, коли Plugin володіє id моделей, специфічними для провайдера, типовими -значеннями base URL або метаданими моделей, обмеженими автентифікацією. +Використовуйте `catalog`, коли plugin володіє специфічними для провайдера id моделей, типовими значеннями `base URL` +або метаданими моделей, захищеними auth. -`catalog.order` керує тим, коли каталог Plugin об’єднується відносно -вбудованих неявних провайдерів OpenClaw: +`catalog.order` визначає, коли каталог plugin зливається відносно вбудованих +неявних провайдерів OpenClaw: -- `simple`: звичайні провайдери на основі API-key або env -- `profile`: провайдери, які з’являються, коли існують профілі автентифікації -- `paired`: провайдери, які синтезують кілька пов’язаних записів провайдерів +- `simple`: звичайні провайдери з API-ключем або на основі env +- `profile`: провайдери, що з’являються, коли існують профілі auth +- `paired`: провайдери, які синтезують кілька пов’язаних записів провайдера - `late`: останній прохід, після інших неявних провайдерів -Пізніші провайдери перемагають у разі колізії ключів, тому Plugin можуть навмисно перевизначати +Пізніші провайдери перемагають у разі конфлікту ключів, тож plugins можуть навмисно перевизначати вбудований запис провайдера з тим самим id провайдера. Сумісність: -- `discovery` усе ще працює як застарілий псевдонім +- `discovery` і далі працює як застарілий псевдонім - якщо зареєстровано і `catalog`, і `discovery`, OpenClaw використовує `catalog` -## Інспекція каналу лише для читання +## Лише читання для перевірки каналу -Якщо ваш Plugin реєструє канал, віддавайте перевагу реалізації -`plugin.config.inspectAccount(cfg, accountId)` разом із `resolveAccount(...)`. +Якщо ваш plugin реєструє канал, віддавайте перевагу реалізації +`plugin.config.inspectAccount(cfg, accountId)` поруч із `resolveAccount(...)`. Чому: - `resolveAccount(...)` — це шлях runtime. Він може припускати, що облікові дані - повністю матеріалізовані, і швидко завершуватися з помилкою, коли потрібних секретів бракує. -- Шляхи команд лише для читання, такі як `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve` і потоки відновлення doctor/config - не повинні потребувати матеріалізації runtime-облікових даних лише для - опису конфігурації. + повністю матеріалізовані, і може швидко завершуватися з помилкою, коли обов’язкові секрети відсутні. +- Шляхи команд лише для читання, як-от `openclaw status`, `openclaw status --all`, + `openclaw channels status`, `openclaw channels resolve` та потоки + repair doctor/config, не повинні матеріалізовувати runtime-облікові дані лише для того, + щоб описати конфігурацію. Рекомендована поведінка `inspectAccount(...)`: -- Повертайте лише описовий стан облікового запису. -- Зберігайте `enabled` і `configured`. -- Включайте поля джерела/стану облікових даних, коли це доречно, наприклад: +- Повертає лише описовий стан облікового запису. +- Зберігає `enabled` і `configured`. +- За потреби включає поля джерела/статусу облікових даних, як-от: - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Вам не потрібно повертати сирі значення токенів лише для звітування про доступність у режимі лише читання. Повернення `tokenStatus: "available"` (і відповідного поля джерела) достатньо для команд на кшталт status. +- Не потрібно повертати сирі значення токенів лише для звітування про доступність у режимі лише читання. Для команд на кшталт status достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела). - Використовуйте `configured_unavailable`, коли облікові дані налаштовано через SecretRef, але вони недоступні в поточному шляху команди. -Це дає змогу командам лише для читання повідомляти "налаштовано, але недоступно в цьому шляху команди" замість аварійного завершення або помилкового повідомлення, що обліковий запис не налаштовано. +Це дає змогу командам лише для читання повідомляти «налаштовано, але недоступно в цьому шляху команди» +замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштовано. -## Пакетні pack-и +## Пакети пакетів -Каталог Plugin може містити `package.json` з `openclaw.extensions`: +Каталог plugin може містити `package.json` з `openclaw.extensions`: ```json { @@ -774,42 +777,42 @@ Plugin провайдерів можуть визначати каталоги } ``` -Кожен запис стає Plugin. Якщо pack містить кілька extensions, id Plugin +Кожен запис стає plugin. Якщо пакет перелічує кілька extensions, 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 через +Примітка щодо безпеки: `openclaw plugins install` встановлює залежності plugin через локальний для проєкту `npm install --omit=dev --ignore-scripts` (без lifecycle scripts, -без dev dependencies під час runtime), ігноруючи успадковані глобальні налаштування npm install. -Підтримуйте дерева залежностей Plugin "чистими JS/TS" і уникайте пакетів, яким потрібні -збірки `postinstall`. +без dev dependencies у runtime), ігноруючи успадковані глобальні налаштування npm install. +Підтримуйте дерева залежностей plugin «чистими JS/TS» і уникайте пакетів, яким потрібні +збірки через `postinstall`. Необов’язково: `openclaw.setupEntry` може вказувати на легкий модуль лише для setup. -Коли OpenClaw потребує поверхонь setup для вимкненого Plugin каналу або -коли Plugin каналу ввімкнено, але ще не налаштовано, він завантажує `setupEntry` -замість повної точки входу Plugin. Це робить запуск і setup легшими, -коли ваша основна точка входу Plugin також підключає інструменти, hooks або інший код лише для runtime. +Коли OpenClaw потребує поверхонь setup для вимкненого channel plugin, або +коли channel plugin увімкнений, але ще не налаштований, він завантажує `setupEntry` +замість повної точки входу plugin. Це робить запуск і setup легшими, +коли основна точка входу plugin також підключає інструменти, хуки або інший код лише для runtime. Необов’язково: `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -може перевести Plugin каналу на той самий шлях `setupEntry` під час -фази запуску gateway до `listen`, навіть коли канал уже налаштовано. +може перевести channel plugin на той самий шлях `setupEntry` під час +передслухової фази запуску gateway, навіть якщо канал уже налаштований. Використовуйте це лише тоді, коли `setupEntry` повністю покриває поверхню запуску, яка має існувати до того, як gateway почне слухати. На практиці це означає, що точка входу setup -має зареєструвати кожну можливість, що належить каналу, від якої залежить запуск, наприклад: +має реєструвати всі можливості, що належать каналу, від яких залежить запуск, наприклад: - саму реєстрацію каналу - будь-які HTTP-маршрути, які мають бути доступні до того, як gateway почне слухати -- будь-які методи gateway, інструменти або служби, які мають існувати в це саме вікно +- будь-які методи gateway, інструменти або сервіси, які мають існувати впродовж того самого вікна Якщо ваша повна точка входу все ще володіє будь-якою необхідною можливістю запуску, не вмикайте -цей прапорець. Залишайте Plugin на типовій поведінці й дозвольте OpenClaw завантажити +цей прапорець. Залиште plugin на типовій поведінці й дозвольте OpenClaw завантажувати повну точку входу під час запуску. Вбудовані канали також можуть публікувати helper-и поверхні контракту лише для setup, які ядро @@ -820,20 +823,22 @@ Plugin провайдерів можуть визначати каталоги - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -Ядро використовує цю поверхню, коли йому потрібно підвищити застарілу конфігурацію -каналу з одним обліковим записом до `channels..accounts.*` без завантаження повної точки входу Plugin. -Matrix — поточний вбудований приклад: він переносить лише auth/bootstrap-ключі в -іменований підвищений обліковий запис, коли іменовані облікові записи вже існують, і може -зберігати налаштований неканонічний ключ типового облікового запису замість того, щоб завжди створювати +Ядро використовує цю поверхню, коли йому потрібно просунути застарілу +конфігурацію однокористувацького каналу в `channels..accounts.*` без +завантаження повної точки входу plugin. Поточний вбудований приклад — Matrix: +він переносить у просунутий іменований обліковий запис лише ключі auth/bootstrap, +коли іменовані облікові записи вже існують, і може зберегти налаштований +неканонічний ключ облікового запису за замовчуванням замість того, щоб завжди створювати `accounts.default`. -Ці адаптери patch setup зберігають ліниве виявлення поверхні контракту вбудованих пакетів. -Час імпорту лишається малим; поверхня просування завантажується лише під час першого використання, а не через повторний вхід у запуск вбудованого каналу під час імпорту модуля. +Ці адаптери patch setup зберігають ліниве виявлення поверхні контракту для вбудованих компонентів. Час +імпорту залишається малим; поверхня просування завантажується лише під час першого використання +замість повторного входу в запуск вбудованого каналу під час імпорту модуля. -Коли ці поверхні запуску включають Gateway RPC methods, зберігайте їх на -префіксі, специфічному для Plugin. Простори назв admin ядра (`config.*`, +Коли ці поверхні запуску включають Gateway RPC-методи, тримайте їх на +префіксі, специфічному для plugin. Простори імен адміністратора ядра (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди визначаються -як `operator.admin`, навіть якщо Plugin запитує вужчу область. +як `operator.admin`, навіть якщо plugin запитує вужчу область. Приклад: @@ -852,8 +857,8 @@ Matrix — поточний вбудований приклад: він пере ### Метадані каталогу каналу -Plugin каналів можуть оголошувати метадані setup/discovery через `openclaw.channel` і -підказки щодо встановлення через `openclaw.install`. Це дозволяє ядру не містити даних каталогу. +Plugins каналів можуть оголошувати метадані setup/discovery через `openclaw.channel` та +підказки встановлення через `openclaw.install`. Це дозволяє не зберігати дані в каталозі ядра. Приклад: @@ -883,20 +888,20 @@ Plugin каналів можуть оголошувати метадані setup Корисні поля `openclaw.channel` понад мінімальний приклад: -- `detailLabel`: вторинна мітка для багатших поверхонь каталогу/status +- `detailLabel`: вторинна мітка для багатших поверхонь каталогу/статусу - `docsLabel`: перевизначення тексту посилання для посилання на документацію -- `preferOver`: id Plugin/каналів нижчого пріоритету, які цей запис каталогу має випереджати -- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: засоби керування текстом поверхні вибору -- `markdownCapable`: позначає канал як сумісний із markdown для рішень форматування вихідних даних +- `preferOver`: id plugin/каналу з нижчим пріоритетом, які цей запис каталогу має випереджати +- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: елементи керування текстом поверхні вибору +- `markdownCapable`: позначає канал як сумісний з markdown для рішень щодо форматування вихідних повідомлень - `exposure.configured`: приховує канал із поверхонь списку налаштованих каналів, коли встановлено `false` -- `exposure.setup`: приховує канал із інтерактивних picker-ів setup/configure, коли встановлено `false` -- `exposure.docs`: позначає канал як внутрішній/приватний для поверхонь навігації документації -- `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; віддавайте перевагу `exposure` -- `quickstartAllowFrom`: додає канал до стандартного потоку quickstart `allowFrom` +- `exposure.setup`: приховує канал з інтерактивних засобів вибору setup/configure, коли встановлено `false` +- `exposure.docs`: позначає канал як внутрішній/приватний для поверхонь навігації документацією +- `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; надавайте перевагу `exposure` +- `quickstartAllowFrom`: підключає канал до стандартного потоку quickstart `allowFrom` - `forceAccountBinding`: вимагає явної прив’язки облікового запису, навіть коли існує лише один обліковий запис -- `preferSessionLookupForAnnounceTarget`: віддає перевагу пошуку сесії під час визначення цілей announce +- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення цілей announce -OpenClaw також може об’єднувати **зовнішні каталоги каналів** (наприклад, експорт +OpenClaw також може зливати **зовнішні каталоги каналів** (наприклад, експорт реєстру MPM). Помістіть JSON-файл в одне з таких місць: - `~/.openclaw/mpm/plugins.json` @@ -904,41 +909,45 @@ OpenClaw також може об’єднувати **зовнішні ката - `~/.openclaw/plugins/catalog.json` Або вкажіть `OPENCLAW_PLUGIN_CATALOG_PATHS` (або `OPENCLAW_MPM_CATALOG_PATHS`) на -один або кілька JSON-файлів (розділених комами/крапками з комою/`PATH`). Кожен файл має +один чи кілька JSON-файлів (розділених комами/крапками з комою/через `PATH`). Кожен файл має містити `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. Парсер також приймає `"packages"` або `"plugins"` як застарілі псевдоніми для ключа `"entries"`. Згенеровані записи каталогу каналів і записи каталогу встановлення провайдерів відкривають -нормалізовані факти джерела встановлення поруч із сирим блоком `openclaw.install`. Нормалізовані факти -визначають, чи є npm spec точною версією чи плаваючим селектором, чи присутні -очікувані метадані цілісності, і чи доступний також локальний шлях до джерела. Коли ідентичність каталогу/пакета відома, нормалізовані факти попереджають, якщо розібране ім’я npm-пакета відхиляється від цієї ідентичності. -Вони також попереджають, коли `defaultChoice` є некоректним або вказує на джерело, яке -недоступне, і коли метадані цілісності npm присутні без коректного джерела npm. -Споживачі мають розглядати `installSource` як адитивне необов’язкове поле, щоб -записи, створені вручну, і shim-и каталогу не мусили його синтезувати. -Це дає змогу onboarding і діагностиці пояснювати стан площини джерела без -імпорту runtime Plugin. +нормалізовані факти про джерело встановлення поруч із сирим блоком `openclaw.install`. Ці +нормалізовані факти визначають, чи є npm-специфікація точною версією або плаваючим селектором, +чи присутні очікувані метадані цілісності та чи доступний також локальний шлях джерела. +Коли відома ідентичність каталогу/пакета, нормалізовані факти попереджають, якщо розібране ім’я npm-пакета відхиляється від цієї ідентичності. +Вони також попереджають, коли `defaultChoice` є недійсним або вказує на джерело, яке +недоступне, а також коли метадані цілісності npm присутні без дійсного npm- +джерела. Споживачі мають ставитися до `installSource` як до додаткового необов’язкового поля, щоб +вручну створені записи й shim-и каталогів не мусили його синтезувати. +Це дає змогу онбордингу та діагностиці пояснювати стан площини джерела без +імпорту runtime plugin. -Офіційні зовнішні записи npm мають віддавати перевагу точному `npmSpec` плюс -`expectedIntegrity`. Голі імена пакетів і dist-tag-и все ще працюють для -сумісності, але показують попередження площини джерела, щоб каталог міг -рухатися до інсталяцій із фіксованими версіями та перевіркою цілісності без порушення роботи наявних Plugin. -Коли onboarding встановлює з локального шляху каталогу, він записує керований запис індексу Plugin -із `source: "path"` і `sourcePath`, відносним до робочого простору, коли це можливо. Абсолютний робочий шлях завантаження залишається в -`plugins.load.paths`; запис інсталяції уникає дублювання локальних шляхів робочої станції -в довготривалій конфігурації. Це дозволяє діагностиці площини джерела бачити локальні інсталяції розробки без додавання другої поверхні розкриття сирого шляху файлової системи. -Збережений індекс Plugin `plugins/installs.json` є джерелом істини для джерела встановлення і може бути оновлений без завантаження runtime-модулів Plugin. -Його мапа `installRecords` є стійкою, навіть коли маніфест Plugin відсутній або -некоректний; його масив `plugins` — це відтворюване подання маніфесту/кешу. +Офіційні зовнішні npm-записи мають надавати перевагу точному `npmSpec` разом із +`expectedIntegrity`. Голі назви пакетів і dist-tag-и все ще працюють для +сумісності, але вони показують попередження площини джерела, щоб каталог міг рухатися +до pinned- та integrity-checked-встановлень без порушення роботи наявних plugins. +Коли онбординг встановлює з локального шляху каталогу, він записує керований plugin +у запис індексу plugin із `source: "path"` і workspace-відносним +`sourcePath`, коли це можливо. Абсолютний робочий шлях завантаження залишається в +`plugins.load.paths`; запис встановлення уникає дублювання шляхів локальної робочої станції +в довготривалій конфігурації. Це зберігає видимість локальних розробницьких встановлень для +діагностики площини джерела без додавання другої поверхні розкриття сирих шляхів файлової системи. +Збережений індекс plugin `plugins/installs.json` є джерелом істини для встановлення й може +оновлюватися без завантаження runtime-модулів plugin. +Його мапа `installRecords` є довговічною, навіть коли маніфест plugin відсутній або +недійсний; його масив `plugins` — це перебудовуваний вигляд маніфесту/кешу. -## Plugin engine контексту +## Plugins рушія контексту -Plugin engine контексту володіють оркестрацією контексту сесії для поглинання, складання -та Compaction. Реєструйте їх зі свого Plugin через -`api.registerContextEngine(id, factory)`, а потім вибирайте активний engine через +Plugins рушія контексту володіють оркестрацією контексту сесії для ingеst, assembly +і Compaction. Реєструйте їх зі свого plugin через +`api.registerContextEngine(id, factory)`, а потім вибирайте активний рушій через `plugins.slots.contextEngine`. -Використовуйте це, коли вашому Plugin потрібно замінити або розширити типовий -конвеєр контексту, а не просто додати пошук у пам’яті або hooks. +Використовуйте це, коли вашому plugin потрібно замінити або розширити типовий +конвеєр контексту, а не просто додати пошук у пам’яті чи хуки. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -966,7 +975,7 @@ export default function (api) { } ``` -Якщо ваш engine **не** володіє алгоритмом Compaction, залиште `compact()` +Якщо ваш рушій **не** володіє алгоритмом Compaction, залиште `compact()` реалізованим і явно делегуйте його: ```ts @@ -1004,60 +1013,60 @@ export default function (api) { ## Додавання нової можливості -Коли Plugin потребує поведінки, яка не вписується в поточний API, не обходьте -систему Plugin через приватне проникнення всередину. Додайте відсутню можливість. +Коли plugin потрібна поведінка, яка не вписується в поточний API, не обходьте +систему plugin через приватне пряме звернення. Додайте відсутню можливість. Рекомендована послідовність: 1. визначте контракт ядра - Вирішіть, якою спільною поведінкою має володіти ядро: політикою, резервним перемиканням, об’єднанням конфігурації, - життєвим циклом, семантикою для каналів і формою runtime helper-а. -2. додайте типізовані поверхні реєстрації/runtime Plugin + Вирішіть, якою спільною поведінкою має володіти ядро: політикою, резервним шляхом, злиттям конфігурації, + життєвим циклом, семантикою для каналів і формою runtime-helper-а. +2. додайте типізовані поверхні реєстрації/runtime для plugin Розширте `OpenClawPluginApi` та/або `api.runtime` найменшою корисною типізованою поверхнею можливості. 3. підключіть ядро + споживачів каналів/функцій - Канали та Plugin функцій мають споживати нову можливість через ядро, - а не імпортувати реалізацію вендора безпосередньо. -4. зареєструйте реалізації вендора - Потім Plugin вендорів реєструють свої backend-и щодо цієї можливості. + Канали та plugins функцій мають використовувати нову можливість через ядро, + а не імпортувати реалізацію вендора напряму. +4. зареєструйте реалізації вендорів + Потім plugins вендорів реєструють свої бекенди для цієї можливості. 5. додайте покриття контракту - Додайте тести, щоб володіння та форма реєстрації залишалися явними з часом. + Додайте тести, щоб з часом володіння та форма реєстрації залишалися явними. -Саме так OpenClaw лишається цілеспрямованим, не стаючи жорстко прив’язаним до +Саме так OpenClaw залишається думкоцентричним, не стаючи жорстко прив’язаним до світогляду одного провайдера. Див. [Кулінарну книгу можливостей](/uk/plugins/architecture), -щоб побачити конкретний контрольний список файлів і приклад реалізації. +щоб отримати конкретний перелік файлів і розгорнутий приклад. ### Контрольний список можливості -Коли ви додаєте нову можливість, реалізація зазвичай має зачіпати такі -поверхні разом: +Коли ви додаєте нову можливість, реалізація зазвичай має разом зачіпати такі +поверхні: -- типи контрактів ядра в `src//types.ts` -- виконавець/helper runtime ядра в `src//runtime.ts` -- поверхню реєстрації API Plugin у `src/plugins/types.ts` -- wiring реєстру Plugin у `src/plugins/registry.ts` -- runtime-експозицію Plugin у `src/plugins/runtime/*`, коли Plugin функцій/каналів - мають її споживати -- helper-и capture/test у `src/test-utils/plugin-registration.ts` -- перевірки володіння/контракту в `src/plugins/contracts/registry.ts` -- документацію для операторів/Plugin у `docs/` +- типи контракту ядра в `src//types.ts` +- runner/runtime-helper ядра в `src//runtime.ts` +- поверхню реєстрації API plugin в `src/plugins/types.ts` +- підключення реєстру plugin в `src/plugins/registry.ts` +- відкриття runtime plugin в `src/plugins/runtime/*`, коли plugins функцій/каналів + мають її використовувати +- helper-и capture/test в `src/test-utils/plugin-registration.ts` +- твердження володіння/контракту в `src/plugins/contracts/registry.ts` +- документацію для операторів/plugin у `docs/` -Якщо однієї з цих поверхонь бракує, це зазвичай ознака того, що можливість -ще не повністю інтегровано. +Якщо одна з цих поверхонь відсутня, це зазвичай ознака того, що можливість +ще не повністю інтегрована. ### Шаблон можливості Мінімальний шаблон: ```ts -// core contract +// контракт ядра export type VideoGenerationProviderPlugin = { id: string; label: string; generateVideo: (req: VideoGenerationRequest) => Promise; }; -// plugin API +// API plugin api.registerVideoGenerationProvider({ id: "openai", label: "OpenAI", @@ -1066,14 +1075,14 @@ api.registerVideoGenerationProvider({ }, }); -// shared runtime helper for feature/channel plugins +// спільний runtime-helper для plugins функцій/каналів const clip = await api.runtime.videoGeneration.generate({ prompt: "Show the robot walking through the lab.", cfg, }); ``` -Шаблон контрактного тесту: +Шаблон тесту контракту: ```ts expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); @@ -1082,13 +1091,13 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Це зберігає правило простим: - ядро володіє контрактом можливості + оркестрацією -- Plugin вендорів володіють реалізаціями вендорів -- Plugin функцій/каналів споживають runtime helper-и -- контрактні тести зберігають володіння явним +- plugins вендорів володіють реалізаціями вендорів +- plugins функцій/каналів використовують runtime-helper-и +- тести контракту зберігають явність володіння ## Пов’язане -- [Архітектура Plugin](/uk/plugins/architecture) — публічна модель можливостей і форми +- [Архітектура Plugin](/uk/plugins/architecture) — публічна модель і форми можливостей - [Підшляхи Plugin SDK](/uk/plugins/sdk-subpaths) - [Налаштування Plugin SDK](/uk/plugins/sdk-setup) -- [Створення Plugin](/uk/plugins/building-plugins) +- [Створення plugins](/uk/plugins/building-plugins) diff --git a/docs/uk/plugins/architecture.md b/docs/uk/plugins/architecture.md index e93a2b254..0d1ead59e 100644 --- a/docs/uk/plugins/architecture.md +++ b/docs/uk/plugins/architecture.md @@ -1,51 +1,51 @@ --- read_when: - - Створення або налагодження рідних Plugin OpenClaw + - Збирання або налагодження нативних Plugin OpenClaw - Розуміння моделі можливостей Plugin або меж володіння - Робота над конвеєром завантаження Plugin або реєстром - - Реалізація runtime-хуків провайдера або плагінів каналів + - Реалізація гачків середовища виконання постачальника або Plugin каналів sidebarTitle: Internals -summary: 'Внутрішня будова Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби runtime' -title: Внутрішня будова Plugin +summary: 'Внутрішні компоненти Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби середовища виконання' +title: Внутрішні компоненти Plugin x-i18n: - generated_at: "2026-04-27T12:52:39Z" + generated_at: "2026-04-27T16:06:50Z" model: gpt-5.4 provider: openai - source_hash: bf11e7e9098283f5a489e9843c338ef235748663580dfeaef62f6f6766b55621 + source_hash: 846b3ec4ddd38b87c7b4f5e039556373075d058013ed568175e8fd1b6de2aa4d source_path: plugins/architecture.md workflow: 15 --- -Це **поглиблений архітектурний довідник** для системи Plugin в OpenClaw. Для практичних посібників почніть з однієї з наведених нижче спеціалізованих сторінок. +Це **поглиблене архітектурне довідкове пояснення** системи Plugin в OpenClaw. Для практичних інструкцій почніть з однієї з наведених нижче спеціалізованих сторінок. - - Посібник для кінцевих користувачів із додавання, увімкнення й усунення несправностей плагінів. + + Посібник для кінцевих користувачів із додавання, увімкнення та усунення проблем із Plugin. - - Перший навчальний приклад плагіна з найменшим робочим manifest. + + Навчальний посібник зі створення першого Plugin з найменшим працездатним маніфестом. - - Створення плагіна каналу обміну повідомленнями. + + Створіть Plugin каналу обміну повідомленнями. - - Створення плагіна провайдера моделей. + + Створіть Plugin постачальника моделей. - Довідник з import map і API реєстрації. + Карта імпорту та довідник API реєстрації. ## Публічна модель можливостей -Можливості — це публічна модель **рідних плагінів** усередині OpenClaw. Кожен рідний Plugin OpenClaw реєструється щодо одного або кількох типів можливостей: +Можливості — це публічна модель **нативних Plugin** усередині OpenClaw. Кожен нативний Plugin OpenClaw реєструється для одного або кількох типів можливостей: -| Можливість | Метод реєстрації | Приклади плагінів | +| Можливість | Метод реєстрації | Приклади Plugin | | --------------------- | ---------------------------------------------- | ------------------------------------ | -| Текстовий inference | `api.registerProvider(...)` | `openai`, `anthropic` | -| CLI-бекенд inference | `api.registerCliBackend(...)` | `openai`, `anthropic` | +| Текстовий висновок | `api.registerProvider(...)` | `openai`, `anthropic` | +| Backend висновку CLI | `api.registerCliBackend(...)` | `openai`, `anthropic` | | Мовлення | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | -| Транскрибування в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | +| Транскрипція в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | | Голос у реальному часі | `api.registerRealtimeVoiceProvider(...)` | `openai` | | Розуміння медіа | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | | Генерація зображень | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | @@ -53,152 +53,156 @@ x-i18n: | Генерація відео | `api.registerVideoGenerationProvider(...)` | `qwen` | | Отримання вебданих | `api.registerWebFetchProvider(...)` | `firecrawl` | | Вебпошук | `api.registerWebSearchProvider(...)` | `google` | -| Канал / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | +| Канал / повідомлення | `api.registerChannel(...)` | `msteams`, `matrix` | | Виявлення Gateway | `api.registerGatewayDiscoveryService(...)` | `bonjour` | -Плагін, який не реєструє жодної можливості, але надає хуки, інструменти, сервіси виявлення або фонові сервіси, є **застарілим плагіном лише з хуками**. Цей шаблон усе ще повністю підтримується. +Plugin, який реєструє нуль можливостей, але надає hooks, інструменти, служби виявлення або фонові служби, є **застарілим Plugin лише з hooks**. Цей шаблон усе ще повністю підтримується. ### Позиція щодо зовнішньої сумісності -Модель можливостей уже впроваджена в core і використовується сьогодні вбудованими/рідними плагінами, але сумісність зовнішніх плагінів усе ще потребує вищої планки, ніж «експортовано, отже, заморожено». +Модель можливостей уже впроваджена в core і сьогодні використовується вбудованими/нативними Plugin, але сумісність із зовнішніми Plugin усе ще потребує суворішого критерію, ніж «якщо це експортується, значить це зафіксовано». -| Ситуація з плагіном | Рекомендація | -| ---------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| Наявні зовнішні плагіни | Підтримуйте роботу інтеграцій на основі хуків; це базовий рівень сумісності. | -| Нові вбудовані/рідні плагіни | Віддавайте перевагу явній реєстрації можливостей замість vendor-specific reach-ins або нових дизайнів лише з хуками. | -| Зовнішні плагіни, що переходять на реєстрацію можливостей | Дозволено, але вважайте допоміжні поверхні, специфічні для можливостей, такими, що еволюціонують, якщо документація не позначає їх як стабільні. | +| Ситуація з Plugin | Рекомендація | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| Наявні зовнішні Plugin | Підтримуйте працездатність інтеграцій на основі hooks; це базовий рівень сумісності. | +| Нові вбудовані/нативні Plugin | Надавайте перевагу явній реєстрації можливостей замість специфічних для постачальника втручань або нових дизайнів лише з hooks. | +| Зовнішні Plugin, що переходять на реєстрацію можливостей | Дозволено, але вважайте допоміжні поверхні для конкретних можливостей такими, що ще розвиваються, якщо документація не позначає їх як стабільні. | -Реєстрація можливостей — це бажаний напрям. Застарілі хуки залишаються найбезпечнішим шляхом без зламів для зовнішніх плагінів під час переходу. Не всі експортовані допоміжні підшляхи однакові — надавайте перевагу вузьким документованим контрактам замість випадкових експортів допоміжних засобів. +Реєстрація можливостей — це бажаний напрямок. Застарілі hooks залишаються найбезпечнішим шляхом без порушення сумісності для зовнішніх Plugin під час переходу. Експортовані допоміжні підшляхи не всі однакові — надавайте перевагу вузьким задокументованим контрактам замість випадкових експортів допоміжних засобів. -### Форми плагінів +### Форми Plugin -OpenClaw класифікує кожен завантажений Plugin за формою на основі його фактичної поведінки реєстрації (а не лише статичних метаданих): +OpenClaw класифікує кожен завантажений Plugin за формою на основі його фактичної поведінки під час реєстрації (а не лише статичних метаданих): - Реєструє рівно один тип можливості (наприклад, плагін лише провайдера, як-от `mistral`). + Реєструє рівно один тип можливості (наприклад, Plugin лише постачальника, як-от `mistral`). - Реєструє кілька типів можливостей (наприклад, `openai` володіє текстовим inference, мовленням, розумінням медіа та генерацією зображень). + Реєструє кілька типів можливостей (наприклад, `openai` володіє текстовим висновком, мовленням, розумінням медіа та генерацією зображень). - Реєструє лише хуки (типізовані або власні), без можливостей, інструментів, команд чи сервісів. + Реєструє лише hooks (типізовані або користувацькі), без можливостей, інструментів, команд чи служб. - Реєструє інструменти, команди, сервіси або маршрути, але не можливості. + Реєструє інструменти, команди, служби або маршрути, але не можливості. -Використовуйте `openclaw plugins inspect `, щоб побачити форму плагіна та розподіл можливостей. Докладніше див. у [Довіднику CLI](/uk/cli/plugins#inspect). +Використовуйте `openclaw plugins inspect `, щоб побачити форму Plugin і розподіл можливостей. Докладніше див. у [довіднику CLI](/uk/cli/plugins#inspect). -### Застарілі хуки +### Застарілі hooks -Хук `before_agent_start` залишається підтримуваним як шлях сумісності для плагінів лише з хуками. Від нього досі залежать застарілі реальні плагіни. +Hook `before_agent_start` залишається підтримуваним як шлях сумісності для Plugin лише з hooks. Реальні застарілі Plugin досі від нього залежать. -Напрям: +Напрямок: -- зберігати його працездатним +- зберігати його працездатність - документувати його як застарілий -- надавати перевагу `before_model_resolve` для роботи з перевизначенням моделі/провайдера -- надавати перевагу `before_prompt_build` для зміни промптів -- видаляти лише після того, як реальне використання зменшиться і покриття фікстурами доведе безпечність міграції +- для перевизначення моделі/постачальника надавати перевагу `before_model_resolve` +- для змінювання prompt надавати перевагу `before_prompt_build` +- видаляти лише після зниження реального використання й після того, як покриття фікстурами доведе безпечність міграції ### Сигнали сумісності -Коли ви запускаєте `openclaw doctor` або `openclaw plugins inspect `, ви можете побачити одну з таких міток: +Коли ви запускаєте `openclaw doctor` або `openclaw plugins inspect `, ви можете побачити одну з таких позначок: -| Сигнал | Значення | -| ------------------------ | ------------------------------------------------------------ | -| **config valid** | Конфігурація коректно парситься, а плагіни успішно розв’язуються | -| **compatibility advisory** | Плагін використовує підтримуваний, але старіший шаблон (наприклад, `hook-only`) | -| **legacy warning** | Плагін використовує `before_agent_start`, який є застарілим | -| **hard error** | Конфігурація невалідна або плагін не вдалося завантажити | +| Сигнал | Значення | +| -------------------------- | ---------------------------------------------------------- | +| **config valid** | Конфігурація коректно розбирається, і Plugin успішно визначаються | +| **compatibility advisory** | Plugin використовує підтримуваний, але старіший шаблон (наприклад, `hook-only`) | +| **legacy warning** | Plugin використовує `before_agent_start`, який є застарілим | +| **hard error** | Конфігурація некоректна або Plugin не вдалося завантажити | -Ні `hook-only`, ні `before_agent_start` сьогодні не зламають ваш плагін: `hook-only` є лише рекомендаційним сигналом, а `before_agent_start` викликає лише попередження. Ці сигнали також з’являються в `openclaw status --all` і `openclaw plugins doctor`. +Ні `hook-only`, ні `before_agent_start` сьогодні не зламають ваш Plugin: `hook-only` є рекомендаційним сигналом, а `before_agent_start` лише викликає попередження. Ці сигнали також з’являються в `openclaw status --all` і `openclaw plugins doctor`. ## Огляд архітектури Система Plugin OpenClaw має чотири шари: - - OpenClaw знаходить кандидатів у плагіни у налаштованих шляхах, коренях робочих просторів, глобальних коренях плагінів і серед вбудованих плагінів. Виявлення спочатку читає рідні manifest `openclaw.plugin.json` разом із підтримуваними manifest пакетів. + + OpenClaw знаходить потенційні Plugin у налаштованих шляхах, коренях робочого простору, глобальних коренях Plugin і серед вбудованих Plugin. Виявлення спочатку читає нативні маніфести `openclaw.plugin.json` разом із підтримуваними маніфестами пакунків. - Core вирішує, чи виявлений плагін увімкнено, вимкнено, заблоковано або вибрано для ексклюзивного слота, такого як memory. + Core визначає, чи знайдений Plugin увімкнений, вимкнений, заблокований або вибраний для ексклюзивного слота, такого як пам’ять. - - Рідні Plugin OpenClaw завантажуються в межах процесу через jiti і реєструють можливості в центральному реєстрі. Сумісні пакети нормалізуються в записи реєстру без імпорту коду runtime. + + Нативні Plugin OpenClaw завантажуються в межах процесу через jiti та реєструють можливості в центральному реєстрі. Сумісні пакунки нормалізуються в записи реєстру без імпорту коду середовища виконання. - - Решта OpenClaw читає реєстр, щоб надавати інструменти, канали, налаштування провайдерів, хуки, HTTP-маршрути, команди CLI та сервіси. + + Решта OpenClaw читає реєстр, щоб надавати інструменти, канали, налаштування постачальників, hooks, HTTP-маршрути, команди CLI та служби. -Зокрема для CLI плагінів, виявлення кореневих команд розділено на дві фази: +Саме для CLI Plugin виявлення кореневих команд поділено на дві фази: -- метадані на етапі парсингу надходять із `registerCli(..., { descriptors: [...] })` -- реальний модуль CLI плагіна може залишатися lazy і реєструватися під час першого виклику +- метадані на етапі розбору надходять із `registerCli(..., { descriptors: [...] })` +- справжній модуль CLI Plugin може залишатися лінивим і реєструватися під час першого виклику -Це дає змогу зберігати CLI-код, яким володіє плагін, усередині плагіна, водночас дозволяючи OpenClaw резервувати імена кореневих команд до парсингу. +Це дозволяє тримати код CLI, що належить Plugin, усередині самого Plugin, водночас даючи OpenClaw можливість резервувати імена кореневих команд ще до розбору. Важлива межа проєктування: -- валідація manifest/config має працювати на основі **метаданих manifest/schema** без виконання коду плагіна -- виявлення рідних можливостей може завантажувати код точки входу довіреного плагіна для побудови неактивуючого знімка реєстру -- нативна поведінка runtime походить із шляху `register(api)` модуля плагіна з `api.registrationMode === "full"` +- валідація маніфесту/конфігурації має працювати на основі **метаданих маніфесту/схеми** без виконання коду Plugin +- виявлення нативних можливостей може завантажувати код входу довіреного Plugin, щоб побудувати знімок реєстру без активації +- нативна поведінка середовища виконання походить із шляху `register(api)` модуля Plugin, де `api.registrationMode === "full"` -Такий поділ дає OpenClaw змогу перевіряти конфігурацію, пояснювати відсутні/вимкнені плагіни й будувати підказки UI/schema до того, як повний runtime стане активним. +Такий поділ дозволяє OpenClaw перевіряти конфігурацію, пояснювати відсутні/вимкнені Plugin і будувати підказки для UI/схеми до повної активації середовища виконання. -### Таблиця пошуку плагінів +### Знімок метаданих Plugin і таблиця пошуку -Під час запуску Gateway будує `PluginLookUpTable` з індексу встановлених плагінів і реєстру manifest для поточного знімка конфігурації. Таблиця є лише метаданими: вона зберігає id плагінів, записи manifest, діагностику, мапи власників, нормалізатор id плагінів і стартовий план плагінів. Вона не містить завантажених модулів плагінів, SDK провайдерів, вмісту пакетів або експортів runtime. +Під час запуску Gateway будується один `PluginMetadataSnapshot` для поточного знімка конфігурації. Цей знімок містить лише метадані: індекс установлених Plugin, реєстр маніфестів, діагностику маніфестів, карти власників, нормалізатор ідентифікаторів Plugin і записи маніфестів. Він не містить завантажених модулів Plugin, SDK постачальників, вмісту пакунків або експортів середовища виконання. -Таблиця пошуку тримає повторні рішення під час запуску на швидкому шляху: +Валідація конфігурації, що враховує Plugin, автоматичне ввімкнення під час запуску та bootstrap Plugin у Gateway використовують цей знімок замість того, щоб окремо перебудовувати метадані маніфестів/індексів. `PluginLookUpTable` походить із того самого знімка й додає план запуску Plugin для поточної конфігурації середовища виконання. -- володіння каналами -- відкладений запуск каналів -- стартові id плагінів -- володіння провайдерами та CLI-бекендами -- володіння setup provider, aliases команд, провайдерами каталогу моделей і контрактами manifest +Знімок і таблиця пошуку тримають повторювані рішення під час запуску на швидкому шляху: -Межею безпеки є заміна знімка, а не мутація. Перебудовуйте таблицю, коли змінюються конфігурація, інвентар плагінів, записи встановлення або політика збереженого індексу. Не сприймайте її як широкий змінний глобальний реєстр і не зберігайте необмежену кількість історичних таблиць. Завантаження плагінів runtime залишається окремим від метаданих таблиці пошуку, щоб застарілий runtime-стан не міг сховатися за кешем метаданих. +- володіння каналом +- відкладений запуск каналу +- ідентифікатори Plugin для запуску +- володіння постачальником і backend CLI +- володіння setup provider, псевдонімом команди, постачальником каталогу моделей і контрактом маніфесту +- валідація схеми конфігурації Plugin і схеми конфігурації каналу +- рішення щодо автоматичного ввімкнення під час запуску -Деякі викликачи холодного шляху все ще реконструюють реєстри manifest безпосередньо зі збереженого індексу встановлених плагінів замість отримання Gateway `PluginLookUpTable`. Цей резервний шлях зберігає невеликий обмежений кеш у пам’яті, ключований індексом встановлення, формою запиту, політикою конфігурації, коренями runtime і сигнатурами файлів manifest/package. Це резервна страховка для повторної реконструкції індексу, а не бажаний гарячий шлях Gateway. Надавайте перевагу передаванню поточної таблиці пошуку або явного реєстру manifest через потоки runtime, коли викликач уже його має. +Межею безпеки є заміна знімка, а не його мутація. Перебудовуйте знімок, коли змінюються конфігурація, інвентар Plugin, записи встановлення або політика збереженого індексу. Не сприймайте його як широкий змінюваний глобальний реєстр і не зберігайте необмежену кількість історичних знімків. Завантаження Plugin у середовищі виконання залишається окремим від знімків метаданих, щоб застарілий стан середовища виконання не міг бути прихований за кешем метаданих. + +Деякі виклики холодного шляху все ще напряму реконструюють реєстри маніфестів із збереженого індексу встановлених Plugin замість отримання `PluginLookUpTable` Gateway. Цей резервний шлях підтримує невеликий обмежений кеш у пам’яті з ключами за встановленим індексом, формою запиту, політикою конфігурації, коренями середовища виконання та сигнатурами файлів маніфесту/пакунка. Це резервний механізм безпеки для повторної реконструкції індексу, а не бажаний гарячий шлях Gateway. Надавайте перевагу передаванню поточної таблиці пошуку або явного реєстру маніфестів через потоки середовища виконання, коли викликач уже має їх. ### Планування активації -Планування активації є частиною control plane. Викликачі можуть запитати, які плагіни релевантні для конкретної команди, провайдера, каналу, маршруту, agent harness або можливості, перш ніж завантажувати ширші реєстри runtime. +Планування активації є частиною площини керування. Викликачі можуть запитувати, які Plugin стосуються конкретної команди, постачальника, каналу, маршруту, harness агента або можливості, ще до завантаження ширших реєстрів середовища виконання. -Планувальник зберігає сумісність поточної поведінки manifest: +Планувальник зберігає поточну поведінку маніфестів сумісною: - поля `activation.*` — це явні підказки для планувальника -- `providers`, `channels`, `commandAliases`, `setup.providers`, `contracts.tools` і хуки залишаються резервним варіантом володіння manifest +- `providers`, `channels`, `commandAliases`, `setup.providers`, `contracts.tools` і hooks залишаються резервним варіантом володіння маніфесту - API планувальника лише з id залишається доступним для наявних викликачів - API плану повідомляє мітки причин, щоб діагностика могла відрізняти явні підказки від резервного володіння -Не сприймайте `activation` як хук життєвого циклу або заміну для `register(...)`. Це метадані, що використовуються для звуження завантаження. Надавайте перевагу полям володіння, коли вони вже описують зв’язок; використовуйте `activation` лише для додаткових підказок планувальника. +Не сприймайте `activation` як hook життєвого циклу або заміну для `register(...)`. Це метадані, які використовуються для звуження завантаження. Надавайте перевагу полям володіння, коли вони вже описують зв’язок; використовуйте `activation` лише для додаткових підказок планувальника. -### Плагіни каналів і спільний інструмент message +### Plugin каналів і спільний інструмент повідомлень -Плагінам каналів не потрібно реєструвати окремий інструмент надсилання/редагування/реакції для звичайних дій чату. OpenClaw зберігає один спільний інструмент `message` у core, а плагіни каналів володіють специфічним для каналу виявленням і виконанням за ним. +Plugin каналів не потрібно реєструвати окремий інструмент send/edit/react для звичайних дій у чаті. OpenClaw зберігає один спільний інструмент `message` у core, а Plugin каналів володіють специфічним для каналу виявленням і виконанням за ним. Поточна межа така: -- core володіє хостом спільного інструмента `message`, підключенням до промптів, обліком сесій/потоків і диспетчеризацією виконання -- плагіни каналів володіють виявленням дій в області видимості, виявленням можливостей і будь-якими специфічними для каналу фрагментами schema -- плагіни каналів володіють граматикою розмов сесії, специфічною для провайдера, наприклад тим, як id розмов кодують id потоків або успадковуються від батьківських розмов -- плагіни каналів виконують фінальну дію через свій адаптер дій +- core володіє хостом спільного інструмента `message`, wiring prompt, обліком сесій/потоків і диспетчеризацією виконання +- Plugin каналів володіють виявленням дій в обмеженій області, виявленням можливостей і будь-якими фрагментами схеми, специфічними для каналу +- Plugin каналів володіють граматикою розмов сесій, специфічною для постачальника, наприклад тим, як ідентифікатори розмов кодують ідентифікатори потоків або успадковуються від батьківських розмов +- Plugin каналів виконують фінальну дію через свій адаптер дій -Для плагінів каналів поверхнею SDK є `ChannelMessageActionAdapter.describeMessageTool(...)`. Цей уніфікований виклик виявлення дає плагіну змогу повертати видимі дії, можливості та внески у schema разом, щоб ці частини не розходилися. +Для Plugin каналів поверхнею SDK є `ChannelMessageActionAdapter.describeMessageTool(...)`. Цей уніфікований виклик виявлення дає Plugin змогу повертати видимі дії, можливості та внески до схеми разом, щоб ці частини не розходилися. -Коли параметр інструмента message, специфічний для каналу, містить джерело медіа, наприклад локальний шлях або віддалений URL медіа, плагін також має повертати `mediaSourceParams` з `describeMessageTool(...)`. Core використовує цей явний список для застосування нормалізації шляхів sandbox і підказок доступу до вихідних медіа без жорсткого кодування назв параметрів, якими володіє плагін. Надавайте перевагу мапам на рівні дій, а не одному плоскому списку на весь канал, щоб параметр медіа лише для профілю не нормалізувався для нерелевантних дій, таких як `send`. +Коли параметр інструмента повідомлень, специфічний для каналу, містить джерело медіа, наприклад локальний шлях або віддалений URL медіа, Plugin також має повертати `mediaSourceParams` із `describeMessageTool(...)`. Core використовує цей явний список, щоб застосовувати нормалізацію шляхів у sandbox і підказки доступу до вихідних медіа без жорсткого кодування назв параметрів, що належать Plugin. Надавайте там перевагу картам, обмеженим дією, а не одному плоскому списку на весь канал, щоб параметр медіа лише для профілю не нормалізувався для не пов’язаних дій, як-от `send`. -Core передає область runtime у цей крок виявлення. Важливі поля включають: +Core передає область середовища виконання в цей крок виявлення. Важливі поля включають: - `accountId` - `currentChannelId` @@ -209,106 +213,106 @@ Core передає область runtime у цей крок виявлення - `agentId` - довірений вхідний `requesterSenderId` -Це важливо для плагінів, чутливих до контексту. Канал може приховувати або показувати дії message залежно від активного облікового запису, поточної кімнати/потоку/повідомлення або довіреної ідентичності запитувача без жорсткого кодування специфічних для каналу розгалужень у core-інструменті `message`. +Це важливо для Plugin, чутливих до контексту. Канал може приховувати або показувати дії інструмента повідомлень залежно від активного облікового запису, поточної кімнати/потоку/повідомлення або довіреної ідентичності запитувача без жорсткого кодування специфічних для каналу гілок у core-інструменті `message`. -Саме тому зміни маршрутизації embedded-runner усе ще залишаються роботою плагіна: runner відповідає за передавання поточної ідентичності чату/сесії в межу виявлення плагіна, щоб спільний інструмент `message` показував правильну поверхню, якою володіє канал, для поточного ходу. +Саме тому зміни маршрутизації embedded-runner усе ще залишаються роботою Plugin: runner відповідає за передавання поточної ідентичності чату/сесії в межу виявлення Plugin, щоб спільний інструмент `message` показував правильну поверхню, що належить каналу, для поточного ходу. -Для допоміжних засобів виконання, якими володіє канал, вбудовані плагіни мають зберігати runtime виконання всередині власних модулів extension. Core більше не володіє runtime дій повідомлень Discord, Slack, Telegram або WhatsApp у `src/agents/tools`. Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, а вбудовані плагіни мають імпортувати власний локальний runtime-код безпосередньо зі своїх модулів, якими володіє extension. +Для допоміжних засобів виконання, що належать каналу, вбудовані Plugin мають тримати середовище виконання всередині власних модулів extension. Core більше не володіє середовищами виконання дій повідомлень Discord, Slack, Telegram або WhatsApp у `src/agents/tools`. Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, і вбудовані Plugin мають напряму імпортувати свій локальний код середовища виконання з модулів, що належать їхнім extension. -Та сама межа застосовується і до SDK-seam із назвами провайдерів загалом: core не повинен імпортувати специфічні для каналу convenience-barrel для Slack, Discord, Signal, WhatsApp або подібних extension. Якщо core потрібна певна поведінка, він має або споживати власний barrel `api.ts` / `runtime-api.ts` вбудованого плагіна, або підняти цю потребу до вузької узагальненої можливості в спільному SDK. +Та сама межа загалом застосовується і до іменованих за постачальником швів SDK: core не має імпортувати зручні barrel-модулі, специфічні для каналів Slack, Discord, Signal, WhatsApp або подібних extension. Якщо core потрібна певна поведінка, він має або споживати власний barrel `api.ts` / `runtime-api.ts` вбудованого Plugin, або підняти цю потребу до вузької узагальненої можливості в спільному SDK. -Вбудовані плагіни дотримуються того самого правила. `runtime-api.ts` вбудованого плагіна не повинен повторно експортувати власний брендовий фасад `openclaw/plugin-sdk/`. Такі брендові фасади залишаються shim сумісності для зовнішніх плагінів і старіших споживачів, але вбудовані плагіни мають використовувати локальні експорти плюс вузькі узагальнені підшляхи SDK, такі як `openclaw/plugin-sdk/channel-policy`, `openclaw/plugin-sdk/runtime-store` або `openclaw/plugin-sdk/webhook-ingress`. Новий код не повинен додавати SDK-фасади, специфічні для id плагіна, якщо цього не вимагає межа сумісності для наявної зовнішньої екосистеми. +Вбудовані Plugin дотримуються того самого правила. `runtime-api.ts` вбудованого Plugin не має повторно експортувати власний фірмовий фасад `openclaw/plugin-sdk/`. Такі фірмові фасади залишаються сумісними shim для зовнішніх Plugin і старіших споживачів, але вбудовані Plugin мають використовувати локальні експорти разом із вузькими узагальненими підшляхами SDK, такими як `openclaw/plugin-sdk/channel-policy`, `openclaw/plugin-sdk/runtime-store` або `openclaw/plugin-sdk/webhook-ingress`. Новий код не повинен додавати фасади SDK, специфічні для ідентифікатора Plugin, якщо цього не вимагає межа сумісності для вже наявної зовнішньої екосистеми. Зокрема для опитувань є два шляхи виконання: -- `outbound.sendPoll` — спільна базова лінія для каналів, які відповідають загальній моделі опитувань -- `actions.handleAction("poll")` — бажаний шлях для специфічної для каналу семантики опитувань або додаткових параметрів опитування +- `outbound.sendPoll` — це спільна базова лінія для каналів, які відповідають загальній моделі опитувань +- `actions.handleAction("poll")` — це бажаний шлях для специфічної для каналу семантики опитувань або додаткових параметрів опитування -Тепер core відкладає спільний розбір опитувань до моменту, коли диспетчеризація опитування плагіна відхиляє дію, щоб обробники опитувань, якими володіє плагін, могли приймати специфічні для каналу поля опитувань і не блокувалися спочатку узагальненим парсером опитувань. +Тепер core відкладає спільний розбір опитувань доти, доки dispatch опитування Plugin не відхилить дію, щоб обробники опитувань, що належать Plugin, могли приймати специфічні для каналу поля опитування, не будучи спочатку заблокованими узагальненим аналізатором опитувань. -Повну послідовність запуску див. у [Внутрішній архітектурі плагінів](/uk/plugins/architecture-internals). +Повну послідовність запуску див. у [внутрішній архітектурі Plugin](/uk/plugins/architecture-internals). ## Модель володіння можливостями -OpenClaw розглядає рідний Plugin як межу володіння для **компанії** або **функції**, а не як набір не пов’язаних між собою інтеграцій. +OpenClaw розглядає нативний Plugin як межу володіння для **компанії** або **функції**, а не як набір не пов’язаних між собою інтеграцій. Це означає: -- плагін компанії зазвичай має володіти всіма поверхнями OpenClaw цієї компанії -- плагін функції зазвичай має володіти всією поверхнею функції, яку він запроваджує -- канали мають споживати спільні можливості core замість того, щоб щоразу перевпроваджувати поведінку провайдера +- Plugin компанії зазвичай має володіти всіма поверхнями цієї компанії, видимими для OpenClaw +- Plugin функції зазвичай має володіти повною поверхнею функції, яку він запроваджує +- канали мають споживати спільні можливості core замість того, щоб довільно повторно реалізовувати поведінку постачальника - - `openai` володіє текстовим inference, мовленням, голосом у реальному часі, розумінням медіа та генерацією зображень. `google` володіє текстовим inference, а також розумінням медіа, генерацією зображень і вебпошуком. `qwen` володіє текстовим inference, а також розумінням медіа й генерацією відео. + + `openai` володіє текстовим висновком, мовленням, голосом у реальному часі, розумінням медіа та генерацією зображень. `google` володіє текстовим висновком, а також розумінням медіа, генерацією зображень і вебпошуком. `qwen` володіє текстовим висновком, а також розумінням медіа й генерацією відео. - - `elevenlabs` і `microsoft` володіють мовленням; `firecrawl` володіє web-fetch; `minimax` / `mistral` / `moonshot` / `zai` володіють бекендами розуміння медіа. + + `elevenlabs` і `microsoft` володіють мовленням; `firecrawl` володіє отриманням вебданих; `minimax` / `mistral` / `moonshot` / `zai` володіють backend-реалізаціями розуміння медіа. - - `voice-call` володіє транспортом викликів, інструментами, CLI, маршрутами та мостом медіапотоку Twilio, але споживає спільні можливості мовлення, транскрибування в реальному часі та голосу в реальному часі замість прямого імпорту вендорських плагінів. + + `voice-call` володіє транспортом викликів, інструментами, CLI, маршрутами та мостом Twilio media-stream, але споживає спільні можливості мовлення, транскрипції в реальному часі та голосу в реальному часі замість прямого імпорту Plugin постачальників. -Бажаний кінцевий стан: +Бажаний кінцевий стан такий: -- OpenAI живе в одному плагіні, навіть якщо він охоплює текстові моделі, мовлення, зображення та майбутнє відео -- інший вендор може зробити те саме для власної області -- каналам байдуже, який плагін вендора володіє провайдером; вони споживають спільний контракт можливості, який надає core +- OpenAI міститься в одному Plugin, навіть якщо він охоплює текстові моделі, мовлення, зображення та майбутнє відео +- інший постачальник може робити те саме для власної поверхні +- каналам байдуже, який Plugin постачальника володіє provider; вони споживають спільний контракт можливості, який надає core Ось ключова відмінність: - **plugin** = межа володіння -- **capability** = контракт core, який можуть реалізовувати або споживати кілька плагінів +- **capability** = контракт core, який можуть реалізовувати або споживати кілька Plugin -Тож якщо OpenClaw додає нову доменну область, наприклад відео, перше питання не таке: «який провайдер має жорстко закодувати обробку відео?» Перше питання таке: «який контракт core для можливості відео?» Щойно такий контракт з’являється, вендорські плагіни можуть реєструватися щодо нього, а плагіни каналів/функцій можуть його споживати. +Тому якщо OpenClaw додає новий домен, наприклад відео, перше запитання — не «який provider має жорстко закодувати обробку відео?». Перше запитання — «який контракт core для можливості відео?». Щойно цей контракт з’являється, Plugin постачальників можуть реєструватися для нього, а Plugin каналів/функцій можуть його споживати. -Якщо можливість ще не існує, правильний крок зазвичай такий: +Якщо можливість ще не існує, правильним кроком зазвичай є: Визначте відсутню можливість у core. - - Експонуйте її через API/runtime плагіна в типізований спосіб. + + Надайте її через API/runtime Plugin у типізований спосіб. Підключіть канали/функції до цієї можливості. - - Дозвольте вендорським плагінам реєструвати реалізації. + + Дозвольте Plugin постачальників реєструвати реалізації. -Це робить володіння явним і водночас уникає поведінки core, яка залежить від одного вендора або від одноразового шляху коду, специфічного для плагіна. +Це зберігає явне володіння та водночас уникає поведінки core, що залежить від одного постачальника або одноразового кодового шляху, специфічного для Plugin. ### Шарування можливостей -Використовуйте таку ментальну модель, вирішуючи, де має належати код: +Використовуйте цю ментальну модель, коли вирішуєте, де має належати код: Спільна оркестрація, політика, fallback, правила злиття конфігурації, семантика доставки та типізовані контракти. - - Специфічні для вендора API, автентифікація, каталоги моделей, синтез мовлення, генерація зображень, майбутні відеобекенди, ендпоїнти usage. + + API, автентифікація, каталоги моделей, синтез мовлення, генерація зображень, майбутні backend-реалізації відео, кінцеві точки використання, специфічні для постачальника. - - Інтеграція Slack/Discord/voice-call тощо, яка споживає можливості core і подає їх на власній поверхні. + + Інтеграція Slack/Discord/voice-call тощо, яка споживає можливості core і представляє їх на своїй поверхні. Наприклад, TTS має таку форму: -- core володіє політикою TTS під час відповіді, порядком fallback, prefs і доставкою в канал +- core володіє політикою TTS під час відповіді, порядком fallback, налаштуваннями та доставкою в канал - `openai`, `elevenlabs` і `microsoft` володіють реалізаціями синтезу -- `voice-call` споживає допоміжний засіб runtime для телефонного TTS +- `voice-call` споживає допоміжний засіб середовища виконання TTS для телефонії -Того самого шаблону слід надавати перевагу і для майбутніх можливостей. +Той самий шаблон слід надавати перевагу і для майбутніх можливостей. -### Приклад плагіна компанії з багатьма можливостями +### Приклад Plugin компанії з кількома можливостями -Плагін компанії має виглядати цілісно зовні. Якщо OpenClaw має спільні контракти для моделей, мовлення, транскрибування в реальному часі, голосу в реальному часі, розуміння медіа, генерації зображень, генерації відео, web fetch і вебпошуку, вендор може володіти всіма своїми поверхнями в одному місці: +Plugin компанії має виглядати цілісним ззовні. Якщо OpenClaw має спільні контракти для моделей, мовлення, транскрипції в реальному часі, голосу в реальному часі, розуміння медіа, генерації зображень, генерації відео, отримання вебданих і вебпошуку, постачальник може володіти всіма своїми поверхнями в одному місці: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -362,58 +366,58 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -Важливими є не точні назви допоміжних засобів. Важлива форма: +Важливі не точні назви допоміжних засобів. Важлива форма: -- один плагін володіє поверхнею вендора -- core, як і раніше, володіє контрактами можливостей -- канали та плагіни функцій споживають допоміжні засоби `api.runtime.*`, а не код вендора -- тести контрактів можуть перевіряти, що плагін зареєстрував можливості, якими він стверджує, що володіє +- один Plugin володіє поверхнею постачальника +- core усе ще володіє контрактами можливостей +- канали та Plugin функцій споживають допоміжні засоби `api.runtime.*`, а не код постачальника +- контрактні тести можуть перевіряти, що Plugin зареєстрував можливості, якими, як він стверджує, володіє ### Приклад можливості: розуміння відео -OpenClaw уже розглядає розуміння зображень/аудіо/відео як одну спільну можливість. До неї застосовується та сама модель володіння: +OpenClaw уже розглядає розуміння зображень/аудіо/відео як одну спільну можливість. Там застосовується та сама модель володіння: Core визначає контракт розуміння медіа. - - Вендорські плагіни реєструють `describeImage`, `transcribeAudio` і `describeVideo`, коли це застосовно. + + Plugin постачальників реєструють `describeImage`, `transcribeAudio` і `describeVideo`, де це застосовно. - Канали та плагіни функцій споживають спільну поведінку core замість прямого підключення до коду вендора. + Канали та Plugin функцій споживають спільну поведінку core замість прямого підключення до коду постачальника. -Це запобігає вбудовуванню припущень щодо відео одного провайдера в core. Плагін володіє поверхнею вендора; core володіє контрактом можливості та поведінкою fallback. +Це дає змогу уникнути вбудовування припущень одного постачальника щодо відео в core. Plugin володіє поверхнею постачальника; core володіє контрактом можливості та поведінкою fallback. -Генерація відео вже використовує ту саму послідовність: core володіє типізованим контрактом можливості та допоміжним засобом runtime, а вендорські плагіни реєструють реалізації `api.registerVideoGenerationProvider(...)` щодо нього. +Генерація відео вже використовує ту саму послідовність: core володіє типізованим контрактом можливості та допоміжним засобом середовища виконання, а Plugin постачальників реєструють для неї реалізації `api.registerVideoGenerationProvider(...)`. -Потрібен конкретний контрольний список розгортання? Див. [Посібник з можливостей](/uk/plugins/architecture). +Потрібен конкретний контрольний список упровадження? Див. [Кулінарну книгу можливостей](/uk/plugins/architecture). -## Контракти та забезпечення виконання +## Контракти та забезпечення дотримання -Поверхня API плагіна навмисно типізована й централізована в `OpenClawPluginApi`. Цей контракт визначає підтримувані точки реєстрації та допоміжні засоби runtime, на які може покладатися плагін. +Поверхня API Plugin навмисно типізована та централізована в `OpenClawPluginApi`. Цей контракт визначає підтримувані точки реєстрації та допоміжні засоби середовища виконання, на які може покладатися Plugin. Чому це важливо: -- автори плагінів отримують один стабільний внутрішній стандарт -- core може відхиляти дубльоване володіння, наприклад коли два плагіни реєструють той самий id провайдера -- під час запуску можна показувати діагностику, придатну до дій, для некоректної реєстрації -- тести контрактів можуть забезпечувати володіння вбудованих плагінів і запобігати тихому дрейфу +- автори Plugin отримують один стабільний внутрішній стандарт +- core може відхиляти дубльоване володіння, наприклад коли два Plugin реєструють однаковий id provider +- під час запуску можна показувати діагностику з дієвими рекомендаціями для некоректної реєстрації +- контрактні тести можуть забезпечувати володіння вбудованих Plugin і запобігати непомітному дрейфу -Існує два шари забезпечення виконання: +Є два шари забезпечення дотримання: - - Реєстр плагінів перевіряє реєстрації під час завантаження плагінів. Приклади: дубльовані id провайдерів, дубльовані id провайдерів мовлення та некоректні реєстрації створюють діагностику плагіна замість невизначеної поведінки. + + Реєстр Plugin перевіряє реєстрації під час завантаження Plugin. Приклади: дубльовані id provider, дубльовані id постачальників мовлення та некоректні реєстрації породжують діагностику Plugin замість невизначеної поведінки. - - Вбудовані плагіни фіксуються в реєстрах контрактів під час тестових запусків, щоб OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для провайдерів моделей, провайдерів мовлення, провайдерів вебпошуку та володіння реєстраціями вбудованих плагінів. + + Вбудовані Plugin фіксуються в контрактних реєстрах під час тестових запусків, щоб OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для постачальників моделей, постачальників мовлення, постачальників вебпошуку та володіння вбудованою реєстрацією. -Практичний ефект полягає в тому, що OpenClaw заздалегідь знає, який плагін володіє якою поверхнею. Це дає core і каналам змогу безшовно компонуватися, тому що володіння оголошене, типізоване й придатне до тестування, а не неявне. +Практичний наслідок полягає в тому, що OpenClaw заздалегідь знає, який Plugin володіє якою поверхнею. Це дає core і каналам змогу безшовно поєднуватися, оскільки володіння оголошене, типізоване й придатне до тестування, а не неявне. ### Що має входити до контракту @@ -421,67 +425,67 @@ OpenClaw уже розглядає розуміння зображень/ауд - типізовані - малі - - специфічні для можливостей + - специфічні для можливості - належать core - - придатні для повторного використання кількома плагінами - - можуть споживатися каналами/функціями без знання про вендора + - багаторазово використовуються кількома Plugin + - можуть споживатися каналами/функціями без знання про постачальника - - специфічна для вендора політика, прихована в core - - одноразові escape hatch плагіна, які обходять реєстр - - код каналу, що напряму звертається до реалізації вендора - - ad hoc об’єкти runtime, які не є частиною `OpenClawPluginApi` або `api.runtime` + - політика, специфічна для постачальника, прихована в core + - одноразові лазівки для Plugin, які обходять реєстр + - код каналу, що напряму звертається до реалізації постачальника + - довільні runtime-об’єкти, які не є частиною `OpenClawPluginApi` або `api.runtime` -Коли є сумнів, піднімайте рівень абстракції: спочатку визначте можливість, а вже потім дайте плагінам підключатися до неї. +Коли є сумніви, піднімайте рівень абстракції: спочатку визначте можливість, а потім дозвольте Plugin підключатися до неї. ## Модель виконання -Рідні Plugin OpenClaw працюють **у межах процесу** разом із Gateway. Вони не ізольовані в sandbox. Завантажений рідний плагін має ту саму межу довіри на рівні процесу, що й код core. +Нативні Plugin OpenClaw працюють **у межах процесу** разом із Gateway. Вони не ізольовані в sandbox. Завантажений нативний Plugin має ту саму межу довіри на рівні процесу, що й код core. Наслідки: -- рідний Plugin може реєструвати інструменти, мережеві обробники, хуки та сервіси -- помилка в рідному Plugin може аварійно завершити роботу gateway або дестабілізувати його -- зловмисний рідний Plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw +- нативний Plugin може реєструвати інструменти, мережеві обробники, hooks і служби +- помилка в нативному Plugin може призвести до збою або дестабілізації Gateway +- зловмисний нативний Plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw -Сумісні пакети типово безпечніші, тому що OpenClaw наразі розглядає їх як паки метаданих/контенту. У поточних релізах це переважно означає вбудовані Skills. +Сумісні пакунки безпечніші за замовчуванням, тому що OpenClaw наразі розглядає їх як пакунки метаданих/вмісту. У поточних релізах це переважно означає вбудовані Skills. -Використовуйте allowlist і явні шляхи встановлення/завантаження для невбудованих плагінів. Розглядайте плагіни робочого простору як код для часу розробки, а не як типове рішення для production. +Для невбудованих Plugin використовуйте allowlist і явні шляхи встановлення/завантаження. Сприймайте Plugin робочого простору як код для часу розробки, а не як виробничі значення за замовчуванням. -Для назв пакетів вбудованого робочого простору зберігайте id плагіна прив’язаним до назви npm: типово `@openclaw/` або схвалений типізований суфікс, такий як `-provider`, `-plugin`, `-speech`, `-sandbox` чи `-media-understanding`, коли пакет навмисно надає вужчу роль плагіна. +Для імен пакетів workspace, що є вбудованими, прив’язуйте ідентифікатор Plugin до імені npm: `@openclaw/` за замовчуванням або до схваленого типізованого суфікса, такого як `-provider`, `-plugin`, `-speech`, `-sandbox` чи `-media-understanding`, коли пакет навмисно відкриває вужчу роль Plugin. -**Примітка про довіру:** +**Примітка щодо довіри:** -- `plugins.allow` довіряє **id плагінів**, а не походженню джерела. -- Плагін робочого простору з тим самим id, що й вбудований плагін, навмисно затіняє вбудовану копію, коли цей плагін робочого простору увімкнено/додано до allowlist. -- Це нормально й корисно для локальної розробки, тестування патчів і hotfix. -- Довіра до вбудованого плагіна визначається зі знімка джерела — manifest і коду на диску під час завантаження — а не з метаданих встановлення. Пошкоджений або підмінений запис встановлення не може непомітно розширити поверхню довіри вбудованого плагіна понад те, що стверджує реальне джерело. +- `plugins.allow` довіряє **ідентифікаторам Plugin**, а не походженню джерела. +- Plugin workspace з тим самим id, що й вбудований Plugin, навмисно затіняє вбудовану копію, коли цей Plugin workspace увімкнений/доданий до allowlist. +- Це нормально й корисно для локальної розробки, тестування патчів і термінових виправлень. +- Довіра до вбудованого Plugin визначається зі знімка джерела — маніфесту та коду на диску під час завантаження — а не з метаданих встановлення. Пошкоджений або підмінений запис встановлення не може непомітно розширити поверхню довіри вбудованого Plugin понад те, що заявляє фактичне джерело. ## Межа експорту -OpenClaw експортує можливості, а не зручні реалізації. +OpenClaw експортує можливості, а не зручності реалізації. -Зберігайте реєстрацію можливостей публічною. Скорочуйте експорти допоміжних засобів, що не є контрактами: +Залишайте публічною реєстрацію можливостей. Скорочуйте експорти допоміжних засобів, що не є частиною контракту: -- підшляхи допоміжних засобів, специфічні для вбудованих плагінів -- підшляхи plumbing runtime, не призначені як публічний API -- зручні допоміжні засоби, специфічні для вендора +- підшляхи допоміжних засобів, специфічні для вбудованих Plugin +- підшляхи plumbing середовища виконання, не призначені як публічний API +- зручні допоміжні засоби, специфічні для постачальника - допоміжні засоби setup/onboarding, які є деталями реалізації -Деякі підшляхи допоміжних засобів вбудованих плагінів усе ще залишаються у згенерованій мапі експортів SDK для сумісності та супроводу вбудованих плагінів. Поточні приклади включають `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, `plugin-sdk/zalo-setup`, `plugin-sdk/channel-config-schema-legacy` і кілька seam `plugin-sdk/matrix*`. Розглядайте їх як зарезервовані застарілі експорти, а не як рекомендований шаблон SDK для нових сторонніх плагінів. +Деякі підшляхи допоміжних засобів вбудованих Plugin усе ще залишаються в згенерованій карті експорту SDK задля сумісності та обслуговування вбудованих Plugin. Поточні приклади включають `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, `plugin-sdk/zalo-setup`, `plugin-sdk/channel-config-schema-legacy` і кілька швів `plugin-sdk/matrix*`. Сприймайте їх як зарезервовані застарілі експорти, а не як рекомендований шаблон SDK для нових сторонніх Plugin. -## Внутрішні деталі та довідник +## Внутрішні компоненти та довідка -Щоб дізнатися про конвеєр завантаження, модель реєстру, runtime-хуки провайдера, HTTP-маршрути Gateway, schema інструмента message, розв’язання цілей каналів, каталоги провайдерів, плагіни рушія контексту та посібник із додавання нової можливості, див. [Внутрішню архітектуру Plugin](/uk/plugins/architecture-internals). +Щодо конвеєра завантаження, моделі реєстру, гачків runtime постачальника, HTTP-маршрутів Gateway, схем інструмента повідомлень, визначення цілі каналу, каталогів постачальників, Plugin рушія контексту та посібника з додавання нової можливості див. [внутрішню архітектуру Plugin](/uk/plugins/architecture-internals). -## Пов’язане +## Пов’язані матеріали -- [Створення плагінів](/uk/plugins/building-plugins) -- [Manifest Plugin](/uk/plugins/manifest) +- [Створення Plugin](/uk/plugins/building-plugins) +- [Маніфест Plugin](/uk/plugins/manifest) - [Налаштування SDK Plugin](/uk/plugins/sdk-setup)