chore(i18n): refresh uk translations
This commit is contained in:
parent
c5d924cb5a
commit
d03467efbe
@ -7,10 +7,10 @@ sidebarTitle: Channel Plugins
|
||||
summary: Покроковий посібник зі створення Plugin каналу обміну повідомленнями для OpenClaw
|
||||
title: Створення Plugin каналів
|
||||
x-i18n:
|
||||
generated_at: "2026-04-14T16:24:14Z"
|
||||
generated_at: "2026-04-15T16:36:53Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: a7f4c746fe3163a8880e14c433f4db4a1475535d91716a53fb879551d8d62f65
|
||||
source_hash: 80e47e61d1e47738361692522b79aff276544446c58a7b41afe5296635dfad4b
|
||||
source_path: plugins/sdk-channel-plugins.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -19,11 +19,11 @@ x-i18n:
|
||||
|
||||
Цей посібник описує створення Plugin каналу, який підключає OpenClaw до
|
||||
платформи обміну повідомленнями. Наприкінці у вас буде робочий канал із
|
||||
безпекою DM, сполученням, ланцюжками відповідей і вихідними повідомленнями.
|
||||
безпекою DM, сполученням, потоками відповідей і вихідними повідомленнями.
|
||||
|
||||
<Info>
|
||||
Якщо ви раніше не створювали жодного Plugin для OpenClaw, спочатку прочитайте
|
||||
[Getting Started](/uk/plugins/building-plugins) про базову структуру пакета та
|
||||
Якщо ви ще не створювали жодного Plugin для OpenClaw, спочатку прочитайте
|
||||
[Початок роботи](/uk/plugins/building-plugins) про базову структуру пакета та
|
||||
налаштування маніфесту.
|
||||
</Info>
|
||||
|
||||
@ -32,82 +32,83 @@ x-i18n:
|
||||
Plugin каналів не потребують власних інструментів send/edit/react. OpenClaw
|
||||
зберігає один спільний інструмент `message` у ядрі. Ваш Plugin відповідає за:
|
||||
|
||||
- **Конфігурацію** — визначення облікових записів і майстер налаштування
|
||||
- **Конфігурацію** — визначення облікового запису та майстер налаштування
|
||||
- **Безпеку** — політику DM і списки дозволених
|
||||
- **Сполучення** — процес схвалення DM
|
||||
- **Граматику сесії** — як ідентифікатори розмов, специфічні для провайдера, відображаються на базові чати, ідентифікатори гілок і резервні батьківські варіанти
|
||||
- **Вихідні повідомлення** — надсилання тексту, медіа й опитувань на платформу
|
||||
- **Ланцюжки** — як організовуються відповіді в гілках
|
||||
- **Сполучення** — потік підтвердження DM
|
||||
- **Граматику сесії** — як специфічні для провайдера ідентифікатори розмов зіставляються з базовими чатами, ідентифікаторами потоків і резервними батьківськими значеннями
|
||||
- **Вихідні повідомлення** — надсилання тексту, медіа та опитувань на платформу
|
||||
- **Потоки** — як організовуються відповіді у потоки
|
||||
|
||||
Ядро відповідає за спільний інструмент повідомлень, підключення промптів, зовнішню форму ключа сесії,
|
||||
загальний облік `:thread:` і диспетчеризацію.
|
||||
Ядро відповідає за спільний інструмент повідомлень, підключення prompt, зовнішню форму ключа сесії, загальний облік `:thread:` і диспетчеризацію.
|
||||
|
||||
Якщо ваш канал додає параметри інструмента повідомлень, які містять джерела медіа, вкажіть ці
|
||||
Якщо ваш канал додає параметри інструмента повідомлень, які містять джерела медіа, експонуйте ці
|
||||
назви параметрів через `describeMessageTool(...).mediaSourceParams`. Ядро використовує
|
||||
цей явний список для нормалізації шляхів sandbox і політики доступу до вихідних медіа,
|
||||
тому Plugin не потребують особливих винятків у спільному ядрі для специфічних для провайдера
|
||||
параметрів аватарів, вкладень або зображень обкладинки.
|
||||
Переважно повертати мапу, прив’язану до дій, наприклад
|
||||
`{ "set-profile": ["avatarUrl", "avatarPath"] }`, щоб не пов’язані дії не успадковували
|
||||
медіааргументи іншої дії. Плоский масив також працює для параметрів, які
|
||||
навмисно спільні для кожної доступної дії.
|
||||
цей явний список для нормалізації шляху sandbox і політики доступу до вихідних медіа,
|
||||
тому Plugin не потребують винятків у спільному ядрі для специфічних для провайдера
|
||||
параметрів аватарів, вкладень або обкладинок.
|
||||
Надавайте перевагу поверненню мапи з ключами дій, наприклад
|
||||
`{ "set-profile": ["avatarUrl", "avatarPath"] }`, щоб несуміжні дії не
|
||||
успадковували медіа-аргументи іншої дії. Плоский масив також працює для параметрів, які
|
||||
навмисно спільні для кожної експонованої дії.
|
||||
|
||||
Якщо ваша платформа зберігає додаткову область видимості в ідентифікаторах розмов, зберігайте цей розбір
|
||||
у Plugin за допомогою `messaging.resolveSessionConversation(...)`. Це канонічний хук
|
||||
для відображення `rawId` на базовий ідентифікатор розмови, необов’язковий ідентифікатор гілки,
|
||||
явний `baseConversationId` і будь-які `parentConversationCandidates`.
|
||||
Якщо ваша платформа зберігає додаткову область у межах ідентифікаторів розмов, залишайте цей парсинг
|
||||
у Plugin за допомогою `messaging.resolveSessionConversation(...)`. Це
|
||||
канонічний хук для зіставлення `rawId` з базовим ідентифікатором розмови, необов’язковим
|
||||
ідентифікатором потоку, явним `baseConversationId` і будь-якими
|
||||
`parentConversationCandidates`.
|
||||
Коли ви повертаєте `parentConversationCandidates`, зберігайте їх упорядкованими від
|
||||
найвужчого батьківського варіанта до найширшої/базової розмови.
|
||||
найвужчого батьківського елемента до найширшої/базової розмови.
|
||||
|
||||
Вбудовані Plugin, яким потрібен той самий розбір до запуску реєстру каналів,
|
||||
також можуть надавати файл верхнього рівня `session-key-api.ts` із відповідним
|
||||
Bundled Plugin, яким потрібен той самий парсинг до запуску реєстру каналів,
|
||||
також можуть експонувати файл верхнього рівня `session-key-api.ts` із відповідним
|
||||
експортом `resolveSessionConversation(...)`. Ядро використовує цю безпечну для bootstrap поверхню
|
||||
лише тоді, коли реєстр Plugin середовища виконання ще недоступний.
|
||||
лише тоді, коли реєстр Plugin під час виконання ще недоступний.
|
||||
|
||||
`messaging.resolveParentConversationCandidates(...)` залишається доступним як застарілий резервний варіант сумісності, коли Plugin потрібні лише
|
||||
резервні батьківські варіанти поверх загального/raw id. Якщо існують обидва хуки, ядро використовує
|
||||
спочатку `resolveSessionConversation(...).parentConversationCandidates` і лише потім
|
||||
повертається до `resolveParentConversationCandidates(...)`, якщо канонічний хук
|
||||
`messaging.resolveParentConversationCandidates(...)` залишається доступним як
|
||||
застарілий резервний механізм сумісності, коли Plugin потрібні лише
|
||||
резервні батьківські значення поверх загального/raw id. Якщо обидва хуки існують, ядро використовує
|
||||
спочатку `resolveSessionConversation(...).parentConversationCandidates` і лише
|
||||
потім повертається до `resolveParentConversationCandidates(...)`, якщо канонічний хук
|
||||
їх не вказує.
|
||||
|
||||
## Схвалення та можливості каналів
|
||||
## Підтвердження та можливості каналу
|
||||
|
||||
Більшості Plugin каналів не потрібен код, специфічний для схвалень.
|
||||
Більшості Plugin каналів не потрібен код, специфічний для підтверджень.
|
||||
|
||||
- Ядро відповідає за `/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.<channel>.accounts.<id>.execApprovals.*`, а не значення верхнього рівня за замовчуванням.
|
||||
- Якщо канал може вивести стабільні схожі на власника DM-ідентичності з наявної конфігурації, використовуйте `createResolvedApproverActionAuthAdapter` з `openclaw/plugin-sdk/approval-runtime`, щоб обмежити `/approve` у тому самому чаті без додавання специфічної для схвалень логіки ядра.
|
||||
- Якщо каналу потрібна нативна доставка схвалень, зосередьте код каналу на нормалізації цілі та фактах транспорту/представлення. Використовуйте `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` і `createApproverRestrictedNativeApprovalCapability` з `openclaw/plugin-sdk/approval-runtime`. Розміщуйте факти, специфічні для каналу, за `approvalCapability.nativeRuntime`, бажано через `createChannelApprovalNativeRuntimeAdapter(...)` або `createLazyChannelApprovalNativeRuntimeAdapter(...)`, щоб ядро могло зібрати обробник і керувати фільтрацією запитів, маршрутизацією, дедуплікацією, строком дії, підпискою Gateway і повідомленнями про переспрямування. `nativeRuntime` поділено на кілька менших поверхонь:
|
||||
- Ядро відповідає за `/approve` у тому самому чаті, спільні payload кнопок підтвердження та загальну резервну доставку.
|
||||
- Надавайте перевагу одному об’єкту `approvalCapability` у Plugin каналу, коли каналу потрібна поведінка, специфічна для підтверджень.
|
||||
- `ChannelPlugin.approvals` видалено. Розміщуйте факти доставки/native/render/auth для підтверджень у `approvalCapability`.
|
||||
- `plugin.auth` призначений лише для входу/виходу; ядро більше не читає з цього об’єкта auth-хуки підтверджень.
|
||||
- `approvalCapability.authorizeActorAction` і `approvalCapability.getActionAvailabilityState` — це канонічний шов auth підтверджень.
|
||||
- Використовуйте `approvalCapability.getActionAvailabilityState` для доступності auth підтверджень у тому самому чаті.
|
||||
- Якщо ваш канал експонує native exec-підтвердження, використовуйте `approvalCapability.getExecInitiatingSurfaceState` для стану initiating-surface/native-client, коли він відрізняється від auth підтверджень у тому самому чаті. Ядро використовує цей специфічний для exec хук, щоб розрізняти `enabled` і `disabled`, вирішувати, чи підтримує ініціюючий канал native exec-підтвердження, і включати канал до резервних вказівок для native-client. `createApproverRestrictedNativeApprovalCapability(...)` заповнює це для типового випадку.
|
||||
- Використовуйте `outbound.shouldSuppressLocalPayloadPrompt` або `outbound.beforeDeliverPayload` для специфічної для каналу поведінки життєвого циклу payload, як-от приховування дубльованих локальних prompt підтвердження або надсилання індикаторів набору тексту перед доставкою.
|
||||
- Використовуйте `approvalCapability.delivery` лише для маршрутизації native-підтверджень або пригнічення резервної доставки.
|
||||
- Використовуйте `approvalCapability.nativeRuntime` для фактів native-підтверджень, якими володіє канал. Залишайте його лінивим на гарячих entrypoint каналу за допомогою `createLazyChannelApprovalNativeRuntimeAdapter(...)`, який може імпортувати ваш runtime-модуль за потреби, водночас даючи ядру змогу зібрати життєвий цикл підтвердження.
|
||||
- Використовуйте `approvalCapability.render` лише тоді, коли каналу справді потрібні власні payload підтвердження замість спільного renderer.
|
||||
- Використовуйте `approvalCapability.describeExecApprovalSetup`, коли канал хоче, щоб відповідь для шляху `disabled` пояснювала точні параметри конфігурації, потрібні для ввімкнення native exec-підтверджень. Хук отримує `{ channel, channelLabel, accountId }`; канали з іменованими обліковими записами мають рендерити шляхи з областю облікового запису, як-от `channels.<channel>.accounts.<id>.execApprovals.*`, а не верхньорівневі значення за замовчуванням.
|
||||
- Якщо канал може виводити стабільні DM-ідентичності, подібні до власника, з наявної конфігурації, використовуйте `createResolvedApproverActionAuthAdapter` з `openclaw/plugin-sdk/approval-runtime`, щоб обмежити `/approve` у тому самому чаті без додавання специфічної для підтверджень логіки в ядро.
|
||||
- Якщо каналу потрібна доставка native-підтверджень, зосередьте код каналу на нормалізації цілі та фактах транспорту/представлення. Використовуйте `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 для нативних кнопок або реакцій
|
||||
- `presentation` — перетворення спільної view model підтвердження на pending/resolved/expired native payload або фінальні дії
|
||||
- `transport` — підготовка цілей плюс надсилання/оновлення/видалення native-повідомлень підтвердження
|
||||
- `interactions` — необов’язкові хуки bind/unbind/clear-action для native-кнопок або реакцій
|
||||
- `observe` — необов’язкові хуки діагностики доставки
|
||||
- Якщо каналу потрібні об’єкти, що належать середовищу виконання, як-от клієнт, токен, 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, як-от client, token, Bolt app або receiver Webhook, реєструйте їх через `openclaw/plugin-sdk/channel-runtime-context`. Загальний реєстр runtime-context дає ядру змогу bootstrap capability-driven handlers зі стану запуску каналу без додавання glue-коду wrapper, специфічного для підтверджень.
|
||||
- Використовуйте нижчорівневі `createChannelApprovalHandler` або `createChannelNativeApprovalRuntime` лише тоді, коли capability-driven seam ще недостатньо виразний.
|
||||
- Канали native-підтверджень повинні маршрутизувати і `accountId`, і `approvalKind` через ці helper-и. `accountId` зберігає область політики підтверджень для кількох облікових записів прив’язаною до правильного облікового запису бота, а `approvalKind` зберігає доступність поведінки exec проти Plugin-підтверджень для каналу без жорстко закодованих розгалужень у ядрі.
|
||||
- Ядро тепер також відповідає за сповіщення про перенаправлення підтверджень. Plugin каналів не повинні надсилати власні follow-up повідомлення на кшталт «підтвердження перейшло в DM / інший канал» з `createChannelNativeApprovalRuntime`; натомість експонуйте точну маршрутизацію origin + approver-DM через спільні helper-и можливостей підтверджень і дайте ядру агрегувати фактичні доставки перед публікацією будь-якого сповіщення назад в ініціюючий чат.
|
||||
- Зберігайте тип delivered approval id від початку до кінця. Native clients не повинні
|
||||
вгадувати або переписувати маршрутизацію exec чи Plugin-підтверджень на основі локального стану каналу.
|
||||
- Різні типи підтверджень можуть навмисно експонувати різні native-поверхні.
|
||||
Поточні bundled-приклади:
|
||||
- Slack зберігає доступність native-маршрутизації підтверджень як для exec, так і для plugin id.
|
||||
- Matrix зберігає однакову native DM/канальну маршрутизацію і UX реакцій для exec
|
||||
і Plugin-підтверджень, водночас усе ще даючи змогу auth відрізнятися за типом підтвердження.
|
||||
- `createApproverRestrictedNativeApprovalAdapter` усе ще існує як wrapper сумісності, але новий код має надавати перевагу builder можливостей і експонувати `approvalCapability` у Plugin.
|
||||
|
||||
Для гарячих точок входу каналів віддавайте перевагу вужчим runtime-підшляхам, коли вам потрібна лише
|
||||
одна частина цієї групи:
|
||||
Для гарячих entrypoint каналу надавайте перевагу вужчим runtime subpath, коли вам потрібна лише
|
||||
одна частина цієї родини:
|
||||
|
||||
- `openclaw/plugin-sdk/approval-auth-runtime`
|
||||
- `openclaw/plugin-sdk/approval-client-runtime`
|
||||
@ -119,97 +120,96 @@ Plugin каналів не потребують власних інструме
|
||||
- `openclaw/plugin-sdk/approval-reply-runtime`
|
||||
- `openclaw/plugin-sdk/channel-runtime-context`
|
||||
|
||||
Так само віддавайте перевагу `openclaw/plugin-sdk/setup-runtime`,
|
||||
Так само надавайте перевагу `openclaw/plugin-sdk/setup-runtime`,
|
||||
`openclaw/plugin-sdk/setup-adapter-runtime`,
|
||||
`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`, коли вам не потрібна ширша
|
||||
узагальнена поверхня.
|
||||
|
||||
Зокрема для налаштування:
|
||||
|
||||
- `openclaw/plugin-sdk/setup-runtime` охоплює безпечні для runtime допоміжні засоби налаштування:
|
||||
безпечні для імпорту адаптери patch налаштування (`createPatchedAccountSetupAdapter`,
|
||||
- `openclaw/plugin-sdk/setup-runtime` охоплює безпечні для runtime helper-и налаштування:
|
||||
безпечні для import адаптери patch налаштування (`createPatchedAccountSetupAdapter`,
|
||||
`createEnvPatchedAccountSetupAdapter`,
|
||||
`createSetupInputPresenceValidator`), виведення приміток пошуку,
|
||||
`promptResolvedAllowFrom`, `splitSetupEntries` і делеговані
|
||||
конструктори setup-proxy
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузька env-aware поверхня
|
||||
адаптера для `createEnvPatchedAccountSetupAdapter`
|
||||
- `openclaw/plugin-sdk/channel-setup` охоплює конструктори налаштування з необов’язковим встановленням
|
||||
`promptResolvedAllowFrom`, `splitSetupEntries` і delegated
|
||||
builder-и setup-proxy
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузький env-aware adapter
|
||||
seam для `createEnvPatchedAccountSetupAdapter`
|
||||
- `openclaw/plugin-sdk/channel-setup` охоплює builder-и optional-install setup
|
||||
плюс кілька безпечних для setup примітивів:
|
||||
`createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`,
|
||||
|
||||
Якщо ваш канал підтримує налаштування або автентифікацію, керовані env, і загальні процеси запуску/конфігурації
|
||||
Якщо ваш канал підтримує налаштування або auth через env і загальні потоки startup/config
|
||||
мають знати ці назви env до завантаження runtime, оголосіть їх у
|
||||
маніфесті Plugin за допомогою `channelEnvVars`. Зберігайте `envVars` runtime каналу або локальні
|
||||
константи лише для копії, орієнтованої на операторів.
|
||||
маніфесті Plugin через `channelEnvVars`. Залишайте runtime `envVars` каналу або локальні
|
||||
константи лише для copy, орієнтованого на операторів.
|
||||
`createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`,
|
||||
`createTopLevelChannelDmPolicy`, `setSetupChannelEnabled` і
|
||||
`splitSetupEntries`
|
||||
|
||||
- використовуйте ширшу поверхню `openclaw/plugin-sdk/setup`, лише якщо вам також потрібні
|
||||
важчі спільні допоміжні засоби setup/config, такі як
|
||||
- використовуйте ширший seam `openclaw/plugin-sdk/setup` лише тоді, коли вам також потрібні
|
||||
важчі спільні helper-и setup/config, як-от
|
||||
`moveSingleAccountChannelSectionToDefaultAccount(...)`
|
||||
|
||||
Якщо ваш канал лише хоче показувати «спочатку встановіть цей Plugin» на поверхнях налаштування,
|
||||
віддавайте перевагу `createOptionalChannelSetupSurface(...)`. Згенеровані
|
||||
adapter/wizard за замовчуванням забороняють запис у конфігурацію та завершення, і вони повторно використовують
|
||||
те саме повідомлення про необхідність встановлення для перевірки, завершення та тексту
|
||||
з посиланням на документацію.
|
||||
Якщо ваш канал хоче лише оголошувати «спочатку встановіть цей Plugin» у поверхнях налаштування,
|
||||
надавайте перевагу `createOptionalChannelSetupSurface(...)`. Згенеровані
|
||||
adapter/wizard закриваються безпечно під час запису конфігурації та фіналізації, і вони повторно використовують
|
||||
те саме повідомлення про необхідність встановлення в copy перевірки, finalize і docs-link.
|
||||
|
||||
Для інших гарячих шляхів каналів віддавайте перевагу вузьким 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/inbound-envelope` і
|
||||
`openclaw/plugin-sdk/inbound-reply-dispatch` для маршруту/конверта вхідних даних і
|
||||
зв’язування record-and-dispatch
|
||||
- `openclaw/plugin-sdk/messaging-targets` для розбору/зіставлення цілей
|
||||
`openclaw/plugin-sdk/inbound-reply-dispatch` для wiring маршруту/конверта вхідних повідомлень і
|
||||
record-and-dispatch
|
||||
- `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 agent/media
|
||||
- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram, перевірки дублікатів/конфліктів і стабільного щодо резервного сценарію контракту конфігурації команд
|
||||
- `openclaw/plugin-sdk/agent-media-payload` лише тоді, коли все ще потрібна
|
||||
застаріла структура полів payload агента/медіа
|
||||
- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram, перевірки дублювання/конфліктів і стабільного при резервному поверненні контракту конфігурації команд
|
||||
|
||||
Канали лише з автентифікацією зазвичай можуть зупинитися на стандартному шляху: ядро обробляє схвалення, а Plugin лише надає можливості outbound/auth. Канали нативних схвалень, як-от Matrix, Slack, Telegram і спеціальні транспортні засоби чату, мають використовувати спільні нативні helper, а не реалізовувати власний життєвий цикл схвалень.
|
||||
Канали лише з auth зазвичай можуть зупинитися на стандартному шляху: ядро обробляє підтвердження, а Plugin лише експонує можливості outbound/auth. Канали native-підтверджень, як-от Matrix, Slack, Telegram і власні chat-транспорти, мають використовувати спільні native helper-и замість того, щоб самостійно реалізовувати життєвий цикл підтверджень.
|
||||
|
||||
## Політика вхідних згадок
|
||||
|
||||
Зберігайте обробку вхідних згадок розділеною на два шари:
|
||||
Розділяйте обробку вхідних згадок на два шари:
|
||||
|
||||
- збір доказів, що належить Plugin
|
||||
- оцінка спільної політики
|
||||
- збирання доказів, яким володіє Plugin
|
||||
- оцінювання спільної політики
|
||||
|
||||
Для спільного шару використовуйте `openclaw/plugin-sdk/channel-inbound`.
|
||||
|
||||
Добре підходить для локальної логіки Plugin:
|
||||
|
||||
- виявлення відповіді боту
|
||||
- виявлення цитування бота
|
||||
- перевірки участі в гілці
|
||||
- виявлення reply-to-bot
|
||||
- виявлення quoted-bot
|
||||
- перевірки участі в потоці
|
||||
- виключення службових/системних повідомлень
|
||||
- платформонативні кеші, потрібні для підтвердження участі бота
|
||||
- platform-native кеші, потрібні для підтвердження участі бота
|
||||
|
||||
Добре підходить для спільного helper:
|
||||
Добре підходить для спільного helper-а:
|
||||
|
||||
- `requireMention`
|
||||
- явний результат згадки
|
||||
- список дозволених неявних згадок
|
||||
- обхід для команд
|
||||
- обхід команд
|
||||
- фінальне рішення про пропуск
|
||||
|
||||
Рекомендований процес:
|
||||
Бажаний потік:
|
||||
|
||||
1. Обчисліть локальні факти згадки.
|
||||
1. Обчисліть локальні факти згадок.
|
||||
2. Передайте ці факти в `resolveInboundMentionDecision({ facts, policy })`.
|
||||
3. Використовуйте `decision.effectiveWasMentioned`, `decision.shouldBypassMention` і `decision.shouldSkip` у вашому вхідному шлюзі.
|
||||
|
||||
@ -250,8 +250,8 @@ const decision = resolveInboundMentionDecision({
|
||||
if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
`api.runtime.channel.mentions` надає ті самі спільні helper для згадок для
|
||||
вбудованих Plugin каналів, які вже залежать від інʼєкції runtime:
|
||||
`api.runtime.channel.mentions` експонує ті самі спільні helper-и згадок для
|
||||
bundled Plugin каналів, які вже залежать від injection під час runtime:
|
||||
|
||||
- `buildMentionRegexes`
|
||||
- `matchesMentionPatterns`
|
||||
@ -259,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 })`.
|
||||
|
||||
## Покроковий розбір
|
||||
@ -268,9 +268,9 @@ if (decision.shouldSkip) return;
|
||||
<Steps>
|
||||
<a id="step-1-package-and-manifest"></a>
|
||||
<Step title="Пакет і маніфест">
|
||||
Створіть стандартні файли Plugin. Поле `channel` у `package.json` — це
|
||||
те, що робить його Plugin каналу. Повну поверхню метаданих пакета
|
||||
див. у [Налаштування Plugin і конфігурація](/uk/plugins/sdk-setup#openclaw-channel):
|
||||
Створіть стандартні файли Plugin. Поле `channel` у `package.json`
|
||||
робить це Plugin каналу. Повний опис поверхні метаданих пакета дивіться в
|
||||
[Налаштування Plugin і конфігурація](/uk/plugins/sdk-setup#openclaw-channel):
|
||||
|
||||
<CodeGroup>
|
||||
```json package.json
|
||||
@ -319,8 +319,8 @@ if (decision.shouldSkip) return;
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Створіть обʼєкт Plugin каналу">
|
||||
Інтерфейс `ChannelPlugin` має багато необовʼязкових поверхонь адаптера. Почніть із
|
||||
<Step title="Створіть об’єкт Plugin каналу">
|
||||
Інтерфейс `ChannelPlugin` має багато необов’язкових поверхонь адаптерів. Почніть із
|
||||
мінімуму — `id` і `setup` — і додавайте адаптери за потреби.
|
||||
|
||||
Створіть `src/channel.ts`:
|
||||
@ -331,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"; // your platform API client
|
||||
|
||||
type ResolvedAccount = {
|
||||
accountId: string | null;
|
||||
@ -372,7 +372,7 @@ if (decision.shouldSkip) return;
|
||||
},
|
||||
}),
|
||||
|
||||
// Безпека DM: хто може писати боту
|
||||
// DM security: who can message the bot
|
||||
security: {
|
||||
dm: {
|
||||
channelKey: "acme-chat",
|
||||
@ -382,7 +382,7 @@ if (decision.shouldSkip) return;
|
||||
},
|
||||
},
|
||||
|
||||
// Сполучення: процес схвалення для нових контактів у DM
|
||||
// Pairing: approval flow for new DM contacts
|
||||
pairing: {
|
||||
text: {
|
||||
idLabel: "Acme Chat username",
|
||||
@ -393,10 +393,10 @@ if (decision.shouldSkip) return;
|
||||
},
|
||||
},
|
||||
|
||||
// Ланцюжки: як доставляються відповіді
|
||||
// Threading: how replies are delivered
|
||||
threading: { topLevelReplyToMode: "reply" },
|
||||
|
||||
// Вихідні повідомлення: надсилання повідомлень на платформу
|
||||
// Outbound: send messages to the platform
|
||||
outbound: {
|
||||
attachedResults: {
|
||||
sendText: async (params) => {
|
||||
@ -417,23 +417,23 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
<Accordion title="Що `createChatChannelPlugin` робить для вас">
|
||||
Замість ручної реалізації низькорівневих інтерфейсів адаптера ви передаєте
|
||||
декларативні параметри, а конструктор поєднує їх:
|
||||
Замість ручної реалізації низькорівневих інтерфейсів адаптерів ви передаєте
|
||||
декларативні параметри, а builder компонує їх:
|
||||
|
||||
| Параметр | Що він підключає |
|
||||
| --- | --- |
|
||||
| `security.dm` | Scoped-розвʼязувач безпеки DM із полів конфігурації |
|
||||
| `pairing.text` | Текстовий процес сполучення в DM з обміном кодами |
|
||||
| `threading` | Розвʼязувач режиму reply-to (фіксований, у межах облікового запису або спеціальний) |
|
||||
| `security.dm` | Scoped resolver безпеки DM з полів конфігурації |
|
||||
| `pairing.text` | Потік текстового сполучення DM з обміном кодами |
|
||||
| `threading` | Resolver режиму reply-to (фіксований, з областю облікового запису або власний) |
|
||||
| `outbound.attachedResults` | Функції надсилання, які повертають метадані результату (ідентифікатори повідомлень) |
|
||||
|
||||
Ви також можете передавати сирі обʼєкти адаптерів замість декларативних параметрів,
|
||||
Ви також можете передавати сирі об’єкти адаптерів замість декларативних параметрів,
|
||||
якщо вам потрібен повний контроль.
|
||||
</Accordion>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Підключіть точку входу">
|
||||
<Step title="Підключіть entrypoint">
|
||||
Створіть `index.ts`:
|
||||
|
||||
```typescript index.ts
|
||||
@ -469,21 +469,21 @@ if (decision.shouldSkip) return;
|
||||
});
|
||||
```
|
||||
|
||||
Розміщуйте дескриптори CLI, що належать каналу, у `registerCliMetadata(...)`, щоб OpenClaw
|
||||
міг показувати їх у кореневій довідці без активації повного runtime каналу,
|
||||
тоді як звичайні повні завантаження все одно підхоплять ті самі дескриптори для реєстрації
|
||||
реальних команд. Зберігайте `registerFull(...)` для роботи лише в runtime.
|
||||
Якщо `registerFull(...)` реєструє RPC-методи Gateway, використовуйте
|
||||
Розміщуйте дескриптори CLI, якими володіє канал, у `registerCliMetadata(...)`, щоб OpenClaw
|
||||
міг показувати їх у довідці кореневого рівня без активації повного runtime каналу,
|
||||
тоді як звичайне повне завантаження все одно підхоплюватиме ті самі дескриптори для реєстрації
|
||||
реальних команд. Зберігайте `registerFull(...)` для роботи лише під час runtime.
|
||||
Якщо `registerFull(...)` реєструє методи Gateway RPC, використовуйте
|
||||
префікс, специфічний для Plugin. Простори імен адміністрування ядра (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди
|
||||
розвʼязуються в `operator.admin`.
|
||||
зіставляються з `operator.admin`.
|
||||
`defineChannelPluginEntry` автоматично обробляє поділ режимів реєстрації. Усі
|
||||
параметри див. у [Точки входу](/uk/plugins/sdk-entrypoints#definechannelpluginentry).
|
||||
параметри дивіться в [Entry Points](/uk/plugins/sdk-entrypoints#definechannelpluginentry).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Додайте setup entry">
|
||||
Створіть `setup-entry.ts` для полегшеного завантаження під час онбордингу:
|
||||
<Step title="Додайте entry setup">
|
||||
Створіть `setup-entry.ts` для легкого завантаження під час онбордингу:
|
||||
|
||||
```typescript setup-entry.ts
|
||||
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -492,9 +492,14 @@ if (decision.shouldSkip) return;
|
||||
export default defineSetupPluginEntry(acmeChatPlugin);
|
||||
```
|
||||
|
||||
OpenClaw завантажує цей файл замість повної точки входу, коли канал вимкнений
|
||||
або не налаштований. Це дозволяє не підтягувати важкий runtime-код під час процесів налаштування.
|
||||
Докладніше див. у [Налаштування і конфігурація](/uk/plugins/sdk-setup#setup-entry).
|
||||
OpenClaw завантажує це замість повного entry, коли канал вимкнений
|
||||
або не налаштований. Це дозволяє не підтягувати важкий runtime-код під час потоків setup.
|
||||
Докладніше дивіться в [Налаштування і конфігурація](/uk/plugins/sdk-setup#setup-entry).
|
||||
|
||||
Bundled workspace канали, які виносять безпечні для setup експорти в sidecar-модулі,
|
||||
можуть використовувати `defineBundledChannelSetupEntry(...)` з
|
||||
`openclaw/plugin-sdk/channel-entry-contract`, коли їм також потрібен
|
||||
явний setter runtime під час setup.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -507,13 +512,13 @@ if (decision.shouldSkip) return;
|
||||
registerFull(api) {
|
||||
api.registerHttpRoute({
|
||||
path: "/acme-chat/webhook",
|
||||
auth: "plugin", // автентифікація під керуванням Plugin (перевіряйте підписи самостійно)
|
||||
auth: "plugin", // plugin-managed auth (verify signatures yourself)
|
||||
handler: async (req, res) => {
|
||||
const event = parseWebhookPayload(req);
|
||||
|
||||
// Ваш вхідний обробник диспетчеризує повідомлення до OpenClaw.
|
||||
// Точне підключення залежить від SDK вашої платформи —
|
||||
// див. реальний приклад у вбудованому пакеті Plugin Microsoft Teams або Google Chat.
|
||||
// Your inbound handler dispatches the message to OpenClaw.
|
||||
// The exact wiring depends on your platform SDK —
|
||||
// see a real example in the bundled Microsoft Teams or Google Chat plugin package.
|
||||
await handleAcmeChatInbound(api, event);
|
||||
|
||||
res.statusCode = 200;
|
||||
@ -525,16 +530,16 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
<Note>
|
||||
Обробка вхідних повідомлень залежить від конкретного каналу. Кожен Plugin каналу
|
||||
володіє власним вхідним конвеєром. Подивіться на вбудовані Plugin каналів
|
||||
(наприклад, пакет Plugin Microsoft Teams або Google Chat), щоб побачити реальні шаблони.
|
||||
Обробка вхідних повідомлень є специфічною для каналу. Кожен Plugin каналу
|
||||
володіє власним вхідним конвеєром. Подивіться на bundled Plugin каналів
|
||||
(наприклад, пакет Plugin Microsoft Teams або Google Chat) як на реальні шаблони.
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
|
||||
<a id="step-6-test"></a>
|
||||
<Step title="Тестування">
|
||||
Пишіть colocated-тести в `src/channel.test.ts`:
|
||||
Пишіть colocated тести в `src/channel.test.ts`:
|
||||
|
||||
```typescript src/channel.test.ts
|
||||
import { describe, it, expect } from "vitest";
|
||||
@ -572,7 +577,7 @@ if (decision.shouldSkip) return;
|
||||
pnpm test -- <bundled-plugin-root>/acme-chat/
|
||||
```
|
||||
|
||||
Для спільних helper тестування див. [Тестування](/uk/plugins/sdk-testing).
|
||||
Для спільних test helper-ів дивіться [Тестування](/uk/plugins/sdk-testing).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
@ -590,37 +595,37 @@ if (decision.shouldSkip) return;
|
||||
└── src/
|
||||
├── channel.ts # ChannelPlugin через createChatChannelPlugin
|
||||
├── channel.test.ts # Тести
|
||||
├── client.ts # API-клієнт платформи
|
||||
└── runtime.ts # Runtime-сховище (за потреби)
|
||||
├── client.ts # API client платформи
|
||||
└── runtime.ts # Runtime store (за потреби)
|
||||
```
|
||||
|
||||
## Розширені теми
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Параметри ланцюжків" icon="git-branch" href="/uk/plugins/sdk-entrypoints#registration-mode">
|
||||
Фіксовані, scoped до облікового запису або спеціальні режими відповіді
|
||||
<Card title="Параметри потоків" icon="git-branch" href="/uk/plugins/sdk-entrypoints#registration-mode">
|
||||
Фіксовані, з областю облікового запису або власні режими відповіді
|
||||
</Card>
|
||||
<Card title="Інтеграція інструмента повідомлень" icon="puzzle" href="/uk/plugins/architecture#channel-plugins-and-the-shared-message-tool">
|
||||
describeMessageTool і виявлення дій
|
||||
</Card>
|
||||
<Card title="Розв’язання цілі" icon="crosshair" href="/uk/plugins/architecture#channel-target-resolution">
|
||||
<Card title="Визначення цілі" icon="crosshair" href="/uk/plugins/architecture#channel-target-resolution">
|
||||
inferTargetChatType, looksLikeId, resolveTarget
|
||||
</Card>
|
||||
<Card title="Runtime helper" icon="settings" href="/uk/plugins/sdk-runtime">
|
||||
<Card title="Runtime helper-и" icon="settings" href="/uk/plugins/sdk-runtime">
|
||||
TTS, STT, медіа, subagent через api.runtime
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
Деякі вбудовані поверхні helper усе ще існують для підтримки вбудованих Plugin і
|
||||
Деякі bundled helper seam-и все ще існують для супроводу bundled-plugin і
|
||||
сумісності. Вони не є рекомендованим шаблоном для нових Plugin каналів;
|
||||
віддавайте перевагу загальним channel/setup/reply/runtime-підшляхам зі спільної
|
||||
поверхні SDK, якщо лише ви не підтримуєте цю родину вбудованих Plugin безпосередньо.
|
||||
надавайте перевагу загальним subpath channel/setup/reply/runtime зі спільної
|
||||
поверхні SDK, якщо тільки ви безпосередньо не підтримуєте цю родину bundled Plugin.
|
||||
</Note>
|
||||
|
||||
## Наступні кроки
|
||||
|
||||
- [Provider Plugins](/uk/plugins/sdk-provider-plugins) — якщо ваш Plugin також надає моделі
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) — повний довідник імпортів за підшляхами
|
||||
- [Тестування SDK](/uk/plugins/sdk-testing) — утиліти тестування та контрактні тести
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) — повний довідник з import subpath
|
||||
- [Тестування SDK](/uk/plugins/sdk-testing) — тестові утиліти та contract-тести
|
||||
- [Маніфест Plugin](/uk/plugins/manifest) — повна схема маніфесту
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
---
|
||||
read_when:
|
||||
- Вам потрібен точний сигнатурний тип definePluginEntry або defineChannelPluginEntry
|
||||
- Ви хочете зрозуміти режим реєстрації (full vs setup vs метадані CLI)
|
||||
- Вам потрібен точний сигнатурний тип `definePluginEntry` або `defineChannelPluginEntry`
|
||||
- Ви хочете зрозуміти режим реєстрації (`full` проти `setup` проти метаданих CLI)
|
||||
- Ви шукаєте параметри точки входу
|
||||
sidebarTitle: Entry Points
|
||||
summary: Довідник для definePluginEntry, defineChannelPluginEntry і defineSetupPluginEntry
|
||||
title: Точки входу плагінів
|
||||
summary: Довідник для definePluginEntry, defineChannelPluginEntry та defineSetupPluginEntry
|
||||
title: Точки входу Plugin
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T18:12:02Z"
|
||||
generated_at: "2026-04-15T16:36:52Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 799dbfe71e681dd8ba929a7a631dfe745c3c5c69530126fea2f9c137b120f51f
|
||||
source_hash: aabca25bc9b8ff1b5bb4852bafe83640ffeba006ea6b6a8eff4e2c37a10f1fe4
|
||||
source_path: plugins/sdk-entrypoints.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Точки входу плагінів
|
||||
# Точки входу Plugin
|
||||
|
||||
Кожен плагін експортує типовий об’єкт точки входу. SDK надає три допоміжні функції для
|
||||
Кожен plugin експортує типовий об’єкт точки входу. SDK надає три хелпери для
|
||||
їх створення.
|
||||
|
||||
<Tip>
|
||||
**Шукаєте покрокове пояснення?** Див. [Channel Plugins](/plugins/sdk-channel-plugins)
|
||||
або [Provider Plugins](/plugins/sdk-provider-plugins) для покрокових посібників.
|
||||
**Шукаєте покрокове пояснення?** Дивіться [Channel Plugins](/uk/plugins/sdk-channel-plugins)
|
||||
або [Provider Plugins](/uk/plugins/sdk-provider-plugins) для покрокових інструкцій.
|
||||
</Tip>
|
||||
|
||||
## `definePluginEntry`
|
||||
|
||||
**Імпорт:** `openclaw/plugin-sdk/plugin-entry`
|
||||
|
||||
Для плагінів провайдерів, плагінів інструментів, плагінів хуків і всього, що **не** є
|
||||
Для provider plugins, tool plugins, hook plugins і всього, що **не** є
|
||||
каналом обміну повідомленнями.
|
||||
|
||||
```typescript
|
||||
@ -50,7 +50,7 @@ export default definePluginEntry({
|
||||
});
|
||||
```
|
||||
|
||||
| Поле | Тип | Обов’язкове | Типове значення |
|
||||
| Поле | Тип | Обов’язково | Типово |
|
||||
| -------------- | ---------------------------------------------------------------- | ----------- | ------------------- |
|
||||
| `id` | `string` | Так | — |
|
||||
| `name` | `string` | Так | — |
|
||||
@ -60,18 +60,18 @@ export default definePluginEntry({
|
||||
| `register` | `(api: OpenClawPluginApi) => void` | Так | — |
|
||||
|
||||
- `id` має збігатися з вашим маніфестом `openclaw.plugin.json`.
|
||||
- `kind` призначено для ексклюзивних слотів: `"memory"` або `"context-engine"`.
|
||||
- `configSchema` може бути функцією для ледачого обчислення.
|
||||
- OpenClaw визначає та мемоїзує цю схему при першому доступі, тому витратні побудовники схем
|
||||
виконуються лише один раз.
|
||||
- `kind` призначений для ексклюзивних слотів: `"memory"` або `"context-engine"`.
|
||||
- `configSchema` може бути функцією для лінивого обчислення.
|
||||
- OpenClaw розв’язує та мемоїзує цю схему під час першого доступу, тож затратні
|
||||
побудовники схем запускаються лише один раз.
|
||||
|
||||
## `defineChannelPluginEntry`
|
||||
|
||||
**Імпорт:** `openclaw/plugin-sdk/channel-core`
|
||||
|
||||
Обгортає `definePluginEntry` логікою, специфічною для каналів. Автоматично викликає
|
||||
`api.registerChannel({ plugin })`, надає необов’язковий шов метаданих CLI для кореневої довідки
|
||||
та обмежує `registerFull` режимом реєстрації.
|
||||
Обгортає `definePluginEntry` логікою, специфічною для каналу. Автоматично викликає
|
||||
`api.registerChannel({ plugin })`, відкриває необов’язковий шов метаданих CLI
|
||||
для кореневої довідки та керує `registerFull` залежно від режиму реєстрації.
|
||||
|
||||
```typescript
|
||||
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -91,7 +91,7 @@ export default defineChannelPluginEntry({
|
||||
});
|
||||
```
|
||||
|
||||
| Поле | Тип | Обов’язкове | Типове значення |
|
||||
| Поле | Тип | Обов’язково | Типово |
|
||||
| --------------------- | ---------------------------------------------------------------- | ----------- | ------------------- |
|
||||
| `id` | `string` | Так | — |
|
||||
| `name` | `string` | Так | — |
|
||||
@ -102,24 +102,25 @@ export default defineChannelPluginEntry({
|
||||
| `registerCliMetadata` | `(api: OpenClawPluginApi) => void` | Ні | — |
|
||||
| `registerFull` | `(api: OpenClawPluginApi) => void` | Ні | — |
|
||||
|
||||
- `setRuntime` викликається під час реєстрації, щоб ви могли зберегти посилання на runtime
|
||||
(зазвичай через `createPluginRuntimeStore`). Під час захоплення метаданих CLI вона пропускається.
|
||||
- `setRuntime` викликається під час реєстрації, щоб ви могли зберегти посилання
|
||||
на runtime (зазвичай через `createPluginRuntimeStore`). Воно пропускається під час
|
||||
захоплення метаданих CLI.
|
||||
- `registerCliMetadata` виконується і під час `api.registrationMode === "cli-metadata"`,
|
||||
і під час `api.registrationMode === "full"`.
|
||||
Використовуйте це як канонічне місце для дескрипторів CLI, що належать каналу, щоб коренева довідка
|
||||
залишалася без активації, а звичайна реєстрація команд CLI зберігала сумісність
|
||||
із повними завантаженнями плагінів.
|
||||
- `registerFull` виконується лише тоді, коли `api.registrationMode === "full"`. Воно пропускається
|
||||
під час завантаження лише для setup.
|
||||
- Як і у `definePluginEntry`, `configSchema` може бути лінивою фабрикою, а OpenClaw
|
||||
мемоїзує визначену схему при першому доступі.
|
||||
- Для кореневих CLI-команд, що належать плагіну, надавайте перевагу `api.registerCli(..., { descriptors: [...] })`,
|
||||
якщо хочете, щоб команда залишалася ліниво завантажуваною, але не зникала з
|
||||
дерева розбору кореневого CLI. Для каналових плагінів надавайте перевагу реєстрації цих дескрипторів
|
||||
із `registerCliMetadata(...)`, а `registerFull(...)` зосередьте на роботі, потрібній лише під час runtime.
|
||||
- Якщо `registerFull(...)` також реєструє gateway RPC-методи, тримайте їх на
|
||||
префіксі, специфічному для плагіна. Зарезервовані простори назв адміністрування ядра (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) завжди примусово переводяться в
|
||||
Використовуйте його як канонічне місце для дескрипторів CLI, що належать каналу,
|
||||
щоб коренева довідка не активувала plugin, а звичайна реєстрація команд CLI
|
||||
залишалася сумісною з повним завантаженням plugin.
|
||||
- `registerFull` виконується лише коли `api.registrationMode === "full"`. Воно пропускається
|
||||
під час завантаження лише для налаштування.
|
||||
- Як і в `definePluginEntry`, `configSchema` може бути лінивою фабрикою, а OpenClaw
|
||||
мемоїзує розв’язану схему під час першого доступу.
|
||||
- Для кореневих команд CLI, що належать plugin, віддавайте перевагу `api.registerCli(..., { descriptors: [...] })`,
|
||||
коли хочете, щоб команда лишалася ліниво завантажуваною, але не зникала з
|
||||
дерева розбору кореневого CLI. Для channel plugins краще реєструвати ці дескриптори
|
||||
з `registerCliMetadata(...)`, а `registerFull(...)` залишати для суто runtime-роботи.
|
||||
- Якщо `registerFull(...)` також реєструє методи Gateway RPC, тримайте їх у
|
||||
префіксі, специфічному для plugin. Зарезервовані простори назв адміністрування ядра (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) завжди примусово переводяться до
|
||||
`operator.admin`.
|
||||
|
||||
## `defineSetupPluginEntry`
|
||||
@ -127,7 +128,7 @@ export default defineChannelPluginEntry({
|
||||
**Імпорт:** `openclaw/plugin-sdk/channel-core`
|
||||
|
||||
Для полегшеного файла `setup-entry.ts`. Повертає лише `{ plugin }` без
|
||||
логіки runtime або CLI.
|
||||
runtime або логіки CLI.
|
||||
|
||||
```typescript
|
||||
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -135,34 +136,61 @@ import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
export default defineSetupPluginEntry(myChannelPlugin);
|
||||
```
|
||||
|
||||
OpenClaw завантажує це замість повної точки входу, коли канал вимкнено,
|
||||
не налаштовано або коли ввімкнено відкладене завантаження. Див.
|
||||
[Setup and Config](/plugins/sdk-setup#setup-entry), щоб зрозуміти, коли це важливо.
|
||||
OpenClaw завантажує це замість повної точки входу, коли канал вимкнений,
|
||||
не налаштований або коли ввімкнене відкладене завантаження. Дивіться
|
||||
[Налаштування та конфігурація](/uk/plugins/sdk-setup#setup-entry), щоб зрозуміти,
|
||||
коли це має значення.
|
||||
|
||||
На практиці поєднуйте `defineSetupPluginEntry(...)` із вузькими сімействами допоміжних функцій setup:
|
||||
На практиці поєднуйте `defineSetupPluginEntry(...)` із вузькими сімействами
|
||||
хелперів для налаштування:
|
||||
|
||||
- `openclaw/plugin-sdk/setup-runtime` для безпечних для runtime допоміжних функцій setup, як-от
|
||||
безпечні для імпорту адаптери патчів setup, вивід приміток lookup,
|
||||
`promptResolvedAllowFrom`, `splitSetupEntries` і делеговані проксі setup
|
||||
- `openclaw/plugin-sdk/channel-setup` для поверхонь setup необов’язкового встановлення
|
||||
- `openclaw/plugin-sdk/setup-tools` для допоміжних функцій CLI/архівів/документації для setup/install
|
||||
- `openclaw/plugin-sdk/setup-runtime` для безпечних для runtime хелперів налаштування, таких як
|
||||
безпечні для імпорту адаптери setup patch, виведення приміток пошуку,
|
||||
`promptResolvedAllowFrom`, `splitSetupEntries` і делеговані проксі налаштування
|
||||
- `openclaw/plugin-sdk/channel-setup` для поверхонь налаштування з необов’язковим встановленням
|
||||
- `openclaw/plugin-sdk/setup-tools` для хелперів CLI/архіву/документації для налаштування/встановлення
|
||||
|
||||
Тримайте важкі SDK, реєстрацію CLI та довготривалі сервіси runtime у повній
|
||||
Тримайте важкі SDK, реєстрацію CLI та довгоживучі runtime-сервіси в повній
|
||||
точці входу.
|
||||
|
||||
Вбудовані workspace channels, які розділяють поверхні налаштування та runtime,
|
||||
можуть натомість використовувати `defineBundledChannelSetupEntry(...)` з
|
||||
`openclaw/plugin-sdk/channel-entry-contract`. Цей контракт дозволяє точці входу
|
||||
налаштування зберігати безпечні для setup експорти plugin/secrets і водночас
|
||||
відкривати setter для runtime:
|
||||
|
||||
```typescript
|
||||
import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
||||
|
||||
export default defineBundledChannelSetupEntry({
|
||||
importMetaUrl: import.meta.url,
|
||||
plugin: {
|
||||
specifier: "./channel-plugin-api.js",
|
||||
exportName: "myChannelPlugin",
|
||||
},
|
||||
runtime: {
|
||||
specifier: "./runtime-api.js",
|
||||
exportName: "setMyChannelRuntime",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Використовуйте цей вбудований контракт лише тоді, коли потокам налаштування
|
||||
справді потрібен полегшений setter runtime до завантаження повної точки входу каналу.
|
||||
|
||||
## Режим реєстрації
|
||||
|
||||
`api.registrationMode` повідомляє вашому плагіну, як саме його було завантажено:
|
||||
`api.registrationMode` повідомляє вашому plugin, як саме його було завантажено:
|
||||
|
||||
| Режим | Коли | Що реєструвати |
|
||||
| ----------------- | --------------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| `"full"` | Звичайний запуск gateway | Усе |
|
||||
| `"setup-only"` | Вимкнений/не налаштований канал | Лише реєстрацію каналу |
|
||||
| `"setup-runtime"` | Потік setup із доступним runtime | Реєстрацію каналу плюс лише легкий runtime, потрібний до завантаження повної точки входу |
|
||||
| `"full"` | Звичайний запуск Gateway | Усе |
|
||||
| `"setup-only"` | Вимкнений/неналаштований канал | Лише реєстрацію каналу |
|
||||
| `"setup-runtime"` | Потік налаштування з доступним runtime | Реєстрацію каналу плюс лише полегшений runtime, потрібний до завантаження повної точки входу |
|
||||
| `"cli-metadata"` | Коренева довідка / захоплення метаданих CLI | Лише дескриптори CLI |
|
||||
|
||||
`defineChannelPluginEntry` обробляє цей поділ автоматично. Якщо ви використовуєте
|
||||
`definePluginEntry` безпосередньо для каналу, перевіряйте режим самостійно:
|
||||
`definePluginEntry` напряму для каналу, перевіряйте режим самостійно:
|
||||
|
||||
```typescript
|
||||
register(api) {
|
||||
@ -174,42 +202,42 @@ register(api) {
|
||||
api.registerChannel({ plugin: myPlugin });
|
||||
if (api.registrationMode !== "full") return;
|
||||
|
||||
// Heavy runtime-only registrations
|
||||
// Важкі реєстрації лише для runtime
|
||||
api.registerService(/* ... */);
|
||||
}
|
||||
```
|
||||
|
||||
Розглядайте `"setup-runtime"` як проміжок, у якому поверхні запуску лише для setup мають
|
||||
існувати без повторного входу в повний bundled runtime каналу. Добре підходять
|
||||
реєстрація каналу, безпечні для setup HTTP-маршрути, безпечні для setup gateway-методи та
|
||||
делеговані допоміжні функції setup. Важкі фонові сервіси, реєстратори CLI та
|
||||
завантаження SDK провайдерів/клієнтів, як і раніше, належать до `"full"`.
|
||||
Сприймайте `"setup-runtime"` як вікно, у якому поверхні запуску лише для налаштування
|
||||
мають існувати без повторного входу в повний runtime вбудованого каналу. Добре
|
||||
підходять реєстрація каналу, безпечні для setup HTTP-маршрути, безпечні для setup
|
||||
методи Gateway і делеговані хелпери налаштування. Важкі фонові сервіси, реєстратори CLI
|
||||
та ініціалізація provider/client SDK усе ще мають належати до `"full"`.
|
||||
|
||||
Зокрема для реєстраторів CLI:
|
||||
|
||||
- використовуйте `descriptors`, коли реєстратор володіє однією або кількома кореневими командами і ви
|
||||
хочете, щоб OpenClaw ліниво завантажував справжній модуль CLI при першому виклику
|
||||
хочете, щоб OpenClaw ліниво завантажував справжній модуль CLI під час першого виклику
|
||||
- переконайтеся, що ці дескриптори охоплюють кожен корінь команди верхнього рівня, який відкриває
|
||||
реєстратор
|
||||
- використовуйте лише `commands` для жадібних шляхів сумісності
|
||||
- використовуйте лише `commands` тільки для eager-шляхів сумісності
|
||||
|
||||
## Форми плагінів
|
||||
## Форми plugin
|
||||
|
||||
OpenClaw класифікує завантажені плагіни за їхньою поведінкою реєстрації:
|
||||
OpenClaw класифікує завантажені plugins за їхньою поведінкою під час реєстрації:
|
||||
|
||||
| Форма | Опис |
|
||||
| -------------------- | -------------------------------------------------- |
|
||||
| **plain-capability** | Один тип можливостей (наприклад, лише провайдер) |
|
||||
| **hybrid-capability** | Кілька типів можливостей (наприклад, провайдер + speech) |
|
||||
| **hook-only** | Лише hooks, без можливостей |
|
||||
| **non-capability** | Інструменти/команди/сервіси, але без можливостей |
|
||||
| Форма | Опис |
|
||||
| --------------------- | -------------------------------------------------- |
|
||||
| **plain-capability** | Один тип capability (наприклад, лише provider) |
|
||||
| **hybrid-capability** | Кілька типів capability (наприклад, provider + speech) |
|
||||
| **hook-only** | Лише hooks, без capability |
|
||||
| **non-capability** | Tools/commands/services, але без capability |
|
||||
|
||||
Використовуйте `openclaw plugins inspect <id>`, щоб побачити форму плагіна.
|
||||
Використовуйте `openclaw plugins inspect <id>`, щоб побачити форму plugin.
|
||||
|
||||
## Пов’язане
|
||||
## Пов’язані матеріали
|
||||
|
||||
- [Огляд SDK](/plugins/sdk-overview) — API реєстрації та довідник за subpath
|
||||
- [Допоміжні функції runtime](/plugins/sdk-runtime) — `api.runtime` і `createPluginRuntimeStore`
|
||||
- [Setup and Config](/plugins/sdk-setup) — маніфест, setup entry, відкладене завантаження
|
||||
- [Channel Plugins](/plugins/sdk-channel-plugins) — створення об’єкта `ChannelPlugin`
|
||||
- [Provider Plugins](/plugins/sdk-provider-plugins) — реєстрація провайдерів і hooks
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) — API реєстрації та довідник за subpath
|
||||
- [Хелпери runtime](/uk/plugins/sdk-runtime) — `api.runtime` і `createPluginRuntimeStore`
|
||||
- [Налаштування та конфігурація](/uk/plugins/sdk-setup) — маніфест, точка входу налаштування, відкладене завантаження
|
||||
- [Channel Plugins](/uk/plugins/sdk-channel-plugins) — побудова об’єкта `ChannelPlugin`
|
||||
- [Provider Plugins](/uk/plugins/sdk-provider-plugins) — реєстрація provider та hooks
|
||||
|
||||
@ -1,30 +1,29 @@
|
||||
---
|
||||
read_when:
|
||||
- Вам потрібно викликати допоміжні засоби ядра з плагіна (TTS, STT, генерація зображень, вебпошук, субагент)
|
||||
- Ви хочете зрозуміти, що надає api.runtime
|
||||
- Ви отримуєте доступ до допоміжних засобів конфігурації, агента або медіа з коду плагіна
|
||||
- Вам потрібно викликати допоміжні функції ядра з Plugin-а (TTS, STT, генерація зображень, вебпошук, subagent)
|
||||
- Ви хочете зрозуміти, що надає `api.runtime`
|
||||
- Ви отримуєте доступ до допоміжних функцій конфігурації, агента або медіа з коду Plugin-а
|
||||
sidebarTitle: Runtime Helpers
|
||||
summary: api.runtime -- впроваджені допоміжні засоби середовища виконання, доступні для плагінів
|
||||
title: Допоміжні засоби середовища виконання плагіна
|
||||
summary: api.runtime — впроваджені допоміжні функції середовища виконання, доступні для Plugin-ів
|
||||
title: Допоміжні функції середовища виконання Plugin-ів
|
||||
x-i18n:
|
||||
generated_at: "2026-04-10T20:23:46Z"
|
||||
generated_at: "2026-04-15T16:36:59Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: fbf8a6ecd970300f784b8aca20eed40ba12c83107abd27385bfdc3347d2544be
|
||||
source_hash: c77a6e9cd48c84affa17dce684bbd0e072c8b63485e4a5d569f3793a4ea4f9c8
|
||||
source_path: plugins/sdk-runtime.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Допоміжні засоби середовища виконання плагіна
|
||||
# Допоміжні функції середовища виконання Plugin-ів
|
||||
|
||||
Довідка щодо об’єкта `api.runtime`, який впроваджується в кожен плагін під час
|
||||
реєстрації. Використовуйте ці допоміжні засоби замість прямого імпорту внутрішніх
|
||||
компонентів хоста.
|
||||
Довідник для об’єкта `api.runtime`, який впроваджується в кожен Plugin під час
|
||||
реєстрації. Використовуйте ці допоміжні функції замість прямого імпорту внутрішніх компонентів хоста.
|
||||
|
||||
<Tip>
|
||||
**Шукаєте покрокове пояснення?** Перегляньте [Плагіни каналів](/uk/plugins/sdk-channel-plugins)
|
||||
або [Плагіни провайдерів](/uk/plugins/sdk-provider-plugins), щоб знайти покрокові посібники,
|
||||
які показують ці допоміжні засоби в контексті.
|
||||
**Шукаєте покроковий огляд?** Див. [Channel Plugins](/uk/plugins/sdk-channel-plugins)
|
||||
або [Provider Plugins](/uk/plugins/sdk-provider-plugins), щоб переглянути покрокові інструкції,
|
||||
які показують ці допоміжні функції в контексті.
|
||||
</Tip>
|
||||
|
||||
```typescript
|
||||
@ -70,14 +69,13 @@ const result = await api.runtime.agent.runEmbeddedAgent({
|
||||
});
|
||||
```
|
||||
|
||||
`runEmbeddedAgent(...)` — це нейтральний допоміжний засіб для запуску звичайного
|
||||
ходу агента OpenClaw з коду плагіна. Він використовує той самий механізм
|
||||
визначення провайдера/моделі та вибору harness агента, що й відповіді,
|
||||
запущені каналом.
|
||||
`runEmbeddedAgent(...)` — це нейтральна допоміжна функція для запуску звичайного ходу
|
||||
агента OpenClaw з коду Plugin-а. Вона використовує те саме визначення provider/model і
|
||||
вибір agent-harness, що й відповіді, ініційовані каналом.
|
||||
|
||||
`runEmbeddedPiAgent(...)` залишається псевдонімом для сумісності.
|
||||
`runEmbeddedPiAgent(...)` залишається сумісним псевдонімом.
|
||||
|
||||
**Допоміжні засоби сховища сесій** розміщені в `api.runtime.agent.session`:
|
||||
**Допоміжні функції сховища сесій** розміщені в `api.runtime.agent.session`:
|
||||
|
||||
```typescript
|
||||
const storePath = api.runtime.agent.session.resolveStorePath(cfg);
|
||||
@ -88,7 +86,7 @@ const filePath = api.runtime.agent.session.resolveSessionFilePath(cfg, sessionId
|
||||
|
||||
### `api.runtime.agent.defaults`
|
||||
|
||||
Константи стандартної моделі та провайдера:
|
||||
Константи моделі та provider за замовчуванням:
|
||||
|
||||
```typescript
|
||||
const model = api.runtime.agent.defaults.model; // e.g. "anthropic/claude-sonnet-4-6"
|
||||
@ -97,7 +95,7 @@ const provider = api.runtime.agent.defaults.provider; // e.g. "anthropic"
|
||||
|
||||
### `api.runtime.subagent`
|
||||
|
||||
Запуск і керування фоновими запусками субагента.
|
||||
Запуск і керування фоновими запусками subagent.
|
||||
|
||||
```typescript
|
||||
// Start a subagent run
|
||||
@ -125,17 +123,15 @@ await api.runtime.subagent.deleteSession({
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Перевизначення моделі (`provider`/`model`) потребує явної згоди оператора через
|
||||
Перевизначення моделі (`provider`/`model`) потребує згоди оператора через
|
||||
`plugins.entries.<id>.subagent.allowModelOverride: true` у конфігурації.
|
||||
Ненадійні плагіни все одно можуть запускати субагентів, але запити на
|
||||
перевизначення буде відхилено.
|
||||
Ненадійні plugins усе ще можуть запускати subagents, але запити на перевизначення відхиляються.
|
||||
</Warning>
|
||||
|
||||
### `api.runtime.taskFlow`
|
||||
|
||||
Прив’язує середовище виконання Task Flow до наявного ключа сесії OpenClaw або
|
||||
контексту довіреного інструмента, а потім дає змогу створювати й керувати Task Flow
|
||||
без передавання власника в кожному виклику.
|
||||
Прив’язка середовища виконання TaskFlow до наявного ключа сесії OpenClaw або довіреного
|
||||
контексту інструмента, а потім створення й керування TaskFlow без передавання власника під час кожного виклику.
|
||||
|
||||
```typescript
|
||||
const taskFlow = api.runtime.taskFlow.fromToolContext(ctx);
|
||||
@ -163,8 +159,8 @@ const waiting = taskFlow.setWaiting({
|
||||
```
|
||||
|
||||
Використовуйте `bindSession({ sessionKey, requesterOrigin })`, коли у вас уже є
|
||||
довірений ключ сесії OpenClaw із вашого власного шару прив’язки. Не виконуйте
|
||||
прив’язку на основі необробленого користувацького вводу.
|
||||
довірений ключ сесії OpenClaw з вашого власного шару прив’язки. Не виконуйте прив’язку з необробленого
|
||||
користувацького вводу.
|
||||
|
||||
### `api.runtime.tts`
|
||||
|
||||
@ -190,8 +186,8 @@ const voices = await api.runtime.tts.listVoices({
|
||||
});
|
||||
```
|
||||
|
||||
Використовує основну конфігурацію `messages.tts` і механізм вибору провайдера.
|
||||
Повертає буфер аудіо PCM + частоту дискретизації.
|
||||
Використовує основну конфігурацію `messages.tts` і вибір provider. Повертає PCM-аудіобуфер
|
||||
і частоту дискретизації.
|
||||
|
||||
### `api.runtime.mediaUnderstanding`
|
||||
|
||||
@ -225,11 +221,10 @@ const result = await api.runtime.mediaUnderstanding.runFile({
|
||||
});
|
||||
```
|
||||
|
||||
Повертає `{ text: undefined }`, якщо вихідні дані не було створено
|
||||
(наприклад, якщо вхідні дані було пропущено).
|
||||
Повертає `{ text: undefined }`, коли вихідні дані не створено (наприклад, якщо ввід пропущено).
|
||||
|
||||
<Info>
|
||||
`api.runtime.stt.transcribeAudioFile(...)` залишається псевдонімом для сумісності
|
||||
`api.runtime.stt.transcribeAudioFile(...)` залишається сумісним псевдонімом
|
||||
для `api.runtime.mediaUnderstanding.transcribeAudioFile(...)`.
|
||||
</Info>
|
||||
|
||||
@ -261,7 +256,7 @@ const result = await api.runtime.webSearch.search({
|
||||
|
||||
### `api.runtime.media`
|
||||
|
||||
Низькорівневі мультимедійні утиліти.
|
||||
Низькорівневі медіаутиліти.
|
||||
|
||||
```typescript
|
||||
const webMedia = await api.runtime.media.loadWebMedia(url);
|
||||
@ -283,7 +278,7 @@ await api.runtime.config.writeConfigFile(cfg);
|
||||
|
||||
### `api.runtime.system`
|
||||
|
||||
Утиліти системного рівня.
|
||||
Системні утиліти.
|
||||
|
||||
```typescript
|
||||
await api.runtime.system.enqueueSystemEvent(event);
|
||||
@ -307,7 +302,7 @@ api.runtime.events.onSessionTranscriptUpdate((update) => {
|
||||
|
||||
### `api.runtime.logging`
|
||||
|
||||
Журналювання.
|
||||
Логування.
|
||||
|
||||
```typescript
|
||||
const verbose = api.runtime.logging.shouldLogVerbose();
|
||||
@ -316,7 +311,7 @@ const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" },
|
||||
|
||||
### `api.runtime.modelAuth`
|
||||
|
||||
Визначення автентифікації моделі та провайдера.
|
||||
Визначення автентифікації моделі та provider.
|
||||
|
||||
```typescript
|
||||
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });
|
||||
@ -346,11 +341,10 @@ api.runtime.tools.registerMemoryCli(/* ... */);
|
||||
|
||||
### `api.runtime.channel`
|
||||
|
||||
Допоміжні засоби середовища виконання, специфічні для каналу (доступні, коли
|
||||
завантажено плагін каналу).
|
||||
Допоміжні функції середовища виконання для конкретного каналу (доступні, коли завантажено channel Plugin).
|
||||
|
||||
`api.runtime.channel.mentions` — це спільна поверхня політики вхідних згадок для
|
||||
вбудованих плагінів каналів, які використовують впровадження середовища виконання:
|
||||
`api.runtime.channel.mentions` — це спільна поверхня політики згадок для вхідних повідомлень
|
||||
для вбудованих channel Plugin-ів, які використовують впровадження середовища виконання:
|
||||
|
||||
```typescript
|
||||
const mentionMatch = api.runtime.channel.mentions.matchesMentionWithExplicit(text, {
|
||||
@ -377,7 +371,7 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({
|
||||
});
|
||||
```
|
||||
|
||||
Доступні допоміжні засоби для згадок:
|
||||
Доступні допоміжні функції згадок:
|
||||
|
||||
- `buildMentionRegexes`
|
||||
- `matchesMentionPatterns`
|
||||
@ -385,20 +379,23 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({
|
||||
- `implicitMentionKindWhen`
|
||||
- `resolveInboundMentionDecision`
|
||||
|
||||
`api.runtime.channel.mentions` навмисно не надає старі допоміжні засоби сумісності
|
||||
`resolveMentionGating*`. Надавайте перевагу нормалізованому шляху
|
||||
`{ facts, policy }`.
|
||||
`api.runtime.channel.mentions` навмисно не надає старі
|
||||
сумісні допоміжні функції `resolveMentionGating*`. Надавайте перевагу нормалізованому
|
||||
шляху `{ facts, policy }`.
|
||||
|
||||
## Зберігання посилань на середовище виконання
|
||||
|
||||
Використовуйте `createPluginRuntimeStore`, щоб зберігати посилання на середовище
|
||||
виконання для використання поза зворотним викликом `register`:
|
||||
Використовуйте `createPluginRuntimeStore`, щоб зберегти посилання на середовище виконання для використання поза межами
|
||||
зворотного виклику `register`:
|
||||
|
||||
```typescript
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";
|
||||
|
||||
const store = createPluginRuntimeStore<PluginRuntime>("my-plugin runtime not initialized");
|
||||
const store = createPluginRuntimeStore<PluginRuntime>({
|
||||
pluginId: "my-plugin",
|
||||
errorMessage: "my-plugin runtime not initialized",
|
||||
});
|
||||
|
||||
// In your entry point
|
||||
export default defineChannelPluginEntry({
|
||||
@ -419,22 +416,25 @@ export function tryGetRuntime() {
|
||||
}
|
||||
```
|
||||
|
||||
Для ідентичності runtime-store надавайте перевагу `pluginId`. Нижчорівнева форма `key`
|
||||
призначена для нечастих випадків, коли одному Plugin-у навмисно потрібно більше одного слота середовища виконання.
|
||||
|
||||
## Інші поля верхнього рівня `api`
|
||||
|
||||
Окрім `api.runtime`, об’єкт API також надає:
|
||||
|
||||
| Поле | Тип | Опис |
|
||||
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `api.id` | `string` | Ідентифікатор плагіна |
|
||||
| `api.name` | `string` | Відображувана назва плагіна |
|
||||
| `api.id` | `string` | Ідентифікатор Plugin-а |
|
||||
| `api.name` | `string` | Відображувана назва Plugin-а |
|
||||
| `api.config` | `OpenClawConfig` | Поточний знімок конфігурації (активний знімок середовища виконання в пам’яті, коли доступний) |
|
||||
| `api.pluginConfig` | `Record<string, unknown>` | Конфігурація, специфічна для плагіна, з `plugins.entries.<id>.config` |
|
||||
| `api.logger` | `PluginLogger` | Logger з областю видимості (`debug`, `info`, `warn`, `error`) |
|
||||
| `api.pluginConfig` | `Record<string, unknown>` | Конфігурація Plugin-а з `plugins.entries.<id>.config` |
|
||||
| `api.logger` | `PluginLogger` | Logger з областю видимості (`debug`, `info`, `warn`, `error`) |
|
||||
| `api.registrationMode` | `PluginRegistrationMode` | Поточний режим завантаження; `"setup-runtime"` — це полегшене вікно запуску/налаштування перед повним запуском entry point |
|
||||
| `api.resolvePath(input)` | `(string) => string` | Визначає шлях відносно кореня плагіна |
|
||||
| `api.resolvePath(input)` | `(string) => string` | Визначає шлях відносно кореня Plugin-а |
|
||||
|
||||
## Пов’язане
|
||||
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) -- довідка щодо підшляхів
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) -- довідник щодо subpath
|
||||
- [Точки входу SDK](/uk/plugins/sdk-entrypoints) -- параметри `definePluginEntry`
|
||||
- [Внутрішня структура плагіна](/uk/plugins/architecture) -- модель можливостей і реєстр
|
||||
- [Внутрішні компоненти Plugin-ів](/uk/plugins/architecture) -- модель можливостей і реєстр
|
||||
|
||||
@ -1,37 +1,37 @@
|
||||
---
|
||||
read_when:
|
||||
- Ви додаєте майстер налаштування до плагіна
|
||||
- Ви додаєте майстер налаштування до Plugin
|
||||
- Вам потрібно зрозуміти різницю між setup-entry.ts і index.ts
|
||||
- Ви визначаєте схеми конфігурації плагіна або метадані openclaw у package.json
|
||||
- Ви визначаєте схеми конфігурації Plugin або метадані openclaw у package.json
|
||||
sidebarTitle: Setup and Config
|
||||
summary: Майстри налаштування, setup-entry.ts, схеми конфігурації та метадані package.json
|
||||
title: Налаштування плагінів і конфігурація
|
||||
title: Налаштування Plugin та конфігурація
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T22:37:37Z"
|
||||
generated_at: "2026-04-15T16:36:55Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: eac2586516d27bcd94cc4c259fe6274c792b3f9938c7ddd6dbf04a6dbb988dc9
|
||||
source_hash: ddf28e25e381a4a38ac478e531586f59612e1a278732597375f87c2eeefc521b
|
||||
source_path: plugins/sdk-setup.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Налаштування плагінів і конфігурація
|
||||
# Налаштування Plugin та конфігурація
|
||||
|
||||
Довідник щодо пакування плагінів (метадані `package.json`), маніфестів
|
||||
(`openclaw.plugin.json`), точок входу налаштування та схем конфігурації.
|
||||
Довідка щодо пакування plugin (`package.json` metadata), маніфестів
|
||||
(`openclaw.plugin.json`), записів налаштування та схем конфігурації.
|
||||
|
||||
<Tip>
|
||||
**Шукаєте покроковий посібник?** Практичні інструкції розглядають пакування в контексті:
|
||||
**Шукаєте покроковий приклад?** Практичні посібники охоплюють пакування в контексті:
|
||||
[Channel Plugins](/uk/plugins/sdk-channel-plugins#step-1-package-and-manifest) і
|
||||
[Provider Plugins](/uk/plugins/sdk-provider-plugins#step-1-package-and-manifest).
|
||||
</Tip>
|
||||
|
||||
## Метадані пакета
|
||||
## Метадані пакунка
|
||||
|
||||
Вашому `package.json` потрібне поле `openclaw`, яке повідомляє системі плагінів, що
|
||||
саме надає ваш плагін:
|
||||
Ваш `package.json` має містити поле `openclaw`, яке повідомляє системі plugin, що саме
|
||||
надає ваш plugin:
|
||||
|
||||
**Плагін каналу:**
|
||||
**Channel plugin:**
|
||||
|
||||
```json
|
||||
{
|
||||
@ -50,7 +50,7 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
**Плагін провайдера / базовий варіант для публікації ClawHub:**
|
||||
**Provider plugin / базовий шаблон публікації ClawHub:**
|
||||
|
||||
```json openclaw-clawhub-package.json
|
||||
{
|
||||
@ -71,47 +71,47 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
Якщо ви публікуєте плагін зовнішньо в ClawHub, поля `compat` і `build`
|
||||
Якщо ви публікуєте plugin зовнішньо в ClawHub, поля `compat` і `build`
|
||||
є обов’язковими. Канонічні фрагменти для публікації знаходяться в
|
||||
`docs/snippets/plugin-publish/`.
|
||||
|
||||
### Поля `openclaw`
|
||||
|
||||
| Поле | Тип | Опис |
|
||||
| ------------ | ---------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `extensions` | `string[]` | Файли точок входу (відносно кореня пакета) |
|
||||
| `setupEntry` | `string` | Легка точка входу лише для налаштування (необов’язково) |
|
||||
| `channel` | `object` | Метадані каталогу каналів для налаштування, вибору, швидкого старту та поверхонь стану |
|
||||
| `providers` | `string[]` | Ідентифікатори провайдерів, зареєстрованих цим плагіном |
|
||||
| `install` | `object` | Підказки для встановлення: `npmSpec`, `localPath`, `defaultChoice`, `minHostVersion`, `allowInvalidConfigRecovery` |
|
||||
| `startup` | `object` | Прапорці поведінки під час запуску |
|
||||
| Поле | Тип | Опис |
|
||||
| ------------ | ---------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `extensions` | `string[]` | Файли точок входу (відносно кореня пакунка) |
|
||||
| `setupEntry` | `string` | Полегшена точка входу лише для налаштування (необов’язково) |
|
||||
| `channel` | `object` | Метадані каталогу channel для налаштування, вибору, швидкого старту та поверхонь статусу |
|
||||
| `providers` | `string[]` | Ідентифікатори provider, зареєстрованих цим plugin |
|
||||
| `install` | `object` | Підказки встановлення: `npmSpec`, `localPath`, `defaultChoice`, `minHostVersion`, `allowInvalidConfigRecovery` |
|
||||
| `startup` | `object` | Прапори поведінки під час запуску |
|
||||
|
||||
### `openclaw.channel`
|
||||
|
||||
`openclaw.channel` — це недорогі метадані пакета для виявлення каналів і
|
||||
поверхонь налаштування до завантаження середовища виконання.
|
||||
`openclaw.channel` — це недорогі метадані пакунка для виявлення channel і поверхонь
|
||||
налаштування до завантаження runtime.
|
||||
|
||||
| Поле | Тип | Що це означає |
|
||||
| -------------------------------------- | ---------- | ----------------------------------------------------------------------------- |
|
||||
| `id` | `string` | Канонічний ідентифікатор каналу. |
|
||||
| `label` | `string` | Основна мітка каналу. |
|
||||
| `selectionLabel` | `string` | Мітка у виборі/налаштуванні, якщо вона має відрізнятися від `label`. |
|
||||
| `detailLabel` | `string` | Додаткова мітка для багатших каталогів каналів і поверхонь стану. |
|
||||
| `docsPath` | `string` | Шлях до документації для посилань налаштування й вибору. |
|
||||
| `docsLabel` | `string` | Перевизначення мітки для посилань на документацію, якщо вона має відрізнятися від ідентифікатора каналу. |
|
||||
| `blurb` | `string` | Короткий опис для онбордингу/каталогу. |
|
||||
| `order` | `number` | Порядок сортування в каталогах каналів. |
|
||||
| `aliases` | `string[]` | Додаткові псевдоніми пошуку для вибору каналу. |
|
||||
| `preferOver` | `string[]` | Ідентифікатори плагінів/каналів нижчого пріоритету, які цей канал має випереджати. |
|
||||
| `systemImage` | `string` | Необов’язкова назва значка/system-image для UI-каталогів каналів. |
|
||||
| `selectionDocsPrefix` | `string` | Текст-префікс перед посиланнями на документацію в поверхнях вибору. |
|
||||
| `selectionDocsOmitLabel` | `boolean` | Показувати шлях до документації напряму замість підписаного посилання в тексті вибору. |
|
||||
| `selectionExtras` | `string[]` | Додаткові короткі рядки, додані в тексті вибору. |
|
||||
| `markdownCapable` | `boolean` | Позначає канал як сумісний із Markdown для рішень щодо вихідного форматування. |
|
||||
| `exposure` | `object` | Керування видимістю каналу для налаштування, списків налаштованих каналів і поверхонь документації. |
|
||||
| `quickstartAllowFrom` | `boolean` | Вмикає для цього каналу стандартний потік налаштування quickstart `allowFrom`. |
|
||||
| Поле | Тип | Що це означає |
|
||||
| -------------------------------------- | ---------- | ---------------------------------------------------------------------------- |
|
||||
| `id` | `string` | Канонічний ідентифікатор channel. |
|
||||
| `label` | `string` | Основна мітка channel. |
|
||||
| `selectionLabel` | `string` | Мітка у виборі/налаштуванні, якщо вона має відрізнятися від `label`. |
|
||||
| `detailLabel` | `string` | Додаткова детальна мітка для багатших каталогів channel і поверхонь статусу. |
|
||||
| `docsPath` | `string` | Шлях до документації для посилань у налаштуванні та виборі. |
|
||||
| `docsLabel` | `string` | Перевизначення мітки для посилань на документацію, якщо вона має відрізнятися від ідентифікатора channel. |
|
||||
| `blurb` | `string` | Короткий опис для онбордингу/каталогу. |
|
||||
| `order` | `number` | Порядок сортування в каталогах channel. |
|
||||
| `aliases` | `string[]` | Додаткові псевдоніми для пошуку під час вибору channel. |
|
||||
| `preferOver` | `string[]` | Ідентифікатори plugin/channel з нижчим пріоритетом, які цей channel має випереджати. |
|
||||
| `systemImage` | `string` | Необов’язкова назва піктограми/system-image для каталогів UI channel. |
|
||||
| `selectionDocsPrefix` | `string` | Текст-префікс перед посиланнями на документацію в поверхнях вибору. |
|
||||
| `selectionDocsOmitLabel` | `boolean` | Показувати шлях документації безпосередньо замість підписаного посилання в тексті вибору. |
|
||||
| `selectionExtras` | `string[]` | Додаткові короткі рядки, що додаються в тексті вибору. |
|
||||
| `markdownCapable` | `boolean` | Позначає channel як сумісний з markdown для рішень щодо вихідного форматування. |
|
||||
| `exposure` | `object` | Керування видимістю channel для налаштування, списків налаштованих елементів і поверхонь документації. |
|
||||
| `quickstartAllowFrom` | `boolean` | Додає цей channel до стандартного потоку налаштування quickstart `allowFrom`. |
|
||||
| `forceAccountBinding` | `boolean` | Вимагає явної прив’язки облікового запису, навіть якщо існує лише один обліковий запис. |
|
||||
| `preferSessionLookupForAnnounceTarget` | `boolean` | Надає перевагу пошуку сесії під час визначення announce-target для цього каналу. |
|
||||
| `preferSessionLookupForAnnounceTarget` | `boolean` | Віддавати перевагу пошуку сесії під час визначення цілей announce для цього channel. |
|
||||
|
||||
Приклад:
|
||||
|
||||
@ -145,38 +145,37 @@ x-i18n:
|
||||
|
||||
`exposure` підтримує:
|
||||
|
||||
- `configured`: включати канал до поверхонь переліку налаштованих каналів/стану
|
||||
- `setup`: включати канал до інтерактивних засобів вибору налаштування/конфігурації
|
||||
- `docs`: позначати канал як публічний у поверхнях документації/навігації
|
||||
- `configured`: включати channel у поверхні списків налаштованих елементів/статусів
|
||||
- `setup`: включати channel в інтерактивні засоби вибору налаштування/конфігурації
|
||||
- `docs`: позначати channel як публічно видимий у поверхнях документації/навігації
|
||||
|
||||
`showConfigured` і `showInSetup` залишаються підтримуваними як застарілі псевдоніми. Рекомендується
|
||||
`exposure`.
|
||||
`showConfigured` і `showInSetup` залишаються підтримуваними як застарілі псевдоніми. Рекомендовано
|
||||
використовувати `exposure`.
|
||||
|
||||
### `openclaw.install`
|
||||
|
||||
`openclaw.install` — це метадані пакета, а не метадані маніфесту.
|
||||
`openclaw.install` — це метадані пакунка, а не метадані маніфесту.
|
||||
|
||||
| Поле | Тип | Що це означає |
|
||||
| ---------------------------- | -------------------- | -------------------------------------------------------------------------------- |
|
||||
| `npmSpec` | `string` | Канонічна npm-специфікація для потоків встановлення/оновлення. |
|
||||
| `localPath` | `string` | Локальний шлях для розробки або вбудованого встановлення. |
|
||||
| ---------------------------- | -------------------- | ------------------------------------------------------------------------------- |
|
||||
| `npmSpec` | `string` | Канонічний npm spec для потоків встановлення/оновлення. |
|
||||
| `localPath` | `string` | Локальний шлях встановлення для розробки або вбудованого пакета. |
|
||||
| `defaultChoice` | `"npm"` \| `"local"` | Бажане джерело встановлення, коли доступні обидва варіанти. |
|
||||
| `minHostVersion` | `string` | Мінімальна підтримувана версія OpenClaw у формі `>=x.y.z`. |
|
||||
| `allowInvalidConfigRecovery` | `boolean` | Дає змогу потокам перевстановлення вбудованих плагінів відновлюватися після окремих збоїв через застарілу конфігурацію. |
|
||||
| `minHostVersion` | `string` | Мінімально підтримувана версія OpenClaw у форматі `>=x.y.z`. |
|
||||
| `allowInvalidConfigRecovery` | `boolean` | Дозволяє потокам перевстановлення вбудованого plugin відновлюватися після окремих збоїв через застарілу конфігурацію. |
|
||||
|
||||
Якщо задано `minHostVersion`, його перевіряють як під час встановлення, так і
|
||||
під час завантаження реєстру маніфестів. Старіші хости пропускають плагін;
|
||||
некоректні рядки версій відхиляються.
|
||||
Якщо задано `minHostVersion`, і встановлення, і завантаження реєстру маніфестів
|
||||
застосовують цю перевірку. Старіші хости пропускають plugin; некоректні рядки версій відхиляються.
|
||||
|
||||
`allowInvalidConfigRecovery` — це не загальний обхід для зламаних конфігурацій. Він
|
||||
призначений лише для вузького відновлення вбудованих плагінів, щоб перевстановлення/налаштування
|
||||
могло виправити відомі залишки після оновлення, як-от відсутній шлях до вбудованого плагіна або застарілий запис `channels.<id>`
|
||||
для цього самого плагіна. Якщо конфігурація зламана з інших причин, встановлення
|
||||
все одно завершується із закритою відмовою та пропонує оператору виконати `openclaw doctor --fix`.
|
||||
`allowInvalidConfigRecovery` не є загальним обходом для зламаних конфігурацій. Воно
|
||||
призначене лише для вузького сценарію відновлення вбудованого plugin, щоб перевстановлення/налаштування
|
||||
могли виправити відомі залишки після оновлення, як-от відсутній шлях до вбудованого plugin або застарілий запис `channels.<id>`
|
||||
для цього самого plugin. Якщо конфігурація зламана з інших причин, встановлення
|
||||
усе одно завершується з відмовою і пропонує оператору виконати `openclaw doctor --fix`.
|
||||
|
||||
### Відкладене повне завантаження
|
||||
|
||||
Плагіни каналів можуть увімкнути відкладене завантаження за допомогою:
|
||||
Channel plugins можуть увімкнути відкладене завантаження так:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -190,26 +189,26 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
Якщо цю можливість увімкнено, OpenClaw завантажує лише `setupEntry` під час
|
||||
передслуховувальної фази запуску, навіть для вже налаштованих каналів. Повна точка входу
|
||||
завантажується після того, як gateway починає слухати.
|
||||
Коли це ввімкнено, OpenClaw завантажує лише `setupEntry` під час фази запуску до
|
||||
початку прослуховування, навіть для вже налаштованих channel. Повна точка входу завантажується після того,
|
||||
як Gateway починає прослуховування.
|
||||
|
||||
<Warning>
|
||||
Вмикайте відкладене завантаження лише тоді, коли ваш `setupEntry` реєструє все,
|
||||
що gateway потрібно до початку прослуховування (реєстрацію каналів, HTTP-маршрути,
|
||||
методи gateway). Якщо повна точка входу володіє необхідними можливостями запуску, залиште
|
||||
Увімкнюйте відкладене завантаження лише тоді, коли ваш `setupEntry` реєструє все,
|
||||
що Gateway потрібно до початку прослуховування (реєстрація channel, HTTP-маршрути,
|
||||
методи Gateway). Якщо повна точка входу володіє потрібними можливостями запуску, залиште
|
||||
поведінку за замовчуванням.
|
||||
</Warning>
|
||||
|
||||
Якщо ваш setup/full entry реєструє RPC-методи gateway, залишайте їх на
|
||||
префіксі, специфічному для плагіна. Зарезервовані простори імен основного адміністратора (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) належать ядру й завжди зіставляються
|
||||
Якщо ваш запис налаштування/повний запис реєструє методи Gateway RPC, використовуйте для них
|
||||
префікс, специфічний для plugin. Зарезервовані простори імен основного адміністратора (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) залишаються під керуванням core і завжди зіставляються
|
||||
з `operator.admin`.
|
||||
|
||||
## Маніфест плагіна
|
||||
## Маніфест Plugin
|
||||
|
||||
Кожен нативний плагін має постачатися з `openclaw.plugin.json` у корені пакета.
|
||||
OpenClaw використовує його для перевірки конфігурації без виконання коду плагіна.
|
||||
Кожен native plugin має постачати `openclaw.plugin.json` у корені пакунка.
|
||||
OpenClaw використовує це для перевірки конфігурації без виконання коду plugin.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -229,7 +228,7 @@ OpenClaw використовує його для перевірки конфі
|
||||
}
|
||||
```
|
||||
|
||||
Для плагінів каналів додайте `kind` і `channels`:
|
||||
Для channel plugins додайте `kind` і `channels`:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -244,7 +243,7 @@ OpenClaw використовує його для перевірки конфі
|
||||
}
|
||||
```
|
||||
|
||||
Навіть плагіни без конфігурації мають постачатися зі схемою. Порожня схема є коректною:
|
||||
Навіть plugins без конфігурації мають постачати схему. Порожня схема є валідною:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -256,25 +255,25 @@ OpenClaw використовує його для перевірки конфі
|
||||
}
|
||||
```
|
||||
|
||||
Див. [Plugin Manifest](/uk/plugins/manifest), щоб отримати повний довідник зі схеми.
|
||||
Див. [Plugin Manifest](/uk/plugins/manifest) для повної довідки щодо схеми.
|
||||
|
||||
## Публікація в ClawHub
|
||||
|
||||
Для пакетів плагінів використовуйте команду ClawHub, специфічну для пакета:
|
||||
Для пакунків plugin використовуйте команду ClawHub, специфічну для пакунків:
|
||||
|
||||
```bash
|
||||
clawhub package publish your-org/your-plugin --dry-run
|
||||
clawhub package publish your-org/your-plugin
|
||||
```
|
||||
|
||||
Застарілий псевдонім публікації лише для skills призначений для Skills. Пакети плагінів
|
||||
Застарілий псевдонім публікації лише для Skills призначений для skills. Пакунки plugin
|
||||
завжди мають використовувати `clawhub package publish`.
|
||||
|
||||
## Точка входу налаштування
|
||||
|
||||
Файл `setup-entry.ts` — це легка альтернатива `index.ts`, яку
|
||||
Файл `setup-entry.ts` — це полегшена альтернатива `index.ts`, яку
|
||||
OpenClaw завантажує, коли йому потрібні лише поверхні налаштування (онбординг, відновлення конфігурації,
|
||||
перевірка вимкнених каналів).
|
||||
перевірка вимкненого channel).
|
||||
|
||||
```typescript
|
||||
// setup-entry.ts
|
||||
@ -287,74 +286,79 @@ export default defineSetupPluginEntry(myChannelPlugin);
|
||||
Це дає змогу уникнути завантаження важкого runtime-коду (криптографічних бібліотек, реєстрацій CLI,
|
||||
фонових сервісів) під час потоків налаштування.
|
||||
|
||||
Вбудовані workspace channel, які тримають безпечні для налаштування експорти в sidecar-модулях, можуть
|
||||
використовувати `defineBundledChannelSetupEntry(...)` з
|
||||
`openclaw/plugin-sdk/channel-entry-contract` замість
|
||||
`defineSetupPluginEntry(...)`. Цей вбудований контракт також підтримує необов’язковий експорт
|
||||
`runtime`, щоб підключення runtime під час налаштування залишалося полегшеним і явним.
|
||||
|
||||
**Коли OpenClaw використовує `setupEntry` замість повної точки входу:**
|
||||
|
||||
- Канал вимкнено, але потрібні поверхні налаштування/онбордингу
|
||||
- Канал увімкнено, але не налаштовано
|
||||
- Channel вимкнено, але потрібні поверхні налаштування/онбордингу
|
||||
- Channel увімкнено, але не налаштовано
|
||||
- Увімкнено відкладене завантаження (`deferConfiguredChannelFullLoadUntilAfterListen`)
|
||||
|
||||
**Що має реєструвати `setupEntry`:**
|
||||
|
||||
- Об’єкт плагіна каналу (через `defineSetupPluginEntry`)
|
||||
- Будь-які HTTP-маршрути, потрібні до початку прослуховування gateway
|
||||
- Будь-які методи gateway, потрібні під час запуску
|
||||
- Об’єкт channel plugin (через `defineSetupPluginEntry`)
|
||||
- Будь-які HTTP-маршрути, потрібні до початку прослуховування Gateway
|
||||
- Будь-які методи Gateway, потрібні під час запуску
|
||||
|
||||
Ці методи gateway для запуску все одно мають уникати зарезервованих
|
||||
просторів імен основного адміністратора, як-от `config.*` або `update.*`.
|
||||
Ці методи Gateway для запуску все одно мають уникати зарезервованих
|
||||
просторів імен core admin, таких як `config.*` або `update.*`.
|
||||
|
||||
**Що НЕ має містити `setupEntry`:**
|
||||
|
||||
- Реєстрації CLI
|
||||
- Фонові сервіси
|
||||
- Важкі імпорти runtime (криптографія, SDK)
|
||||
- Методи gateway, потрібні лише після запуску
|
||||
- Важкі імпорти runtime (crypto, SDKs)
|
||||
- Методи Gateway, потрібні лише після запуску
|
||||
|
||||
### Вузькі імпорти допоміжних засобів налаштування
|
||||
|
||||
Для гарячих шляхів лише налаштування віддавайте перевагу вузьким швам допоміжних засобів налаштування замість ширшої
|
||||
парасольки `plugin-sdk/setup`, коли вам потрібна лише частина поверхні налаштування:
|
||||
Для гарячих шляхів лише для налаштування надавайте перевагу вузьким швам допоміжних засобів налаштування замість ширшого
|
||||
парасолькового `plugin-sdk/setup`, коли вам потрібна лише частина поверхні налаштування:
|
||||
|
||||
| Шлях імпорту | Використовуйте для | Ключові експорти |
|
||||
| ---------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `plugin-sdk/setup-runtime` | допоміжні засоби runtime під час налаштування, які залишаються доступними в `setupEntry` / відкладеному запуску каналу | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` |
|
||||
| `plugin-sdk/setup-adapter-runtime` | адаптери налаштування облікових записів, що враховують середовище | `createEnvPatchedAccountSetupAdapter` |
|
||||
| `plugin-sdk/setup-tools` | допоміжні засоби CLI/архівів/документації для налаштування/встановлення | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
|
||||
| Шлях імпорту | Для чого використовувати | Ключові експорти |
|
||||
| --------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `plugin-sdk/setup-runtime` | допоміжні засоби runtime під час налаштування, які лишаються доступними в `setupEntry` / відкладеному запуску channel | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` |
|
||||
| `plugin-sdk/setup-adapter-runtime` | адаптери налаштування облікових записів з урахуванням середовища | `createEnvPatchedAccountSetupAdapter` |
|
||||
| `plugin-sdk/setup-tools` | допоміжні засоби CLI/архіву/документації для налаштування та встановлення | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
|
||||
|
||||
Використовуйте ширший шов `plugin-sdk/setup`, коли вам потрібен повний спільний
|
||||
набір інструментів налаштування, включно з допоміжними засобами patch-конфігурації, такими як
|
||||
набір інструментів для налаштування, включно з допоміжними засобами patch для конфігурації, такими як
|
||||
`moveSingleAccountChannelSectionToDefaultAccount(...)`.
|
||||
|
||||
Адаптери patch для налаштування залишаються безпечними для імпорту на гарячому шляху. Їхня вбудована
|
||||
ледача перевірка contract-surface для підвищення одного облікового запису
|
||||
є лінивою, тому імпорт `plugin-sdk/setup-runtime` не завантажує завчасно
|
||||
виявлення вбудованої contract-surface до фактичного використання адаптера.
|
||||
Адаптери patch для налаштування залишаються безпечними для гарячого шляху під час імпорту. Їхній вбудований
|
||||
ледачий пошук поверхні контракту для просування одного облікового запису є відкладеним, тому імпорт
|
||||
`plugin-sdk/setup-runtime` не завантажує завчасно виявлення поверхні вбудованого контракту до фактичного використання адаптера.
|
||||
|
||||
### Підвищення одного облікового запису, яке належить каналу
|
||||
### Просування одного облікового запису, що належить channel
|
||||
|
||||
Коли канал оновлюється з верхньорівневої конфігурації одного облікового запису до
|
||||
`channels.<id>.accounts.*`, типовою спільною поведінкою є переміщення значень,
|
||||
що належать обліковому запису, до `accounts.default`.
|
||||
Коли channel оновлюється з верхньорівневої конфігурації одного облікового запису до
|
||||
`channels.<id>.accounts.*`, типова спільна поведінка полягає в переміщенні значень,
|
||||
що належать області облікового запису, до `accounts.default`.
|
||||
|
||||
Вбудовані канали можуть звузити або перевизначити це підвищення через свою
|
||||
contract-surface налаштування:
|
||||
Вбудовані channels можуть звузити або перевизначити це просування через свою
|
||||
поверхню контракту налаштування:
|
||||
|
||||
- `singleAccountKeysToMove`: додаткові верхньорівневі ключі, які слід перемістити до
|
||||
підвищеного облікового запису
|
||||
- `namedAccountPromotionKeys`: коли іменовані облікові записи вже існують, лише ці
|
||||
ключі переміщуються до підвищеного облікового запису; спільні ключі політики/доставки залишаються в корені
|
||||
каналу
|
||||
- `resolveSingleAccountPromotionTarget(...)`: вибір наявного облікового запису,
|
||||
який отримує підвищені значення
|
||||
- `singleAccountKeysToMove`: додаткові верхньорівневі ключі, які потрібно перемістити до
|
||||
просунутого облікового запису
|
||||
- `namedAccountPromotionKeys`: якщо іменовані облікові записи вже існують, лише ці
|
||||
ключі переміщуються до просунутого облікового запису; спільні ключі policy/delivery залишаються в корені
|
||||
channel
|
||||
- `resolveSingleAccountPromotionTarget(...)`: вибір наявного облікового запису, який
|
||||
отримає просунуті значення
|
||||
|
||||
Matrix — поточний вбудований приклад. Якщо вже існує рівно один іменований обліковий запис Matrix
|
||||
або якщо `defaultAccount` вказує на наявний неканонічний ключ, наприклад
|
||||
`Ops`, підвищення зберігає цей обліковий запис замість створення нового запису
|
||||
`accounts.default`.
|
||||
Matrix — поточний вбудований приклад. Якщо вже існує рівно один іменований обліковий запис Matrix,
|
||||
або якщо `defaultAccount` вказує на наявний неканонічний ключ
|
||||
на кшталт `Ops`, просування зберігає цей обліковий запис замість створення нового
|
||||
запису `accounts.default`.
|
||||
|
||||
## Схема конфігурації
|
||||
|
||||
Конфігурація плагіна перевіряється відповідно до JSON Schema у вашому маніфесті. Користувачі
|
||||
налаштовують плагіни через:
|
||||
Конфігурація plugin проходить перевірку за JSON Schema у вашому маніфесті. Користувачі
|
||||
налаштовують plugins через:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -370,9 +374,9 @@ Matrix — поточний вбудований приклад. Якщо вже
|
||||
}
|
||||
```
|
||||
|
||||
Ваш плагін отримує цю конфігурацію як `api.pluginConfig` під час реєстрації.
|
||||
Ваш plugin отримує цю конфігурацію як `api.pluginConfig` під час реєстрації.
|
||||
|
||||
Для конфігурації, специфічної для каналу, використовуйте натомість розділ конфігурації каналу:
|
||||
Для конфігурації, специфічної для channel, використовуйте натомість розділ конфігурації channel:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -385,7 +389,7 @@ Matrix — поточний вбудований приклад. Якщо вже
|
||||
}
|
||||
```
|
||||
|
||||
### Побудова схем конфігурації каналу
|
||||
### Побудова схем конфігурації channel
|
||||
|
||||
Використовуйте `buildChannelConfigSchema` з `openclaw/plugin-sdk/core`, щоб перетворити
|
||||
схему Zod на обгортку `ChannelConfigSchema`, яку перевіряє OpenClaw:
|
||||
@ -406,7 +410,7 @@ const configSchema = buildChannelConfigSchema(accountSchema);
|
||||
|
||||
## Майстри налаштування
|
||||
|
||||
Плагіни каналів можуть надавати інтерактивні майстри налаштування для `openclaw onboard`.
|
||||
Channel plugins можуть надавати інтерактивні майстри налаштування для `openclaw onboard`.
|
||||
Майстер — це об’єкт `ChannelSetupWizard` у `ChannelPlugin`:
|
||||
|
||||
```typescript
|
||||
@ -441,20 +445,19 @@ const setupWizard: ChannelSetupWizard = {
|
||||
```
|
||||
|
||||
Тип `ChannelSetupWizard` підтримує `credentials`, `textInputs`,
|
||||
`dmPolicy`, `allowFrom`, `groupAccess`, `prepare`, `finalize` та інші можливості.
|
||||
Див. пакети вбудованих плагінів (наприклад, плагін Discord `src/channel.setup.ts`) для
|
||||
повних прикладів.
|
||||
`dmPolicy`, `allowFrom`, `groupAccess`, `prepare`, `finalize` тощо.
|
||||
Повні приклади дивіться у вбудованих пакунках plugin (наприклад, у plugin Discord `src/channel.setup.ts`).
|
||||
|
||||
Для запитів списку дозволених DM, яким потрібен лише стандартний
|
||||
потік `note -> prompt -> parse -> merge -> patch`, віддавайте перевагу спільним допоміжним засобам налаштування
|
||||
Для запитів allowlist у DM, яким потрібен лише стандартний
|
||||
потік `note -> prompt -> parse -> merge -> patch`, надавайте перевагу спільним допоміжним засобам налаштування
|
||||
з `openclaw/plugin-sdk/setup`: `createPromptParsedAllowFromForAccount(...)`,
|
||||
`createTopLevelChannelParsedAllowFromPrompt(...)` і
|
||||
`createNestedChannelParsedAllowFromPrompt(...)`.
|
||||
|
||||
Для блоків статусу налаштування каналу, які відрізняються лише мітками, оцінками та необов’язковими
|
||||
додатковими рядками, віддавайте перевагу `createStandardChannelSetupStatus(...)` з
|
||||
`openclaw/plugin-sdk/setup` замість ручного створення однакового об’єкта `status` у
|
||||
кожному плагіні.
|
||||
Для блоків статусу налаштування channel, які відрізняються лише мітками, оцінками та необов’язковими
|
||||
додатковими рядками, надавайте перевагу `createStandardChannelSetupStatus(...)` з
|
||||
`openclaw/plugin-sdk/setup` замість ручного створення того самого об’єкта `status` у
|
||||
кожному plugin.
|
||||
|
||||
Для необов’язкових поверхонь налаштування, які мають з’являтися лише в певних контекстах, використовуйте
|
||||
`createOptionalChannelSetupSurface` з `openclaw/plugin-sdk/channel-setup`:
|
||||
@ -476,47 +479,47 @@ const setupSurface = createOptionalChannelSetupSurface({
|
||||
`createOptionalChannelSetupWizard(...)`, коли вам потрібна лише одна половина
|
||||
цієї необов’язкової поверхні встановлення.
|
||||
|
||||
Згенеровані необов’язкові adapter/wizard відмовляють у закритому режимі під час реальних записів конфігурації. Вони
|
||||
повторно використовують одне повідомлення про необхідність встановлення у `validateInput`,
|
||||
Згенеровані необов’язкові adapter/wizard завершуються з відмовою для реальних записів конфігурації. Вони
|
||||
повторно використовують одне повідомлення про обов’язковість встановлення в `validateInput`,
|
||||
`applyAccountConfig` і `finalize`, а також додають посилання на документацію, якщо задано `docsPath`.
|
||||
|
||||
Для UI налаштування, що спираються на бінарні файли, віддавайте перевагу спільним делегованим допоміжним засобам замість
|
||||
копіювання однакового glue-коду бінарних файлів/стану в кожен канал:
|
||||
Для UI налаштування, що спираються на двійкові файли, надавайте перевагу спільним делегованим допоміжним засобам замість
|
||||
копіювання однакового glue-коду для binary/status у кожен channel:
|
||||
|
||||
- `createDetectedBinaryStatus(...)` для блоків стану, що відрізняються лише мітками,
|
||||
підказками, оцінками та виявленням бінарного файла
|
||||
- `createCliPathTextInput(...)` для текстових полів на основі шляху
|
||||
- `createDetectedBinaryStatus(...)` для блоків статусу, що відрізняються лише мітками,
|
||||
підказками, оцінками та виявленням двійкового файла
|
||||
- `createCliPathTextInput(...)` для текстових полів, прив’язаних до шляху
|
||||
- `createDelegatedSetupWizardStatusResolvers(...)`,
|
||||
`createDelegatedPrepare(...)`, `createDelegatedFinalize(...)` і
|
||||
`createDelegatedResolveConfigured(...)`, коли `setupEntry` має ліниво переспрямовувати до
|
||||
`createDelegatedResolveConfigured(...)`, коли `setupEntry` має ледачо пересилати до
|
||||
важчого повного майстра
|
||||
- `createDelegatedTextInputShouldPrompt(...)`, коли `setupEntry` потрібно лише
|
||||
делегувати рішення `textInputs[*].shouldPrompt`
|
||||
|
||||
## Публікація та встановлення
|
||||
|
||||
**Зовнішні плагіни:** опублікуйте в [ClawHub](/uk/tools/clawhub) або npm, а потім встановіть:
|
||||
**Зовнішні plugins:** публікуйте в [ClawHub](/uk/tools/clawhub) або npm, а потім встановлюйте:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @myorg/openclaw-my-plugin
|
||||
```
|
||||
|
||||
OpenClaw спочатку намагається використати ClawHub і автоматично переходить до npm у разі невдачі. Ви також можете
|
||||
OpenClaw спочатку пробує ClawHub і автоматично переходить до npm у разі невдачі. Ви також можете
|
||||
явно примусово використати ClawHub:
|
||||
|
||||
```bash
|
||||
openclaw plugins install clawhub:@myorg/openclaw-my-plugin # Лише ClawHub
|
||||
openclaw plugins install clawhub:@myorg/openclaw-my-plugin # лише ClawHub
|
||||
```
|
||||
|
||||
Відповідного перевизначення `npm:` не існує. Використовуйте звичайну специфікацію npm-пакета, коли
|
||||
вам потрібен шлях npm після резервного переходу з ClawHub:
|
||||
Відповідного перевизначення `npm:` не існує. Використовуйте звичайний npm package spec, коли
|
||||
потрібен шлях npm після fallback із ClawHub:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @myorg/openclaw-my-plugin
|
||||
```
|
||||
|
||||
**Плагіни в репозиторії:** розмістіть їх у дереві workspace вбудованих плагінів, і вони
|
||||
автоматично виявлятимуться під час збірки.
|
||||
**Plugins у репозиторії:** розміщуйте їх у дереві workspace вбудованих plugin, і вони будуть автоматично
|
||||
виявлені під час збірки.
|
||||
|
||||
**Користувачі можуть встановлювати:**
|
||||
|
||||
@ -525,13 +528,13 @@ openclaw plugins install <package-name>
|
||||
```
|
||||
|
||||
<Info>
|
||||
Для встановлень із джерела npm `openclaw plugins install` виконує
|
||||
`npm install --ignore-scripts` (без lifecycle-скриптів). Зберігайте дерева залежностей плагіна
|
||||
чистими JS/TS і уникайте пакетів, які потребують збірок через `postinstall`.
|
||||
Для встановлень із npm `openclaw plugins install` виконує
|
||||
`npm install --ignore-scripts` (без lifecycle scripts). Зберігайте дерева залежностей plugin
|
||||
чистими JS/TS і уникайте пакунків, які потребують збірки через `postinstall`.
|
||||
</Info>
|
||||
|
||||
## Пов’язане
|
||||
|
||||
- [SDK Entry Points](/uk/plugins/sdk-entrypoints) -- `definePluginEntry` і `defineChannelPluginEntry`
|
||||
- [Plugin Manifest](/uk/plugins/manifest) -- повний довідник зі схемою маніфесту
|
||||
- [Plugin Manifest](/uk/plugins/manifest) -- повна довідка щодо схеми маніфесту
|
||||
- [Building Plugins](/uk/plugins/building-plugins) -- покроковий посібник для початку роботи
|
||||
|
||||
@ -1,36 +1,35 @@
|
||||
---
|
||||
read_when:
|
||||
- Ви пишете тести для plugin
|
||||
- Вам потрібні утиліти тестування з plugin SDK
|
||||
- Ви хочете зрозуміти контрактні тести для bundled plugin
|
||||
- Ви пишете тести для Plugin.
|
||||
- Вам потрібні утиліти тестування з Plugin SDK.
|
||||
- Ви хочете зрозуміти контрактні тести для вбудованих плагінів.
|
||||
sidebarTitle: Testing
|
||||
summary: Утиліти тестування та шаблони для plugin OpenClaw
|
||||
title: Тестування plugin
|
||||
summary: Утиліти та шаблони тестування для Plugin OpenClaw
|
||||
title: Тестування Plugin
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T18:12:59Z"
|
||||
generated_at: "2026-04-15T16:36:53Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 2e95ed58ed180feadad17bb5138bd09e3b45f1f3ecdff4e2fba4874bb80099fe
|
||||
source_hash: 2f75bd3f3b5ba34b05786e0dd96d493c36db73a1d258998bf589e27e45c0bd09
|
||||
source_path: plugins/sdk-testing.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Тестування plugin
|
||||
# Тестування Plugin
|
||||
|
||||
Довідник з утиліт тестування, шаблонів і контролю lint для plugin
|
||||
OpenClaw.
|
||||
Довідник з утиліт тестування, шаблонів і перевірок lint для plugin OpenClaw.
|
||||
|
||||
<Tip>
|
||||
**Шукаєте приклади тестів?** Посібники містять готові приклади тестів:
|
||||
[Тести plugin каналів](/plugins/sdk-channel-plugins#step-6-test) і
|
||||
[Тести plugin провайдерів](/plugins/sdk-provider-plugins#step-6-test).
|
||||
**Шукаєте приклади тестів?** Практичні посібники містять готові приклади тестів:
|
||||
[Тести channel plugin](/uk/plugins/sdk-channel-plugins#step-6-test) і
|
||||
[Тести provider plugin](/uk/plugins/sdk-provider-plugins#step-6-test).
|
||||
</Tip>
|
||||
|
||||
## Утиліти тестування
|
||||
|
||||
**Імпорт:** `openclaw/plugin-sdk/testing`
|
||||
|
||||
Subpath для тестування експортує вузький набір helper для авторів plugin:
|
||||
Підшлях testing експортує вузький набір допоміжних засобів для авторів plugin:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
@ -42,15 +41,15 @@ import {
|
||||
|
||||
### Доступні експорти
|
||||
|
||||
| Export | Призначення |
|
||||
| -------------------------------------- | ------------------------------------------------------ |
|
||||
| `installCommonResolveTargetErrorCases` | Спільні тестові випадки для обробки помилок визначення цілей |
|
||||
| `shouldAckReaction` | Перевіряє, чи має канал додавати ack-реакцію |
|
||||
| `removeAckReactionAfterReply` | Видаляє ack-реакцію після доставки відповіді |
|
||||
| Export | Purpose |
|
||||
| -------------------------------------- | ------------------------------------------------ |
|
||||
| `installCommonResolveTargetErrorCases` | Спільні тести для обробки помилок визначення цілі |
|
||||
| `shouldAckReaction` | Перевіряє, чи має канал додавати ack-реакцію |
|
||||
| `removeAckReactionAfterReply` | Видаляє ack-реакцію після доставки відповіді |
|
||||
|
||||
### Типи
|
||||
|
||||
Subpath для тестування також повторно експортує типи, корисні у тестових файлах:
|
||||
Підшлях testing також повторно експортує типи, корисні у файлах тестів:
|
||||
|
||||
```typescript
|
||||
import type {
|
||||
@ -63,25 +62,25 @@ import type {
|
||||
} from "openclaw/plugin-sdk/testing";
|
||||
```
|
||||
|
||||
## Тестування визначення цілей
|
||||
## Тестування визначення цілі
|
||||
|
||||
Використовуйте `installCommonResolveTargetErrorCases`, щоб додати стандартні випадки помилок для
|
||||
визначення цілей каналу:
|
||||
визначення цілі каналу:
|
||||
|
||||
```typescript
|
||||
import { describe } from "vitest";
|
||||
import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/testing";
|
||||
|
||||
describe("визначення цілей my-channel", () => {
|
||||
describe("my-channel target resolution", () => {
|
||||
installCommonResolveTargetErrorCases({
|
||||
resolveTarget: ({ to, mode, allowFrom }) => {
|
||||
// Логіка визначення цілей вашого каналу
|
||||
// Your channel's target resolution logic
|
||||
return myChannelResolveTarget({ to, mode, allowFrom });
|
||||
},
|
||||
implicitAllowFrom: ["user1", "user2"],
|
||||
});
|
||||
|
||||
// Додайте тестові випадки, специфічні для каналу
|
||||
// Add channel-specific test cases
|
||||
it("should resolve @username targets", () => {
|
||||
// ...
|
||||
});
|
||||
@ -90,12 +89,12 @@ describe("визначення цілей my-channel", () => {
|
||||
|
||||
## Шаблони тестування
|
||||
|
||||
### Модульне тестування plugin каналу
|
||||
### Модульне тестування channel plugin
|
||||
|
||||
```typescript
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
|
||||
describe("plugin my-channel", () => {
|
||||
describe("my-channel plugin", () => {
|
||||
it("should resolve account from config", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
@ -120,18 +119,18 @@ describe("plugin my-channel", () => {
|
||||
const inspection = myPlugin.setup.inspectAccount(cfg, undefined);
|
||||
expect(inspection.configured).toBe(true);
|
||||
expect(inspection.tokenStatus).toBe("available");
|
||||
// Значення token не розкривається
|
||||
// No token value exposed
|
||||
expect(inspection).not.toHaveProperty("token");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Модульне тестування plugin провайдера
|
||||
### Модульне тестування provider plugin
|
||||
|
||||
```typescript
|
||||
import { describe, it, expect } from "vitest";
|
||||
|
||||
describe("plugin my-provider", () => {
|
||||
describe("my-provider plugin", () => {
|
||||
it("should resolve dynamic models", () => {
|
||||
const model = myProvider.resolveDynamicModel({
|
||||
modelId: "custom-model-v2",
|
||||
@ -154,17 +153,20 @@ describe("plugin my-provider", () => {
|
||||
});
|
||||
```
|
||||
|
||||
### Мокання runtime plugin
|
||||
### Імітація runtime Plugin
|
||||
|
||||
Для коду, який використовує `createPluginRuntimeStore`, мокуйте runtime у тестах:
|
||||
Для коду, який використовує `createPluginRuntimeStore`, імітуйте runtime у тестах:
|
||||
|
||||
```typescript
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";
|
||||
|
||||
const store = createPluginRuntimeStore<PluginRuntime>("test runtime not set");
|
||||
const store = createPluginRuntimeStore<PluginRuntime>({
|
||||
pluginId: "test-plugin",
|
||||
errorMessage: "test runtime not set",
|
||||
});
|
||||
|
||||
// У налаштуванні тестів
|
||||
// In test setup
|
||||
const mockRuntime = {
|
||||
agent: {
|
||||
resolveAgentDir: vi.fn().mockReturnValue("/tmp/agent"),
|
||||
@ -179,26 +181,26 @@ const mockRuntime = {
|
||||
|
||||
store.setRuntime(mockRuntime);
|
||||
|
||||
// Після тестів
|
||||
// After tests
|
||||
store.clearRuntime();
|
||||
```
|
||||
|
||||
### Тестування з per-instance stub
|
||||
### Тестування зі stub для окремих екземплярів
|
||||
|
||||
Надавайте перевагу per-instance stub замість мутації prototype:
|
||||
Надавайте перевагу stub для окремих екземплярів замість мутації prototype:
|
||||
|
||||
```typescript
|
||||
// Рекомендовано: per-instance stub
|
||||
// Preferred: per-instance stub
|
||||
const client = new MyChannelClient();
|
||||
client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" });
|
||||
|
||||
// Уникайте: мутація prototype
|
||||
// Avoid: prototype mutation
|
||||
// MyChannelClient.prototype.sendMessage = vi.fn();
|
||||
```
|
||||
|
||||
## Контрактні тести (plugin у репозиторії)
|
||||
|
||||
Bundled plugin мають контрактні тести, які перевіряють належність реєстрації:
|
||||
Вбудовані plugin мають контрактні тести, які перевіряють відповідальність за реєстрацію:
|
||||
|
||||
```bash
|
||||
pnpm test -- src/plugins/contracts/
|
||||
@ -206,12 +208,12 @@ pnpm test -- src/plugins/contracts/
|
||||
|
||||
Ці тести перевіряють:
|
||||
|
||||
- Які plugin реєструють які провайдери
|
||||
- Які plugin реєструють які мовленнєві провайдери
|
||||
- Які plugin реєструють які providers
|
||||
- Які plugin реєструють які speech providers
|
||||
- Коректність форми реєстрації
|
||||
- Відповідність runtime-контракту
|
||||
|
||||
### Запуск scoped-тестів
|
||||
### Запуск вибіркових тестів
|
||||
|
||||
Для конкретного plugin:
|
||||
|
||||
@ -227,32 +229,32 @@ pnpm test -- src/plugins/contracts/auth.contract.test.ts
|
||||
pnpm test -- src/plugins/contracts/runtime.contract.test.ts
|
||||
```
|
||||
|
||||
## Контроль lint (plugin у репозиторії)
|
||||
## Перевірки lint (plugin у репозиторії)
|
||||
|
||||
`pnpm check` застосовує три правила для plugin у репозиторії:
|
||||
`pnpm check` примусово застосовує три правила для plugin у репозиторії:
|
||||
|
||||
1. **Без монолітних імпортів із root** -- root barrel `openclaw/plugin-sdk` заборонено
|
||||
1. **Без монолітних імпортів із кореня** -- кореневий barrel `openclaw/plugin-sdk` заборонено
|
||||
2. **Без прямих імпортів `src/`** -- plugin не можуть напряму імпортувати `../../src/`
|
||||
3. **Без self-import** -- plugin не можуть імпортувати власний subpath `plugin-sdk/<name>`
|
||||
3. **Без самоімпортів** -- plugin не можуть імпортувати власний підшлях `plugin-sdk/<name>`
|
||||
|
||||
Зовнішні plugin не підпадають під ці правила lint, але дотримуватися тих самих
|
||||
шаблонів рекомендується.
|
||||
|
||||
## Конфігурація тестів
|
||||
## Конфігурація тестування
|
||||
|
||||
OpenClaw використовує Vitest із порогами покриття V8. Для тестів plugin:
|
||||
|
||||
```bash
|
||||
# Запустити всі тести
|
||||
# Run all tests
|
||||
pnpm test
|
||||
|
||||
# Запустити тести конкретного plugin
|
||||
# Run specific plugin tests
|
||||
pnpm test -- <bundled-plugin-root>/my-channel/src/channel.test.ts
|
||||
|
||||
# Запустити з фільтром за конкретною назвою тесту
|
||||
# Run with a specific test name filter
|
||||
pnpm test -- <bundled-plugin-root>/my-channel/ -t "resolves account"
|
||||
|
||||
# Запустити з покриттям
|
||||
# Run with coverage
|
||||
pnpm test:coverage
|
||||
```
|
||||
|
||||
@ -264,7 +266,7 @@ OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test
|
||||
|
||||
## Пов’язане
|
||||
|
||||
- [SDK Overview](/plugins/sdk-overview) -- правила import
|
||||
- [SDK Channel Plugins](/plugins/sdk-channel-plugins) -- інтерфейс plugin каналу
|
||||
- [SDK Provider Plugins](/plugins/sdk-provider-plugins) -- hooks plugin провайдера
|
||||
- [Building Plugins](/plugins/building-plugins) -- посібник для початку роботи
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) -- правила імпорту
|
||||
- [SDK Channel Plugins](/uk/plugins/sdk-channel-plugins) -- інтерфейс channel plugin
|
||||
- [SDK Provider Plugins](/uk/plugins/sdk-provider-plugins) -- хуки provider plugin
|
||||
- [Створення plugin](/uk/plugins/building-plugins) -- посібник для початку роботи
|
||||
|
||||
Loading…
Reference in New Issue
Block a user