From 82d6a9c64d11e669b5d5a28923cc80aba5b89ffe Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Tue, 14 Apr 2026 16:29:18 +0000 Subject: [PATCH] chore(i18n): refresh uk translations --- docs/uk/plugins/architecture.md | 1447 ++++++++++++------------ docs/uk/plugins/sdk-channel-plugins.md | 352 +++--- 2 files changed, 915 insertions(+), 884 deletions(-) diff --git a/docs/uk/plugins/architecture.md b/docs/uk/plugins/architecture.md index cf5cce68a..28490ea15 100644 --- a/docs/uk/plugins/architecture.md +++ b/docs/uk/plugins/architecture.md @@ -3,15 +3,15 @@ read_when: - Створення або налагодження власних Plugin для OpenClaw - Розуміння моделі можливостей Plugin або меж володіння - Робота над конвеєром завантаження Plugin або реєстром - - Реалізація хуків середовища виконання постачальника або плагінів каналів + - Реалізація хуків часу виконання провайдера або Plugin каналів sidebarTitle: Internals -summary: 'Внутрішні механізми Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби середовища виконання' +summary: 'Внутрішні механізми Plugin: модель можливостей, володіння, контракти, конвеєр завантаження та допоміжні засоби часу виконання' title: Внутрішні механізми Plugin x-i18n: - generated_at: "2026-04-12T16:25:39Z" + generated_at: "2026-04-14T16:24:10Z" model: gpt-5.4 provider: openai - source_hash: 37361c1e9d2da57c77358396f19dfc7f749708b66ff68f1bf737d051b5d7675d + source_hash: f86798b5d2b0ad82d2397a52a6c21ed37fe6eee1dd3d124a9e4150c4f630b841 source_path: plugins/architecture.md workflow: 15 --- @@ -19,167 +19,183 @@ x-i18n: # Внутрішні механізми Plugin - Це **довідник із глибокої архітектури**. Практичні посібники дивіться тут: + Це **поглиблений довідник з архітектури**. Практичні посібники дивіться тут: - [Установлення та використання плагінів](/uk/tools/plugin) — посібник користувача - [Початок роботи](/uk/plugins/building-plugins) — перший навчальний посібник зі створення плагіна - - [Плагіни каналів](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями - - [Плагіни постачальників](/uk/plugins/sdk-provider-plugins) — створення постачальника моделей - - [Огляд SDK](/uk/plugins/sdk-overview) — карта імпорту та API реєстрації + - [Plugin каналів](/uk/plugins/sdk-channel-plugins) — створення каналу обміну повідомленнями + - [Plugin провайдерів](/uk/plugins/sdk-provider-plugins) — створення провайдера моделей + - [Огляд SDK](/uk/plugins/sdk-overview) — карта імпортів і API реєстрації -Ця сторінка описує внутрішню архітектуру системи плагінів OpenClaw. +Ця сторінка описує внутрішню архітектуру системи Plugin в OpenClaw. -## Загальнодоступна модель можливостей +## Публічна модель можливостей -Можливості — це загальнодоступна модель **власних плагінів** усередині OpenClaw. Кожен -власний плагін OpenClaw реєструється для одного або кількох типів можливостей: +Можливості — це публічна модель **власних Plugin** у межах OpenClaw. Кожен +власний Plugin OpenClaw реєструється для одного або кількох типів можливостей: -| Можливість | Метод реєстрації | Приклади плагінів | -| --------------------- | ---------------------------------------------- | ------------------------------------ | -| Текстовий inference | `api.registerProvider(...)` | `openai`, `anthropic` | -| Бекенд CLI inference | `api.registerCliBackend(...)` | `openai`, `anthropic` | -| Мовлення | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | -| Транскрибування в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | -| Голос у реальному часі | `api.registerRealtimeVoiceProvider(...)` | `openai` | -| Розуміння медіа | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | -| Генерація зображень | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | -| Генерація музики | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | -| Генерація відео | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Отримання даних з вебу | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Вебпошук | `api.registerWebSearchProvider(...)` | `google` | -| Канал / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | +| Можливість | Метод реєстрації | Приклади Plugin | +| --------------------- | --------------------------------------------- | ----------------------------------- | +| Текстовий інференс | `api.registerProvider(...)` | `openai`, `anthropic` | +| Backend інференсу CLI | `api.registerCliBackend(...)` | `openai`, `anthropic` | +| Мовлення | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | +| Транскрибування в реальному часі | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | +| Голос у реальному часі | `api.registerRealtimeVoiceProvider(...)` | `openai` | +| Розуміння медіа | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | +| Генерація зображень | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | +| Генерація музики | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | +| Генерація відео | `api.registerVideoGenerationProvider(...)` | `qwen` | +| Отримання вебданих | `api.registerWebFetchProvider(...)` | `firecrawl` | +| Вебпошук | `api.registerWebSearchProvider(...)` | `google` | +| Канал / обмін повідомленнями | `api.registerChannel(...)` | `msteams`, `matrix` | -Плагін, який реєструє нуль можливостей, але надає хуки, інструменти або -служби, є **застарілим плагіном лише з хуками**. Цей шаблон усе ще повністю підтримується. +Plugin, який не реєструє жодної можливості, але надає хуки, інструменти або +сервіси, є **застарілим plugin лише з хуками**. Цей шаблон і далі повністю підтримується. ### Позиція щодо зовнішньої сумісності -Модель можливостей реалізована в core і вже сьогодні використовується -вбудованими/власними плагінами, але сумісність із зовнішніми плагінами все ще -потребує жорсткішої планки, ніж «це експортовано, отже це вже стабільно». +Модель можливостей уже реалізована в core і сьогодні використовується +вбудованими/власними Plugin, але сумісність із зовнішніми Plugin усе ще +потребує вищої планки, ніж «це експортується, отже це незмінний контракт». Поточні рекомендації: -- **наявні зовнішні плагіни:** зберігайте працездатність інтеграцій на основі хуків; вважайте - це базовим рівнем сумісності -- **нові вбудовані/власні плагіни:** надавайте перевагу явній реєстрації можливостей замість - vendor-specific звернень усередину або нових дизайнів лише з хуками -- **зовнішні плагіни, що переходять на реєстрацію можливостей:** це дозволено, але - вважайте допоміжні поверхні, специфічні для можливостей, такими, що змінюються, - якщо документація явно не позначає контракт як стабільний +- **наявні зовнішні Plugin:** зберігайте працездатність інтеграцій на основі + хуків; вважайте це базовим рівнем сумісності +- **нові вбудовані/власні Plugin:** надавайте перевагу явній реєстрації + можливостей замість vendor-specific звернень углиб системи або нових + реалізацій лише з хуками +- **зовнішні Plugin, що переходять на реєстрацію можливостей:** це дозволено, + але вважайте допоміжні поверхні для конкретних можливостей такими, що + еволюціонують, якщо в документації контракт явно не позначено як стабільний Практичне правило: -- API реєстрації можливостей — це бажаний напрямок -- застарілі хуки залишаються найбезпечнішим шляхом без порушення сумісності для зовнішніх плагінів під час - переходу -- не всі експортовані допоміжні підшляхи однаково важливі; віддавайте перевагу вузькому - задокументованому контракту, а не випадковим допоміжним експортам +- API реєстрації можливостей — це цільовий напрямок +- застарілі хуки залишаються найбезпечнішим шляхом без ризику поломок для + зовнішніх Plugin під час переходу +- не всі експортовані допоміжні підшляхи однакові; надавайте перевагу + вузькому задокументованому контракту, а не випадковим допоміжним експортам -### Форми плагінів +### Форми Plugin -OpenClaw класифікує кожен завантажений плагін за формою на основі його фактичної -поведінки під час реєстрації (а не лише статичних метаданих): +OpenClaw класифікує кожен завантажений Plugin за формою на основі його +фактичної поведінки реєстрації, а не лише статичних метаданих: - **plain-capability** -- реєструє рівно один тип можливості (наприклад, - плагін лише постачальника, як-от `mistral`) + Plugin лише провайдера, як-от `mistral`) - **hybrid-capability** -- реєструє кілька типів можливостей (наприклад, - `openai` відповідає за текстовий inference, мовлення, розуміння медіа та - генерацію зображень) -- **hook-only** -- реєструє лише хуки (типізовані або користувацькі), без можливостей, - інструментів, команд чи служб -- **non-capability** -- реєструє інструменти, команди, служби або маршрути, але не можливості + `openai` володіє текстовим інференсом, мовленням, розумінням медіа та + генерацією зображень) +- **hook-only** -- реєструє лише хуки (типізовані або власні), без + можливостей, інструментів, команд чи сервісів +- **non-capability** -- реєструє інструменти, команди, сервіси або маршрути, + але не можливості -Використовуйте `openclaw plugins inspect `, щоб побачити форму плагіна та розподіл -можливостей. Докладніше див. у [довідці CLI](/cli/plugins#inspect). +Використовуйте `openclaw plugins inspect `, щоб побачити форму Plugin і +розподіл можливостей. Докладніше дивіться в [довіднику CLI](/cli/plugins#inspect). ### Застарілі хуки -Хук `before_agent_start` залишається підтримуваним як шлях сумісності для -плагінів лише з хуками. Реальні застарілі плагіни все ще залежать від нього. +Хук `before_agent_start` залишається підтримуваним шляхом сумісності для +Plugin лише з хуками. Від нього все ще залежать реальні застарілі Plugin. Напрямок: -- зберігати його працездатним +- зберігати його працездатність - документувати його як застарілий -- для роботи з перевизначенням моделі/постачальника віддавати перевагу `before_model_resolve` -- для зміни prompt віддавати перевагу `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`. ## Огляд архітектури -Система плагінів OpenClaw має чотири рівні: +Система Plugin в OpenClaw має чотири шари: 1. **Маніфест + виявлення** - OpenClaw знаходить кандидатів у плагіни в налаштованих шляхах, коренях workspace, - глобальних коренях розширень і вбудованих розширеннях. Під час виявлення спочатку читаються - власні маніфести `openclaw.plugin.json` і підтримувані маніфести пакунків. + OpenClaw знаходить кандидатів у Plugin у налаштованих шляхах, коренях + робочих просторів, глобальних коренях розширень і вбудованих розширеннях. + Під час виявлення спочатку зчитуються власні маніфести `openclaw.plugin.json` + разом із підтримуваними маніфестами пакетів. 2. **Увімкнення + валідація** - Core визначає, чи знайдений плагін увімкнений, вимкнений, заблокований або - вибраний для ексклюзивного слота, наприклад пам’яті. -3. **Завантаження середовища виконання** - Власні плагіни OpenClaw завантажуються в межах процесу через jiti і реєструють - можливості в центральному реєстрі. Сумісні пакунки нормалізуються в записи - реєстру без імпорту коду середовища виконання. + Core вирішує, чи є знайдений Plugin увімкненим, вимкненим, заблокованим або + вибраним для ексклюзивного слота, наприклад пам’яті. +3. **Завантаження часу виконання** + Власні Plugin OpenClaw завантажуються в межах процесу через jiti і + реєструють можливості в центральному реєстрі. Сумісні пакети + нормалізуються в записи реєстру без імпорту коду часу виконання. 4. **Використання поверхонь** Решта OpenClaw читає реєстр, щоб надавати інструменти, канали, налаштування - постачальників, хуки, HTTP-маршрути, команди CLI та служби. + провайдерів, хуки, HTTP-маршрути, команди CLI та сервіси. -Зокрема для CLI плагінів виявлення кореневих команд поділяється на дві фази: +Зокрема для CLI Plugin, виявлення кореневих команд поділено на дві фази: -- метадані на етапі розбору надходять із `registerCli(..., { descriptors: [...] })` -- реальний модуль CLI плагіна може залишатися лінивим і реєструватися під час першого виклику +- метадані під час розбору надходять із `registerCli(..., { descriptors: [...] })` +- фактичний модуль CLI Plugin може залишатися лінивим і реєструватися лише під час першого виклику -Це дозволяє зберігати код CLI, що належить плагіну, всередині плагіна, водночас даючи OpenClaw -зарезервувати імена кореневих команд до розбору. +Це дозволяє зберігати код CLI, який належить Plugin, усередині самого Plugin, +водночас даючи OpenClaw можливість резервувати імена кореневих команд ще до розбору. -Важлива межа дизайну: +Важлива межа проєктування: - виявлення + валідація конфігурації мають працювати на основі **метаданих маніфесту/схеми** - без виконання коду плагіна -- власна поведінка середовища виконання походить зі шляху `register(api)` модуля плагіна + без виконання коду Plugin +- власна поведінка часу виконання надходить із шляху `register(api)` модуля Plugin -Це розділення дозволяє OpenClaw перевіряти конфігурацію, пояснювати відсутні/вимкнені плагіни та -будувати підказки для UI/схеми до того, як повне середовище виконання стане активним. +Такий поділ дозволяє OpenClaw валідувати конфігурацію, пояснювати відсутні або +вимкнені Plugin і будувати підказки для UI/схеми ще до повної активації часу виконання. -### Плагіни каналів та спільний інструмент повідомлень +### Plugin каналів і спільний інструмент повідомлень -Плагінам каналів не потрібно реєструвати окремий інструмент для надсилання/редагування/реакції для -звичайних дій у чаті. OpenClaw зберігає один спільний інструмент `message` у core, а -плагіни каналів відповідають за специфічне для каналу виявлення та виконання за ним. +Plugin каналів не потрібно реєструвати окремий інструмент send/edit/react для +звичайних дій чату. OpenClaw зберігає один спільний інструмент `message` у core, +а Plugin каналів володіють специфічним для каналу виявленням і виконанням за ним. Поточна межа така: -- core відповідає за host спільного інструмента `message`, зв’язування з prompt, ведення - обліку сесій/гілок і диспетчеризацію виконання -- плагіни каналів відповідають за виявлення дій в обмеженому контексті, виявлення можливостей - і будь-які фрагменти схем, специфічні для каналу -- плагіни каналів відповідають за граматику розмови сесії, специфічну для постачальника, наприклад - за те, як ідентифікатори розмов кодують ідентифікатори гілок або успадковують їх від батьківських розмов -- плагіни каналів виконують фінальну дію через свій адаптер дій +- core володіє хостом спільного інструмента `message`, підключенням до prompt, + веденням сесій/гілок і диспетчеризацією виконання +- Plugin каналів володіють виявленням дій у межах області, виявленням + можливостей і будь-якими фрагментами схеми, специфічними для каналу +- Plugin каналів володіють граматикою розмови сесії, специфічною для провайдера, + наприклад тим, як ідентифікатори розмов кодують ідентифікатори гілок або + успадковуються від батьківських розмов +- Plugin каналів виконують фінальну дію через свій адаптер дій -Для плагінів каналів поверхня SDK — це +Для Plugin каналів поверхня SDK — це `ChannelMessageActionAdapter.describeMessageTool(...)`. Цей уніфікований виклик -виявлення дозволяє плагіну повертати видимі дії, можливості та внески у схему +виявлення дозволяє Plugin повертати видимі дії, можливості та внески в схему разом, щоб ці частини не розходилися. -Core передає область середовища виконання на цей етап виявлення. Важливі поля включають: +Коли параметр інструмента повідомлень, специфічний для каналу, містить джерело +медіа, наприклад локальний шлях або віддалений URL медіа, Plugin також має +повертати `mediaSourceParams` з `describeMessageTool(...)`. Core використовує +цей явний список, щоб застосовувати нормалізацію шляхів sandbox і підказки +щодо вихідного доступу до медіа без жорсткого кодування імен параметрів, +які належать Plugin. +Там слід надавати перевагу maps з областю дії на рівні дій, а не одному +плоскому списку для всього каналу, щоб параметр медіа лише для профілю не +нормалізувався для не пов’язаних дій, таких як `send`. + +Core передає область часу виконання в цей крок виявлення. Важливі поля містять: - `accountId` - `currentChannelId` @@ -190,125 +206,127 @@ Core передає область середовища виконання на - `agentId` - довірений вхідний `requesterSenderId` -Це важливо для плагінів, чутливих до контексту. Канал може приховувати або показувати -дії повідомлень залежно від активного облікового запису, поточної кімнати/гілки/повідомлення або -довіреної ідентичності запитувача без жорстко закодованих гілок, специфічних для каналу, в -інструменті `message` у core. +Це важливо для Plugin, чутливих до контексту. Канал може приховувати або +відкривати дії повідомлень залежно від активного облікового запису, поточної +кімнати/гілки/повідомлення або довіреної ідентичності запитувача без +жорсткого кодування специфічних для каналу гілок у core-інструменті `message`. -Саме тому зміни маршрутизації embedded-runner усе ще належать до роботи плагіна: runner -відповідає за передавання поточної ідентичності чату/сесії до межі виявлення плагіна, щоб -спільний інструмент `message` відкривав правильну поверхню, що належить каналу, -для поточного кроку. +Саме тому зміни маршрутизації embedded-runner усе ще належать до роботи Plugin: +runner відповідає за передавання поточної ідентичності чату/сесії в межу +виявлення Plugin, щоб спільний інструмент `message` відкривав правильну +поверхню, яка належить каналу, для поточного ходу. -Для допоміжних засобів виконання, що належать каналу, вбудовані плагіни повинні зберігати runtime -виконання всередині власних модулів розширення. Core більше не відповідає за -runtime дій повідомлень Discord, Slack, Telegram або WhatsApp у `src/agents/tools`. -Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, і вбудовані -плагіни повинні імпортувати свій власний локальний runtime-код безпосередньо зі своїх -модулів, що належать розширенню. +Для допоміжних засобів виконання, які належать каналу, вбудовані Plugin мають +зберігати runtime виконання у власних модулях розширень. Core більше не +володіє runtime дій повідомлень Discord, Slack, Telegram або WhatsApp у +`src/agents/tools`. Ми не публікуємо окремі підшляхи `plugin-sdk/*-action-runtime`, +а вбудовані Plugin мають імпортувати свій локальний runtime-код напряму з +модулів, що належать їхнім розширенням. -Така сама межа застосовується і до SDK seams, названих на честь постачальників, загалом: core не повинен -імпортувати зручні канально-специфічні barrels для розширень Slack, Discord, Signal, -WhatsApp або подібних. Якщо core потрібна певна поведінка, слід або використовувати -власний barrel `api.ts` / `runtime-api.ts` відповідного вбудованого плагіна, або підняти цю потребу -до вузької узагальненої можливості в спільному SDK. +Така сама межа застосовується і до SDK-швів, названих на честь провайдерів, загалом: +core не має імпортувати зручні barrels, специфічні для каналів Slack, Discord, +Signal, WhatsApp або подібних розширень. Якщо core потрібна певна поведінка, +слід або використати власний barrel `api.ts` / `runtime-api.ts` вбудованого Plugin, +або підняти цю потребу до вузької узагальненої можливості в спільному SDK. -Для опитувань зокрема є два шляхи виконання: +Зокрема для опитувань є два шляхи виконання: -- `outbound.sendPoll` — це спільна базова можливість для каналів, які відповідають загальній - моделі опитувань -- `actions.handleAction("poll")` — це бажаний шлях для канально-специфічної семантики - опитувань або додаткових параметрів опитувань +- `outbound.sendPoll` — спільна базова реалізація для каналів, що відповідають + загальній моделі опитувань +- `actions.handleAction("poll")` — бажаний шлях для специфічної для каналу + семантики опитувань або додаткових параметрів опитування -Тепер Core відкладає спільний розбір опитувань до моменту, коли надсилання опитування через плагін -відхиляє дію, тож обробники опитувань, що належать плагіну, можуть приймати -канально-специфічні поля опитувань, не будучи спочатку заблокованими узагальненим парсером опитувань. +Тепер Core відкладає спільний розбір опитувань до моменту, коли диспетчеризація +опитування Plugin відхиляє дію, тож обробники опитувань, що належать Plugin, +можуть приймати специфічні для каналу поля опитувань, не блокуючись спочатку +загальним парсером опитувань. -Повну послідовність запуску див. у [Конвеєрі завантаження](#load-pipeline). +Повну послідовність запуску дивіться в розділі [Конвеєр завантаження](#load-pipeline). ## Модель володіння можливостями -OpenClaw розглядає власний плагін як межу володіння для **компанії** або -**можливості**, а не як набір не пов’язаних між собою інтеграцій. +OpenClaw розглядає власний Plugin як межу володіння для **компанії** або +**функції**, а не як набір не пов’язаних інтеграцій. Це означає: -- плагін компанії зазвичай повинен володіти всіма поверхнями OpenClaw, що належать цій компанії -- плагін можливості зазвичай повинен володіти всією поверхнею можливості, яку він додає -- канали повинні споживати спільні можливості core замість того, щоб перевпроваджувати - поведінку постачальника ad hoc +- Plugin компанії зазвичай має володіти всіма поверхнями OpenClaw, що + належать цій компанії +- Plugin функції зазвичай має володіти повною поверхнею функції, яку він додає +- канали мають споживати спільні можливості core замість того, щоб довільно + повторно реалізовувати поведінку провайдерів Приклади: -- вбудований плагін `openai` відповідає за поведінку постачальника моделей OpenAI та поведінку OpenAI для - мовлення + голосу в реальному часі + розуміння медіа + генерації зображень -- вбудований плагін `elevenlabs` відповідає за поведінку ElevenLabs для мовлення -- вбудований плагін `microsoft` відповідає за поведінку Microsoft для мовлення -- вбудований плагін `google` відповідає за поведінку постачальника моделей Google, а також за Google - розуміння медіа + генерацію зображень + вебпошук -- вбудований плагін `firecrawl` відповідає за поведінку Firecrawl для отримання даних з вебу -- вбудовані плагіни `minimax`, `mistral`, `moonshot` і `zai` відповідають за свої - бекенди розуміння медіа -- вбудований плагін `qwen` відповідає за поведінку текстового постачальника Qwen, а також за - розуміння медіа і генерацію відео -- плагін `voice-call` є плагіном можливості: він відповідає за транспорт викликів, інструменти, - CLI, маршрути та Twilio media-stream bridging, але використовує спільні можливості - мовлення, а також транскрибування і голосу в реальному часі, замість прямого - імпорту vendor plugin +- вбудований Plugin `openai` володіє поведінкою провайдера моделей OpenAI і + поведінкою OpenAI для мовлення + голосу в реальному часі + розуміння медіа + генерації зображень +- вбудований Plugin `elevenlabs` володіє поведінкою мовлення ElevenLabs +- вбудований Plugin `microsoft` володіє поведінкою мовлення Microsoft +- вбудований Plugin `google` володіє поведінкою провайдера моделей Google, а також + поведінкою Google для розуміння медіа + генерації зображень + вебпошуку +- вбудований Plugin `firecrawl` володіє поведінкою Firecrawl для отримання вебданих +- вбудовані Plugin `minimax`, `mistral`, `moonshot` і `zai` володіють своїми + backends розуміння медіа +- вбудований Plugin `qwen` володіє поведінкою текстового провайдера Qwen, а також + поведінкою для розуміння медіа і генерації відео +- Plugin `voice-call` є Plugin функції: він володіє транспортом викликів, інструментами, + CLI, маршрутами та мостом медіапотоку Twilio, але споживає спільні можливості мовлення, + а також транскрибування в реальному часі й голосу в реальному часі замість прямого + імпорту vendor Plugin Бажаний кінцевий стан: -- OpenAI розміщується в одному Plugin, навіть якщо він охоплює текстові моделі, мовлення, зображення та +- OpenAI живе в одному Plugin, навіть якщо він охоплює текстові моделі, мовлення, зображення та майбутнє відео -- інший вендор може зробити так само для власної області відповідальності -- канали не залежать від того, який саме вендорський Plugin володіє постачальником; вони використовують +- інший vendor може зробити те саме для власної області поверхонь +- канали не повинні зважати на те, який vendor Plugin володіє провайдером; вони споживають спільний контракт можливостей, який надає core -Це ключове розрізнення: +Ось ключова відмінність: - **plugin** = межа володіння -- **capability** = контракт core, який можуть реалізовувати або використовувати кілька Plugin +- **capability** = контракт core, який можуть реалізовувати або споживати кілька Plugin -Тож якщо OpenClaw додає нову сферу, наприклад відео, перше запитання не таке: -«який постачальник має жорстко закодувати обробку відео?» Перше запитання таке: «який -контракт можливостей для відео має бути в core?» Щойно такий контракт з’являється, -вендорські Plugin можуть реєструватися для нього, а плагіни каналів/можливостей можуть його використовувати. +Тому якщо OpenClaw додає нову область, наприклад відео, перше запитання не таке: +«який провайдер має жорстко закодувати обробку відео?» Перше запитання таке: «який +контракт можливостей відео має бути в core?» Щойно такий контракт з’являється, +vendor Plugin можуть реєструватися для нього, а Plugin каналів/функцій можуть його споживати. Якщо можливість ще не існує, правильний крок зазвичай такий: 1. визначити відсутню можливість у core -2. типізовано відкрити її через API/runtime плагінів -3. під’єднати канали/можливості до цієї можливості -4. дозволити вендорським Plugin реєструвати реалізації +2. відкрити її через API/runtime Plugin у типізований спосіб +3. під’єднати канали/функції до цієї можливості +4. дозволити vendor Plugin реєструвати реалізації -Це зберігає явне володіння й водночас запобігає поведінці core, яка залежить від -одного вендора або одноразового шляху коду, специфічного для плагіна. +Це зберігає явне володіння й водночас уникає поведінки core, яка залежить від +одного vendor або одноразового шляху коду, специфічного для Plugin. ### Шарування можливостей -Використовуйте таку ментальну модель, коли вирішуєте, де має розміщуватися код: +Користуйтеся цією ментальною моделлю, коли вирішуєте, де має бути код: -- **шар можливостей core**: спільна оркестрація, політики, резервні сценарії, правила - об’єднання конфігурації, семантика доставки та типізовані контракти -- **шар вендорських Plugin**: API конкретного вендора, автентифікація, каталоги моделей, синтез мовлення, - генерація зображень, майбутні відеобекенди, кінцеві точки використання -- **шар плагінів каналів/можливостей**: інтеграції Slack/Discord/voice-call тощо, - які використовують можливості core і подають їх на певній поверхні +- **шар можливостей core**: спільна оркестрація, політика, fallback, правила + злиття конфігурації, семантика доставки та типізовані контракти +- **шар vendor Plugin**: API, автентифікація, каталоги моделей, синтез мовлення, + генерація зображень, майбутні backends відео, endpoints використання, специфічні для vendor +- **шар Plugin каналу/функції**: інтеграція Slack/Discord/voice-call тощо, + яка споживає можливості core і подає їх на певну поверхню Наприклад, TTS має таку форму: -- core володіє політикою TTS під час відповіді, порядком резервних сценаріїв, налаштуваннями та доставкою каналами +- core володіє політикою TTS під час відповіді, порядком fallback, налаштуваннями та доставкою в канал - `openai`, `elevenlabs` і `microsoft` володіють реалізаціями синтезу -- `voice-call` використовує допоміжний runtime для телекомунікаційного TTS +- `voice-call` споживає допоміжний runtime засіб TTS для телефонії -Той самий шаблон слід віддавати перевагу і для майбутніх можливостей. +Тому самому шаблону слід надавати перевагу й для майбутніх можливостей. -### Приклад company Plugin з кількома можливостями +### Приклад Plugin компанії з кількома можливостями Plugin компанії має виглядати цілісно ззовні. Якщо OpenClaw має спільні -контракти для моделей, мовлення, транскрибування в реальному часі, голосу в реальному часі, розуміння медіа, -генерації зображень, генерації відео, отримання даних із вебу та вебпошуку, -вендор може володіти всіма своїми поверхнями в одному місці: +контракти для моделей, мовлення, транскрибування в реальному часі, голосу в реальному часі, +розуміння медіа, генерації зображень, генерації відео, отримання вебданих і вебпошуку, +vendor може володіти всіма своїми поверхнями в одному місці: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -364,198 +382,199 @@ export default plugin; Важливі не точні назви допоміжних засобів. Важлива форма: -- один Plugin володіє вендорською поверхнею -- core усе ще володіє контрактами можливостей -- канали та плагіни можливостей використовують допоміжні засоби `api.runtime.*`, а не вендорський код -- contract tests можуть перевіряти, що Plugin зареєстрував ті можливості, якими +- один Plugin володіє поверхнею vendor +- core, як і раніше, володіє контрактами можливостей +- Plugin каналів і функцій споживають допоміжні засоби `api.runtime.*`, а не код vendor +- тести контрактів можуть перевіряти, що Plugin зареєстрував можливості, якими він заявляє, що володіє ### Приклад можливості: розуміння відео OpenClaw уже розглядає розуміння зображень/аудіо/відео як одну спільну -можливість. Та сама модель володіння застосовується і тут: +можливість. Тут застосовується та сама модель володіння: -1. core визначає контракт media-understanding -2. вендорські Plugin за потреби реєструють `describeImage`, `transcribeAudio` і - `describeVideo` -3. канали та плагіни можливостей використовують спільну поведінку core замість - прямого під’єднання до вендорського коду +1. core визначає контракт розуміння медіа +2. vendor Plugin реєструють `describeImage`, `transcribeAudio` і + `describeVideo`, де це застосовно +3. Plugin каналів і функцій споживають спільну поведінку core замість + прямого підключення до коду vendor -Це запобігає вбудовуванню в core припущень про відео одного постачальника. Plugin володіє -вендорською поверхнею; core володіє контрактом можливостей і резервною поведінкою. +Це дозволяє не вшивати в core відеоприпущення одного провайдера. Plugin володіє +поверхнею vendor; core володіє контрактом можливості й поведінкою fallback. Генерація відео вже використовує ту саму послідовність: core володіє типізованим -контрактом можливості та допоміжним runtime, а вендорські Plugin реєструють -реалізації `api.registerVideoGenerationProvider(...)` для нього. +контрактом можливості та допоміжним runtime-засобом, а vendor Plugin реєструють +реалізації `api.registerVideoGenerationProvider(...)` для цього контракту. -Потрібен конкретний контрольний список для впровадження? Див. -[Збірник рецептів можливостей](/uk/plugins/architecture). +Потрібен конкретний контрольний список розгортання? Дивіться +[Capability Cookbook](/uk/plugins/architecture). -## Контракти та забезпечення виконання +## Контракти та примусове забезпечення -Поверхня API плагінів навмисно типізована та централізована в +Поверхня API Plugin навмисно типізована й централізована в `OpenClawPluginApi`. Цей контракт визначає підтримувані точки реєстрації та -допоміжні засоби runtime, на які може покладатися Plugin. +допоміжні runtime-засоби, на які може покладатися Plugin. Чому це важливо: -- автори плагінів отримують один стабільний внутрішній стандарт -- core може відхиляти дубльоване володіння, наприклад коли два плагіни реєструють той самий - id постачальника -- під час запуску можна показувати діагностику, придатну до дії, для некоректної реєстрації -- contract tests можуть забезпечувати володіння вбудованими плагінами та запобігати тихому дрейфу +- автори Plugin отримують єдиний стабільний внутрішній стандарт +- core може відхиляти дубльоване володіння, наприклад коли два Plugin реєструють один і той самий id провайдера +- під час запуску можна показувати діагностику з конкретними порадами для неправильної реєстрації +- тести контрактів можуть забезпечувати володіння вбудованих Plugin і запобігати тихому дрейфу -Є два шари забезпечення виконання: +Є два шари забезпечення: -1. **забезпечення виконання реєстрації під час runtime** - Реєстр плагінів перевіряє реєстрації під час завантаження плагінів. Приклади: - дубльовані id постачальників, дубльовані id постачальників мовлення та некоректні - реєстрації створюють діагностику плагінів замість невизначеної поведінки. -2. **contract tests** - Вбудовані плагіни фіксуються в contract registries під час виконання тестів, щоб - OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для model - providers, speech providers, web search providers та володіння вбудованою реєстрацією. +1. **забезпечення під час runtime-реєстрації** + Реєстр Plugin перевіряє реєстрації під час завантаження Plugin. Наприклад: + дубльовані id провайдерів, дубльовані id провайдерів мовлення та + неправильно сформовані реєстрації призводять до діагностики Plugin, а не до невизначеної поведінки. +2. **тести контрактів** + Вбудовані Plugin фіксуються в реєстрах контрактів під час виконання тестів, щоб + OpenClaw міг явно перевіряти володіння. Сьогодні це використовується для + провайдерів моделей, провайдерів мовлення, провайдерів вебпошуку та + володіння реєстрацією вбудованих Plugin. -Практичний ефект полягає в тому, що OpenClaw заздалегідь знає, який плагін володіє якою -поверхнею. Це дозволяє core та каналам безшовно компонуватися, тому що володіння -задеклароване, типізоване й таке, що піддається тестуванню, а не неявне. +Практичний ефект такий: OpenClaw заздалегідь знає, який Plugin якою поверхнею володіє. +Це дає змогу core і каналам безшовно компонуватися, оскільки володіння +задеклароване, типізоване та придатне до тестування, а не неявне. ### Що має входити до контракту -Хороші контракти плагінів: +Хороші контракти Plugin: - типізовані - невеликі - специфічні для можливості - належать core -- придатні до повторного використання кількома Plugin -- можуть використовуватися каналами/можливостями без знання про вендора +- придатні для повторного використання кількома Plugin +- можуть споживатися каналами/функціями без знання про vendor -Погані контракти плагінів: +Погані контракти Plugin: -- політики, специфічні для вендора, приховані в core -- одноразові escape hatch для плагінів, які оминають реєстр -- код каналів, що напряму звертається до реалізації вендора +- політика, специфічна для vendor, прихована в core +- одноразові обхідні шляхи Plugin, які оминають реєстр +- код каналу, що напряму звертається до реалізації vendor - ad hoc runtime-об’єкти, які не є частиною `OpenClawPluginApi` або `api.runtime` -Якщо є сумніви, піднімайте рівень абстракції: спочатку визначте можливість, а тоді -дозвольте Plugin підключатися до неї. +Якщо є сумніви, підніміть рівень абстракції: спочатку визначте можливість, а +потім дозвольте Plugin підключитися до неї. ## Модель виконання -Власні Plugin OpenClaw працюють **у межах процесу** разом із Gateway. Вони не -ізольовані. Завантажений власний Plugin має ту саму межу довіри на рівні процесу, що й -код core. +Власні Plugin OpenClaw виконуються **в межах процесу** разом із Gateway. Вони не +ізольовані sandbox-середовищем. Завантажений власний Plugin має ту саму межу +довіри на рівні процесу, що й код core. Наслідки: -- власний Plugin може реєструвати інструменти, мережеві обробники, хуки та служби -- помилка у власному Plugin може аварійно завершити роботу gateway або дестабілізувати його +- власний Plugin може реєструвати інструменти, мережеві обробники, хуки та сервіси +- помилка власного Plugin може аварійно завершити роботу gateway або дестабілізувати його - зловмисний власний Plugin еквівалентний довільному виконанню коду всередині процесу OpenClaw -Сумісні пакунки безпечніші за замовчуванням, тому що OpenClaw наразі розглядає їх -як пакети метаданих/вмісту. У поточних випусках це здебільшого означає +Сумісні пакети за замовчуванням безпечніші, оскільки OpenClaw наразі розглядає їх +як пакети метаданих/вмісту. У поточних релізах це переважно означає вбудовані Skills. -Використовуйте allowlist-и та явні шляхи встановлення/завантаження для невбудованих плагінів. Сприймайте -workspace plugins як код для етапу розробки, а не як виробничі типові значення. +Для невбудованих Plugin використовуйте allowlists і явні шляхи встановлення/завантаження. +Розглядайте Plugin робочого простору як код для часу розробки, а не як типові production-налаштування. -Для назв вбудованих пакетів workspace зберігайте прив’язку id плагіна в назві npm: -`@openclaw/` за замовчуванням або затверджений типізований суфікс, наприклад -`-provider`, `-plugin`, `-speech`, `-sandbox` або `-media-understanding`, коли -пакет навмисно відкриває вужчу роль плагіна. +Для назв пакетів вбудованого робочого простору зберігайте прив’язку id Plugin до npm-імені: +`@openclaw/` за замовчуванням або схвалений типізований суфікс, наприклад +`-provider`, `-plugin`, `-speech`, `-sandbox` або `-media-understanding`, якщо +пакет навмисно відкриває вужчу роль Plugin. Важлива примітка щодо довіри: -- `plugins.allow` довіряє **id плагінів**, а не походженню джерела. -- Plugin workspace з тим самим id, що й у вбудованого плагіна, навмисно затіняє - вбудовану копію, коли цей plugin workspace увімкнено/додано до allowlist. +- `plugins.allow` довіряє **id Plugin**, а не походженню джерела. +- Plugin робочого простору з тим самим id, що й у вбудованого Plugin, навмисно затіняє + вбудовану копію, коли такий Plugin робочого простору ввімкнено/додано до allowlist. - Це нормально й корисно для локальної розробки, тестування патчів і hotfix-ів. -## Межа експорту +## Межа експортів -OpenClaw експортує можливості, а не зручності реалізації. +OpenClaw експортує можливості, а не зручні реалізації. -Зберігайте реєстрацію можливостей загальнодоступною. Скорочуйте експорти допоміжних засобів, що не є контрактами: +Зберігайте публічною реєстрацію можливостей. Прибирайте експорти допоміжних засобів, які не є контрактами: -- підшляхи допоміжних засобів, специфічних для вбудованих плагінів -- підшляхи runtime plumbing, не призначені як загальнодоступний API -- зручні допоміжні засоби, специфічні для вендора -- допоміжні засоби налаштування/onboarding, які є деталями реалізації +- підшляхи допоміжних засобів, специфічні для вбудованих Plugin +- підшляхи runtime-проводки, не призначені як публічний API +- зручні допоміжні засоби, специфічні для vendor +- допоміжні засоби setup/onboarding, що є деталями реалізації -Деякі допоміжні підшляхи вбудованих плагінів усе ще залишаються у згенерованій карті -експорту SDK для сумісності та супроводу вбудованих плагінів. Поточні приклади включають -`plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, -`plugin-sdk/zalo-setup` і кілька seam-ів `plugin-sdk/matrix*`. Сприймайте їх як +Деякі підшляхи допоміжних засобів вбудованих Plugin і далі залишаються в +згенерованій карті експортів SDK задля сумісності та супроводу вбудованих Plugin. +Поточні приклади містять `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, +`plugin-sdk/zalo-setup` і кілька швів `plugin-sdk/matrix*`. Розглядайте їх як зарезервовані експорти деталей реалізації, а не як рекомендований шаблон SDK для -нових сторонніх плагінів. +нових сторонніх Plugin. ## Конвеєр завантаження -Під час запуску OpenClaw приблизно робить таке: +Під час запуску OpenClaw приблизно виконує таке: -1. виявляє корені кандидатів у плагіни -2. читає власні маніфести або маніфести сумісних пакунків і метадані пакетів +1. виявляє корені кандидатів для Plugin +2. зчитує власні маніфести або маніфести сумісних пакетів і метадані пакетів 3. відхиляє небезпечних кандидатів -4. нормалізує конфігурацію плагінів (`plugins.enabled`, `allow`, `deny`, `entries`, +4. нормалізує конфігурацію Plugin (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. визначає стан увімкнення для кожного кандидата +5. вирішує стан увімкнення для кожного кандидата 6. завантажує увімкнені власні модулі через jiti -7. викликає нативні хуки `register(api)` (або `activate(api)` — застарілий псевдонім) і збирає реєстрації в реєстр плагінів -8. відкриває реєстр для команд/поверхонь runtime +7. викликає власні хуки `register(api)` (або `activate(api)` — застарілий псевдонім) і збирає реєстрації в реєстр Plugin +8. відкриває реєстр для поверхонь команд/runtime -`activate` — це застарілий псевдонім для `register` — завантажувач визначає, що саме присутнє (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані плагіни використовують `register`; для нових плагінів віддавайте перевагу `register`. +`activate` — це застарілий псевдонім для `register` — завантажувач визначає, що саме є (`def.register ?? def.activate`), і викликає це в тій самій точці. Усі вбудовані Plugin використовують `register`; для нових Plugin надавайте перевагу `register`. -Перевірки безпеки відбуваються **до** виконання під час runtime. Кандидати блокуються, -коли точка входу виходить за межі кореня плагіна, шлях доступний для запису всім, або -володіння шляхом виглядає підозріло для невбудованих плагінів. +Перевірки безпеки відбуваються **до** виконання runtime. Кандидати блокуються, +коли точка входу виходить за межі кореня Plugin, шлях є world-writable або +володіння шляхом виглядає підозріло для невбудованих Plugin. ### Поведінка manifest-first -Маніфест — це контрольна площина і джерело істини. OpenClaw використовує його, щоб: +Маніфест — це джерело істини для control plane. OpenClaw використовує його, щоб: - ідентифікувати Plugin -- виявляти оголошені канали/Skills/схему конфігурації або можливості пакунка -- перевіряти `plugins.entries..config` -- доповнювати підписи/placeholder-и Control UI +- виявляти задекларовані канали/Skills/схему конфігурації або можливості пакета +- валідувати `plugins.entries..config` +- доповнювати мітки/placeholder-значення Control UI - показувати метадані встановлення/каталогу -- зберігати дешеві дескриптори активації та налаштування без завантаження runtime плагіна +- зберігати дешеві дескриптори активації та setup без завантаження runtime Plugin -Для власних плагінів runtime-модуль є частиною площини даних. Він реєструє -фактичну поведінку, таку як хуки, інструменти, команди або потоки постачальників. +Для власних Plugin runtime-модуль є частиною data plane. Він реєструє фактичну +поведінку, таку як хуки, інструменти, команди або потоки провайдера. -Необов’язкові блоки маніфесту `activation` і `setup` залишаються в контрольній площині. -Це дескриптори лише метаданих для планування активації та виявлення налаштування; -вони не замінюють реєстрацію під час runtime, `register(...)` або `setupEntry`. -Перші активні споживачі активації тепер використовують підказки маніфесту щодо команд, каналів і постачальників, -щоб звузити завантаження плагінів до ширшої матеріалізації реєстру: +Необов’язкові блоки маніфесту `activation` і `setup` залишаються в control plane. +Це лише дескриптори метаданих для планування активації та виявлення setup; +вони не замінюють runtime-реєстрацію, `register(...)` або `setupEntry`. +Перші активні споживачі активації тепер використовують підказки маніфесту щодо команд, каналів і провайдерів, +щоб звузити завантаження Plugin до ширшої матеріалізації реєстру: -- завантаження CLI звужується до Plugin, які володіють запитуваною основною командою -- налаштування каналу/визначення plugin звужується до Plugin, які володіють запитуваним +- завантаження CLI звужується до Plugin, які володіють запитаною основною командою +- визначення setup/Plugin каналу звужується до Plugin, які володіють запитаним id каналу -- явне визначення налаштування/runtime постачальника звужується до Plugin, які володіють - запитуваним id постачальника +- явне визначення setup/runtime провайдера звужується до Plugin, які володіють + запитаним id провайдера -Виявлення налаштування тепер віддає перевагу id, що належать дескрипторам, таким як `setup.providers` і -`setup.cliBackends`, щоб звузити коло кандидатів Plugin, перш ніж переходити до -`setup-api` для плагінів, яким усе ще потрібні runtime-хуки під час налаштування. Якщо більше -ніж один знайдений Plugin заявляє однаковий нормалізований id постачальника налаштування або CLI backend, -пошук налаштування відмовляє через неоднозначного власника замість того, щоб покладатися на порядок виявлення. +Виявлення setup тепер надає перевагу id, що належать дескрипторам, таким як `setup.providers` і +`setup.cliBackends`, щоб звузити коло кандидатів Plugin, перш ніж повертатися до +`setup-api` для Plugin, яким усе ще потрібні runtime-хуки на етапі setup. Якщо більше +ніж один виявлений Plugin заявляє про один і той самий нормалізований id провайдера setup +або backend CLI, пошук setup відмовляється від неоднозначного власника замість того, щоб +покладатися на порядок виявлення. ### Що кешує завантажувач -OpenClaw зберігає короткочасні внутрішньопроцесні кеші для: +OpenClaw зберігає короткоживучі кеші в межах процесу для: - результатів виявлення - даних реєстру маніфестів -- завантажених реєстрів плагінів +- завантажених реєстрів Plugin -Ці кеші зменшують різкі витрати під час запуску й накладні витрати повторних команд. Їх безпечно -сприймати як короткочасні кеші продуктивності, а не як постійне збереження. +Ці кеші зменшують пікове навантаження під час запуску та повторних викликів команд. Їх безпечно +розглядати як короткоживучі кеші продуктивності, а не як збереження стану. Примітка щодо продуктивності: @@ -566,37 +585,37 @@ OpenClaw зберігає короткочасні внутрішньопроц ## Модель реєстру -Завантажені Plugin не змінюють напряму випадкові глобальні об’єкти core. Вони реєструються в -центральному реєстрі плагінів. +Завантажені Plugin не змінюють безпосередньо довільні глобальні об’єкти core. Вони +реєструються в центральному реєстрі Plugin. Реєстр відстежує: - записи Plugin (ідентичність, джерело, походження, статус, діагностика) - інструменти -- застарілі хуки та типізовані хуки +- застарілі хуки й типізовані хуки - канали -- постачальників +- провайдери - обробники Gateway RPC - HTTP-маршрути - реєстратори CLI -- фонові служби -- команди, що належать плагіну +- фонові сервіси +- команди, що належать Plugin -Потім можливості core читають із цього реєстру, а не звертаються безпосередньо до модулів плагінів. -Це зберігає односпрямоване завантаження: +Потім можливості core читають з цього реєстру замість того, щоб напряму взаємодіяти з +модулями Plugin. Це зберігає односторонність завантаження: - модуль Plugin -> реєстрація в реєстрі - runtime core -> споживання реєстру -Це розділення важливе для підтримуваності. Воно означає, що більшості поверхонь core потрібна -лише одна точка інтеграції: «читати реєстр», а не «створювати special-case для кожного модуля плагіна». +Це розділення важливе для підтримуваності. Воно означає, що більшості поверхонь core +потрібна лише одна точка інтеграції: «читати реєстр», а не «створювати спеціальний випадок для кожного модуля Plugin». -## Зворотні виклики прив’язки розмови +## Зворотні виклики прив’язування розмови -Plugin, які прив’язують розмову, можуть реагувати, коли схвалення вирішено. +Plugin, які прив’язують розмову, можуть реагувати, коли схвалення завершено. Використовуйте `api.onConversationBindingResolved(...)`, щоб отримати зворотний виклик після того, -як запит на прив’язку буде схвалено або відхилено: +як запит на прив’язування буде схвалено або відхилено: ```ts export default { @@ -616,28 +635,28 @@ export default { }; ``` -Поля корисного навантаження зворотного виклику: +Поля в корисному навантаженні зворотного виклику: - `status`: `"approved"` або `"denied"` - `decision`: `"allow-once"`, `"allow-always"` або `"deny"` -- `binding`: вирішена прив’язка для схвалених запитів -- `request`: підсумок початкового запиту, підказка від’єднання, id відправника та +- `binding`: узгоджене прив’язування для схвалених запитів +- `request`: початковий зведений запит, підказка від’єднання, id відправника та метадані розмови -Цей зворотний виклик призначений лише для сповіщення. Він не змінює, хто має право прив’язувати -розмову, і запускається після завершення обробки схвалення в core. +Цей зворотний виклик є лише сповіщенням. Він не змінює того, кому дозволено прив’язувати +розмову, і виконується після завершення обробки схвалення в core. -## Хуки runtime постачальника +## Runtime-хуки провайдера -Плагіни постачальників тепер мають два шари: +Plugin провайдерів тепер мають два шари: -- метадані маніфесту: `providerAuthEnvVars` для недорогого пошуку env-auth постачальника - до завантаження runtime, `providerAuthAliases` для варіантів постачальника, що спільно використовують - автентифікацію, `channelEnvVars` для недорогого пошуку env/setup каналу до - завантаження runtime, а також `providerAuthChoices` для недорогих міток onboarding/вибору автентифікації та +- метадані маніфесту: `providerAuthEnvVars` для дешевого пошуку env-auth провайдера + до завантаження runtime, `providerAuthAliases` для варіантів провайдера, які спільно + використовують auth, `channelEnvVars` для дешевого пошуку env/setup каналу до + завантаження runtime, а також `providerAuthChoices` для дешевих міток onboarding/auth-choice і метаданих прапорців CLI до завантаження runtime - хуки часу конфігурації: `catalog` / застарілий `discovery` плюс `applyConfigDefaults` -- хуки runtime: `normalizeModelId`, `normalizeTransport`, +- runtime-хуки: `normalizeModelId`, `normalizeTransport`, `normalizeConfig`, `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, `resolveSyntheticAuth`, `resolveExternalAuthProfiles`, @@ -657,90 +676,89 @@ export default { `buildReplayPolicy`, `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` -OpenClaw, як і раніше, володіє загальним циклом агента, failover, обробкою транскрипту та -політикою інструментів. Ці хуки є поверхнею розширення для поведінки, специфічної для постачальника, без -потреби в повністю користувацькому транспорті inference. +OpenClaw, як і раніше, володіє загальним циклом агента, failover, обробкою транскриптів і +політикою інструментів. Ці хуки є поверхнею розширення для поведінки, специфічної для провайдера, +без потреби в повністю власному транспорті інференсу. -Використовуйте маніфест `providerAuthEnvVars`, коли постачальник має облікові дані на основі env, -які загальні шляхи auth/status/model-picker повинні бачити без завантаження runtime плагіна. -Використовуйте маніфест `providerAuthAliases`, коли один id постачальника має повторно використовувати -env vars, профілі автентифікації, автентифікацію на основі конфігурації та вибір onboarding API-key -іншого id постачальника. Використовуйте маніфест `providerAuthChoices`, коли поверхні -CLI onboarding/вибору автентифікації мають знати id вибору постачальника, мітки груп і просту -схему автентифікації з одним прапорцем без завантаження runtime постачальника. Зберігайте `envVars` у runtime -постачальника для операторських підказок, таких як мітки onboarding або змінні -налаштування OAuth client-id/client-secret. +Використовуйте маніфест `providerAuthEnvVars`, коли провайдер має облікові дані на основі env, +які мають бачити узагальнені шляхи auth/status/model-picker без завантаження runtime Plugin. +Використовуйте маніфест `providerAuthAliases`, коли один id провайдера має повторно +використовувати env vars, auth profiles, auth на основі конфігурації та варіант onboarding choice для API-ключа +іншого id провайдера. Використовуйте маніфест `providerAuthChoices`, коли поверхні CLI для onboarding/auth-choice +мають знати choice id провайдера, мітки груп і просту auth-проводку з одним прапорцем +без завантаження runtime провайдера. Зберігайте runtime `envVars` провайдера для операторських підказок, +таких як мітки onboarding або setup vars для OAuth client-id/client-secret. -Використовуйте маніфест `channelEnvVars`, коли канал має автентифікацію або налаштування на основі env, -які загальний резервний shell-env, перевірки config/status або підказки setup повинні бачити +Використовуйте маніфест `channelEnvVars`, коли канал має auth або setup на основі env, які +мають бачити узагальнений shell-env fallback, перевірки config/status або підказки setup без завантаження runtime каналу. ### Порядок хуків і використання -Для плагінів моделей/постачальників OpenClaw викликає хуки приблизно в такому порядку. -Стовпець «Коли використовувати» — це швидкий посібник для ухвалення рішень. +Для Plugin моделей/провайдерів OpenClaw викликає хуки приблизно в такому порядку. +Стовпець «Коли використовувати» — це короткий посібник для ухвалення рішень. -| # | Хук | Що він робить | Коли використовувати | -| --- | --------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | Публікує конфігурацію постачальника в `models.providers` під час генерації `models.json` | Постачальник володіє каталогом або типовими значеннями `base URL` | -| 2 | `applyConfigDefaults` | Застосовує глобальні типові значення конфігурації, що належать постачальнику, під час матеріалізації конфігурації | Типові значення залежать від режиму автентифікації, env або семантики сімейства моделей постачальника | -| -- | _(вбудований пошук моделі)_ | OpenClaw спочатку пробує звичайний шлях через реєстр/каталог | _(це не хук плагіна)_ | -| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми `model-id` перед пошуком | Постачальник володіє очищенням псевдонімів до канонічного визначення моделі | -| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` для сімейства постачальника перед загальним складанням моделі | Постачальник володіє очищенням транспорту для користувацьких id постачальників у межах того самого сімейства транспорту | -| 5 | `normalizeConfig` | Нормалізує `models.providers.` перед визначенням runtime/постачальника | Постачальнику потрібне очищення конфігурації, яке має жити разом із плагіном; вбудовані допоміжні засоби сімейства Google також страхують підтримувані записи конфігурації Google | -| 6 | `applyNativeStreamingUsageCompat` | Застосовує compat-переписування native streaming-usage до конфігурованих постачальників | Постачальнику потрібні виправлення метаданих native streaming usage, що залежать від кінцевої точки | -| 7 | `resolveConfigApiKey` | Визначає env-marker auth для конфігурованих постачальників до завантаження runtime auth | Постачальник має власне визначення API-key через env-marker; тут `amazon-bedrock` також має вбудований AWS env-marker resolver | -| 8 | `resolveSyntheticAuth` | Показує локальну/self-hosted або засновану на конфігурації auth без збереження відкритого тексту | Постачальник може працювати із synthetic/local маркером облікових даних | -| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі auth, що належать постачальнику; типовий `persistence` — `runtime-only` для облікових даних, що належать CLI/app | Постачальник повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token | -| 10 | `shouldDeferSyntheticProfileAuth` | Опускає збережені synthetic placeholder-профілі нижче за auth, що базується на env/config | Постачальник зберігає synthetic placeholder-профілі, які не мають мати вищий пріоритет | -| 11 | `resolveDynamicModel` | Синхронний резервний варіант для model id, що належать постачальнику, але ще відсутні в локальному реєстрі | Постачальник приймає довільні id моделей вищого рівня | -| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` запускається знову | Постачальнику потрібні мережеві метадані перед визначенням невідомих id | -| 13 | `normalizeResolvedModel` | Фінальне переписування перед тим, як embedded runner використає визначену модель | Постачальнику потрібні переписування транспорту, але він усе ще використовує транспорт core | -| 14 | `contributeResolvedModelCompat` | Додає compat-прапорці для вендорських моделей за іншим сумісним транспортом | Постачальник розпізнає власні моделі на проксі-транспортах, не перебираючи на себе володіння постачальником | -| 15 | `capabilities` | Метадані транскриптів/інструментів, що належать постачальнику та використовуються спільною логікою core | Постачальнику потрібні особливості транскрипту/сімейства постачальника | -| 16 | `normalizeToolSchemas` | Нормалізує схеми інструментів до того, як їх побачить embedded runner | Постачальнику потрібне очищення схем для сімейства транспорту | -| 17 | `inspectToolSchemas` | Показує діагностику схем, що належить постачальнику, після нормалізації | Постачальник хоче попередження щодо ключових слів без навчання core правилам, специфічним для постачальника | -| 18 | `resolveReasoningOutputMode` | Вибирає native або tagged контракт виводу reasoning | Постачальнику потрібен tagged reasoning/final output замість native-полів | -| 19 | `prepareExtraParams` | Нормалізація параметрів запиту перед загальними обгортками параметрів потоку | Постачальнику потрібні типові параметри запиту або очищення параметрів для конкретного постачальника | -| 20 | `createStreamFn` | Повністю замінює звичайний шлях потоку на користувацький транспорт | Постачальнику потрібен користувацький wire protocol, а не просто обгортка | -| 21 | `wrapStreamFn` | Обгортка потоку після застосування загальних обгорток | Постачальнику потрібні обгортки сумісності для заголовків/тіла/modелі запиту без користувацького транспорту | -| 22 | `resolveTransportTurnState` | Приєднує native-заголовки або метадані транспорту для кожного ходу | Постачальник хоче, щоб загальні транспорти надсилали native-ідентичність ходу постачальника | -| 23 | `resolveWebSocketSessionPolicy` | Приєднує native WebSocket-заголовки або політику охолодження сесії | Постачальник хоче, щоб загальні WS-транспорти налаштовували заголовки сесії або політику резервного сценарію | -| 24 | `formatApiKey` | Форматер auth-профілю: збережений профіль стає runtime-рядком `apiKey` | Постачальник зберігає додаткові метадані auth і потребує користувацької форми runtime-токена | -| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для користувацьких кінцевих точок оновлення або політики помилки оновлення | Постачальник не відповідає спільним засобам оновлення `pi-ai` | -| 26 | `buildAuthDoctorHint` | Підказка для виправлення, що додається, коли оновлення OAuth завершується помилкою | Постачальнику потрібні власні рекомендації щодо відновлення auth після помилки оновлення | -| 27 | `matchesContextOverflowError` | Matcher переповнення вікна контексту, що належить постачальнику | У постачальника є сирі помилки переповнення, які загальні евристики не помічають | -| 28 | `classifyFailoverReason` | Класифікація причин failover, що належить постачальнику | Постачальник може зіставляти сирі помилки API/транспорту з rate-limit/перевантаженням тощо | -| 29 | `isCacheTtlEligible` | Політика prompt-cache для проксі/backhaul-постачальників | Постачальнику потрібне керування TTL кешу, специфічне для проксі | -| 30 | `buildMissingAuthMessage` | Заміна загального повідомлення про відновлення у випадку відсутньої auth | Постачальнику потрібна власна підказка для відновлення після відсутньої auth | -| 31 | `suppressBuiltInModel` | Приховування застарілих upstream-моделей плюс необов’язкова підказка помилки для користувача | Постачальнику потрібно приховувати застарілі upstream-рядки або замінювати їх вендорською підказкою | -| 32 | `augmentModelCatalog` | Synthetic/final рядки каталогу, що додаються після виявлення | Постачальнику потрібні synthetic-рядки для forward-compat у `models list` і засобах вибору | -| 33 | `isBinaryThinking` | Перемикач reasoning увімк./вимк. для постачальників із binary-thinking | Постачальник підтримує лише бінарне thinking увімк./вимк. | -| 34 | `supportsXHighThinking` | Підтримка reasoning `xhigh` для вибраних моделей | Постачальник хоче мати `xhigh` лише для підмножини моделей | -| 35 | `resolveDefaultThinkingLevel` | Типовий рівень `/think` для конкретного сімейства моделей | Постачальник володіє типовою політикою `/think` для сімейства моделей | -| 36 | `isModernModelRef` | Matcher сучасної моделі для фільтрів live profile і вибору smoke | Постачальник володіє зіставленням бажаних моделей для live/smoke | -| 37 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний runtime-токен/ключ безпосередньо перед inference | Постачальнику потрібен обмін токена або короткоживучі облікові дані запиту | -| 38 | `resolveUsageAuth` | Визначає облікові дані usage/billing для `/usage` і пов’язаних поверхонь статусу | Постачальнику потрібен користувацький розбір токена usage/quota або інші облікові дані usage | -| 39 | `fetchUsageSnapshot` | Отримує та нормалізує snapshots usage/quota, специфічні для постачальника, після визначення auth | Постачальнику потрібна кінцева точка usage або парсер payload, специфічні для постачальника | -| 40 | `createEmbeddingProvider` | Створює embedding-адаптер, що належить постачальнику, для memory/search | Поведінка embedding для пам’яті має належати плагіну постачальника | -| 41 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою транскрипту для постачальника | Постачальнику потрібна користувацька політика транскрипту (наприклад, видалення блоків thinking) | -| 42 | `sanitizeReplayHistory` | Переписує історію replay після загального очищення транскрипту | Постачальнику потрібні переписування replay, специфічні для постачальника, понад спільні допоміжні засоби Compaction | -| 43 | `validateReplayTurns` | Фінальна перевірка або зміна форми ходів replay перед embedded runner | Транспорт постачальника потребує суворішої перевірки ходів після загального очищення | -| 44 | `onModelSelected` | Запускає побічні ефекти після вибору моделі, що належать постачальнику | Постачальнику потрібна телеметрія або стан, що належить постачальнику, коли модель стає активною | +| # | Хук | Що він робить | Коли використовувати | +| --- | -------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | `catalog` | Публікує конфігурацію провайдера в `models.providers` під час генерації `models.json` | Провайдер володіє каталогом або базовими значеннями `base URL` | +| 2 | `applyConfigDefaults` | Застосовує глобальні значення конфігурації за замовчуванням, які належать провайдеру, під час матеріалізації конфігурації | Значення за замовчуванням залежать від режиму auth, env або семантики сімейства моделей провайдера | +| -- | _(вбудований пошук моделі)_ | OpenClaw спочатку пробує звичайний шлях через реєстр/каталог | _(це не хук Plugin)_ | +| 3 | `normalizeModelId` | Нормалізує застарілі або preview-псевдоніми id моделей перед пошуком | Провайдер володіє очищенням псевдонімів до канонічного визначення моделі | +| 4 | `normalizeTransport` | Нормалізує `api` / `baseUrl` сімейства провайдера перед узагальненим складанням моделі | Провайдер володіє очищенням транспорту для власних id провайдера в межах того самого сімейства транспорту | +| 5 | `normalizeConfig` | Нормалізує `models.providers.` до визначення runtime/провайдера | Провайдеру потрібне очищення конфігурації, яке має жити разом із Plugin; допоміжні засоби вбудованого сімейства Google також страхують підтримувані записи конфігурації Google | +| 6 | `applyNativeStreamingUsageCompat` | Застосовує compat-переписування native streaming usage до конфігурації провайдерів | Провайдеру потрібні виправлення метаданих native streaming usage, що залежать від endpoint | +| 7 | `resolveConfigApiKey` | Визначає auth на основі env-marker для конфігураційних провайдерів до завантаження runtime auth | Провайдер має власне визначення API-ключа через env-marker; `amazon-bedrock` також має тут вбудований resolver AWS env-marker | +| 8 | `resolveSyntheticAuth` | Виводить локальний/self-hosted або auth на основі конфігурації без збереження відкритого тексту | Провайдер може працювати із synthetic/local маркером облікових даних | +| 9 | `resolveExternalAuthProfiles` | Накладає зовнішні профілі auth, що належать провайдеру; типове значення `persistence` — `runtime-only` для облікових даних, що належать CLI/app | Провайдер повторно використовує зовнішні облікові дані auth без збереження скопійованих refresh token | +| 10 | `shouldDeferSyntheticProfileAuth` | Понижує пріоритет збережених synthetic placeholder-профілів порівняно з auth на основі env/config | Провайдер зберігає synthetic placeholder-профілі, які не повинні мати вищий пріоритет | +| 11 | `resolveDynamicModel` | Синхронний fallback для id моделей, що належать провайдеру, але ще відсутні в локальному реєстрі | Провайдер приймає довільні id моделей від upstream | +| 12 | `prepareDynamicModel` | Асинхронний прогрів, після чого `resolveDynamicModel` запускається знову | Провайдеру потрібні мережеві метадані до визначення невідомих id | +| 13 | `normalizeResolvedModel` | Остаточне переписування перед тим, як embedded runner використає визначену модель | Провайдеру потрібні переписування транспорту, але при цьому він усе ще використовує транспорт core | +| 14 | `contributeResolvedModelCompat` | Додає compat-прапорці для моделей vendor за іншим сумісним транспортом | Провайдер розпізнає власні моделі на proxy-транспортах, не перебираючи на себе провайдера | +| 15 | `capabilities` | Метадані транскрипту/інструментів, що належать провайдеру, і використовуються спільною логікою core | Провайдеру потрібні особливості транскрипту/сімейства провайдера | +| 16 | `normalizeToolSchemas` | Нормалізує схеми інструментів до того, як їх побачить embedded runner | Провайдеру потрібне очищення схем для сімейства транспорту | +| 17 | `inspectToolSchemas` | Показує діагностику схем, що належить провайдеру, після нормалізації | Провайдер хоче мати попередження щодо ключових слів без навчання core правилам, специфічним для провайдера | +| 18 | `resolveReasoningOutputMode` | Вибирає native чи tagged-контракт виводу reasoning | Провайдеру потрібен tagged reasoning/final output замість native-полів | +| 19 | `prepareExtraParams` | Нормалізація параметрів запиту до застосування узагальнених обгорток параметрів потоку | Провайдеру потрібні параметри запиту за замовчуванням або очищення параметрів для конкретного провайдера | +| 20 | `createStreamFn` | Повністю замінює звичайний шлях потоку власним транспортом | Провайдеру потрібен власний wire protocol, а не просто обгортка | +| 21 | `wrapStreamFn` | Обгортка потоку після застосування узагальнених обгорток | Провайдеру потрібні обгортки сумісності заголовків/тіла/моделі запиту без власного транспорту | +| 22 | `resolveTransportTurnState` | Прикріплює native-заголовки транспорту або метадані для кожного ходу | Провайдер хоче, щоб узагальнені транспорти надсилали native-ідентичність ходу провайдера | +| 23 | `resolveWebSocketSessionPolicy` | Прикріплює native-заголовки WebSocket або політику cooling-down сесії | Провайдер хоче, щоб узагальнені WS-транспорти налаштовували заголовки сесії або політику fallback | +| 24 | `formatApiKey` | Форматер профілю auth: збережений профіль стає runtime-рядком `apiKey` | Провайдер зберігає додаткові метадані auth і потребує власної форми runtime-токена | +| 25 | `refreshOAuth` | Перевизначення оновлення OAuth для власних endpoint оновлення або політики помилки оновлення | Провайдер не відповідає спільним refreshers `pi-ai` | +| 26 | `buildAuthDoctorHint` | Підказка виправлення, що додається, коли оновлення OAuth не вдається | Провайдеру потрібна власна порада з відновлення auth після помилки оновлення | +| 27 | `matchesContextOverflowError` | Matcher переповнення контекстного вікна, що належить провайдеру | Провайдер має сирі помилки переповнення, які узагальнені евристики пропустили б | +| 28 | `classifyFailoverReason` | Класифікація причини failover, що належить провайдеру | Провайдер може зіставляти сирі API/транспортні помилки з rate-limit, overload тощо | +| 29 | `isCacheTtlEligible` | Політика prompt-cache для proxy/backhaul-провайдерів | Провайдеру потрібне керування TTL кешу, специфічне для proxy | +| 30 | `buildMissingAuthMessage` | Замінник узагальненого повідомлення відновлення за відсутності auth | Провайдеру потрібна власна підказка відновлення за відсутності auth | +| 31 | `suppressBuiltInModel` | Приховування застарілих upstream-моделей плюс необов’язкова підказка про помилку для користувача | Провайдеру потрібно приховати застарілі upstream-рядки або замінити їх підказкою від vendor | +| 32 | `augmentModelCatalog` | Synthetic/остаточні рядки каталогу, додані після виявлення | Провайдеру потрібні synthetic-рядки прямої сумісності в `models list` і вибирачах | +| 33 | `isBinaryThinking` | Перемикач reasoning увімк./вимк. для провайдерів із binary-thinking | Провайдер відкриває лише binary thinking on/off | +| 34 | `supportsXHighThinking` | Підтримка reasoning `xhigh` для вибраних моделей | Провайдер хоче `xhigh` лише для підмножини моделей | +| 35 | `resolveDefaultThinkingLevel` | Типовий рівень `/think` для конкретного сімейства моделей | Провайдер володіє типовою політикою `/think` для сімейства моделей | +| 36 | `isModernModelRef` | Matcher сучасної моделі для фільтрів live profile і вибору smoke | Провайдер володіє зіставленням preferred-model для live/smoke | +| 37 | `prepareRuntimeAuth` | Обмінює налаштовані облікові дані на фактичний runtime-токен/ключ безпосередньо перед інференсом | Провайдеру потрібен обмін токена або короткоживучі облікові дані запиту | +| 38 | `resolveUsageAuth` | Визначає облікові дані usage/billing для `/usage` і пов’язаних поверхонь статусу | Провайдеру потрібен власний парсер токенів usage/quota або інші облікові дані для usage | +| 39 | `fetchUsageSnapshot` | Отримує та нормалізує знімки usage/quota, специфічні для провайдера, після визначення auth | Провайдеру потрібен endpoint usage, специфічний для провайдера, або парсер корисного навантаження | +| 40 | `createEmbeddingProvider` | Створює адаптер embedding, що належить провайдеру, для пам’яті/пошуку | Поведінка memory embedding має належати Plugin провайдера | +| 41 | `buildReplayPolicy` | Повертає політику replay, яка керує обробкою транскриптів для провайдера | Провайдеру потрібна власна політика транскриптів (наприклад, видалення блоків thinking) | +| 42 | `sanitizeReplayHistory` | Переписує історію replay після узагальненого очищення транскрипту | Провайдеру потрібні власні переписування replay, специфічні для провайдера, понад спільні допоміжні засоби Compaction | +| 43 | `validateReplayTurns` | Остаточна валідація або переформатування ходів replay перед embedded runner | Транспорту провайдера потрібна суворіша валідація ходів після узагальненої санітизації | +| 44 | `onModelSelected` | Запускає побічні ефекти після вибору моделі, що належать провайдеру | Провайдеру потрібна телеметрія або стан, що належить провайдеру, коли модель стає активною | `normalizeModelId`, `normalizeTransport` і `normalizeConfig` спочатку перевіряють -відповідний plugin постачальника, а потім переходять до інших плагінів постачальників, які підтримують хуки, -доки один із них справді не змінить id моделі або транспорт/конфігурацію. Це зберігає -працездатність shim-ів псевдонімів/сумісності постачальників без необхідності, щоб викликач знав, -який саме вбудований Plugin володіє цим переписуванням. Якщо жоден хук постачальника не перепише -підтримуваний запис конфігурації сімейства Google, вбудований нормалізатор конфігурації Google все одно -застосує це очищення сумісності. +відповідний Plugin провайдера, а потім переходять до інших Plugin провайдерів, здатних обробляти хуки, +доки один із них справді не змінить id моделі або transport/config. Це зберігає +працездатність shim-рішень alias/compat для провайдерів без вимоги, щоб викликач знав, +який саме вбудований Plugin володіє переписуванням. Якщо жоден хук провайдера не переписує +підтримуваний запис конфігурації сімейства Google, нормалізатор конфігурації вбудованого Google +усе одно застосовує це сумісне очищення. -Якщо постачальнику потрібен повністю користувацький wire protocol або користувацький виконавець запитів, -це інший клас розширення. Ці хуки призначені для поведінки постачальника, яка все ще -працює в межах звичайного циклу inference OpenClaw. +Якщо провайдеру потрібен повністю власний wire protocol або власний виконавець запитів, +це вже інший клас розширення. Ці хуки призначені для поведінки провайдера, яка все ще +виконується в межах звичайного циклу інференсу OpenClaw. -### Приклад постачальника +### Приклад провайдера ```ts api.registerProvider({ @@ -799,114 +817,114 @@ api.registerProvider({ - Anthropic використовує `resolveDynamicModel`, `capabilities`, `buildAuthDoctorHint`, `resolveUsageAuth`, `fetchUsageSnapshot`, `isCacheTtlEligible`, `resolveDefaultThinkingLevel`, `applyConfigDefaults`, `isModernModelRef` - і `wrapStreamFn`, оскільки він володіє forward-compat для Claude 4.6, - підказками сімейства постачальника, рекомендаціями з відновлення auth, інтеграцією - кінцевої точки usage, допустимістю prompt-cache, типовими значеннями config з урахуванням auth, політикою - типового/адаптивного thinking для Claude та формуванням потоку, специфічним для Anthropic, для - beta-заголовків, `/fast` / `serviceTier` і `context1m`. -- Допоміжні засоби потоку Anthropic, специфічні для Claude, поки що залишаються у власному - загальнодоступному seam `api.ts` / `contract-api.ts` вбудованого плагіна. Ця поверхня пакета - експортує `wrapAnthropicProviderStream`, `resolveAnthropicBetas`, - `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` і нижчорівневі - засоби побудови обгорток Anthropic замість розширення загального SDK навколо правил beta-header - одного постачальника. + і `wrapStreamFn`, оскільки він володіє прямою сумісністю з Claude 4.6, + підказками сімейства провайдера, вказівками з відновлення auth, інтеграцією + з endpoint usage, придатністю prompt-cache, значеннями конфігурації за замовчуванням, + що враховують auth, типовою/адаптивною політикою thinking для Claude і + формуванням потоку, специфічним для Anthropic, для beta headers, + `/fast` / `serviceTier` та `context1m`. +- Допоміжні засоби потоку Anthropic, специфічні для Claude, поки що залишаються у + власному публічному шві `api.ts` / `contract-api.ts` вбудованого Plugin. Ця + поверхня пакета експортує `wrapAnthropicProviderStream`, `resolveAnthropicBetas`, + `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` і низькорівневі + засоби побудови обгорток Anthropic замість розширення узагальненого SDK + навколо правил beta headers одного провайдера. - OpenAI використовує `resolveDynamicModel`, `normalizeResolvedModel` і `capabilities`, а також `buildMissingAuthMessage`, `suppressBuiltInModel`, `augmentModelCatalog`, `supportsXHighThinking` і `isModernModelRef`, - оскільки він володіє forward-compat для GPT-5.4, прямою нормалізацією OpenAI + оскільки він володіє прямою сумісністю з GPT-5.4, прямою нормалізацією OpenAI `openai-completions` -> `openai-responses`, підказками auth з урахуванням Codex, - приховуванням Spark, synthetic-рядками списку OpenAI і політикою thinking / + приглушенням Spark, synthetic-рядками списку OpenAI та політикою thinking / live-model для GPT-5; сімейство потоків `openai-responses-defaults` володіє - спільними native-обгортками OpenAI Responses для заголовків атрибуції, - `/fast`/`serviceTier`, деталізації тексту, native вебпошуку Codex, - формування payload reasoning-compat і керування контекстом Responses. -- OpenRouter використовує `catalog`, а також `resolveDynamicModel` і - `prepareDynamicModel`, оскільки цей постачальник є наскрізним і може відкривати нові - model id до оновлення статичного каталогу OpenClaw; він також використовує - `capabilities`, `wrapStreamFn` і `isCacheTtlEligible`, щоб тримати - специфічні для постачальника заголовки запитів, метадані маршрутизації, виправлення reasoning і - політику prompt-cache поза core. Його політика replay походить із + спільними native-обгортками OpenAI Responses для attribution headers, + `/fast`/`serviceTier`, багатослівності тексту, native вебпошуку Codex, + формуванням корисного навантаження reasoning-compat і керуванням контекстом Responses. +- OpenRouter використовує `catalog` разом із `resolveDynamicModel` і + `prepareDynamicModel`, оскільки провайдер є наскрізним і може відкривати нові + id моделей раніше, ніж оновиться статичний каталог OpenClaw; він також використовує + `capabilities`, `wrapStreamFn` і `isCacheTtlEligible`, щоб + заголовки запитів, метадані маршрутизації, патчі reasoning і + політика prompt-cache, специфічні для провайдера, не потрапляли в core. Його політика replay надходить із сімейства `passthrough-gemini`, тоді як сімейство потоків `openrouter-thinking` - володіє ін’єкцією reasoning на проксі та пропусками для непідтримуваних моделей / `auto`. + володіє ін’єкцією reasoning через proxy і пропусками для непідтримуваних моделей / `auto`. - GitHub Copilot використовує `catalog`, `auth`, `resolveDynamicModel` і `capabilities`, а також `prepareRuntimeAuth` і `fetchUsageSnapshot`, оскільки йому - потрібні device login, що належить постачальнику, поведінка резервних моделей, - особливості транскрипту Claude, обмін токена GitHub на токен Copilot і - кінцева точка usage, що належить постачальнику. + потрібні вхід через пристрій, що належить провайдеру, поведінка fallback моделей, + особливості транскриптів Claude, обмін GitHub token -> Copilot token і + endpoint usage, що належить провайдеру. - OpenAI Codex використовує `catalog`, `resolveDynamicModel`, `normalizeResolvedModel`, `refreshOAuth` і `augmentModelCatalog`, а також `prepareExtraParams`, `resolveUsageAuth` і `fetchUsageSnapshot`, оскільки він усе ще працює на транспортах core OpenAI, але володіє нормалізацією свого - транспорту/base URL, політикою резервного сценарію оновлення OAuth, типовим вибором транспорту, - synthetic-рядками каталогу Codex і інтеграцією з кінцевою точкою usage ChatGPT; він - використовує те саме сімейство потоків `openai-responses-defaults`, що й прямий OpenAI. + transport/base URL, політикою fallback для оновлення OAuth, типовим вибором + транспорту, synthetic-рядками каталогу Codex та інтеграцією з endpoint usage ChatGPT; + він використовує те саме сімейство потоків `openai-responses-defaults`, що й прямий OpenAI. - Google AI Studio та Gemini CLI OAuth використовують `resolveDynamicModel`, `buildReplayPolicy`, `sanitizeReplayHistory`, `resolveReasoningOutputMode`, `wrapStreamFn` і `isModernModelRef`, оскільки - сімейство replay `google-gemini` володіє резервним сценарієм forward-compat для Gemini 3.1, - native-перевіркою replay Gemini, очищенням bootstrap replay, - режимом tagged reasoning-output і зіставленням сучасних моделей, тоді як - сімейство потоків `google-thinking` володіє нормалізацією payload thinking для Gemini; + сімейство replay `google-gemini` володіє fallback прямої сумісності для Gemini 3.1, + native-валідацією replay Gemini, санітизацією bootstrap replay, режимом + tagged reasoning-output і зіставленням сучасних моделей, тоді як + сімейство потоків `google-thinking` володіє нормалізацією payload thinking Gemini; Gemini CLI OAuth також використовує `formatApiKey`, `resolveUsageAuth` і - `fetchUsageSnapshot` для форматування токена, розбору токена та - під’єднання кінцевої точки quota. + `fetchUsageSnapshot` для форматування токена, розбору токена і + проводки endpoint quota. - Anthropic Vertex використовує `buildReplayPolicy` через сімейство replay `anthropic-by-model`, щоб очищення replay, специфічне для Claude, залишалося - обмеженим id Claude, а не кожним транспортом `anthropic-messages`. + в межах id Claude, а не кожного транспорту `anthropic-messages`. - Amazon Bedrock використовує `buildReplayPolicy`, `matchesContextOverflowError`, `classifyFailoverReason` і `resolveDefaultThinkingLevel`, оскільки він володіє класифікацією помилок throttle/not-ready/context-overflow, специфічною для Bedrock, - для трафіку Anthropic-on-Bedrock; його політика replay усе ще використовує той самий + для трафіку Anthropic-on-Bedrock; його політика replay і далі використовує той самий guard `anthropic-by-model`, призначений лише для Claude. - OpenRouter, Kilocode, Opencode і Opencode Go використовують `buildReplayPolicy` через сімейство replay `passthrough-gemini`, оскільки вони проксіюють моделі Gemini - через транспорти, сумісні з OpenAI, і потребують очищення thought-signature Gemini - без native-перевірки replay Gemini або переписувань bootstrap. + через транспорти, сумісні з OpenAI, і потребують санітизації thought-signature Gemini + без native-валідації replay Gemini або переписувань bootstrap. - MiniMax використовує `buildReplayPolicy` через - сімейство replay `hybrid-anthropic-openai`, оскільки один постачальник володіє і - семантикою повідомлень Anthropic, і семантикою, сумісною з OpenAI; він зберігає - видалення блоків thinking лише для Claude на боці Anthropic, одночасно перевизначаючи режим - виводу reasoning назад до native, а сімейство потоків `minimax-fast-mode` володіє - переписуванням моделей fast-mode на спільному шляху потоку. -- Moonshot використовує `catalog` разом із `wrapStreamFn`, оскільки він усе ще використовує спільний - транспорт OpenAI, але потребує нормалізації payload thinking, що належить постачальнику; сімейство потоків - `moonshot-thinking` відображає config плюс стан `/think` на його - native binary thinking payload. + сімейство replay `hybrid-anthropic-openai`, оскільки один провайдер володіє як + семантикою повідомлень Anthropic, так і OpenAI-сумісною семантикою; він зберігає + відкидання блоків thinking лише для Claude на боці Anthropic, водночас + перевизначаючи режим виводу reasoning назад на native, а сімейство потоків + `minimax-fast-mode` володіє переписуванням моделей fast-mode на спільному шляху потоку. +- Moonshot використовує `catalog` разом із `wrapStreamFn`, оскільки він і далі використовує спільний + транспорт OpenAI, але потребує нормалізації payload thinking, що належить провайдеру; сімейство потоків + `moonshot-thinking` відображає config і стан `/think` у його native payload binary thinking. - Kilocode використовує `catalog`, `capabilities`, `wrapStreamFn` і - `isCacheTtlEligible`, оскільки йому потрібні заголовки запитів, що належать постачальнику, - нормалізація payload reasoning, підказки транскрипту Gemini та gating cache-TTL для Anthropic; - сімейство потоків `kilocode-thinking` зберігає ін’єкцію thinking Kilo - на спільному шляху проксі-потоку, пропускаючи `kilo/auto` та - інші id проксі-моделей, які не підтримують явні payload reasoning. + `isCacheTtlEligible`, оскільки йому потрібні заголовки запитів, що належать провайдеру, + нормалізація payload reasoning, підказки транскриптів Gemini та керування + TTL кешу Anthropic; сімейство потоків `kilocode-thinking` утримує ін’єкцію thinking Kilo + на спільному шляху proxy-потоку, водночас пропускаючи `kilo/auto` та інші proxy id моделей, + які не підтримують явні payload reasoning. - Z.AI використовує `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`, `isCacheTtlEligible`, `isBinaryThinking`, `isModernModelRef`, - `resolveUsageAuth` і `fetchUsageSnapshot`, оскільки він володіє резервним сценарієм для GLM-5, - типовими значеннями `tool_stream`, UX для binary thinking, зіставленням сучасних моделей, а також - і auth для usage, і отриманням quota; сімейство потоків `tool-stream-default-on` зберігає - обгортку `tool_stream`, увімкнену за замовчуванням, поза рукописним glue для кожного постачальника. + `resolveUsageAuth` і `fetchUsageSnapshot`, оскільки він володіє fallback для GLM-5, + значеннями `tool_stream` за замовчуванням, UX binary thinking, зіставленням сучасних моделей + і як auth для usage, так і отриманням quota; сімейство потоків `tool-stream-default-on` + утримує обгортку `tool_stream`, увімкнену за замовчуванням, поза вручну написаним glue-кодом для кожного провайдера. - xAI використовує `normalizeResolvedModel`, `normalizeTransport`, `contributeResolvedModelCompat`, `prepareExtraParams`, `wrapStreamFn`, `resolveSyntheticAuth`, `resolveDynamicModel` і `isModernModelRef`, - оскільки він володіє нормалізацією native xAI Responses transport, переписуванням псевдонімів - Grok fast-mode, типовим `tool_stream`, очищенням strict-tool / reasoning-payload, - повторним використанням резервної auth для інструментів, що належать плагіну, визначенням моделей - Grok із forward-compat і compat-виправленнями, що належать постачальнику, такими як профіль схем інструментів xAI, - непідтримувані ключові слова схем, native `web_search` і декодування аргументів - виклику інструментів із HTML-entity. -- Mistral, OpenCode Zen і OpenCode Go використовують лише `capabilities`, щоб тримати - особливості транскриптів/інструментів поза core. -- Вбудовані постачальники лише з каталогом, такі як `byteplus`, `cloudflare-ai-gateway`, + оскільки він володіє нормалізацією native-транспорту xAI Responses, переписуванням + псевдонімів fast-mode для Grok, типовим `tool_stream`, очищенням strict-tool / reasoning-payload, + повторним використанням fallback auth для інструментів, що належать Plugin, + прямим визначенням моделей Grok і compat-патчами, що належать провайдеру, такими як профіль + schema інструментів xAI, непідтримувані ключові слова schema, native `web_search` і декодування + аргументів виклику інструментів із HTML-сутностями. +- Mistral, OpenCode Zen і OpenCode Go використовують лише `capabilities`, щоб + не виносити особливості транскриптів/інструментів у core. +- Вбудовані провайдери лише з каталогом, такі як `byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, `synthetic`, `together`, `venice`, `vercel-ai-gateway` і `volcengine`, використовують лише `catalog`. -- Qwen використовує `catalog` для свого текстового постачальника, а також спільні реєстрації - media-understanding і video-generation для своїх мультимодальних поверхонь. -- MiniMax і Xiaomi використовують `catalog` разом із хуками usage, оскільки їхня поведінка `/usage` - належить плагіну, хоча inference усе ще працює через спільні транспорти. +- Qwen використовує `catalog` для свого текстового провайдера разом зі спільними реєстраціями + розуміння медіа й генерації відео для своїх мультимодальних поверхонь. +- MiniMax і Xiaomi використовують `catalog` разом із usage-хуками, оскільки їхня поведінка `/usage` + належить Plugin, хоча сам інференс і далі виконується через спільні транспорти. ## Допоміжні засоби runtime -Плагіни можуть отримувати доступ до вибраних допоміжних засобів core через `api.runtime`. Для TTS: +Plugin можуть отримувати доступ до вибраних допоміжних засобів core через `api.runtime`. Для TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -927,14 +945,14 @@ const voices = await api.runtime.tts.listVoices({ Примітки: -- `textToSpeech` повертає звичайний payload виводу TTS із core для поверхонь файлів/голосових нотаток. -- Використовує конфігурацію `messages.tts` із core і вибір постачальника. -- Повертає PCM audio buffer + частоту дискретизації. Плагіни мають виконувати ресемплінг/кодування для постачальників. -- `listVoices` є необов’язковим для кожного постачальника. Використовуйте його для засобів вибору голосу або потоків setup, що належать вендору. -- Списки голосів можуть містити багатші метадані, такі як locale, gender і теги personality для picker-ів з урахуванням постачальника. -- OpenAI і ElevenLabs сьогодні підтримують telephony. Microsoft — ні. +- `textToSpeech` повертає звичайне корисне навантаження виводу TTS із core для поверхонь файлів/голосових нотаток. +- Використовує конфігурацію core `messages.tts` і вибір провайдера. +- Повертає PCM-аудіобуфер + sample rate. Plugin мають виконати повторну дискретизацію/кодування для провайдерів. +- `listVoices` є необов’язковим для кожного провайдера. Використовуйте його для вибирачів голосу або потоків setup, що належать vendor. +- Списки голосів можуть містити багатші метадані, такі як locale, gender і теги personality для вибирачів, обізнаних про провайдера. +- OpenAI і ElevenLabs сьогодні підтримують телефонію. Microsoft — ні. -Плагіни також можуть реєструвати постачальників мовлення через `api.registerSpeechProvider(...)`. +Plugin також можуть реєструвати провайдери мовлення через `api.registerSpeechProvider(...)`. ```ts api.registerSpeechProvider({ @@ -954,15 +972,15 @@ api.registerSpeechProvider({ Примітки: -- Зберігайте політику TTS, резервні сценарії та доставку відповідей у core. -- Використовуйте постачальників мовлення для поведінки синтезу, що належить вендору. -- Застаріле значення Microsoft `edge` нормалізується до id постачальника `microsoft`. -- Бажана модель володіння орієнтована на компанію: один вендорський Plugin може володіти - текстом, мовленням, зображеннями та майбутніми медіапостачальниками, коли OpenClaw додає відповідні +- Зберігайте політику TTS, fallback і доставку відповіді в core. +- Використовуйте провайдери мовлення для поведінки синтезу, що належить vendor. +- Застарілий вхід Microsoft `edge` нормалізується до id провайдера `microsoft`. +- Бажана модель володіння є орієнтованою на компанію: один vendor Plugin може володіти + текстовими, мовленнєвими, графічними та майбутніми медіапровайдерами, коли OpenClaw додає відповідні контракти можливостей. -Для розуміння зображень/аудіо/відео плагіни реєструють одного типізованого -постачальника media-understanding замість узагальненого набору ключ/значення: +Для розуміння зображень/аудіо/відео Plugin реєструють один типізований +провайдер розуміння медіа, а не узагальнений набір ключ/значення: ```ts api.registerMediaUnderstandingProvider({ @@ -976,16 +994,16 @@ api.registerMediaUnderstandingProvider({ Примітки: -- Зберігайте оркестрацію, резервні сценарії, конфігурацію та під’єднання каналів у core. -- Зберігайте поведінку вендора в plugin постачальника. +- Зберігайте оркестрацію, fallback, конфігурацію та підключення каналів у core. +- Зберігайте поведінку vendor у Plugin провайдера. - Адитивне розширення має залишатися типізованим: нові необов’язкові методи, нові необов’язкові поля результату, нові необов’язкові можливості. - Генерація відео вже дотримується того самого шаблону: - - core володіє контрактом можливостей і допоміжним засобом runtime - - вендорські Plugin реєструють `api.registerVideoGenerationProvider(...)` - - плагіни можливостей/каналів використовують `api.runtime.videoGeneration.*` + - core володіє контрактом можливості та допоміжним runtime-засобом + - vendor Plugin реєструють `api.registerVideoGenerationProvider(...)` + - Plugin функцій/каналів споживають `api.runtime.videoGeneration.*` -Для допоміжних засобів runtime media-understanding плагіни можуть викликати: +Для допоміжних runtime-засобів розуміння медіа Plugin можуть викликати: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -1000,8 +1018,8 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -Для транскрибування аудіо плагіни можуть використовувати або runtime -media-understanding, або старіший псевдонім STT: +Для транскрибування аудіо Plugin можуть використовувати або runtime +розуміння медіа, або старіший псевдонім STT: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -1016,11 +1034,11 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ - `api.runtime.mediaUnderstanding.*` — це бажана спільна поверхня для розуміння зображень/аудіо/відео. -- Використовує аудіоконфігурацію media-understanding із core (`tools.media.audio`) і порядок резервних постачальників. -- Повертає `{ text: undefined }`, коли вивід транскрибування не створюється (наприклад, для пропущеного/непідтримуваного вводу). -- `api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом сумісності. +- Використовує конфігурацію аудіо розуміння медіа з core (`tools.media.audio`) і порядок fallback провайдерів. +- Повертає `{ text: undefined }`, коли вихід транскрибування не створюється (наприклад, у разі пропущеного/непідтримуваного вводу). +- `api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом для сумісності. -Плагіни також можуть запускати фонові виконання subagent через `api.runtime.subagent`: +Plugin також можуть запускати фонові виконання subagent через `api.runtime.subagent`: ```ts const result = await api.runtime.subagent.run({ @@ -1036,12 +1054,12 @@ const result = await api.runtime.subagent.run({ - `provider` і `model` — це необов’язкові перевизначення для окремого запуску, а не постійні зміни сесії. - OpenClaw враховує ці поля перевизначення лише для довірених викликачів. -- Для резервних запусків, що належать плагіну, оператори мають явно увімкнути `plugins.entries..subagent.allowModelOverride: true`. -- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені плагіни конкретними канонічними цілями `provider/model`, або `"*"`, щоб явно дозволити будь-яку ціль. -- Запуски subagent із недовірених плагінів також працюють, але запити на перевизначення відхиляються замість тихого переходу до резервного сценарію. +- Для запусків fallback, що належать Plugin, оператори мають явно дозволити це через `plugins.entries..subagent.allowModelOverride: true`. +- Використовуйте `plugins.entries..subagent.allowedModels`, щоб обмежити довірені Plugin конкретними канонічними цілями `provider/model`, або `"*"`, щоб явно дозволити будь-яку ціль. +- Виконання subagent для недовірених Plugin усе одно працюють, але запити на перевизначення відхиляються, а не тихо переходять до fallback. -Для вебпошуку плагіни можуть використовувати спільний допоміжний засіб runtime замість -звернення до під’єднання інструментів агента: +Для вебпошуку Plugin можуть споживати спільний допоміжний runtime-засіб замість +того, щоб звертатися до підключення інструментів агента: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -1057,14 +1075,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -Плагіни також можуть реєструвати постачальників вебпошуку через +Plugin також можуть реєструвати провайдери вебпошуку через `api.registerWebSearchProvider(...)`. Примітки: -- Зберігайте вибір постачальника, визначення облікових даних і спільну семантику запитів у core. -- Використовуйте постачальників вебпошуку для транспортів пошуку, специфічних для вендора. -- `api.runtime.webSearch.*` — це бажана спільна поверхня для плагінів можливостей/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструментів агента. +- Зберігайте вибір провайдера, визначення облікових даних і спільну семантику запитів у core. +- Використовуйте провайдери вебпошуку для транспортів пошуку, специфічних для vendor. +- `api.runtime.webSearch.*` — це бажана спільна поверхня для Plugin функцій/каналів, яким потрібна поведінка пошуку без залежності від обгортки інструментів агента. ### `api.runtime.imageGeneration` @@ -1079,12 +1097,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`: генерує зображення за допомогою налаштованого ланцюжка постачальників генерації зображень. -- `listProviders(...)`: перелічує доступних постачальників генерації зображень і їхні можливості. +- `generate(...)`: генерує зображення, використовуючи налаштований ланцюжок провайдерів генерації зображень. +- `listProviders(...)`: перелічує доступні провайдери генерації зображень та їхні можливості. ## HTTP-маршрути Gateway -Плагіни можуть відкривати HTTP-кінцеві точки за допомогою `api.registerHttpRoute(...)`. +Plugin можуть відкривати HTTP-endpoint-и через `api.registerHttpRoute(...)`. ```ts api.registerHttpRoute({ @@ -1102,31 +1120,31 @@ api.registerHttpRoute({ Поля маршруту: - `path`: шлях маршруту в HTTP-сервері gateway. -- `auth`: обов’язкове поле. Використовуйте `"gateway"`, щоб вимагати звичайну auth gateway, або `"plugin"` для auth/webhook verification, якими керує plugin. +- `auth`: обов’язкове поле. Використовуйте `"gateway"`, щоб вимагати звичайну auth Gateway, або `"plugin"` для auth/webhook verification, якими керує Plugin. - `match`: необов’язкове поле. `"exact"` (типово) або `"prefix"`. -- `replaceExisting`: необов’язкове поле. Дозволяє тому самому плагіну замінити власну наявну реєстрацію маршруту. -- `handler`: повертайте `true`, коли маршрут обробив запит. +- `replaceExisting`: необов’язкове поле. Дозволяє тому самому Plugin замінити власну наявну реєстрацію маршруту. +- `handler`: повертає `true`, якщо маршрут обробив запит. Примітки: -- `api.registerHttpHandler(...)` видалено, і він спричинить помилку завантаження плагіна. Використовуйте натомість `api.registerHttpRoute(...)`. -- Маршрути плагінів мають явно оголошувати `auth`. -- Конфлікти точного `path + match` відхиляються, якщо не задано `replaceExisting: true`, і один плагін не може замінити маршрут іншого плагіна. -- Маршрути, що перекриваються, з різними рівнями `auth` відхиляються. Ланцюжки fallthrough для `exact`/`prefix` мають залишатися лише в межах одного рівня `auth`. -- Маршрути `auth: "plugin"` **не** отримують runtime scopes оператора автоматично. Вони призначені для webhooks/signature verification, якими керує plugin, а не для привілейованих допоміжних викликів Gateway. -- Маршрути `auth: "gateway"` працюють у межах runtime scope запиту Gateway, але цей scope навмисно консервативний: - - bearer auth зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) утримує runtime scopes маршрутів плагіна на рівні `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` - - довірені HTTP-режими з ідентичністю (наприклад, `trusted-proxy` або `gateway.auth.mode = "none"` на приватному ingress) враховують `x-openclaw-scopes` лише тоді, коли цей заголовок явно присутній - - якщо `x-openclaw-scopes` відсутній у таких запитах до маршруту плагіна з ідентичністю, runtime scope повертається до `operator.write` -- Практичне правило: не вважайте маршрут плагіна з gateway-auth неявною поверхнею адміністратора. Якщо вашому маршруту потрібна поведінка лише для адміністратора, вимагайте режим auth з ідентичністю та документуйте явний контракт заголовка `x-openclaw-scopes`. +- `api.registerHttpHandler(...)` вилучено, і він спричинить помилку завантаження Plugin. Натомість використовуйте `api.registerHttpRoute(...)`. +- Маршрути Plugin мають явно оголошувати `auth`. +- Конфлікти точного `path + match` відхиляються, якщо не вказано `replaceExisting: true`, і один Plugin не може замінити маршрут іншого Plugin. +- Маршрути, що перекриваються та мають різні рівні `auth`, відхиляються. Зберігайте ланцюги проходження `exact`/`prefix` лише в межах одного рівня auth. +- Маршрути `auth: "plugin"` **не** отримують автоматично runtime-scopes оператора. Вони призначені для webhook-ів/перевірки підписів, якими керує Plugin, а не для привілейованих допоміжних викликів Gateway. +- Маршрути `auth: "gateway"` працюють у межах runtime-scope запиту Gateway, але цей scope навмисно консервативний: + - bearer auth зі спільним секретом (`gateway.auth.mode = "token"` / `"password"`) утримує runtime-scopes маршрутів Plugin зафіксованими на `operator.write`, навіть якщо викликач надсилає `x-openclaw-scopes` + - довірені HTTP-режими з ідентичністю (наприклад, `trusted-proxy` або `gateway.auth.mode = "none"` у приватному ingress) враховують `x-openclaw-scopes` лише тоді, коли цей заголовок явно присутній + - якщо `x-openclaw-scopes` відсутній у таких запитах до маршрутів Plugin з ідентичністю, runtime-scope переходить до `operator.write` +- Практичне правило: не вважайте маршрут Plugin із gateway-auth неявною admin-поверхнею. Якщо вашому маршруту потрібна поведінка лише для admin, вимагайте режим auth із носієм ідентичності та задокументуйте явний контракт заголовка `x-openclaw-scopes`. ## Шляхи імпорту Plugin SDK -Під час створення плагінів використовуйте підшляхи SDK замість монолітного імпорту `openclaw/plugin-sdk`: +Під час створення Plugin використовуйте підшляхи SDK замість монолітного імпорту `openclaw/plugin-sdk`: -- `openclaw/plugin-sdk/plugin-entry` для примітивів реєстрації плагінів. -- `openclaw/plugin-sdk/core` для загального спільного контракту для плагінів. -- `openclaw/plugin-sdk/config-schema` для експорту кореневої Zod-схеми `openclaw.json` +- `openclaw/plugin-sdk/plugin-entry` для примітивів реєстрації Plugin. +- `openclaw/plugin-sdk/core` для узагальненого спільного контракту, орієнтованого на Plugin. +- `openclaw/plugin-sdk/config-schema` для експорту кореневої схеми Zod `openclaw.json` (`OpenClawSchema`). - Стабільні примітиви каналів, такі як `openclaw/plugin-sdk/channel-setup`, `openclaw/plugin-sdk/setup-runtime`, @@ -1140,18 +1158,18 @@ api.registerHttpRoute({ `openclaw/plugin-sdk/channel-reply-pipeline`, `openclaw/plugin-sdk/command-auth`, `openclaw/plugin-sdk/secret-input` і - `openclaw/plugin-sdk/webhook-ingress` для спільного під’єднання setup/auth/reply/webhook. + `openclaw/plugin-sdk/webhook-ingress` для спільного підключення setup/auth/reply/webhook. `channel-inbound` — це спільне місце для debounce, зіставлення згадок, - допоміжних засобів політики вхідних згадок, форматування envelope і допоміжних - засобів контексту вхідних envelope. - `channel-setup` — це вузький seam setup для необов’язкового встановлення. + допоміжних засобів політики вхідних згадок, форматування envelope і + допоміжних засобів контексту вхідного envelope. + `channel-setup` — це вузький шов setup для необов’язкового встановлення. `setup-runtime` — це безпечна для runtime поверхня setup, яка використовується `setupEntry` / - відкладеним запуском, включно з безпечними для імпорту адаптерами patch для setup. - `setup-adapter-runtime` — це seam адаптера setup облікового запису з урахуванням env. - `setup-tools` — це невеликий seam допоміжних засобів для CLI/архівів/документації (`formatCliCommand`, + відкладеним запуском, зокрема безпечними для імпорту адаптерами патчів setup. + `setup-adapter-runtime` — це env-aware шов адаптера setup облікового запису. + `setup-tools` — це малий шов допоміжних засобів CLI/архівів/документації (`formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR`). -- Підшляхи доменів, такі як `openclaw/plugin-sdk/channel-config-helpers`, +- Доменні підшляхи, такі як `openclaw/plugin-sdk/channel-config-helpers`, `openclaw/plugin-sdk/allow-from`, `openclaw/plugin-sdk/channel-config-schema`, `openclaw/plugin-sdk/telegram-command-config`, @@ -1170,190 +1188,193 @@ api.registerHttpRoute({ `openclaw/plugin-sdk/text-runtime`, `openclaw/plugin-sdk/runtime-store` і `openclaw/plugin-sdk/directory-runtime` для спільних допоміжних засобів runtime/config. - `telegram-command-config` — це вузький загальнодоступний seam для нормалізації/валідації користувацьких - команд Telegram і він залишається доступним, навіть якщо поверхня контракту вбудованого + `telegram-command-config` — це вузький публічний шов для нормалізації/валідації + власних команд Telegram і залишається доступним навіть якщо поверхня контракту вбудованого Telegram тимчасово недоступна. - `text-runtime` — це спільний seam для text/markdown/logging, включно з - видаленням тексту, видимого для assistant, допоміжними засобами рендерингу/chunking markdown, засобами - редагування, допоміжними засобами тегів директив і безпечними утилітами для тексту. -- Для каналів, специфічних для approval, слід надавати перевагу одному контракту `approvalCapability` - у плагіні. Потім core читає auth, доставку, рендеринг, - native-routing і ліниву поведінку native-handler для approval через цю одну можливість - замість змішування поведінки approval з не пов’язаними полями плагіна. -- `openclaw/plugin-sdk/channel-runtime` є застарілим і залишається лише як - shim сумісності для старіших плагінів. Новий код має імпортувати натомість вужчі + `text-runtime` — це спільний шов тексту/markdown/логування, зокрема + видалення видимого для асистента тексту, допоміжні засоби рендерингу/розбиття markdown, засоби редагування, + засоби directive-tag і утиліти безпечного тексту. +- Специфічним для схвалення швам каналу слід надавати перевагу одному контракту + `approvalCapability` у Plugin. Тоді core зчитує auth схвалення, доставку, рендеринг, + native-routing і ліниву поведінку native-handler через цю одну можливість + замість змішування поведінки схвалення з не пов’язаними полями Plugin. +- `openclaw/plugin-sdk/channel-runtime` застарів і залишається лише як + shim сумісності для старіших Plugin. Новий код має імпортувати натомість вужчі узагальнені примітиви, а код репозиторію не повинен додавати нові імпорти цього shim. -- Внутрішні компоненти вбудованих розширень залишаються приватними. Зовнішні плагіни повинні використовувати лише підшляхи `openclaw/plugin-sdk/*`. Код core/test OpenClaw може використовувати загальнодоступні - точки входу репозиторію в корені пакета плагіна, такі як `index.js`, `api.js`, - `runtime-api.js`, `setup-entry.js` і вузько визначені файли, такі як - `login-qr-api.js`. Ніколи не імпортуйте `src/*` пакета плагіна з core або з +- Внутрішні механізми вбудованих розширень залишаються приватними. Зовнішні Plugin повинні використовувати лише підшляхи `openclaw/plugin-sdk/*`. Код core/test OpenClaw може використовувати публічні точки входу репозиторію в корені пакета Plugin, такі як `index.js`, `api.js`, + `runtime-api.js`, `setup-entry.js` і вузькоспрямовані файли, такі як + `login-qr-api.js`. Ніколи не імпортуйте `src/*` пакета Plugin з core або з іншого розширення. - Поділ точок входу репозиторію: `/api.js` — це barrel допоміжних засобів/типів, `/runtime-api.js` — це barrel лише для runtime, - `/index.js` — це точка входу вбудованого плагіна, - а `/setup-entry.js` — це точка входу setup плагіна. -- Поточні приклади вбудованих постачальників: + `/index.js` — це точка входу вбудованого Plugin, + а `/setup-entry.js` — це точка входу Plugin для setup. +- Поточні приклади вбудованих провайдерів: - Anthropic використовує `api.js` / `contract-api.js` для допоміжних засобів потоку Claude, таких - як `wrapAnthropicProviderStream`, допоміжні засоби beta-header і розбір - `service_tier`. - - OpenAI використовує `api.js` для builder-ів постачальника, допоміжних засобів типової моделі та - builder-ів постачальника realtime. - - OpenRouter використовує `api.js` для свого builder-а постачальника, а також допоміжних засобів onboarding/config, - тоді як `register.runtime.js` і далі може повторно експортувати загальні + як `wrapAnthropicProviderStream`, засоби для beta-header і розбір `service_tier`. + - OpenAI використовує `api.js` для builder-ів провайдера, допоміжних засобів типових моделей і + builder-ів провайдера realtime. + - OpenRouter використовує `api.js` для свого builder-а провайдера разом із допоміжними + засобами onboarding/config, тоді як `register.runtime.js` усе ще може повторно експортувати узагальнені допоміжні засоби `plugin-sdk/provider-stream` для локального використання в репозиторії. -- Загальнодоступні точки входу, завантажені через facade, надають перевагу активному snapshot конфігурації runtime, - якщо він існує, а інакше повертаються до визначеного файла конфігурації на диску, коли - OpenClaw ще не обслуговує snapshot runtime. -- Узагальнені спільні примітиви залишаються бажаним загальнодоступним контрактом SDK. Невеликий - зарезервований набір seam-ів допоміжних засобів вбудованих каналів із брендуванням каналів усе ще існує. Сприймайте їх як seam-и для супроводу/сумісності вбудованих компонентів, а не як нові цілі імпорту для сторонніх рішень; нові міжканальні контракти все одно мають з’являтися в узагальнених підшляхах `plugin-sdk/*` або в локальних barrels `api.js` / - `runtime-api.js` плагіна. +- Публічні точки входу, завантажені через facade, надають перевагу активному знімку конфігурації runtime, + коли він існує, а потім переходять до визначеного файла конфігурації на диску, коли + OpenClaw ще не обслуговує знімок runtime. +- Узагальнені спільні примітиви залишаються бажаним публічним контрактом SDK. Невеликий + зарезервований набір брендових допоміжних швів вбудованих каналів для сумісності все ще існує. + Розглядайте їх як шви для супроводу вбудованих рішень/сумісності, а не як нові цілі імпорту для сторонніх рішень; + нові міжканальні контракти, як і раніше, мають з’являтися у вузьких підшляхах + `plugin-sdk/*` або в локальних barrel `api.js` / + `runtime-api.js` самого Plugin. Примітка щодо сумісності: -- Для нового коду уникайте кореневого barrel `openclaw/plugin-sdk`. -- Спочатку надавайте перевагу вузьким стабільним примітивам. Новіші підшляхи setup/pairing/reply/ - feedback/contract/inbound/threading/command/secret-input/webhook/infra/ - allowlist/status/message-tool є бажаним контрактом для нової роботи з - вбудованими та зовнішніми плагінами. +- Уникайте кореневого barrel `openclaw/plugin-sdk` у новому коді. +- Спочатку надавайте перевагу вузьким стабільним примітивам. Новіші підшляхи + setup/pairing/reply/feedback/contract/inbound/threading/command/secret-input/webhook/infra/ + allowlist/status/message-tool є цільовим контрактом для нової роботи з + вбудованими та зовнішніми Plugin. Розбір/зіставлення цілей має належати `openclaw/plugin-sdk/channel-targets`. - Перевірки дій повідомлень і допоміжні засоби для message-id реакцій мають належати + Обмеження дій повідомлень і допоміжні засоби message-id для реакцій мають належати `openclaw/plugin-sdk/channel-actions`. -- Barrels допоміжних засобів, специфічних для вбудованих розширень, не є стабільними за замовчуванням. Якщо - допоміжний засіб потрібен лише вбудованому розширенню, тримайте його за локальним seam - `api.js` або `runtime-api.js` цього розширення, замість того щоб просувати його в +- Barrels допоміжних засобів, специфічні для вбудованих розширень, за замовчуванням не є стабільними. Якщо + допоміжний засіб потрібен лише вбудованому розширенню, тримайте його за локальним швом + `api.js` або `runtime-api.js` цього розширення замість того, щоб просувати його в `openclaw/plugin-sdk/`. -- Нові seam-и спільних допоміжних засобів мають бути узагальненими, а не брендованими під канал. Спільний розбір - цілей має належати `openclaw/plugin-sdk/channel-targets`; внутрішні компоненти, специфічні для каналу, - залишаються за локальним seam `api.js` або `runtime-api.js` плагіна-власника. +- Нові спільні шви допоміжних засобів мають бути узагальненими, а не брендовими для каналу. Спільний розбір + цілей має належати `openclaw/plugin-sdk/channel-targets`; внутрішні механізми, специфічні для каналу, + залишаються за локальним швом `api.js` або `runtime-api.js` Plugin-власника. - Підшляхи, специфічні для можливостей, такі як `image-generation`, - `media-understanding` і `speech`, існують, оскільки вбудовані/власні Plugin - уже використовують їх сьогодні. Їх наявність сама по собі не означає, що кожний експортований допоміжний засіб є - довгостроковим замороженим зовнішнім контрактом. + `media-understanding` і `speech`, існують, бо вбудовані/власні Plugin + уже використовують їх сьогодні. Їхня наявність сама по собі не означає, що кожен + експортований допоміжний засіб є довгостроковим незмінним зовнішнім контрактом. ## Схеми інструмента повідомлень -Plugin мають володіти внесками в схему `describeMessageTool(...)`, специфічними для каналу. -Зберігайте поля, специфічні для постачальника, у плагіні, а не в спільному core. +Plugin мають володіти внесками до схеми `describeMessageTool(...)`, специфічними для каналу. +Зберігайте поля, специфічні для провайдера, у Plugin, а не в спільному core. -Для спільних переносних фрагментів схем повторно використовуйте загальні допоміжні засоби, експортовані через -`openclaw/plugin-sdk/channel-actions`: +Для спільних переносних фрагментів схем повторно використовуйте узагальнені допоміжні засоби, +експортовані через `openclaw/plugin-sdk/channel-actions`: - `createMessageToolButtonsSchema()` для payload у стилі сітки кнопок - `createMessageToolCardSchema()` для структурованих payload карток -Якщо форма схеми має сенс лише для одного постачальника, визначайте її у власному -джерелі цього плагіна, а не просувайте в спільний SDK. +Якщо форма схеми має сенс лише для одного провайдера, визначайте її у власному +коді цього Plugin замість просування в спільний SDK. ## Визначення цілей каналу Plugin каналів мають володіти семантикою цілей, специфічною для каналу. Зберігайте спільний -хост outbound узагальненим і використовуйте поверхню адаптера повідомлень для правил постачальника: +хост вихідних повідомлень узагальненим і використовуйте поверхню адаптера повідомлень для правил провайдера: -- `messaging.inferTargetChatType({ to })` визначає, чи слід сприймати нормалізовану ціль - як `direct`, `group` або `channel` до пошуку в каталозі. -- `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє core, чи потрібно - для певного вводу одразу перейти до визначення як id-подібного значення замість пошуку в каталозі. -- `messaging.targetResolver.resolveTarget(...)` — це резервний варіант плагіна, коли - core потребує фінального визначення, що належить постачальнику, після нормалізації або - після промаху в каталозі. -- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту outbound-сесії, специфічною для постачальника, - після того як ціль визначено. +- `messaging.inferTargetChatType({ to })` визначає, чи нормалізовану ціль + слід трактувати як `direct`, `group` або `channel` до пошуку в директорії. +- `messaging.targetResolver.looksLikeId(raw, normalized)` повідомляє core, чи + слід вводу одразу перейти до визначення як id-подібної цілі, а не до пошуку в директорії. +- `messaging.targetResolver.resolveTarget(...)` — це fallback Plugin, коли + core потребує остаточного визначення, що належить провайдеру, після нормалізації або + після промаху в директорії. +- `messaging.resolveOutboundSessionRoute(...)` володіє побудовою маршруту сесії, специфічного для провайдера, + після того як ціль уже визначена. Рекомендований поділ: -- Використовуйте `inferTargetChatType` для рішень за категоріями, які мають ухвалюватися до - пошуку peer-ів/груп. -- Використовуйте `looksLikeId` для перевірок виду «сприймати це як явний/native id цілі». -- Використовуйте `resolveTarget` для резервної нормалізації, специфічної для постачальника, а не для - широкого пошуку в каталозі. -- Зберігайте native id постачальника, такі як chat id, thread id, JID, handle і room id, - усередині значень `target` або параметрів, специфічних для постачальника, а не в загальних полях SDK. +- Використовуйте `inferTargetChatType` для категорійних рішень, які мають відбуватися до + пошуку peer/group. +- Використовуйте `looksLikeId` для перевірок «трактувати це як явний/native id цілі». +- Використовуйте `resolveTarget` для fallback-нормалізації, специфічної для провайдера, а не для + широкого пошуку в директорії. +- Зберігайте native id провайдера, такі як id чату, id гілки, JID, handle та id кімнати, + всередині значень `target` або параметрів, специфічних для провайдера, а не в узагальнених полях SDK. -## Каталоги на основі конфігурації +## Директорії на основі конфігурації -Plugin, які отримують записи каталогу з конфігурації, повинні тримати цю логіку в -плагіні та повторно використовувати спільні допоміжні засоби з +Plugin, які виводять записи директорії з конфігурації, мають зберігати цю логіку в +Plugin і повторно використовувати спільні допоміжні засоби з `openclaw/plugin-sdk/directory-runtime`. -Використовуйте це, коли каналу потрібні каталоги peer-ів/груп на основі конфігурації, як-от: +Використовуйте це, коли каналу потрібні peer/group на основі конфігурації, наприклад: -- peer-и DM, керовані allowlist -- налаштовані мапи каналів/груп -- статичні резервні каталоги, прив’язані до облікового запису +- peer DM на основі allowlist +- налаштовані maps каналів/group +- fallback статичної директорії в межах облікового запису -Спільні допоміжні засоби в `directory-runtime` обробляють лише загальні операції: +Спільні допоміжні засоби в `directory-runtime` обробляють лише узагальнені операції: -- фільтрування запитів -- застосування обмежень -- допоміжні засоби дедуплікації/нормалізації +- фільтрацію запитів +- застосування ліміту +- допоміжні засоби deduping/normalization - побудову `ChannelDirectoryEntry[]` -Інспекція облікового запису й нормалізація id, специфічні для каналу, мають залишатися в -реалізації плагіна. +Інспекція облікових записів і нормалізація id, специфічні для каналу, мають залишатися +в реалізації Plugin. -## Каталоги постачальників +## Каталоги провайдерів -Плагіни постачальників можуть визначати каталоги моделей для inference через +Plugin провайдерів можуть визначати каталоги моделей для інференсу за допомогою `registerProvider({ catalog: { run(...) { ... } } })`. `catalog.run(...)` повертає ту саму форму, яку OpenClaw записує в `models.providers`: -- `{ provider }` для одного запису постачальника -- `{ providers }` для кількох записів постачальників +- `{ provider }` для одного запису провайдера +- `{ providers }` для кількох записів провайдерів -Використовуйте `catalog`, коли плагін володіє id моделей, типовими значеннями base URL або метаданими моделей, захищеними auth, специфічними для постачальника. +Використовуйте `catalog`, коли Plugin володіє id моделей, базовими значеннями URL або +метаданими моделей, захищеними auth, специфічними для провайдера. -`catalog.order` керує тим, коли каталог плагіна об’єднується відносно -вбудованих неявних постачальників OpenClaw: +`catalog.order` керує тим, коли каталог Plugin зливається відносно +вбудованих неявних провайдерів OpenClaw: -- `simple`: звичайні постачальники на основі API-key або env -- `profile`: постачальники, які з’являються, коли існують auth-профілі -- `paired`: постачальники, які синтезують кілька пов’язаних записів постачальників -- `late`: останній прохід, після інших неявних постачальників +- `simple`: прості провайдери з API-ключем або на основі env +- `profile`: провайдери, які з’являються, коли існують профілі auth +- `paired`: провайдери, які синтезують кілька пов’язаних записів провайдерів +- `late`: останній прохід, після інших неявних провайдерів -Пізніші постачальники перемагають при колізії ключів, тож плагіни можуть навмисно -перевизначати вбудований запис постачальника з тим самим id постачальника. +Пізніші провайдери перемагають у разі колізії ключів, тому Plugin можуть +навмисно перевизначити вбудований запис провайдера з тим самим id провайдера. Сумісність: - `discovery` усе ще працює як застарілий псевдонім - якщо зареєстровано і `catalog`, і `discovery`, OpenClaw використовує `catalog` -## Канальна інспекція лише для читання +## Інспекція каналу лише для читання -Якщо ваш плагін реєструє канал, віддавайте перевагу реалізації +Якщо ваш Plugin реєструє канал, надавайте перевагу реалізації `plugin.config.inspectAccount(cfg, accountId)` разом із `resolveAccount(...)`. Чому: -- `resolveAccount(...)` — це шлях runtime. Він може припускати, що облікові дані - повністю матеріалізовані, і може швидко завершуватися помилкою, коли потрібні секрети відсутні. +- `resolveAccount(...)` — це шлях runtime. Йому дозволено припускати, що облікові дані + повністю матеріалізовані, і швидко завершуватися з помилкою, якщо потрібних секретів бракує. - Шляхи команд лише для читання, такі як `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve` і потоки - doctor/config repair, не повинні потребувати матеріалізації облікових даних runtime лише для - опису конфігурації. + `openclaw channels status`, `openclaw channels resolve`, а також потоки doctor/config + repair не повинні вимагати матеріалізації runtime-облікових даних лише для опису конфігурації. Рекомендована поведінка `inspectAccount(...)`: -- Повертає лише описовий стан облікового запису. -- Зберігає `enabled` і `configured`. -- За потреби включає поля джерела/статусу облікових даних, наприклад: +- Повертайте лише описовий стан облікового запису. +- Зберігайте `enabled` і `configured`. +- Додавайте поля джерела/стану облікових даних, коли це доречно, наприклад: - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Вам не потрібно повертати сирі значення токенів лише для звіту про доступність у режимі тільки читання. Достатньо повернути `tokenStatus: "available"` (і відповідне поле джерела) для команд у стилі status. +- Вам не потрібно повертати сирі значення токенів лише для повідомлення про + доступність у режимі лише читання. Для команд у стилі status достатньо повертати `tokenStatus: "available"` + (і відповідне поле джерела). - Використовуйте `configured_unavailable`, коли облікові дані налаштовані через SecretRef, але недоступні в поточному шляху команди. -Це дозволяє командам лише для читання повідомляти «налаштовано, але недоступно в цьому шляху команди» -замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштований. +Це дозволяє командам лише для читання повідомляти «налаштовано, але недоступно в цьому +шляху команди» замість аварійного завершення або хибного повідомлення, що обліковий запис не налаштований. -## Пакетні набори +## Пакети-pack -Каталог плагіна може містити `package.json` з `openclaw.extensions`: +Каталог Plugin може містити `package.json` з `openclaw.extensions`: ```json { @@ -1365,63 +1386,63 @@ Plugin, які отримують записи каталогу з конфіг } ``` -Кожен запис стає плагіном. Якщо набір перелічує кілька розширень, id плагіна +Кожен запис стає Plugin. Якщо pack перелічує кілька розширень, id Plugin стає `name/`. -Якщо ваш плагін імпортує залежності npm, установіть їх у цьому каталозі, щоб +Якщо ваш Plugin імпортує npm-залежності, встановіть їх у цьому каталозі, щоб `node_modules` був доступний (`npm install` / `pnpm install`). -Захисне обмеження безпеки: кожен запис `openclaw.extensions` має залишатися в межах каталогу плагіна -після визначення символічних посилань. Записи, які виходять за межі каталогу пакета, +Захисне обмеження безпеки: кожен запис `openclaw.extensions` має залишатися в межах каталогу Plugin +після визначення symlink. Записи, які виходять за межі каталогу пакета, відхиляються. -Примітка щодо безпеки: `openclaw plugins install` установлює залежності плагіна через -`npm install --omit=dev --ignore-scripts` (без lifecycle scripts і без dev dependencies у runtime). Зберігайте дерева залежностей плагіна як «чистий JS/TS» і уникайте пакетів, яким потрібні збірки через `postinstall`. +Примітка щодо безпеки: `openclaw plugins install` встановлює залежності Plugin через +`npm install --omit=dev --ignore-scripts` (без lifecycle scripts і без dev-залежностей під час runtime). Зберігайте дерева залежностей Plugin «чистими JS/TS» і уникайте пакетів, яким потрібні збірки через `postinstall`. Необов’язково: `openclaw.setupEntry` може вказувати на легкий модуль лише для setup. -Коли OpenClaw потребує поверхні setup для вимкненого channel plugin, або -коли плагін каналу увімкнено, але ще не налаштовано, він завантажує `setupEntry` -замість повної точки входу плагіна. Це робить запуск і налаштування легшими, -коли головна точка входу вашого плагіна також під’єднує інструменти, хуки або інший код лише для runtime. +Коли OpenClaw потребує поверхонь setup для вимкненого Plugin каналу або +коли Plugin каналу ввімкнений, але ще не налаштований, він завантажує `setupEntry` +замість повної точки входу Plugin. Це зберігає запуск і setup легшими, +коли основна точка входу Plugin також підключає інструменти, хуки чи інший код лише для runtime. Необов’язково: `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -може перевести channel plugin на той самий шлях `setupEntry` під час -фази запуску gateway до початку прослуховування, навіть коли канал уже налаштовано. +може перевести Plugin каналу на той самий шлях `setupEntry` під час +фази запуску gateway до початку прослуховування, навіть якщо канал уже налаштований. Використовуйте це лише тоді, коли `setupEntry` повністю покриває поверхню запуску, яка має існувати -до того, як gateway почне прослуховування. На практиці це означає, що точка входу setup -має реєструвати кожну можливість, що належить каналу і від якої залежить запуск, наприклад: +до того, як gateway почне прослуховувати. На практиці це означає, що точка входу setup +має реєструвати кожну можливість, що належить каналу, від якої залежить запуск, наприклад: - саму реєстрацію каналу -- будь-які HTTP-маршрути, які мають бути доступні до того, як gateway почне прослуховування -- будь-які методи gateway, інструменти або служби, які мають існувати в той самий період +- будь-які HTTP-маршрути, які мають бути доступні до того, як gateway почне прослуховувати +- будь-які методи Gateway, інструменти або сервіси, які мають існувати в тому самому вікні -Якщо ваша повна точка входу все ще володіє будь-якою обов’язковою можливістю запуску, не вмикайте -цей прапорець. Залишайте плагін у типовій поведінці й дозвольте OpenClaw завантажити повну точку входу під час запуску. +Якщо ваша повна точка входу все ще володіє будь-якою потрібною можливістю запуску, не вмикайте +цей прапорець. Залиште Plugin на типовій поведінці й дозвольте OpenClaw завантажити +повну точку входу під час запуску. -Вбудовані канали також можуть публікувати допоміжні засоби поверхні контракту лише для setup, до яких core -може звертатися до завантаження повного runtime каналу. Поточна поверхня -просування setup така: +Вбудовані канали також можуть публікувати допоміжні засоби поверхні контракту лише для setup, які core +може використовувати до завантаження повного runtime каналу. Поточна поверхня просування setup така: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -Core використовує цю поверхню, коли йому потрібно підвищити застарілу конфігурацію каналу з одним обліковим записом -до `channels..accounts.*` без завантаження повної точки входу плагіна. -Matrix — поточний вбудований приклад: він переносить лише ключі auth/bootstrap -до іменованого облікового запису, коли іменовані облікові записи вже існують, і може -зберігати налаштований неканонічний ключ default-account замість того, щоб завжди створювати +Core використовує цю поверхню, коли йому потрібно просунути застарілу конфігурацію каналу з одним обліковим записом у +`channels..accounts.*` без завантаження повної точки входу Plugin. +Matrix — поточний вбудований приклад: він переміщує лише ключі auth/bootstrap у +іменований просунутий обліковий запис, коли іменовані облікові записи вже існують, і може +зберегти налаштований неканонічний ключ типового облікового запису замість того, щоб завжди створювати `accounts.default`. -Ці адаптери patch для setup зберігають ліниве виявлення поверхні контракту вбудованих компонентів. Час -імпорту залишається невеликим; поверхня просування завантажується лише під час першого використання -замість повторного входу у запуск вбудованого каналу під час імпорту модуля. +Ці адаптери патчів setup зберігають ліниве виявлення поверхні контракту вбудованих рішень. Час імпорту +залишається малим; поверхня просування завантажується лише під час першого використання замість +повторного входу в запуск вбудованого каналу під час імпорту модуля. -Коли ці поверхні запуску містять методи Gateway RPC, зберігайте їх під -префіксом, специфічним для плагіна. Простори імен адміністратора core (`config.*`, +Коли ці поверхні запуску містять методи Gateway RPC, зберігайте їх на +префіксі, специфічному для Plugin. Простори імен admin core (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди визначаються -як `operator.admin`, навіть якщо плагін запитує вужчий scope. +як `operator.admin`, навіть якщо Plugin запитує вужчий scope. Приклад: @@ -1440,8 +1461,8 @@ Matrix — поточний вбудований приклад: він пере ### Метадані каталогу каналів -Плагіни каналів можуть оголошувати метадані setup/discovery через `openclaw.channel`, а -підказки щодо встановлення — через `openclaw.install`. Це дозволяє core не містити власних даних каталогу. +Plugin каналів можуть оголошувати метадані setup/discovery через `openclaw.channel` і +підказки встановлення через `openclaw.install`. Це дозволяє не тримати дані каталогу в core. Приклад: @@ -1469,41 +1490,41 @@ Matrix — поточний вбудований приклад: він пере } ``` -Корисні поля `openclaw.channel` поза мінімальним прикладом: +Корисні поля `openclaw.channel`, окрім мінімального прикладу: - `detailLabel`: вторинна мітка для багатших поверхонь каталогу/статусу -- `docsLabel`: перевизначає текст посилання на документацію -- `preferOver`: id плагінів/каналів із нижчим пріоритетом, які цей запис каталогу має випереджати -- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: елементи керування текстом поверхні вибору -- `markdownCapable`: позначає канал як сумісний із markdown для рішень щодо вихідного форматування +- `docsLabel`: перевизначення тексту посилання для посилання на документацію +- `preferOver`: id Plugin/каналів із нижчим пріоритетом, які цей запис каталогу має перевершувати +- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: керування текстом поверхні вибору +- `markdownCapable`: позначає канал як сумісний із markdown для рішень форматування вихідних повідомлень - `exposure.configured`: приховує канал із поверхонь списку налаштованих каналів, якщо встановлено `false` -- `exposure.setup`: приховує канал з інтерактивних picker-ів setup/configure, якщо встановлено `false` +- `exposure.setup`: приховує канал з інтерактивних вибирачів setup/configure, якщо встановлено `false` - `exposure.docs`: позначає канал як внутрішній/приватний для поверхонь навігації документації - `showConfigured` / `showInSetup`: застарілі псевдоніми, які все ще приймаються для сумісності; надавайте перевагу `exposure` - `quickstartAllowFrom`: додає канал до стандартного потоку quickstart `allowFrom` -- `forceAccountBinding`: вимагає явної прив’язки облікового запису, навіть коли існує лише один обліковий запис -- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення цілей announce +- `forceAccountBinding`: вимагає явного прив’язування облікового запису, навіть якщо існує лише один обліковий запис +- `preferSessionLookupForAnnounceTarget`: надає перевагу пошуку сесії під час визначення announce target -OpenClaw також може об’єднувати **зовнішні каталоги каналів** (наприклад, експорт -реєстру MPM). Помістіть JSON-файл в одне з таких місць: +OpenClaw також може зливати **зовнішні каталоги каналів** (наприклад, експорт +реєстру MPM). Розмістіть JSON-файл в одному з таких місць: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` Або вкажіть `OPENCLAW_PLUGIN_CATALOG_PATHS` (або `OPENCLAW_MPM_CATALOG_PATHS`) на -один чи кілька JSON-файлів (розділених комами/крапками з комою/`PATH`). Кожен файл має +один чи кілька JSON-файлів (розділених комою/крапкою з комою/роздільником `PATH`). Кожен файл має містити `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. Парсер також приймає `"packages"` або `"plugins"` як застарілі псевдоніми для ключа `"entries"`. -## Плагіни контекстного рушія +## Plugin рушія контексту -Плагіни контекстного рушія володіють оркестрацією контексту сесії для ingest, assembly -і Compaction. Реєструйте їх зі свого плагіна через +Plugin рушія контексту володіють оркестрацією контексту сесії для ingest, assembly +і Compaction. Реєструйте їх зі свого Plugin через `api.registerContextEngine(id, factory)`, а потім вибирайте активний рушій через `plugins.slots.contextEngine`. -Використовуйте це, коли вашому плагіну потрібно замінити або розширити типовий -контекстний конвеєр, а не просто додати пошук у пам’яті або хуки. +Використовуйте це, коли вашому Plugin потрібно замінити або розширити типовий +конвеєр контексту, а не просто додати пошук у пам’яті чи хуки. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -1569,43 +1590,43 @@ export default function (api) { ## Додавання нової можливості -Коли плагіну потрібна поведінка, яка не вписується в поточний API, не обходьте -систему плагінів через приватне звернення всередину. Додайте відсутню можливість. +Коли Plugin потребує поведінки, яка не вписується в поточний API, не обходьте +систему Plugin через приватне звернення всередину. Додайте відсутню можливість. Рекомендована послідовність: 1. визначте контракт core - Вирішіть, якою спільною поведінкою має володіти core: політика, резервний сценарій, об’єднання конфігурації, - життєвий цикл, семантика для каналів і форма допоміжного засобу runtime. -2. додайте типізовані поверхні реєстрації/runtime плагіна - Розширте `OpenClawPluginApi` та/або `api.runtime` найменшою корисною + Вирішіть, якою спільною поведінкою має володіти core: політика, fallback, злиття конфігурації, + життєвий цикл, семантика для каналів і форма допоміжного runtime-засобу. +2. додайте типізовані поверхні реєстрації/runtime для Plugin + Розширте `OpenClawPluginApi` і/або `api.runtime` найменшою корисною типізованою поверхнею можливості. -3. під’єднайте core + споживачів каналів/можливостей - Канали та плагіни можливостей мають використовувати нову можливість через core, - а не напряму імпортувати реалізацію вендора. -4. зареєструйте реалізації вендорів - Потім вендорські Plugin реєструють свої бекенди для цієї можливості. -5. додайте покриття контракту - Додайте тести, щоб з часом форма володіння та реєстрації залишалася явною. +3. під’єднайте споживачів core + каналів/функцій + Канали та Plugin функцій мають споживати нову можливість через core, + а не імпортуючи реалізацію vendor напряму. +4. зареєструйте реалізації vendor + Потім vendor Plugin реєструють свої backends для цієї можливості. +5. додайте покриття контрактів + Додайте тести, щоб володіння і форма реєстрації з часом залишалися явними. -Саме так OpenClaw залишається opinionated, не стаючи жорстко прив’язаним до -світогляду одного постачальника. Див. [Збірник рецептів можливостей](/uk/plugins/architecture), -щоб отримати конкретний контрольний список файлів і готовий приклад. +Саме так OpenClaw зберігає чітку архітектурну позицію, не стаючи жорстко прив’язаним до +світогляду одного провайдера. Дивіться [Capability Cookbook](/uk/plugins/architecture) +для конкретного контрольного списку файлів і готового прикладу. ### Контрольний список можливості -Коли ви додаєте нову можливість, реалізація зазвичай має торкатися цих -поверхонь разом: +Коли ви додаєте нову можливість, реалізація зазвичай має одночасно торкатися +таких поверхонь: -- типи контракту core у `src//types.ts` -- runner/helper runtime core у `src//runtime.ts` -- поверхня реєстрації API плагіна в `src/plugins/types.ts` -- під’єднання реєстру плагінів у `src/plugins/registry.ts` -- відкриття runtime плагіна в `src/plugins/runtime/*`, коли плагіни можливостей/каналів - мають це використовувати +- типи контракту core в `src//types.ts` +- runner/допоміжний runtime-засіб core в `src//runtime.ts` +- поверхня реєстрації API Plugin в `src/plugins/types.ts` +- підключення реєстру Plugin в `src/plugins/registry.ts` +- відкриття runtime Plugin у `src/plugins/runtime/*`, коли Plugin функцій/каналів + мають це споживати - допоміжні засоби capture/test у `src/test-utils/plugin-registration.ts` -- перевірки володіння/контракту в `src/plugins/contracts/registry.ts` -- документація для операторів/плагінів у `docs/` +- перевірки володіння/контрактів у `src/plugins/contracts/registry.ts` +- документація для операторів/Plugin у `docs/` Якщо однієї з цих поверхонь бракує, це зазвичай ознака того, що можливість ще не повністю інтегрована. @@ -1638,7 +1659,7 @@ const clip = await api.runtime.videoGeneration.generate({ }); ``` -Шаблон contract test: +Шаблон тесту контракту: ```ts expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); @@ -1647,6 +1668,6 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Це зберігає правило простим: - core володіє контрактом можливості + оркестрацією -- вендорські Plugin володіють реалізаціями вендорів -- плагіни можливостей/каналів використовують допоміжні засоби runtime -- contract tests зберігають явність володіння +- vendor Plugin володіють реалізаціями vendor +- Plugin функцій/каналів споживають допоміжні runtime-засоби +- тести контрактів зберігають явність володіння diff --git a/docs/uk/plugins/sdk-channel-plugins.md b/docs/uk/plugins/sdk-channel-plugins.md index f1557f464..52374b0bf 100644 --- a/docs/uk/plugins/sdk-channel-plugins.md +++ b/docs/uk/plugins/sdk-channel-plugins.md @@ -1,104 +1,113 @@ --- read_when: - - Ви створюєте новий плагін каналу обміну повідомленнями + - Ви створюєте новий Plugin каналу обміну повідомленнями - Ви хочете підключити OpenClaw до платформи обміну повідомленнями - Вам потрібно зрозуміти поверхню адаптера ChannelPlugin sidebarTitle: Channel Plugins -summary: Покроковий посібник зі створення плагіна каналу обміну повідомленнями для OpenClaw -title: Створення плагінів каналів +summary: Покроковий посібник зі створення Plugin каналу обміну повідомленнями для OpenClaw +title: Створення Plugin каналів x-i18n: - generated_at: "2026-04-10T20:41:27Z" + generated_at: "2026-04-14T16:24:14Z" model: gpt-5.4 provider: openai - source_hash: 8a026e924f9ae8a3ddd46287674443bcfccb0247be504261522b078e1f440aef + source_hash: a7f4c746fe3163a8880e14c433f4db4a1475535d91716a53fb879551d8d62f65 source_path: plugins/sdk-channel-plugins.md workflow: 15 --- -# Створення плагінів каналів +# Створення Plugin каналів -Цей посібник покроково пояснює створення плагіна каналу, який підключає OpenClaw до -платформи обміну повідомленнями. Наприкінці у вас буде робочий канал із захистом DM, -сполученням, потоками відповідей та вихідними повідомленнями. +Цей посібник описує створення Plugin каналу, який підключає OpenClaw до +платформи обміну повідомленнями. Наприкінці у вас буде робочий канал із +безпекою DM, сполученням, ланцюжками відповідей і вихідними повідомленнями. - Якщо ви раніше не створювали жодного плагіна OpenClaw, спочатку прочитайте - [Початок роботи](/uk/plugins/building-plugins), щоб ознайомитися з базовою - структурою пакета та налаштуванням маніфесту. + Якщо ви раніше не створювали жодного Plugin для OpenClaw, спочатку прочитайте + [Getting Started](/uk/plugins/building-plugins) про базову структуру пакета та + налаштування маніфесту. -## Як працюють плагіни каналів +## Як працюють Plugin каналів -Плагінам каналів не потрібні власні інструменти send/edit/react. OpenClaw зберігає -один спільний інструмент `message` у core. Ваш плагін відповідає за: +Plugin каналів не потребують власних інструментів send/edit/react. OpenClaw +зберігає один спільний інструмент `message` у ядрі. Ваш Plugin відповідає за: -- **Конфігурацію** — визначення облікового запису та майстер налаштування -- **Безпеку** — політику DM і allowlist-списки -- **Сполучення** — потік підтвердження DM -- **Граматику сесій** — як ідентифікатори розмов, специфічні для провайдера, відображаються на базові чати, ідентифікатори потоків і резервні батьківські значення -- **Вихідні повідомлення** — надсилання тексту, медіа та опитувань на платформу -- **Потоковість** — як організовуються потоки відповідей +- **Конфігурацію** — визначення облікових записів і майстер налаштування +- **Безпеку** — політику DM і списки дозволених +- **Сполучення** — процес схвалення DM +- **Граматику сесії** — як ідентифікатори розмов, специфічні для провайдера, відображаються на базові чати, ідентифікатори гілок і резервні батьківські варіанти +- **Вихідні повідомлення** — надсилання тексту, медіа й опитувань на платформу +- **Ланцюжки** — як організовуються відповіді в гілках -Core відповідає за спільний інструмент повідомлень, підключення prompt, зовнішню форму ключа сесії, -загальне ведення обліку `:thread:` та диспетчеризацію. +Ядро відповідає за спільний інструмент повідомлень, підключення промптів, зовнішню форму ключа сесії, +загальний облік `:thread:` і диспетчеризацію. -Якщо ваша платформа зберігає додаткову область видимості всередині ідентифікаторів розмов, -залишайте цей парсинг у плагіні за допомогою `messaging.resolveSessionConversation(...)`. Це канонічний хук -для зіставлення `rawId` з базовим ідентифікатором розмови, необов’язковим ідентифікатором потоку, -явним `baseConversationId` та будь-якими `parentConversationCandidates`. -Коли ви повертаєте `parentConversationCandidates`, зберігайте їхній порядок від -найвужчого батьківського елемента до найширшої/базової розмови. +Якщо ваш канал додає параметри інструмента повідомлень, які містять джерела медіа, вкажіть ці +назви параметрів через `describeMessageTool(...).mediaSourceParams`. Ядро використовує +цей явний список для нормалізації шляхів sandbox і політики доступу до вихідних медіа, +тому Plugin не потребують особливих винятків у спільному ядрі для специфічних для провайдера +параметрів аватарів, вкладень або зображень обкладинки. +Переважно повертати мапу, прив’язану до дій, наприклад +`{ "set-profile": ["avatarUrl", "avatarPath"] }`, щоб не пов’язані дії не успадковували +медіааргументи іншої дії. Плоский масив також працює для параметрів, які +навмисно спільні для кожної доступної дії. -Вбудовані плагіни, яким потрібен той самий парсинг до запуску реєстру каналів, -також можуть експортувати файл верхнього рівня `session-key-api.ts` з відповідним -експортом `resolveSessionConversation(...)`. Core використовує цю безпечну для bootstrap поверхню -лише тоді, коли реєстр runtime-плагінів ще недоступний. +Якщо ваша платформа зберігає додаткову область видимості в ідентифікаторах розмов, зберігайте цей розбір +у Plugin за допомогою `messaging.resolveSessionConversation(...)`. Це канонічний хук +для відображення `rawId` на базовий ідентифікатор розмови, необов’язковий ідентифікатор гілки, +явний `baseConversationId` і будь-які `parentConversationCandidates`. +Коли ви повертаєте `parentConversationCandidates`, зберігайте їх упорядкованими від +найвужчого батьківського варіанта до найширшої/базової розмови. -`messaging.resolveParentConversationCandidates(...)` залишається доступним як застарілий -резервний механізм сумісності, коли плагіну потрібні лише резервні батьківські значення -поверх загального/raw id. Якщо існують обидва хуки, core спочатку використовує -`resolveSessionConversation(...).parentConversationCandidates` і лише потім +Вбудовані Plugin, яким потрібен той самий розбір до запуску реєстру каналів, +також можуть надавати файл верхнього рівня `session-key-api.ts` із відповідним +експортом `resolveSessionConversation(...)`. Ядро використовує цю безпечну для bootstrap поверхню +лише тоді, коли реєстр Plugin середовища виконання ще недоступний. + +`messaging.resolveParentConversationCandidates(...)` залишається доступним як застарілий резервний варіант сумісності, коли Plugin потрібні лише +резервні батьківські варіанти поверх загального/raw id. Якщо існують обидва хуки, ядро використовує +спочатку `resolveSessionConversation(...).parentConversationCandidates` і лише потім повертається до `resolveParentConversationCandidates(...)`, якщо канонічний хук їх не вказує. -## Підтвердження та можливості каналу +## Схвалення та можливості каналів -Більшості плагінів каналів не потрібен код, специфічний для підтверджень. +Більшості Plugin каналів не потрібен код, специфічний для схвалень. -- Core відповідає за `/approve` у тому самому чаті, спільні payload-кнопок підтвердження та загальну резервну доставку. -- Віддавайте перевагу одному об’єкту `approvalCapability` у плагіні каналу, якщо каналу потрібна поведінка, специфічна для підтверджень. -- `ChannelPlugin.approvals` видалено. Розміщуйте факти доставки/нативного режиму/рендерингу/автентифікації підтверджень у `approvalCapability`. -- `plugin.auth` призначений лише для login/logout; core більше не читає хуки автентифікації підтверджень із цього об’єкта. -- `approvalCapability.authorizeActorAction` і `approvalCapability.getActionAvailabilityState` — це канонічна поверхня для auth підтверджень. -- Використовуйте `approvalCapability.getActionAvailabilityState` для доступності auth підтверджень у тому самому чаті. -- Якщо ваш канал надає нативні exec-підтвердження, використовуйте `approvalCapability.getExecInitiatingSurfaceState` для стану ініціювальної поверхні/нативного клієнта, коли він відрізняється від auth підтвердження в тому самому чаті. Core використовує цей exec-специфічний хук, щоб розрізняти `enabled` і `disabled`, визначати, чи підтримує ініціювальний канал нативні exec-підтвердження, і включати канал до інструкцій резервного сценарію нативного клієнта. `createApproverRestrictedNativeApprovalCapability(...)` заповнює це для типового випадку. -- Використовуйте `outbound.shouldSuppressLocalPayloadPrompt` або `outbound.beforeDeliverPayload` для поведінки життєвого циклу payload, специфічної для каналу, наприклад приховування дубльованих локальних prompt-підтверджень або надсилання індикаторів набору тексту перед доставкою. -- Використовуйте `approvalCapability.delivery` лише для нативної маршрутизації підтверджень або придушення резервної доставки. -- Використовуйте `approvalCapability.nativeRuntime` для фактів нативних підтверджень, що належать каналу. Зберігайте його лінивим на гарячих точках входу каналу за допомогою `createLazyChannelApprovalNativeRuntimeAdapter(...)`, який може імпортувати ваш runtime-модуль на вимогу, водночас дозволяючи core зібрати життєвий цикл підтвердження. -- Використовуйте `approvalCapability.render` лише тоді, коли каналу справді потрібні власні payload підтвердження замість спільного рендерера. -- Використовуйте `approvalCapability.describeExecApprovalSetup`, коли канал хоче, щоб відповідь на вимкнений шлях пояснювала точні параметри конфігурації, потрібні для ввімкнення нативних exec-підтверджень. Хук отримує `{ channel, channelLabel, accountId }`; канали з іменованими обліковими записами мають рендерити шляхи з областю облікового запису, такі як `channels..accounts..execApprovals.*`, замість дефолтів верхнього рівня. -- Якщо канал може вивести стабільні DM-ідентичності на кшталт власника з наявної конфігурації, використовуйте `createResolvedApproverActionAuthAdapter` з `openclaw/plugin-sdk/approval-runtime`, щоб обмежити `/approve` у тому самому чаті без додавання логіки підтверджень у core. -- Якщо каналу потрібна нативна доставка підтверджень, зосередьте код каналу на нормалізації цілі та фактах транспорту/представлення. Використовуйте `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` і `createApproverRestrictedNativeApprovalCapability` з `openclaw/plugin-sdk/approval-runtime`. Розміщуйте факти, специфічні для каналу, за `approvalCapability.nativeRuntime`, бажано через `createChannelApprovalNativeRuntimeAdapter(...)` або `createLazyChannelApprovalNativeRuntimeAdapter(...)`, щоб core міг зібрати обробник і відповідати за фільтрацію запитів, маршрутизацію, dedupe, строки дії, підписку gateway та сповіщення про маршрутизацію в інше місце. `nativeRuntime` поділено на кілька менших поверхонь: -- `availability` — чи налаштований обліковий запис і чи потрібно обробляти запит -- `presentation` — відображення спільної view model підтверджень у нативні payload у станах pending/resolved/expired або фінальні дії -- `transport` — підготовка цілей, а також надсилання/оновлення/видалення нативних повідомлень підтвердження +- Ядро відповідає за `/approve` у тому самому чаті, спільні payload кнопок схвалення та загальну резервну доставку. +- Віддавайте перевагу одному об’єкту `approvalCapability` у Plugin каналу, коли каналу потрібна поведінка, специфічна для схвалень. +- `ChannelPlugin.approvals` видалено. Розміщуйте факти про доставку/нативний режим/рендеринг/автентифікацію схвалень у `approvalCapability`. +- `plugin.auth` призначений лише для login/logout; ядро більше не читає хуки автентифікації схвалень із цього об’єкта. +- `approvalCapability.authorizeActorAction` і `approvalCapability.getActionAvailabilityState` — це канонічна поверхня автентифікації схвалень. +- Використовуйте `approvalCapability.getActionAvailabilityState` для доступності автентифікації схвалень у тому самому чаті. +- Якщо ваш канал надає нативні exec-схвалення, використовуйте `approvalCapability.getExecInitiatingSurfaceState` для стану ініціювальної поверхні/нативного клієнта, коли він відрізняється від автентифікації схвалень у тому самому чаті. Ядро використовує цей специфічний для exec хук, щоб розрізняти `enabled` і `disabled`, визначати, чи підтримує ініціювальний канал нативні exec-схвалення, і включати канал у підказки резервного сценарію для нативного клієнта. `createApproverRestrictedNativeApprovalCapability(...)` заповнює це для поширеного випадку. +- Використовуйте `outbound.shouldSuppressLocalPayloadPrompt` або `outbound.beforeDeliverPayload` для специфічної для каналу поведінки життєвого циклу payload, наприклад приховування дублікатів локальних підказок схвалення або надсилання індикаторів набору тексту перед доставкою. +- Використовуйте `approvalCapability.delivery` лише для нативної маршрутизації схвалень або вимкнення резервної доставки. +- Використовуйте `approvalCapability.nativeRuntime` для фактів нативних схвалень, що належать каналу. Зберігайте його ледачим на гарячих точках входу каналу за допомогою `createLazyChannelApprovalNativeRuntimeAdapter(...)`, який може імпортувати ваш модуль середовища виконання на вимогу, водночас дозволяючи ядру збирати життєвий цикл схвалення. +- Використовуйте `approvalCapability.render` лише тоді, коли каналу справді потрібні власні payload схвалення замість спільного рендерера. +- Використовуйте `approvalCapability.describeExecApprovalSetup`, коли канал хоче, щоб відповідь на вимкнений шлях пояснювала точні параметри конфігурації, потрібні для ввімкнення нативних exec-схвалень. Хук отримує `{ channel, channelLabel, accountId }`; канали з іменованими обліковими записами мають виводити шляхи з областю видимості облікового запису, наприклад `channels..accounts..execApprovals.*`, а не значення верхнього рівня за замовчуванням. +- Якщо канал може вивести стабільні схожі на власника DM-ідентичності з наявної конфігурації, використовуйте `createResolvedApproverActionAuthAdapter` з `openclaw/plugin-sdk/approval-runtime`, щоб обмежити `/approve` у тому самому чаті без додавання специфічної для схвалень логіки ядра. +- Якщо каналу потрібна нативна доставка схвалень, зосередьте код каналу на нормалізації цілі та фактах транспорту/представлення. Використовуйте `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` і `createApproverRestrictedNativeApprovalCapability` з `openclaw/plugin-sdk/approval-runtime`. Розміщуйте факти, специфічні для каналу, за `approvalCapability.nativeRuntime`, бажано через `createChannelApprovalNativeRuntimeAdapter(...)` або `createLazyChannelApprovalNativeRuntimeAdapter(...)`, щоб ядро могло зібрати обробник і керувати фільтрацією запитів, маршрутизацією, дедуплікацією, строком дії, підпискою Gateway і повідомленнями про переспрямування. `nativeRuntime` поділено на кілька менших поверхонь: +- `availability` — чи налаштовано обліковий запис і чи слід обробляти запит +- `presentation` — відображення спільної моделі перегляду схвалень у нативні payload pending/resolved/expired або фінальні дії +- `transport` — підготовка цілей і надсилання/оновлення/видалення нативних повідомлень схвалення - `interactions` — необов’язкові хуки bind/unbind/clear-action для нативних кнопок або реакцій - `observe` — необов’язкові хуки діагностики доставки -- Якщо каналу потрібні об’єкти, що належать runtime, наприклад клієнт, токен, застосунок Bolt або отримувач webhook, реєструйте їх через `openclaw/plugin-sdk/channel-runtime-context`. Загальний реєстр runtime-контексту дає core змогу bootstrap-ити обробники на основі можливостей зі стану запуску каналу без додавання обгорток, специфічних для підтверджень. -- Звертайтеся до нижчорівневих `createChannelApprovalHandler` або `createChannelNativeApprovalRuntime` лише тоді, коли поверхня, заснована на можливостях, ще недостатньо виразна. -- Канали з нативними підтвердженнями мають передавати через ці helper-и і `accountId`, і `approvalKind`. `accountId` зберігає політику підтверджень для кількох облікових записів у межах правильного облікового запису бота, а `approvalKind` зберігає поведінку exec чи плагіна доступною для каналу без жорстко закодованих гілок у core. -- Тепер core також відповідає за сповіщення про повторну маршрутизацію підтверджень. Плагіни каналів не повинні надсилати власні додаткові повідомлення на кшталт «підтвердження перейшло в DM / інший канал» із `createChannelNativeApprovalRuntime`; натомість надавайте точну маршрутизацію origin + approver-DM через спільні helper-и можливостей підтверджень і дозвольте core агрегувати фактичні доставки перед публікацією будь-якого сповіщення назад в ініціювальний чат. -- Зберігайте тип ідентифікатора доставленого підтвердження від початку до кінця. Нативні клієнти не повинні - вгадувати або переписувати маршрутизацію exec чи plugin підтвердження на основі локального стану каналу. -- Різні типи підтверджень можуть навмисно відкривати різні нативні поверхні. - Поточні приклади вбудованих плагінів: - - Slack зберігає нативну маршрутизацію підтверджень доступною як для exec-, так і для plugin-id. - - Matrix зберігає ту саму нативну DM/канальну маршрутизацію та UX реакцій для exec - і plugin-підтверджень, водночас дозволяючи auth відрізнятися за типом підтвердження. -- `createApproverRestrictedNativeApprovalAdapter` усе ще існує як обгортка сумісності, але новий код має віддавати перевагу builder-у можливостей і експонувати `approvalCapability` у плагіні. +- Якщо каналу потрібні об’єкти, що належать середовищу виконання, як-от клієнт, токен, Bolt app або отримувач Webhook, реєструйте їх через `openclaw/plugin-sdk/channel-runtime-context`. Загальний реєстр runtime-context дозволяє ядру ініціалізувати обробники, керовані можливостями, зі стану запуску каналу без додавання специфічного для схвалень обгорткового коду. +- Використовуйте нижчорівневі `createChannelApprovalHandler` або `createChannelNativeApprovalRuntime` лише тоді, коли поверхня, керована можливостями, ще недостатньо виразна. +- Канали нативних схвалень мають маршрутизувати і `accountId`, і `approvalKind` через ці допоміжні засоби. `accountId` зберігає політику схвалень для кількох облікових записів у межах правильного облікового запису бота, а `approvalKind` зберігає поведінку exec і Plugin-схвалень доступною для каналу без жорстко закодованих розгалужень у ядрі. +- Ядро тепер також відповідає за повідомлення про переспрямування схвалень. Plugin каналів не повинні надсилати власні додаткові повідомлення на кшталт «схвалення перейшло в DM / інший канал» із `createChannelNativeApprovalRuntime`; натомість надавайте точну маршрутизацію origin + approver-DM через спільні допоміжні засоби можливостей схвалень і дозволяйте ядру агрегувати фактичні доставки перед публікацією будь-якого повідомлення назад в ініціювальний чат. +- Зберігайте тип ідентифікатора доставленого схвалення наскрізно. Нативні клієнти не повинні + вгадувати або переписувати маршрутизацію exec чи Plugin-схвалень на основі локального для каналу стану. +- Різні типи схвалень можуть навмисно надавати різні нативні поверхні. + Поточні вбудовані приклади: + - Slack зберігає доступною маршрутизацію нативних схвалень як для exec-, так і для Plugin-ідентифікаторів. + - Matrix зберігає ту саму нативну маршрутизацію DM/каналу та UX реакцій для exec- + і Plugin-схвалень, водночас дозволяючи автентифікації відрізнятися за типом схвалення. +- `createApproverRestrictedNativeApprovalAdapter` усе ще існує як обгортка сумісності, але новий код має віддавати перевагу конструктору можливостей і надавати `approvalCapability` у Plugin. -Для гарячих точок входу каналу віддавайте перевагу вужчим runtime-підшляхам, коли вам потрібна лише -одна частина цієї сім’ї: +Для гарячих точок входу каналів віддавайте перевагу вужчим runtime-підшляхам, коли вам потрібна лише +одна частина цієї групи: - `openclaw/plugin-sdk/approval-auth-runtime` - `openclaw/plugin-sdk/approval-client-runtime` @@ -115,89 +124,90 @@ Core відповідає за спільний інструмент повід `openclaw/plugin-sdk/reply-runtime`, `openclaw/plugin-sdk/reply-dispatch-runtime`, `openclaw/plugin-sdk/reply-reference` і -`openclaw/plugin-sdk/reply-chunking`, коли вам не потрібна ширша +`openclaw/plugin-sdk/reply-chunking`, якщо вам не потрібна ширша узагальнювальна поверхня. -Зокрема для setup: +Зокрема для налаштування: -- `openclaw/plugin-sdk/setup-runtime` охоплює runtime-безпечні helper-и setup: - безпечні для імпорту patched-адаптери setup (`createPatchedAccountSetupAdapter`, +- `openclaw/plugin-sdk/setup-runtime` охоплює безпечні для runtime допоміжні засоби налаштування: + безпечні для імпорту адаптери patch налаштування (`createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, - `createSetupInputPresenceValidator`), вивід lookup-note, + `createSetupInputPresenceValidator`), виведення приміток пошуку, `promptResolvedAllowFrom`, `splitSetupEntries` і делеговані - builder-и setup-proxy -- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузька env-aware поверхня адаптера - для `createEnvPatchedAccountSetupAdapter` -- `openclaw/plugin-sdk/channel-setup` охоплює builder-и setup для необов’язкового встановлення - плюс кілька setup-безпечних примітивів: + конструктори setup-proxy +- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузька env-aware поверхня + адаптера для `createEnvPatchedAccountSetupAdapter` +- `openclaw/plugin-sdk/channel-setup` охоплює конструктори налаштування з необов’язковим встановленням + плюс кілька безпечних для setup примітивів: `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, -Якщо ваш канал підтримує setup або auth на основі env, і загальні потоки startup/config -мають знати ці env-імена до завантаження runtime, оголосіть їх у маніфесті плагіна через -`channelEnvVars`. Зберігайте runtime `envVars` каналу або локальні константи лише для копірайту, видимого операторам. +Якщо ваш канал підтримує налаштування або автентифікацію, керовані env, і загальні процеси запуску/конфігурації +мають знати ці назви env до завантаження runtime, оголосіть їх у +маніфесті Plugin за допомогою `channelEnvVars`. Зберігайте `envVars` runtime каналу або локальні +константи лише для копії, орієнтованої на операторів. `createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled` і `splitSetupEntries` -- використовуйте ширшу поверхню `openclaw/plugin-sdk/setup` лише тоді, коли вам також потрібні - важчі спільні helper-и setup/config, такі як +- використовуйте ширшу поверхню `openclaw/plugin-sdk/setup`, лише якщо вам також потрібні + важчі спільні допоміжні засоби setup/config, такі як `moveSingleAccountChannelSectionToDefaultAccount(...)` -Якщо ваш канал лише хоче показувати в поверхнях setup повідомлення «спочатку встановіть цей плагін», +Якщо ваш канал лише хоче показувати «спочатку встановіть цей Plugin» на поверхнях налаштування, віддавайте перевагу `createOptionalChannelSetupSurface(...)`. Згенеровані -adapter/wizard закриваються з відмовою для записів конфігурації та фіналізації, і повторно використовують -те саме повідомлення про необхідність встановлення для перевірки, finalize і тексту з посиланням на документацію. +adapter/wizard за замовчуванням забороняють запис у конфігурацію та завершення, і вони повторно використовують +те саме повідомлення про необхідність встановлення для перевірки, завершення та тексту +з посиланням на документацію. -Для інших гарячих шляхів каналу віддавайте перевагу вузьким helper-ам замість ширших застарілих +Для інших гарячих шляхів каналів віддавайте перевагу вузьким helper замість ширших застарілих поверхонь: - `openclaw/plugin-sdk/account-core`, `openclaw/plugin-sdk/account-id`, `openclaw/plugin-sdk/account-resolution` і - `openclaw/plugin-sdk/account-helpers` для конфігурації кількох облікових записів та - резервного переходу до облікового запису за замовчуванням + `openclaw/plugin-sdk/account-helpers` для конфігурації кількох облікових записів і + резервного використання облікового запису за замовчуванням - `openclaw/plugin-sdk/inbound-envelope` і - `openclaw/plugin-sdk/inbound-reply-dispatch` для route/envelope вхідних повідомлень та + `openclaw/plugin-sdk/inbound-reply-dispatch` для маршруту/конверта вхідних даних і зв’язування record-and-dispatch -- `openclaw/plugin-sdk/messaging-targets` для парсингу/зіставлення цілей +- `openclaw/plugin-sdk/messaging-targets` для розбору/зіставлення цілей - `openclaw/plugin-sdk/outbound-media` і - `openclaw/plugin-sdk/outbound-runtime` для завантаження медіа плюс - делегатів ідентичності/надсилання вихідних повідомлень -- `openclaw/plugin-sdk/thread-bindings-runtime` для життєвого циклу прив’язок потоків + `openclaw/plugin-sdk/outbound-runtime` для завантаження медіа плюс делегатів + ідентичності/надсилання вихідних повідомлень +- `openclaw/plugin-sdk/thread-bindings-runtime` для життєвого циклу прив’язки гілок і реєстрації адаптерів -- `openclaw/plugin-sdk/agent-media-payload` лише тоді, коли все ще потрібне - застаріле компонування полів payload агента/медіа -- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram, - перевірки дублікатів/конфліктів і стабільного резервного контракту конфігурації команд +- `openclaw/plugin-sdk/agent-media-payload` лише коли все ще потрібна застаріла + схема полів payload agent/media +- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram, перевірки дублікатів/конфліктів і стабільного щодо резервного сценарію контракту конфігурації команд -Канали лише з auth зазвичай можуть зупинитися на шляху за замовчуванням: core обробляє підтвердження, а плагін лише надає можливості outbound/auth. Канали з нативними підтвердженнями, такі як Matrix, Slack, Telegram і власні транспортні чати, мають використовувати спільні нативні helper-и замість створення власного життєвого циклу підтверджень. +Канали лише з автентифікацією зазвичай можуть зупинитися на стандартному шляху: ядро обробляє схвалення, а Plugin лише надає можливості outbound/auth. Канали нативних схвалень, як-от Matrix, Slack, Telegram і спеціальні транспортні засоби чату, мають використовувати спільні нативні helper, а не реалізовувати власний життєвий цикл схвалень. ## Політика вхідних згадок -Зберігайте обробку вхідних згадок розділеною на два рівні: +Зберігайте обробку вхідних згадок розділеною на два шари: -- збирання доказів, що належить плагіну -- спільне оцінювання політики +- збір доказів, що належить Plugin +- оцінка спільної політики -Використовуйте `openclaw/plugin-sdk/channel-inbound` для спільного рівня. +Для спільного шару використовуйте `openclaw/plugin-sdk/channel-inbound`. -Добре підходить для локальної логіки плагіна: +Добре підходить для локальної логіки Plugin: -- виявлення reply-to-bot -- виявлення quoted-bot -- перевірки участі в потоці +- виявлення відповіді боту +- виявлення цитування бота +- перевірки участі в гілці - виключення службових/системних повідомлень -- платформено-нативні кеші, потрібні для підтвердження участі бота +- платформонативні кеші, потрібні для підтвердження участі бота -Добре підходить для спільного helper-а: +Добре підходить для спільного helper: - `requireMention` - явний результат згадки -- allowlist неявних згадок +- список дозволених неявних згадок - обхід для команд - фінальне рішення про пропуск -Рекомендований потік: +Рекомендований процес: 1. Обчисліть локальні факти згадки. 2. Передайте ці факти в `resolveInboundMentionDecision({ facts, policy })`. @@ -240,8 +250,8 @@ const decision = resolveInboundMentionDecision({ if (decision.shouldSkip) return; ``` -`api.runtime.channel.mentions` надає ті самі спільні helper-и згадок для -вбудованих плагінів каналів, які вже залежать від ін’єкції runtime: +`api.runtime.channel.mentions` надає ті самі спільні helper для згадок для +вбудованих Plugin каналів, які вже залежать від інʼєкції runtime: - `buildMentionRegexes` - `matchesMentionPatterns` @@ -249,8 +259,8 @@ if (decision.shouldSkip) return; - `implicitMentionKindWhen` - `resolveInboundMentionDecision` -Старіші helper-и `resolveMentionGating*` залишаються в -`openclaw/plugin-sdk/channel-inbound` лише як експорт сумісності. Новий код +Старіші helper `resolveMentionGating*` залишаються в +`openclaw/plugin-sdk/channel-inbound` лише як сумісні експорти. Новий код має використовувати `resolveInboundMentionDecision({ facts, policy })`. ## Покроковий розбір @@ -258,9 +268,9 @@ if (decision.shouldSkip) return; - Створіть стандартні файли плагіна. Поле `channel` у `package.json` — - це те, що робить цей плагін плагіном каналу. Повну поверхню метаданих пакета - див. у [Налаштування плагіна та конфігурація](/uk/plugins/sdk-setup#openclaw-channel): + Створіть стандартні файли Plugin. Поле `channel` у `package.json` — це + те, що робить його Plugin каналу. Повну поверхню метаданих пакета + див. у [Налаштування Plugin і конфігурація](/uk/plugins/sdk-setup#openclaw-channel): ```json package.json @@ -274,7 +284,7 @@ if (decision.shouldSkip) return; "channel": { "id": "acme-chat", "label": "Acme Chat", - "blurb": "Підключіть OpenClaw до Acme Chat." + "blurb": "Connect OpenClaw to Acme Chat." } } } @@ -286,7 +296,7 @@ if (decision.shouldSkip) return; "kind": "channel", "channels": ["acme-chat"], "name": "Acme Chat", - "description": "Плагін каналу Acme Chat", + "description": "Acme Chat channel plugin", "configSchema": { "type": "object", "additionalProperties": false, @@ -309,8 +319,8 @@ if (decision.shouldSkip) return; - - Інтерфейс `ChannelPlugin` має багато необов’язкових поверхонь адаптера. Почніть із + + Інтерфейс `ChannelPlugin` має багато необовʼязкових поверхонь адаптера. Почніть із мінімуму — `id` і `setup` — і додавайте адаптери за потреби. Створіть `src/channel.ts`: @@ -321,7 +331,7 @@ if (decision.shouldSkip) return; createChannelPluginBase, } from "openclaw/plugin-sdk/channel-core"; import type { OpenClawConfig } from "openclaw/plugin-sdk/channel-core"; - import { acmeChatApi } from "./client.js"; // ваш клієнт API платформи + import { acmeChatApi } from "./client.js"; // ваш API-клієнт платформи type ResolvedAccount = { accountId: string | null; @@ -372,21 +382,21 @@ if (decision.shouldSkip) return; }, }, - // Сполучення: потік підтвердження для нових контактів у DM + // Сполучення: процес схвалення для нових контактів у DM pairing: { text: { - idLabel: "Ім’я користувача Acme Chat", - message: "Надішліть цей код, щоб підтвердити свою особу:", + idLabel: "Acme Chat username", + message: "Send this code to verify your identity:", notify: async ({ target, code }) => { await acmeChatApi.sendDm(target, `Pairing code: ${code}`); }, }, }, - // Потоковість: як доставляються відповіді + // Ланцюжки: як доставляються відповіді threading: { topLevelReplyToMode: "reply" }, - // Outbound: надсилання повідомлень на платформу + // Вихідні повідомлення: надсилання повідомлень на платформу outbound: { attachedResults: { sendText: async (params) => { @@ -406,18 +416,18 @@ if (decision.shouldSkip) return; }); ``` - - Замість того щоб вручну реалізовувати низькорівневі інтерфейси адаптера, ви передаєте - декларативні параметри, а builder компонує їх: + + Замість ручної реалізації низькорівневих інтерфейсів адаптера ви передаєте + декларативні параметри, а конструктор поєднує їх: | Параметр | Що він підключає | | --- | --- | - | `security.dm` | Резолвер безпеки DM з областю дії на основі полів конфігурації | - | `pairing.text` | Потік сполучення через текстовий DM з обміном кодом | - | `threading` | Резолвер режиму відповіді (фіксований, з областю облікового запису або кастомний) | - | `outbound.attachedResults` | Функції надсилання, що повертають метадані результату (ідентифікатори повідомлень) | + | `security.dm` | Scoped-розвʼязувач безпеки DM із полів конфігурації | + | `pairing.text` | Текстовий процес сполучення в DM з обміном кодами | + | `threading` | Розвʼязувач режиму reply-to (фіксований, у межах облікового запису або спеціальний) | + | `outbound.attachedResults` | Функції надсилання, які повертають метадані результату (ідентифікатори повідомлень) | - Ви також можете передавати сирі об’єкти адаптера замість декларативних параметрів, + Ви також можете передавати сирі обʼєкти адаптерів замість декларативних параметрів, якщо вам потрібен повний контроль. @@ -433,20 +443,20 @@ if (decision.shouldSkip) return; export default defineChannelPluginEntry({ id: "acme-chat", name: "Acme Chat", - description: "Плагін каналу Acme Chat", + description: "Acme Chat channel plugin", plugin: acmeChatPlugin, registerCliMetadata(api) { api.registerCli( ({ program }) => { program .command("acme-chat") - .description("Керування Acme Chat"); + .description("Acme Chat management"); }, { descriptors: [ { name: "acme-chat", - description: "Керування Acme Chat", + description: "Acme Chat management", hasSubcommands: false, }, ], @@ -461,19 +471,19 @@ if (decision.shouldSkip) return; Розміщуйте дескриптори CLI, що належать каналу, у `registerCliMetadata(...)`, щоб OpenClaw міг показувати їх у кореневій довідці без активації повного runtime каналу, - тоді як звичайні повні завантаження все одно підхоплюватимуть ті самі дескриптори для реєстрації - реальних команд. Залишайте `registerFull(...)` для роботи лише під час runtime. - Якщо `registerFull(...)` реєструє gateway RPC-методи, використовуйте - префікс, специфічний для плагіна. Простори імен адміністратора core (`config.*`, - `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими і завжди - резолвляться в `operator.admin`. + тоді як звичайні повні завантаження все одно підхоплять ті самі дескриптори для реєстрації + реальних команд. Зберігайте `registerFull(...)` для роботи лише в runtime. + Якщо `registerFull(...)` реєструє RPC-методи Gateway, використовуйте + префікс, специфічний для Plugin. Простори імен адміністрування ядра (`config.*`, + `exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди + розвʼязуються в `operator.admin`. `defineChannelPluginEntry` автоматично обробляє поділ режимів реєстрації. Усі параметри див. у [Точки входу](/uk/plugins/sdk-entrypoints#definechannelpluginentry). - Створіть `setup-entry.ts` для легкого завантаження під час онбордингу: + Створіть `setup-entry.ts` для полегшеного завантаження під час онбордингу: ```typescript setup-entry.ts import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core"; @@ -483,27 +493,27 @@ if (decision.shouldSkip) return; ``` OpenClaw завантажує цей файл замість повної точки входу, коли канал вимкнений - або не налаштований. Це дозволяє уникнути підтягування важкого runtime-коду під час потоків setup. - Докладніше див. у [Налаштування та конфігурація](/uk/plugins/sdk-setup#setup-entry). + або не налаштований. Це дозволяє не підтягувати важкий runtime-код під час процесів налаштування. + Докладніше див. у [Налаштування і конфігурація](/uk/plugins/sdk-setup#setup-entry). - Ваш плагін має отримувати повідомлення з платформи та пересилати їх до - OpenClaw. Типовий шаблон — це webhook, який перевіряє запит і + Ваш Plugin має отримувати повідомлення з платформи й пересилати їх до + OpenClaw. Типовий шаблон — це Webhook, який перевіряє запит і диспетчеризує його через вхідний обробник вашого каналу: ```typescript registerFull(api) { api.registerHttpRoute({ path: "/acme-chat/webhook", - auth: "plugin", // auth, керований плагіном (перевіряйте підписи самостійно) + auth: "plugin", // автентифікація під керуванням Plugin (перевіряйте підписи самостійно) handler: async (req, res) => { const event = parseWebhookPayload(req); // Ваш вхідний обробник диспетчеризує повідомлення до OpenClaw. // Точне підключення залежить від SDK вашої платформи — - // реальний приклад див. у вбудованому пакеті плагіна Microsoft Teams або Google Chat. + // див. реальний приклад у вбудованому пакеті Plugin Microsoft Teams або Google Chat. await handleAcmeChatInbound(api, event); res.statusCode = 200; @@ -515,16 +525,16 @@ if (decision.shouldSkip) return; ``` - Обробка вхідних повідомлень залежить від каналу. Кожен плагін каналу відповідає - за власний вхідний pipeline. Подивіться на вбудовані плагіни каналів - (наприклад, пакет плагіна Microsoft Teams або Google Chat), щоб побачити реальні шаблони. + Обробка вхідних повідомлень залежить від конкретного каналу. Кожен Plugin каналу + володіє власним вхідним конвеєром. Подивіться на вбудовані Plugin каналів + (наприклад, пакет Plugin Microsoft Teams або Google Chat), щоб побачити реальні шаблони. -Пишіть colocated тести в `src/channel.test.ts`: +Пишіть colocated-тести в `src/channel.test.ts`: ```typescript src/channel.test.ts import { describe, it, expect } from "vitest"; @@ -562,14 +572,14 @@ if (decision.shouldSkip) return; pnpm test -- /acme-chat/ ``` - Спільні helper-и для тестування див. у [Тестування](/uk/plugins/sdk-testing). + Для спільних helper тестування див. [Тестування](/uk/plugins/sdk-testing). ## Структура файлів -```text +``` /acme-chat/ ├── package.json # метадані openclaw.channel ├── openclaw.plugin.json # Маніфест зі схемою конфігурації @@ -580,37 +590,37 @@ if (decision.shouldSkip) return; └── src/ ├── channel.ts # ChannelPlugin через createChatChannelPlugin ├── channel.test.ts # Тести - ├── client.ts # Клієнт API платформи + ├── client.ts # API-клієнт платформи └── runtime.ts # Runtime-сховище (за потреби) ``` ## Розширені теми - - Фіксовані режими відповіді, режими з областю облікового запису або кастомні режими + + Фіксовані, scoped до облікового запису або спеціальні режими відповіді describeMessageTool і виявлення дій - + inferTargetChatType, looksLikeId, resolveTarget - + TTS, STT, медіа, subagent через api.runtime -Деякі вбудовані поверхні helper-ів усе ще існують для супроводу вбудованих плагінів і -сумісності. Це не рекомендований шаблон для нових плагінів каналів; -віддавайте перевагу загальним підшляхам channel/setup/reply/runtime зі спільної -поверхні SDK, якщо тільки ви не супроводжуєте безпосередньо цю сім’ю вбудованих плагінів. +Деякі вбудовані поверхні helper усе ще існують для підтримки вбудованих Plugin і +сумісності. Вони не є рекомендованим шаблоном для нових Plugin каналів; +віддавайте перевагу загальним channel/setup/reply/runtime-підшляхам зі спільної +поверхні SDK, якщо лише ви не підтримуєте цю родину вбудованих Plugin безпосередньо. ## Наступні кроки -- [Плагіни провайдерів](/uk/plugins/sdk-provider-plugins) — якщо ваш плагін також надає моделі +- [Provider Plugins](/uk/plugins/sdk-provider-plugins) — якщо ваш Plugin також надає моделі - [Огляд SDK](/uk/plugins/sdk-overview) — повний довідник імпортів за підшляхами - [Тестування SDK](/uk/plugins/sdk-testing) — утиліти тестування та контрактні тести -- [Маніфест плагіна](/uk/plugins/manifest) — повна схема маніфесту +- [Маніфест Plugin](/uk/plugins/manifest) — повна схема маніфесту