chore(i18n): refresh uk translations
This commit is contained in:
parent
9afa141488
commit
82d6a9c64d
File diff suppressed because it is too large
Load Diff
@ -1,104 +1,113 @@
|
||||
---
|
||||
read_when:
|
||||
- Ви створюєте новий плагін каналу обміну повідомленнями
|
||||
- Ви створюєте новий Plugin каналу обміну повідомленнями
|
||||
- Ви хочете підключити OpenClaw до платформи обміну повідомленнями
|
||||
- Вам потрібно зрозуміти поверхню адаптера ChannelPlugin
|
||||
sidebarTitle: Channel Plugins
|
||||
summary: Покроковий посібник зі створення плагіна каналу обміну повідомленнями для OpenClaw
|
||||
title: Створення плагінів каналів
|
||||
summary: Покроковий посібник зі створення Plugin каналу обміну повідомленнями для OpenClaw
|
||||
title: Створення Plugin каналів
|
||||
x-i18n:
|
||||
generated_at: "2026-04-10T20:41:27Z"
|
||||
generated_at: "2026-04-14T16:24:14Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 8a026e924f9ae8a3ddd46287674443bcfccb0247be504261522b078e1f440aef
|
||||
source_hash: a7f4c746fe3163a8880e14c433f4db4a1475535d91716a53fb879551d8d62f65
|
||||
source_path: plugins/sdk-channel-plugins.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Створення плагінів каналів
|
||||
# Створення Plugin каналів
|
||||
|
||||
Цей посібник покроково пояснює створення плагіна каналу, який підключає OpenClaw до
|
||||
платформи обміну повідомленнями. Наприкінці у вас буде робочий канал із захистом DM,
|
||||
сполученням, потоками відповідей та вихідними повідомленнями.
|
||||
Цей посібник описує створення Plugin каналу, який підключає OpenClaw до
|
||||
платформи обміну повідомленнями. Наприкінці у вас буде робочий канал із
|
||||
безпекою DM, сполученням, ланцюжками відповідей і вихідними повідомленнями.
|
||||
|
||||
<Info>
|
||||
Якщо ви раніше не створювали жодного плагіна OpenClaw, спочатку прочитайте
|
||||
[Початок роботи](/uk/plugins/building-plugins), щоб ознайомитися з базовою
|
||||
структурою пакета та налаштуванням маніфесту.
|
||||
Якщо ви раніше не створювали жодного Plugin для OpenClaw, спочатку прочитайте
|
||||
[Getting Started](/uk/plugins/building-plugins) про базову структуру пакета та
|
||||
налаштування маніфесту.
|
||||
</Info>
|
||||
|
||||
## Як працюють плагіни каналів
|
||||
## Як працюють Plugin каналів
|
||||
|
||||
Плагінам каналів не потрібні власні інструменти send/edit/react. OpenClaw зберігає
|
||||
один спільний інструмент `message` у core. Ваш плагін відповідає за:
|
||||
Plugin каналів не потребують власних інструментів send/edit/react. OpenClaw
|
||||
зберігає один спільний інструмент `message` у ядрі. Ваш Plugin відповідає за:
|
||||
|
||||
- **Конфігурацію** — визначення облікового запису та майстер налаштування
|
||||
- **Безпеку** — політику DM і allowlist-списки
|
||||
- **Сполучення** — потік підтвердження DM
|
||||
- **Граматику сесій** — як ідентифікатори розмов, специфічні для провайдера, відображаються на базові чати, ідентифікатори потоків і резервні батьківські значення
|
||||
- **Вихідні повідомлення** — надсилання тексту, медіа та опитувань на платформу
|
||||
- **Потоковість** — як організовуються потоки відповідей
|
||||
- **Конфігурацію** — визначення облікових записів і майстер налаштування
|
||||
- **Безпеку** — політику DM і списки дозволених
|
||||
- **Сполучення** — процес схвалення DM
|
||||
- **Граматику сесії** — як ідентифікатори розмов, специфічні для провайдера, відображаються на базові чати, ідентифікатори гілок і резервні батьківські варіанти
|
||||
- **Вихідні повідомлення** — надсилання тексту, медіа й опитувань на платформу
|
||||
- **Ланцюжки** — як організовуються відповіді в гілках
|
||||
|
||||
Core відповідає за спільний інструмент повідомлень, підключення prompt, зовнішню форму ключа сесії,
|
||||
загальне ведення обліку `:thread:` та диспетчеризацію.
|
||||
Ядро відповідає за спільний інструмент повідомлень, підключення промптів, зовнішню форму ключа сесії,
|
||||
загальний облік `:thread:` і диспетчеризацію.
|
||||
|
||||
Якщо ваша платформа зберігає додаткову область видимості всередині ідентифікаторів розмов,
|
||||
залишайте цей парсинг у плагіні за допомогою `messaging.resolveSessionConversation(...)`. Це канонічний хук
|
||||
для зіставлення `rawId` з базовим ідентифікатором розмови, необов’язковим ідентифікатором потоку,
|
||||
явним `baseConversationId` та будь-якими `parentConversationCandidates`.
|
||||
Коли ви повертаєте `parentConversationCandidates`, зберігайте їхній порядок від
|
||||
найвужчого батьківського елемента до найширшої/базової розмови.
|
||||
Якщо ваш канал додає параметри інструмента повідомлень, які містять джерела медіа, вкажіть ці
|
||||
назви параметрів через `describeMessageTool(...).mediaSourceParams`. Ядро використовує
|
||||
цей явний список для нормалізації шляхів sandbox і політики доступу до вихідних медіа,
|
||||
тому Plugin не потребують особливих винятків у спільному ядрі для специфічних для провайдера
|
||||
параметрів аватарів, вкладень або зображень обкладинки.
|
||||
Переважно повертати мапу, прив’язану до дій, наприклад
|
||||
`{ "set-profile": ["avatarUrl", "avatarPath"] }`, щоб не пов’язані дії не успадковували
|
||||
медіааргументи іншої дії. Плоский масив також працює для параметрів, які
|
||||
навмисно спільні для кожної доступної дії.
|
||||
|
||||
Вбудовані плагіни, яким потрібен той самий парсинг до запуску реєстру каналів,
|
||||
також можуть експортувати файл верхнього рівня `session-key-api.ts` з відповідним
|
||||
експортом `resolveSessionConversation(...)`. Core використовує цю безпечну для bootstrap поверхню
|
||||
лише тоді, коли реєстр runtime-плагінів ще недоступний.
|
||||
Якщо ваша платформа зберігає додаткову область видимості в ідентифікаторах розмов, зберігайте цей розбір
|
||||
у Plugin за допомогою `messaging.resolveSessionConversation(...)`. Це канонічний хук
|
||||
для відображення `rawId` на базовий ідентифікатор розмови, необов’язковий ідентифікатор гілки,
|
||||
явний `baseConversationId` і будь-які `parentConversationCandidates`.
|
||||
Коли ви повертаєте `parentConversationCandidates`, зберігайте їх упорядкованими від
|
||||
найвужчого батьківського варіанта до найширшої/базової розмови.
|
||||
|
||||
`messaging.resolveParentConversationCandidates(...)` залишається доступним як застарілий
|
||||
резервний механізм сумісності, коли плагіну потрібні лише резервні батьківські значення
|
||||
поверх загального/raw id. Якщо існують обидва хуки, core спочатку використовує
|
||||
`resolveSessionConversation(...).parentConversationCandidates` і лише потім
|
||||
Вбудовані Plugin, яким потрібен той самий розбір до запуску реєстру каналів,
|
||||
також можуть надавати файл верхнього рівня `session-key-api.ts` із відповідним
|
||||
експортом `resolveSessionConversation(...)`. Ядро використовує цю безпечну для bootstrap поверхню
|
||||
лише тоді, коли реєстр Plugin середовища виконання ще недоступний.
|
||||
|
||||
`messaging.resolveParentConversationCandidates(...)` залишається доступним як застарілий резервний варіант сумісності, коли Plugin потрібні лише
|
||||
резервні батьківські варіанти поверх загального/raw id. Якщо існують обидва хуки, ядро використовує
|
||||
спочатку `resolveSessionConversation(...).parentConversationCandidates` і лише потім
|
||||
повертається до `resolveParentConversationCandidates(...)`, якщо канонічний хук
|
||||
їх не вказує.
|
||||
|
||||
## Підтвердження та можливості каналу
|
||||
## Схвалення та можливості каналів
|
||||
|
||||
Більшості плагінів каналів не потрібен код, специфічний для підтверджень.
|
||||
Більшості Plugin каналів не потрібен код, специфічний для схвалень.
|
||||
|
||||
- Core відповідає за `/approve` у тому самому чаті, спільні payload-кнопок підтвердження та загальну резервну доставку.
|
||||
- Віддавайте перевагу одному об’єкту `approvalCapability` у плагіні каналу, якщо каналу потрібна поведінка, специфічна для підтверджень.
|
||||
- `ChannelPlugin.approvals` видалено. Розміщуйте факти доставки/нативного режиму/рендерингу/автентифікації підтверджень у `approvalCapability`.
|
||||
- `plugin.auth` призначений лише для login/logout; core більше не читає хуки автентифікації підтверджень із цього об’єкта.
|
||||
- `approvalCapability.authorizeActorAction` і `approvalCapability.getActionAvailabilityState` — це канонічна поверхня для auth підтверджень.
|
||||
- Використовуйте `approvalCapability.getActionAvailabilityState` для доступності auth підтверджень у тому самому чаті.
|
||||
- Якщо ваш канал надає нативні exec-підтвердження, використовуйте `approvalCapability.getExecInitiatingSurfaceState` для стану ініціювальної поверхні/нативного клієнта, коли він відрізняється від auth підтвердження в тому самому чаті. Core використовує цей exec-специфічний хук, щоб розрізняти `enabled` і `disabled`, визначати, чи підтримує ініціювальний канал нативні exec-підтвердження, і включати канал до інструкцій резервного сценарію нативного клієнта. `createApproverRestrictedNativeApprovalCapability(...)` заповнює це для типового випадку.
|
||||
- Використовуйте `outbound.shouldSuppressLocalPayloadPrompt` або `outbound.beforeDeliverPayload` для поведінки життєвого циклу payload, специфічної для каналу, наприклад приховування дубльованих локальних prompt-підтверджень або надсилання індикаторів набору тексту перед доставкою.
|
||||
- Використовуйте `approvalCapability.delivery` лише для нативної маршрутизації підтверджень або придушення резервної доставки.
|
||||
- Використовуйте `approvalCapability.nativeRuntime` для фактів нативних підтверджень, що належать каналу. Зберігайте його лінивим на гарячих точках входу каналу за допомогою `createLazyChannelApprovalNativeRuntimeAdapter(...)`, який може імпортувати ваш runtime-модуль на вимогу, водночас дозволяючи core зібрати життєвий цикл підтвердження.
|
||||
- Використовуйте `approvalCapability.render` лише тоді, коли каналу справді потрібні власні payload підтвердження замість спільного рендерера.
|
||||
- Використовуйте `approvalCapability.describeExecApprovalSetup`, коли канал хоче, щоб відповідь на вимкнений шлях пояснювала точні параметри конфігурації, потрібні для ввімкнення нативних exec-підтверджень. Хук отримує `{ channel, channelLabel, accountId }`; канали з іменованими обліковими записами мають рендерити шляхи з областю облікового запису, такі як `channels.<channel>.accounts.<id>.execApprovals.*`, замість дефолтів верхнього рівня.
|
||||
- Якщо канал може вивести стабільні DM-ідентичності на кшталт власника з наявної конфігурації, використовуйте `createResolvedApproverActionAuthAdapter` з `openclaw/plugin-sdk/approval-runtime`, щоб обмежити `/approve` у тому самому чаті без додавання логіки підтверджень у core.
|
||||
- Якщо каналу потрібна нативна доставка підтверджень, зосередьте код каналу на нормалізації цілі та фактах транспорту/представлення. Використовуйте `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` і `createApproverRestrictedNativeApprovalCapability` з `openclaw/plugin-sdk/approval-runtime`. Розміщуйте факти, специфічні для каналу, за `approvalCapability.nativeRuntime`, бажано через `createChannelApprovalNativeRuntimeAdapter(...)` або `createLazyChannelApprovalNativeRuntimeAdapter(...)`, щоб core міг зібрати обробник і відповідати за фільтрацію запитів, маршрутизацію, dedupe, строки дії, підписку gateway та сповіщення про маршрутизацію в інше місце. `nativeRuntime` поділено на кілька менших поверхонь:
|
||||
- `availability` — чи налаштований обліковий запис і чи потрібно обробляти запит
|
||||
- `presentation` — відображення спільної view model підтверджень у нативні payload у станах pending/resolved/expired або фінальні дії
|
||||
- `transport` — підготовка цілей, а також надсилання/оновлення/видалення нативних повідомлень підтвердження
|
||||
- Ядро відповідає за `/approve` у тому самому чаті, спільні payload кнопок схвалення та загальну резервну доставку.
|
||||
- Віддавайте перевагу одному об’єкту `approvalCapability` у Plugin каналу, коли каналу потрібна поведінка, специфічна для схвалень.
|
||||
- `ChannelPlugin.approvals` видалено. Розміщуйте факти про доставку/нативний режим/рендеринг/автентифікацію схвалень у `approvalCapability`.
|
||||
- `plugin.auth` призначений лише для login/logout; ядро більше не читає хуки автентифікації схвалень із цього об’єкта.
|
||||
- `approvalCapability.authorizeActorAction` і `approvalCapability.getActionAvailabilityState` — це канонічна поверхня автентифікації схвалень.
|
||||
- Використовуйте `approvalCapability.getActionAvailabilityState` для доступності автентифікації схвалень у тому самому чаті.
|
||||
- Якщо ваш канал надає нативні exec-схвалення, використовуйте `approvalCapability.getExecInitiatingSurfaceState` для стану ініціювальної поверхні/нативного клієнта, коли він відрізняється від автентифікації схвалень у тому самому чаті. Ядро використовує цей специфічний для exec хук, щоб розрізняти `enabled` і `disabled`, визначати, чи підтримує ініціювальний канал нативні exec-схвалення, і включати канал у підказки резервного сценарію для нативного клієнта. `createApproverRestrictedNativeApprovalCapability(...)` заповнює це для поширеного випадку.
|
||||
- Використовуйте `outbound.shouldSuppressLocalPayloadPrompt` або `outbound.beforeDeliverPayload` для специфічної для каналу поведінки життєвого циклу payload, наприклад приховування дублікатів локальних підказок схвалення або надсилання індикаторів набору тексту перед доставкою.
|
||||
- Використовуйте `approvalCapability.delivery` лише для нативної маршрутизації схвалень або вимкнення резервної доставки.
|
||||
- Використовуйте `approvalCapability.nativeRuntime` для фактів нативних схвалень, що належать каналу. Зберігайте його ледачим на гарячих точках входу каналу за допомогою `createLazyChannelApprovalNativeRuntimeAdapter(...)`, який може імпортувати ваш модуль середовища виконання на вимогу, водночас дозволяючи ядру збирати життєвий цикл схвалення.
|
||||
- Використовуйте `approvalCapability.render` лише тоді, коли каналу справді потрібні власні payload схвалення замість спільного рендерера.
|
||||
- Використовуйте `approvalCapability.describeExecApprovalSetup`, коли канал хоче, щоб відповідь на вимкнений шлях пояснювала точні параметри конфігурації, потрібні для ввімкнення нативних exec-схвалень. Хук отримує `{ channel, channelLabel, accountId }`; канали з іменованими обліковими записами мають виводити шляхи з областю видимості облікового запису, наприклад `channels.<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` поділено на кілька менших поверхонь:
|
||||
- `availability` — чи налаштовано обліковий запис і чи слід обробляти запит
|
||||
- `presentation` — відображення спільної моделі перегляду схвалень у нативні payload pending/resolved/expired або фінальні дії
|
||||
- `transport` — підготовка цілей і надсилання/оновлення/видалення нативних повідомлень схвалення
|
||||
- `interactions` — необов’язкові хуки bind/unbind/clear-action для нативних кнопок або реакцій
|
||||
- `observe` — необов’язкові хуки діагностики доставки
|
||||
- Якщо каналу потрібні об’єкти, що належать runtime, наприклад клієнт, токен, застосунок Bolt або отримувач webhook, реєструйте їх через `openclaw/plugin-sdk/channel-runtime-context`. Загальний реєстр runtime-контексту дає core змогу bootstrap-ити обробники на основі можливостей зі стану запуску каналу без додавання обгорток, специфічних для підтверджень.
|
||||
- Звертайтеся до нижчорівневих `createChannelApprovalHandler` або `createChannelNativeApprovalRuntime` лише тоді, коли поверхня, заснована на можливостях, ще недостатньо виразна.
|
||||
- Канали з нативними підтвердженнями мають передавати через ці helper-и і `accountId`, і `approvalKind`. `accountId` зберігає політику підтверджень для кількох облікових записів у межах правильного облікового запису бота, а `approvalKind` зберігає поведінку exec чи плагіна доступною для каналу без жорстко закодованих гілок у core.
|
||||
- Тепер core також відповідає за сповіщення про повторну маршрутизацію підтверджень. Плагіни каналів не повинні надсилати власні додаткові повідомлення на кшталт «підтвердження перейшло в DM / інший канал» із `createChannelNativeApprovalRuntime`; натомість надавайте точну маршрутизацію origin + approver-DM через спільні helper-и можливостей підтверджень і дозвольте core агрегувати фактичні доставки перед публікацією будь-якого сповіщення назад в ініціювальний чат.
|
||||
- Зберігайте тип ідентифікатора доставленого підтвердження від початку до кінця. Нативні клієнти не повинні
|
||||
вгадувати або переписувати маршрутизацію exec чи plugin підтвердження на основі локального стану каналу.
|
||||
- Різні типи підтверджень можуть навмисно відкривати різні нативні поверхні.
|
||||
Поточні приклади вбудованих плагінів:
|
||||
- Slack зберігає нативну маршрутизацію підтверджень доступною як для exec-, так і для plugin-id.
|
||||
- Matrix зберігає ту саму нативну DM/канальну маршрутизацію та UX реакцій для exec
|
||||
і plugin-підтверджень, водночас дозволяючи auth відрізнятися за типом підтвердження.
|
||||
- `createApproverRestrictedNativeApprovalAdapter` усе ще існує як обгортка сумісності, але новий код має віддавати перевагу builder-у можливостей і експонувати `approvalCapability` у плагіні.
|
||||
- Якщо каналу потрібні об’єкти, що належать середовищу виконання, як-от клієнт, токен, Bolt app або отримувач Webhook, реєструйте їх через `openclaw/plugin-sdk/channel-runtime-context`. Загальний реєстр runtime-context дозволяє ядру ініціалізувати обробники, керовані можливостями, зі стану запуску каналу без додавання специфічного для схвалень обгорткового коду.
|
||||
- Використовуйте нижчорівневі `createChannelApprovalHandler` або `createChannelNativeApprovalRuntime` лише тоді, коли поверхня, керована можливостями, ще недостатньо виразна.
|
||||
- Канали нативних схвалень мають маршрутизувати і `accountId`, і `approvalKind` через ці допоміжні засоби. `accountId` зберігає політику схвалень для кількох облікових записів у межах правильного облікового запису бота, а `approvalKind` зберігає поведінку exec і Plugin-схвалень доступною для каналу без жорстко закодованих розгалужень у ядрі.
|
||||
- Ядро тепер також відповідає за повідомлення про переспрямування схвалень. Plugin каналів не повинні надсилати власні додаткові повідомлення на кшталт «схвалення перейшло в DM / інший канал» із `createChannelNativeApprovalRuntime`; натомість надавайте точну маршрутизацію origin + approver-DM через спільні допоміжні засоби можливостей схвалень і дозволяйте ядру агрегувати фактичні доставки перед публікацією будь-якого повідомлення назад в ініціювальний чат.
|
||||
- Зберігайте тип ідентифікатора доставленого схвалення наскрізно. Нативні клієнти не повинні
|
||||
вгадувати або переписувати маршрутизацію exec чи Plugin-схвалень на основі локального для каналу стану.
|
||||
- Різні типи схвалень можуть навмисно надавати різні нативні поверхні.
|
||||
Поточні вбудовані приклади:
|
||||
- Slack зберігає доступною маршрутизацію нативних схвалень як для exec-, так і для Plugin-ідентифікаторів.
|
||||
- Matrix зберігає ту саму нативну маршрутизацію DM/каналу та UX реакцій для exec-
|
||||
і Plugin-схвалень, водночас дозволяючи автентифікації відрізнятися за типом схвалення.
|
||||
- `createApproverRestrictedNativeApprovalAdapter` усе ще існує як обгортка сумісності, але новий код має віддавати перевагу конструктору можливостей і надавати `approvalCapability` у Plugin.
|
||||
|
||||
Для гарячих точок входу каналу віддавайте перевагу вужчим runtime-підшляхам, коли вам потрібна лише
|
||||
одна частина цієї сім’ї:
|
||||
Для гарячих точок входу каналів віддавайте перевагу вужчим runtime-підшляхам, коли вам потрібна лише
|
||||
одна частина цієї групи:
|
||||
|
||||
- `openclaw/plugin-sdk/approval-auth-runtime`
|
||||
- `openclaw/plugin-sdk/approval-client-runtime`
|
||||
@ -115,89 +124,90 @@ Core відповідає за спільний інструмент повід
|
||||
`openclaw/plugin-sdk/reply-runtime`,
|
||||
`openclaw/plugin-sdk/reply-dispatch-runtime`,
|
||||
`openclaw/plugin-sdk/reply-reference` і
|
||||
`openclaw/plugin-sdk/reply-chunking`, коли вам не потрібна ширша
|
||||
`openclaw/plugin-sdk/reply-chunking`, якщо вам не потрібна ширша
|
||||
узагальнювальна поверхня.
|
||||
|
||||
Зокрема для setup:
|
||||
Зокрема для налаштування:
|
||||
|
||||
- `openclaw/plugin-sdk/setup-runtime` охоплює runtime-безпечні helper-и setup:
|
||||
безпечні для імпорту patched-адаптери setup (`createPatchedAccountSetupAdapter`,
|
||||
- `openclaw/plugin-sdk/setup-runtime` охоплює безпечні для runtime допоміжні засоби налаштування:
|
||||
безпечні для імпорту адаптери patch налаштування (`createPatchedAccountSetupAdapter`,
|
||||
`createEnvPatchedAccountSetupAdapter`,
|
||||
`createSetupInputPresenceValidator`), вивід lookup-note,
|
||||
`createSetupInputPresenceValidator`), виведення приміток пошуку,
|
||||
`promptResolvedAllowFrom`, `splitSetupEntries` і делеговані
|
||||
builder-и setup-proxy
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузька env-aware поверхня адаптера
|
||||
для `createEnvPatchedAccountSetupAdapter`
|
||||
- `openclaw/plugin-sdk/channel-setup` охоплює builder-и setup для необов’язкового встановлення
|
||||
плюс кілька setup-безпечних примітивів:
|
||||
конструктори setup-proxy
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` — це вузька env-aware поверхня
|
||||
адаптера для `createEnvPatchedAccountSetupAdapter`
|
||||
- `openclaw/plugin-sdk/channel-setup` охоплює конструктори налаштування з необов’язковим встановленням
|
||||
плюс кілька безпечних для setup примітивів:
|
||||
`createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`,
|
||||
|
||||
Якщо ваш канал підтримує setup або auth на основі env, і загальні потоки startup/config
|
||||
мають знати ці env-імена до завантаження runtime, оголосіть їх у маніфесті плагіна через
|
||||
`channelEnvVars`. Зберігайте runtime `envVars` каналу або локальні константи лише для копірайту, видимого операторам.
|
||||
Якщо ваш канал підтримує налаштування або автентифікацію, керовані env, і загальні процеси запуску/конфігурації
|
||||
мають знати ці назви env до завантаження runtime, оголосіть їх у
|
||||
маніфесті Plugin за допомогою `channelEnvVars`. Зберігайте `envVars` runtime каналу або локальні
|
||||
константи лише для копії, орієнтованої на операторів.
|
||||
`createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`,
|
||||
`createTopLevelChannelDmPolicy`, `setSetupChannelEnabled` і
|
||||
`splitSetupEntries`
|
||||
|
||||
- використовуйте ширшу поверхню `openclaw/plugin-sdk/setup` лише тоді, коли вам також потрібні
|
||||
важчі спільні helper-и setup/config, такі як
|
||||
- використовуйте ширшу поверхню `openclaw/plugin-sdk/setup`, лише якщо вам також потрібні
|
||||
важчі спільні допоміжні засоби setup/config, такі як
|
||||
`moveSingleAccountChannelSectionToDefaultAccount(...)`
|
||||
|
||||
Якщо ваш канал лише хоче показувати в поверхнях setup повідомлення «спочатку встановіть цей плагін»,
|
||||
Якщо ваш канал лише хоче показувати «спочатку встановіть цей Plugin» на поверхнях налаштування,
|
||||
віддавайте перевагу `createOptionalChannelSetupSurface(...)`. Згенеровані
|
||||
adapter/wizard закриваються з відмовою для записів конфігурації та фіналізації, і повторно використовують
|
||||
те саме повідомлення про необхідність встановлення для перевірки, finalize і тексту з посиланням на документацію.
|
||||
adapter/wizard за замовчуванням забороняють запис у конфігурацію та завершення, і вони повторно використовують
|
||||
те саме повідомлення про необхідність встановлення для перевірки, завершення та тексту
|
||||
з посиланням на документацію.
|
||||
|
||||
Для інших гарячих шляхів каналу віддавайте перевагу вузьким helper-ам замість ширших застарілих
|
||||
Для інших гарячих шляхів каналів віддавайте перевагу вузьким helper замість ширших застарілих
|
||||
поверхонь:
|
||||
|
||||
- `openclaw/plugin-sdk/account-core`,
|
||||
`openclaw/plugin-sdk/account-id`,
|
||||
`openclaw/plugin-sdk/account-resolution` і
|
||||
`openclaw/plugin-sdk/account-helpers` для конфігурації кількох облікових записів та
|
||||
резервного переходу до облікового запису за замовчуванням
|
||||
`openclaw/plugin-sdk/account-helpers` для конфігурації кількох облікових записів і
|
||||
резервного використання облікового запису за замовчуванням
|
||||
- `openclaw/plugin-sdk/inbound-envelope` і
|
||||
`openclaw/plugin-sdk/inbound-reply-dispatch` для route/envelope вхідних повідомлень та
|
||||
`openclaw/plugin-sdk/inbound-reply-dispatch` для маршруту/конверта вхідних даних і
|
||||
зв’язування record-and-dispatch
|
||||
- `openclaw/plugin-sdk/messaging-targets` для парсингу/зіставлення цілей
|
||||
- `openclaw/plugin-sdk/messaging-targets` для розбору/зіставлення цілей
|
||||
- `openclaw/plugin-sdk/outbound-media` і
|
||||
`openclaw/plugin-sdk/outbound-runtime` для завантаження медіа плюс
|
||||
делегатів ідентичності/надсилання вихідних повідомлень
|
||||
- `openclaw/plugin-sdk/thread-bindings-runtime` для життєвого циклу прив’язок потоків
|
||||
`openclaw/plugin-sdk/outbound-runtime` для завантаження медіа плюс делегатів
|
||||
ідентичності/надсилання вихідних повідомлень
|
||||
- `openclaw/plugin-sdk/thread-bindings-runtime` для життєвого циклу прив’язки гілок
|
||||
і реєстрації адаптерів
|
||||
- `openclaw/plugin-sdk/agent-media-payload` лише тоді, коли все ще потрібне
|
||||
застаріле компонування полів payload агента/медіа
|
||||
- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram,
|
||||
перевірки дублікатів/конфліктів і стабільного резервного контракту конфігурації команд
|
||||
- `openclaw/plugin-sdk/agent-media-payload` лише коли все ще потрібна застаріла
|
||||
схема полів payload agent/media
|
||||
- `openclaw/plugin-sdk/telegram-command-config` для нормалізації користувацьких команд Telegram, перевірки дублікатів/конфліктів і стабільного щодо резервного сценарію контракту конфігурації команд
|
||||
|
||||
Канали лише з auth зазвичай можуть зупинитися на шляху за замовчуванням: core обробляє підтвердження, а плагін лише надає можливості outbound/auth. Канали з нативними підтвердженнями, такі як Matrix, Slack, Telegram і власні транспортні чати, мають використовувати спільні нативні helper-и замість створення власного життєвого циклу підтверджень.
|
||||
Канали лише з автентифікацією зазвичай можуть зупинитися на стандартному шляху: ядро обробляє схвалення, а Plugin лише надає можливості outbound/auth. Канали нативних схвалень, як-от Matrix, Slack, Telegram і спеціальні транспортні засоби чату, мають використовувати спільні нативні helper, а не реалізовувати власний життєвий цикл схвалень.
|
||||
|
||||
## Політика вхідних згадок
|
||||
|
||||
Зберігайте обробку вхідних згадок розділеною на два рівні:
|
||||
Зберігайте обробку вхідних згадок розділеною на два шари:
|
||||
|
||||
- збирання доказів, що належить плагіну
|
||||
- спільне оцінювання політики
|
||||
- збір доказів, що належить Plugin
|
||||
- оцінка спільної політики
|
||||
|
||||
Використовуйте `openclaw/plugin-sdk/channel-inbound` для спільного рівня.
|
||||
Для спільного шару використовуйте `openclaw/plugin-sdk/channel-inbound`.
|
||||
|
||||
Добре підходить для локальної логіки плагіна:
|
||||
Добре підходить для локальної логіки Plugin:
|
||||
|
||||
- виявлення reply-to-bot
|
||||
- виявлення quoted-bot
|
||||
- перевірки участі в потоці
|
||||
- виявлення відповіді боту
|
||||
- виявлення цитування бота
|
||||
- перевірки участі в гілці
|
||||
- виключення службових/системних повідомлень
|
||||
- платформено-нативні кеші, потрібні для підтвердження участі бота
|
||||
- платформонативні кеші, потрібні для підтвердження участі бота
|
||||
|
||||
Добре підходить для спільного helper-а:
|
||||
Добре підходить для спільного helper:
|
||||
|
||||
- `requireMention`
|
||||
- явний результат згадки
|
||||
- allowlist неявних згадок
|
||||
- список дозволених неявних згадок
|
||||
- обхід для команд
|
||||
- фінальне рішення про пропуск
|
||||
|
||||
Рекомендований потік:
|
||||
Рекомендований процес:
|
||||
|
||||
1. Обчисліть локальні факти згадки.
|
||||
2. Передайте ці факти в `resolveInboundMentionDecision({ facts, policy })`.
|
||||
@ -240,8 +250,8 @@ const decision = resolveInboundMentionDecision({
|
||||
if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
`api.runtime.channel.mentions` надає ті самі спільні helper-и згадок для
|
||||
вбудованих плагінів каналів, які вже залежать від ін’єкції runtime:
|
||||
`api.runtime.channel.mentions` надає ті самі спільні helper для згадок для
|
||||
вбудованих Plugin каналів, які вже залежать від інʼєкції runtime:
|
||||
|
||||
- `buildMentionRegexes`
|
||||
- `matchesMentionPatterns`
|
||||
@ -249,8 +259,8 @@ if (decision.shouldSkip) return;
|
||||
- `implicitMentionKindWhen`
|
||||
- `resolveInboundMentionDecision`
|
||||
|
||||
Старіші helper-и `resolveMentionGating*` залишаються в
|
||||
`openclaw/plugin-sdk/channel-inbound` лише як експорт сумісності. Новий код
|
||||
Старіші helper `resolveMentionGating*` залишаються в
|
||||
`openclaw/plugin-sdk/channel-inbound` лише як сумісні експорти. Новий код
|
||||
має використовувати `resolveInboundMentionDecision({ facts, policy })`.
|
||||
|
||||
## Покроковий розбір
|
||||
@ -258,9 +268,9 @@ if (decision.shouldSkip) return;
|
||||
<Steps>
|
||||
<a id="step-1-package-and-manifest"></a>
|
||||
<Step title="Пакет і маніфест">
|
||||
Створіть стандартні файли плагіна. Поле `channel` у `package.json` —
|
||||
це те, що робить цей плагін плагіном каналу. Повну поверхню метаданих пакета
|
||||
див. у [Налаштування плагіна та конфігурація](/uk/plugins/sdk-setup#openclaw-channel):
|
||||
Створіть стандартні файли Plugin. Поле `channel` у `package.json` — це
|
||||
те, що робить його Plugin каналу. Повну поверхню метаданих пакета
|
||||
див. у [Налаштування Plugin і конфігурація](/uk/plugins/sdk-setup#openclaw-channel):
|
||||
|
||||
<CodeGroup>
|
||||
```json package.json
|
||||
@ -274,7 +284,7 @@ if (decision.shouldSkip) return;
|
||||
"channel": {
|
||||
"id": "acme-chat",
|
||||
"label": "Acme Chat",
|
||||
"blurb": "Підключіть OpenClaw до Acme Chat."
|
||||
"blurb": "Connect OpenClaw to Acme Chat."
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,7 +296,7 @@ if (decision.shouldSkip) return;
|
||||
"kind": "channel",
|
||||
"channels": ["acme-chat"],
|
||||
"name": "Acme Chat",
|
||||
"description": "Плагін каналу Acme Chat",
|
||||
"description": "Acme Chat channel plugin",
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@ -309,8 +319,8 @@ if (decision.shouldSkip) return;
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Побудуйте об’єкт плагіна каналу">
|
||||
Інтерфейс `ChannelPlugin` має багато необов’язкових поверхонь адаптера. Почніть із
|
||||
<Step title="Створіть обʼєкт Plugin каналу">
|
||||
Інтерфейс `ChannelPlugin` має багато необовʼязкових поверхонь адаптера. Почніть із
|
||||
мінімуму — `id` і `setup` — і додавайте адаптери за потреби.
|
||||
|
||||
Створіть `src/channel.ts`:
|
||||
@ -321,7 +331,7 @@ if (decision.shouldSkip) return;
|
||||
createChannelPluginBase,
|
||||
} from "openclaw/plugin-sdk/channel-core";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/channel-core";
|
||||
import { acmeChatApi } from "./client.js"; // ваш клієнт API платформи
|
||||
import { acmeChatApi } from "./client.js"; // ваш API-клієнт платформи
|
||||
|
||||
type ResolvedAccount = {
|
||||
accountId: string | null;
|
||||
@ -372,21 +382,21 @@ if (decision.shouldSkip) return;
|
||||
},
|
||||
},
|
||||
|
||||
// Сполучення: потік підтвердження для нових контактів у DM
|
||||
// Сполучення: процес схвалення для нових контактів у DM
|
||||
pairing: {
|
||||
text: {
|
||||
idLabel: "Ім’я користувача Acme Chat",
|
||||
message: "Надішліть цей код, щоб підтвердити свою особу:",
|
||||
idLabel: "Acme Chat username",
|
||||
message: "Send this code to verify your identity:",
|
||||
notify: async ({ target, code }) => {
|
||||
await acmeChatApi.sendDm(target, `Pairing code: ${code}`);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Потоковість: як доставляються відповіді
|
||||
// Ланцюжки: як доставляються відповіді
|
||||
threading: { topLevelReplyToMode: "reply" },
|
||||
|
||||
// Outbound: надсилання повідомлень на платформу
|
||||
// Вихідні повідомлення: надсилання повідомлень на платформу
|
||||
outbound: {
|
||||
attachedResults: {
|
||||
sendText: async (params) => {
|
||||
@ -406,18 +416,18 @@ if (decision.shouldSkip) return;
|
||||
});
|
||||
```
|
||||
|
||||
<Accordion title="Що робить для вас createChatChannelPlugin">
|
||||
Замість того щоб вручну реалізовувати низькорівневі інтерфейси адаптера, ви передаєте
|
||||
декларативні параметри, а builder компонує їх:
|
||||
<Accordion title="Що `createChatChannelPlugin` робить для вас">
|
||||
Замість ручної реалізації низькорівневих інтерфейсів адаптера ви передаєте
|
||||
декларативні параметри, а конструктор поєднує їх:
|
||||
|
||||
| Параметр | Що він підключає |
|
||||
| --- | --- |
|
||||
| `security.dm` | Резолвер безпеки DM з областю дії на основі полів конфігурації |
|
||||
| `pairing.text` | Потік сполучення через текстовий DM з обміном кодом |
|
||||
| `threading` | Резолвер режиму відповіді (фіксований, з областю облікового запису або кастомний) |
|
||||
| `outbound.attachedResults` | Функції надсилання, що повертають метадані результату (ідентифікатори повідомлень) |
|
||||
| `security.dm` | Scoped-розвʼязувач безпеки DM із полів конфігурації |
|
||||
| `pairing.text` | Текстовий процес сполучення в DM з обміном кодами |
|
||||
| `threading` | Розвʼязувач режиму reply-to (фіксований, у межах облікового запису або спеціальний) |
|
||||
| `outbound.attachedResults` | Функції надсилання, які повертають метадані результату (ідентифікатори повідомлень) |
|
||||
|
||||
Ви також можете передавати сирі об’єкти адаптера замість декларативних параметрів,
|
||||
Ви також можете передавати сирі обʼєкти адаптерів замість декларативних параметрів,
|
||||
якщо вам потрібен повний контроль.
|
||||
</Accordion>
|
||||
|
||||
@ -433,20 +443,20 @@ if (decision.shouldSkip) return;
|
||||
export default defineChannelPluginEntry({
|
||||
id: "acme-chat",
|
||||
name: "Acme Chat",
|
||||
description: "Плагін каналу Acme Chat",
|
||||
description: "Acme Chat channel plugin",
|
||||
plugin: acmeChatPlugin,
|
||||
registerCliMetadata(api) {
|
||||
api.registerCli(
|
||||
({ program }) => {
|
||||
program
|
||||
.command("acme-chat")
|
||||
.description("Керування Acme Chat");
|
||||
.description("Acme Chat management");
|
||||
},
|
||||
{
|
||||
descriptors: [
|
||||
{
|
||||
name: "acme-chat",
|
||||
description: "Керування Acme Chat",
|
||||
description: "Acme Chat management",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
@ -461,19 +471,19 @@ if (decision.shouldSkip) return;
|
||||
|
||||
Розміщуйте дескриптори CLI, що належать каналу, у `registerCliMetadata(...)`, щоб OpenClaw
|
||||
міг показувати їх у кореневій довідці без активації повного runtime каналу,
|
||||
тоді як звичайні повні завантаження все одно підхоплюватимуть ті самі дескриптори для реєстрації
|
||||
реальних команд. Залишайте `registerFull(...)` для роботи лише під час runtime.
|
||||
Якщо `registerFull(...)` реєструє gateway RPC-методи, використовуйте
|
||||
префікс, специфічний для плагіна. Простори імен адміністратора core (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими і завжди
|
||||
резолвляться в `operator.admin`.
|
||||
тоді як звичайні повні завантаження все одно підхоплять ті самі дескриптори для реєстрації
|
||||
реальних команд. Зберігайте `registerFull(...)` для роботи лише в runtime.
|
||||
Якщо `registerFull(...)` реєструє RPC-методи Gateway, використовуйте
|
||||
префікс, специфічний для Plugin. Простори імен адміністрування ядра (`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`) залишаються зарезервованими й завжди
|
||||
розвʼязуються в `operator.admin`.
|
||||
`defineChannelPluginEntry` автоматично обробляє поділ режимів реєстрації. Усі
|
||||
параметри див. у [Точки входу](/uk/plugins/sdk-entrypoints#definechannelpluginentry).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Додайте setup entry">
|
||||
Створіть `setup-entry.ts` для легкого завантаження під час онбордингу:
|
||||
Створіть `setup-entry.ts` для полегшеного завантаження під час онбордингу:
|
||||
|
||||
```typescript setup-entry.ts
|
||||
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -483,27 +493,27 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
OpenClaw завантажує цей файл замість повної точки входу, коли канал вимкнений
|
||||
або не налаштований. Це дозволяє уникнути підтягування важкого runtime-коду під час потоків setup.
|
||||
Докладніше див. у [Налаштування та конфігурація](/uk/plugins/sdk-setup#setup-entry).
|
||||
або не налаштований. Це дозволяє не підтягувати важкий runtime-код під час процесів налаштування.
|
||||
Докладніше див. у [Налаштування і конфігурація](/uk/plugins/sdk-setup#setup-entry).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Обробляйте вхідні повідомлення">
|
||||
Ваш плагін має отримувати повідомлення з платформи та пересилати їх до
|
||||
OpenClaw. Типовий шаблон — це webhook, який перевіряє запит і
|
||||
Ваш Plugin має отримувати повідомлення з платформи й пересилати їх до
|
||||
OpenClaw. Типовий шаблон — це Webhook, який перевіряє запит і
|
||||
диспетчеризує його через вхідний обробник вашого каналу:
|
||||
|
||||
```typescript
|
||||
registerFull(api) {
|
||||
api.registerHttpRoute({
|
||||
path: "/acme-chat/webhook",
|
||||
auth: "plugin", // auth, керований плагіном (перевіряйте підписи самостійно)
|
||||
auth: "plugin", // автентифікація під керуванням Plugin (перевіряйте підписи самостійно)
|
||||
handler: async (req, res) => {
|
||||
const event = parseWebhookPayload(req);
|
||||
|
||||
// Ваш вхідний обробник диспетчеризує повідомлення до OpenClaw.
|
||||
// Точне підключення залежить від SDK вашої платформи —
|
||||
// реальний приклад див. у вбудованому пакеті плагіна Microsoft Teams або Google Chat.
|
||||
// див. реальний приклад у вбудованому пакеті Plugin Microsoft Teams або Google Chat.
|
||||
await handleAcmeChatInbound(api, event);
|
||||
|
||||
res.statusCode = 200;
|
||||
@ -515,16 +525,16 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
<Note>
|
||||
Обробка вхідних повідомлень залежить від каналу. Кожен плагін каналу відповідає
|
||||
за власний вхідний pipeline. Подивіться на вбудовані плагіни каналів
|
||||
(наприклад, пакет плагіна Microsoft Teams або Google Chat), щоб побачити реальні шаблони.
|
||||
Обробка вхідних повідомлень залежить від конкретного каналу. Кожен Plugin каналу
|
||||
володіє власним вхідним конвеєром. Подивіться на вбудовані 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";
|
||||
@ -562,14 +572,14 @@ if (decision.shouldSkip) return;
|
||||
pnpm test -- <bundled-plugin-root>/acme-chat/
|
||||
```
|
||||
|
||||
Спільні helper-и для тестування див. у [Тестування](/uk/plugins/sdk-testing).
|
||||
Для спільних helper тестування див. [Тестування](/uk/plugins/sdk-testing).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Структура файлів
|
||||
|
||||
```text
|
||||
```
|
||||
<bundled-plugin-root>/acme-chat/
|
||||
├── package.json # метадані openclaw.channel
|
||||
├── openclaw.plugin.json # Маніфест зі схемою конфігурації
|
||||
@ -580,37 +590,37 @@ if (decision.shouldSkip) return;
|
||||
└── src/
|
||||
├── channel.ts # ChannelPlugin через createChatChannelPlugin
|
||||
├── channel.test.ts # Тести
|
||||
├── client.ts # Клієнт API платформи
|
||||
├── client.ts # API-клієнт платформи
|
||||
└── runtime.ts # Runtime-сховище (за потреби)
|
||||
```
|
||||
|
||||
## Розширені теми
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Параметри потоковості" icon="git-branch" href="/uk/plugins/sdk-entrypoints#registration-mode">
|
||||
Фіксовані режими відповіді, режими з областю облікового запису або кастомні режими
|
||||
<Card title="Параметри ланцюжків" icon="git-branch" href="/uk/plugins/sdk-entrypoints#registration-mode">
|
||||
Фіксовані, scoped до облікового запису або спеціальні режими відповіді
|
||||
</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-ів усе ще існують для супроводу вбудованих плагінів і
|
||||
сумісності. Це не рекомендований шаблон для нових плагінів каналів;
|
||||
віддавайте перевагу загальним підшляхам channel/setup/reply/runtime зі спільної
|
||||
поверхні SDK, якщо тільки ви не супроводжуєте безпосередньо цю сім’ю вбудованих плагінів.
|
||||
Деякі вбудовані поверхні helper усе ще існують для підтримки вбудованих Plugin і
|
||||
сумісності. Вони не є рекомендованим шаблоном для нових Plugin каналів;
|
||||
віддавайте перевагу загальним channel/setup/reply/runtime-підшляхам зі спільної
|
||||
поверхні SDK, якщо лише ви не підтримуєте цю родину вбудованих Plugin безпосередньо.
|
||||
</Note>
|
||||
|
||||
## Наступні кроки
|
||||
|
||||
- [Плагіни провайдерів](/uk/plugins/sdk-provider-plugins) — якщо ваш плагін також надає моделі
|
||||
- [Provider Plugins](/uk/plugins/sdk-provider-plugins) — якщо ваш Plugin також надає моделі
|
||||
- [Огляд SDK](/uk/plugins/sdk-overview) — повний довідник імпортів за підшляхами
|
||||
- [Тестування SDK](/uk/plugins/sdk-testing) — утиліти тестування та контрактні тести
|
||||
- [Маніфест плагіна](/uk/plugins/manifest) — повна схема маніфесту
|
||||
- [Маніфест Plugin](/uk/plugins/manifest) — повна схема маніфесту
|
||||
|
||||
Loading…
Reference in New Issue
Block a user