Конвеєр завантаження
Під час запуску OpenClaw виконує приблизно такі дії:- виявляє корені кандидатів Plugin
- читає маніфести нативних або сумісних пакетів і метадані пакетів
- відхиляє небезпечних кандидатів
- нормалізує конфігурацію Plugin (
plugins.enabled,allow,deny,entries,slots,load.paths) - визначає, чи слід увімкнути кожного кандидата
- завантажує ввімкнені нативні модулі: зібрані вбудовані модулі використовують нативний завантажувач; локальний вихідний код TypeScript сторонніх розробників використовує аварійний резервний механізм Jiti
- викликає нативні перехоплювачі
register(api)і збирає реєстрації в реєстр Plugin - надає реєстр командам і поверхням середовища виконання
activate — це застарілий псевдонім для register: завантажувач визначає наявний варіант (def.register ?? def.activate) і викликає його в тій самій точці. Усі вбудовані Plugin використовують register; для нових Plugin віддавайте перевагу register.- його визначена точка входу виходить за межі кореня Plugin
- його шлях (або кореневий каталог) доступний для запису всім користувачам
- для невбудованих Plugin власник шляху не відповідає поточному uid (або root)
chmod на місці
(інсталяції npm/глобальні інсталяції можуть постачати каталоги пакетів із правами 0777), після чого перевірка
виконується повторно; для вбудованого походження перевірки власника повністю пропускаються.
Заблоковані кандидати все одно містять свій ідентифікатор Plugin у сформованій діагностиці, якщо
він відомий (зокрема ідентифікатори, визначені з маніфесту всередині
каталогу, який інакше було б відхилено), тому конфігурація, що посилається на цей ідентифікатор, бачить заблокований
Plugin, пов’язаний із попередженням про безпеку шляху, а не непов’язану помилку «невідомий Plugin».
Поведінка з пріоритетом маніфесту
Маніфест є джерелом істини площини керування. OpenClaw використовує його, щоб:- ідентифікувати Plugin
- виявляти оголошені канали/Skills/схему конфігурації або можливості пакета
- перевіряти
plugins.entries.<id>.config - доповнювати підписи/заповнювачі Control UI
- показувати метадані інсталяції/каталогу
- зберігати легковагові дескриптори активації та налаштування без завантаження середовища виконання Plugin
activation і setup залишаються в площині керування.
Це дескриптори лише з метаданими для планування активації та виявлення налаштування;
вони не замінюють реєстрацію середовища виконання, register(...) або setupEntry.
Активні споживачі активації використовують підказки маніфесту щодо команд, каналів і постачальників, щоб
звузити завантаження Plugin до ширшої матеріалізації реєстру:
- завантаження CLI звужується до Plugin, яким належить запитана основна команда
- налаштування каналу/визначення Plugin звужується до Plugin, яким належить запитаний ідентифікатор каналу
- явне налаштування постачальника/визначення середовища виконання звужується до Plugin, яким належить запитаний ідентифікатор постачальника
- планування запуску Gateway використовує
activation.onStartupдля явних імпортів під час запуску; Plugin без метаданих запуску завантажуються лише через вужчі тригери активації
activation.* від резервного визначення за належністю маніфесту:
Цей поділ причин є межею сумісності: наявні метадані Plugin
продовжують працювати, а новий код може виявляти широкі підказки або резервну поведінку
без зміни семантики завантаження середовища виконання.
Попередні завантаження середовища виконання під час запиту, які запитують широку область
all, усе одно формують
явний ефективний набір ідентифікаторів Plugin із конфігурації, планування запуску, налаштованих
каналів, слотів і правил автоматичного ввімкнення
(resolveEffectivePluginIds у src/plugins/effective-plugin-ids.ts). Якщо цей
сформований набір порожній, OpenClaw залишає область порожньою, а не розширює її до
кожного доступного для виявлення Plugin.
Виявлення налаштування віддає перевагу ідентифікаторам, що належать дескрипторам, як-от setup.providers і
setup.cliBackends, щоб звузити кандидатів Plugin перед переходом до резервного
setup-api для Plugin, яким усе ще потрібні перехоплювачі середовища виконання під час налаштування. Списки налаштування
постачальників використовують providerAuthChoices із маніфесту, варіанти налаштування,
отримані з дескрипторів, і метадані каталогу інсталяцій без завантаження середовища виконання постачальника. Явне
setup.requiresRuntime: false є межею, що дозволяє використовувати лише дескриптори; якщо
requiresRuntime пропущено, для сумісності зберігається застарілий резервний механізм setup-api. Якщо
кілька виявлених Plugin заявляють той самий нормалізований ідентифікатор постачальника налаштування або
бекенду CLI, пошук налаштування відхиляє неоднозначного власника, а не покладається на
порядок виявлення. Коли середовище виконання налаштування все ж виконується, діагностика реєстру повідомляє
про розбіжності між setup.providers / setup.cliBackends і постачальниками або бекендами CLI,
фактично зареєстрованими через setup-api, не блокуючи застарілі Plugin.
Межа кешу Plugin
OpenClaw не кешує результати виявлення Plugin або безпосередні дані реєстру маніфестів за часовими вікнами. Інсталяції, зміни маніфестів і зміни шляхів завантаження мають ставати видимими під час наступного явного читання метаданих або перебудови знімка. Парсер файлів маніфестів підтримує обмежений кеш сигнатур файлів із ключем за шляхом відкритого маніфесту разом із пристроєм/inode, розміром і mtime/ctime; цей кеш лише запобігає повторному аналізу незмінених байтів і не повинен кешувати відповіді щодо виявлення, реєстру, власника або політик. Безпечний швидкий шлях метаданих — це явне володіння об’єктами, а не прихований кеш. Гарячі шляхи запуску Gateway мають передавати поточнийPluginMetadataSnapshot,
похідний PluginLookUpTable або явний реєстр маніфестів через ланцюжок
викликів. Перевірка конфігурації, автоматичне ввімкнення під час запуску, початкова ініціалізація Plugin і вибір
постачальника можуть повторно використовувати ці об’єкти, доки вони представляють поточну конфігурацію та
інвентар Plugin. Пошук налаштування все одно відновлює метадані маніфесту на вимогу,
якщо конкретний шлях налаштування не отримує явний реєстр маніфестів; залишайте
це резервним варіантом для холодного шляху, а не додавайте приховані кеші пошуку. Коли
вхідні дані змінюються, перебудовуйте й замінюйте знімок замість його зміни або
зберігання історичних копій. Представлення активного реєстру Plugin і допоміжні засоби
початкової ініціалізації вбудованих каналів слід обчислювати повторно з поточного
реєстру/кореня. Короткоживучі мапи допустимі в межах одного виклику для усунення дублювання роботи або
запобігання повторному входу; вони не повинні ставати кешами метаданих процесу.
Для завантаження Plugin постійним рівнем кешування є завантаження середовища виконання. Він може повторно використовувати
стан завантажувача, коли код або встановлені артефакти фактично завантажуються, наприклад:
PluginLoaderCacheStateі сумісні активні реєстри середовища виконання- кеші jiti/модулів і кеші завантажувачів публічних поверхонь, що використовуються для уникнення повторного імпорту тієї самої поверхні середовища виконання
- кеші файлової системи для встановлених артефактів Plugin
- короткоживучі мапи на один виклик для нормалізації шляхів або усунення дублікатів
- результатів виявлення
- безпосередніх реєстрів маніфестів
- реєстрів маніфестів, відновлених з індексу встановлених Plugin
- пошуку власника постачальника, приховування моделей, політик постачальника або метаданих публічних артефактів
- будь-якої іншої відповіді, отриманої з маніфесту, для якої змінений маніфест, індекс установлених компонентів або шлях завантаження має бути видимим під час наступного читання метаданих
Модель реєстру
Завантажені Plugin не змінюють безпосередньо випадкові глобальні змінні ядра. Вони реєструються в центральному реєстрі Plugin (PluginRegistry у src/plugins/registry-types.ts),
який відстежує записи Plugin (ідентичність, джерело, походження, стан, діагностику),
а також масиви для кожної можливості: інструменти, застарілі й типізовані перехоплювачі,
канали, постачальники, обробники RPC Gateway, HTTP-маршрути, реєстратори CLI,
фонові служби, команди, що належать Plugin, і десятки інших типізованих сімейств постачальників
(мовлення, вбудовування, генерування зображень/відео/музики, отримання/пошук
у вебі, агентські оболонки, дії сеансів тощо).
Потім основні функції читають дані з цього реєстру замість безпосередньої взаємодії з модулями
Plugin. Це зберігає односпрямованість завантаження:
- модуль Plugin -> реєстрація в реєстрі
- середовище виконання ядра -> використання реєстру
Зворотні виклики прив’язування розмови
Plugin, які прив’язують розмову, можуть реагувати на вирішення запиту на схвалення. Використовуйтеapi.onConversationBindingResolved(...), щоб отримати зворотний виклик після схвалення
або відхилення запиту на прив’язування:
status:"approved"або"denied"decision:"allow-once","allow-always"або"deny"binding: визначена прив’язка для схвалених запитівrequest: початковий підсумок запиту, підказка щодо від’єднання, ідентифікатор відправника та метадані розмови
Перехоплювачі середовища виконання постачальника
Plugin постачальників мають три рівні:- Метадані маніфесту для швидкого пошуку до запуску середовища виконання:
setup.providers[].envVars, застарілий сумісний параметрproviderAuthEnvVars,providerAuthAliases,providerAuthChoicesіchannelEnvVars. - Перехоплювачі етапу конфігурації:
catalog(застарілийdiscovery) іapplyConfigDefaults. - Перехоплювачі середовища виконання: понад 40 необов’язкових перехоплювачів, що охоплюють автентифікацію, визначення моделей, обгортання потоків, рівні міркування, політику повторного відтворення й кінцеві точки використання. Див. Порядок перехоплювачів і використання.
setup.providers[].envVars у маніфесті, коли постачальник має облікові дані на основі змінних середовища, які мають бути доступні загальним шляхам автентифікації, перевірки стану та вибору моделі без завантаження середовища виконання плагіна. Застаріле поле providerAuthEnvVars усе ще зчитується адаптером сумісності протягом періоду вилучення, а сторонні плагіни, які його використовують, отримують діагностичне повідомлення маніфесту. Використовуйте providerAuthAliases у маніфесті, коли один ідентифікатор постачальника має повторно використовувати змінні середовища, профілі автентифікації, автентифікацію на основі конфігурації та варіант підключення за допомогою ключа API іншого ідентифікатора постачальника. Використовуйте providerAuthChoices у маніфесті, коли інтерфейсам CLI для підключення та вибору автентифікації потрібно знати ідентифікатор варіанта постачальника, мітки груп і просте налаштування автентифікації одним прапорцем без завантаження середовища виконання постачальника. Залишайте envVars середовища виконання постачальника для підказок операторам, як-от мітки підключення або змінні налаштування ідентифікатора та секрету клієнта OAuth.
Використовуйте channelEnvVars у маніфесті, коли канал має автентифікацію або налаштування на основі змінних середовища, які мають бути доступні загальному резервному механізму змінних середовища оболонки, перевіркам конфігурації та стану або запитам налаштування без завантаження середовища виконання каналу.
Порядок і використання обробників
Для плагінів моделей і постачальників OpenClaw викликає обробники приблизно в такому порядку. Стовпець «Коли використовувати» є коротким посібником із вибору. Поля постачальника, призначені лише для сумісності, які OpenClaw більше не викликає, як-отProviderPlugin.capabilities і suppressBuiltInModel, навмисно тут не наведено.
normalizeModelId, normalizeTransport і normalizeConfig спочатку перевіряють
відповідний Plugin постачальника, а потім переходять до інших Plugin постачальників,
що підтримують хуки, доки один із них справді не змінить ідентифікатор моделі або
транспорт/конфігурацію. Це дає змогу сумісним адаптерам і псевдонімам постачальників
працювати без потреби для викликового коду знати, якому вбудованому Plugin належить
перетворення. Якщо жоден хук постачальника не перетворює підтримуваний запис
конфігурації сімейства Google, вбудований нормалізатор конфігурації Google усе одно
виконує це очищення для сумісності.
Якщо постачальнику потрібен повністю власний мережевий протокол або власний виконавець
запитів, це інший клас розширення. Ці хуки призначені для поведінки постачальника,
яка й надалі працює у звичайному циклі інференсу OpenClaw.
resolveUsageAuth визначає, чи має OpenClaw викликати fetchUsageSnapshot, чи
повернутися до загального визначення облікових даних для інтерфейсів використання/стану.
Повертайте { token, accountId?, subscriptionType?, rateLimitTier? }, коли
постачальник має облікові дані для отримання даних про використання (необов’язкові
метадані тарифного плану передаються до fetchUsageSnapshot), повертайте
{ handled: true }, коли автентифікація використання, якою керує постачальник,
обробила запит і має запобігти загальному резервному переходу до ключа API/OAuth,
і повертайте null або undefined, коли постачальник не обробив автентифікацію
використання.
Оголошуйте облікові дані організації або платіжного обліку в
providerUsageAuthEnvVars маніфесту. Це дає змогу загальним механізмам виявлення
та очищення секретів розпізнавати їх, не перетворюючи на кандидатів для автентифікації
інференсу.
Приклад постачальника
Вбудовані приклади
Вбудовані Plugin постачальників поєднують наведені вище хуки відповідно до потреб кожного постачальника щодо каталогу, автентифікації, міркування, повторного відтворення та використання. Авторитетний набір хуків міститься в кожному Plugin уextensions/; ця сторінка ілюструє їхню структуру, а не дублює перелік.
Постачальники каталогів із наскрізним передаванням
Постачальники каталогів із наскрізним передаванням
OpenRouter, Kilocode, Z.AI, xAI реєструють
catalog разом із
resolveDynamicModel / prepareDynamicModel, щоб показувати ідентифікатори
моделей вищого рівня раніше за статичний каталог OpenClaw.Постачальники кінцевих точок OAuth і використання
Постачальники кінцевих точок OAuth і використання
GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi, z.ai поєднують
prepareRuntimeAuth або formatApiKey із resolveUsageAuth +
fetchUsageSnapshot, щоб керувати обміном токенів та інтеграцією /usage.Сімейства очищення повторного відтворення та транскриптів
Сімейства очищення повторного відтворення та транскриптів
Спільні іменовані сімейства (
google-gemini, passthrough-gemini,
anthropic-by-model, hybrid-anthropic-openai) дають змогу постачальникам
підключатися до політики транскриптів через buildReplayPolicy, замість того
щоб кожен Plugin повторно реалізовував очищення.Постачальники лише каталогів
Постачальники лише каталогів
byteplus, cloudflare-ai-gateway, huggingface, kimi-coding, nvidia,
qianfan, synthetic, together, venice, vercel-ai-gateway і
volcengine реєструють лише catalog та використовують спільний цикл інференсу.Спеціалізовані допоміжні засоби потоків Anthropic
Спеціалізовані допоміжні засоби потоків Anthropic
Бета-заголовки,
/fast / serviceTier і context1m містяться у публічній
межі api.ts / contract-api.ts Plugin Anthropic
(wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier), а не в
загальному SDK.Допоміжні засоби середовища виконання
Plugin можуть отримувати доступ до вибраних допоміжних засобів ядра черезapi.runtime. Для TTS:
textToSpeechповертає звичайне корисне навантаження результату TTS ядра для інтерфейсів файлів/голосових нотаток.- Використовує конфігурацію
messages.ttsядра та вибір постачальника. - Повертає аудіобуфер PCM і частоту дискретизації. Plugin мають передискретизувати/закодувати дані для постачальників.
listVoicesє необов’язковим для кожного постачальника. Використовуйте його для засобів вибору голосу або процесів налаштування, якими керує постачальник.- Ядро передає визначений кінцевий термін запиту до хуків
listVoicesпостачальника; параметри часу очікування конкретного постачальника можуть його перевизначити. - Списки голосів можуть містити докладніші метадані, як-от локаль, стать і теги характеру, для засобів вибору з урахуванням постачальника.
- OpenAI та ElevenLabs наразі підтримують телефонію. Microsoft — ні.
api.registerSpeechProvider(...).
- Зберігайте політику TTS, резервний перехід і доставку відповіді в ядрі.
- Використовуйте постачальників мовлення для керованої постачальником поведінки синтезу.
- Застаріле вхідне значення Microsoft
edgeнормалізується до ідентифікатора постачальникаmicrosoft. - Бажана модель володіння орієнтована на компанію: один Plugin постачальника може керувати постачальниками тексту, мовлення, зображень і майбутніх медіа, коли OpenClaw додаватиме відповідні контракти можливостей.
- Зберігайте оркестрацію, резервний перехід, конфігурацію та підключення каналів у ядрі.
- Зберігайте поведінку постачальника в його Plugin.
- Адитивне розширення має залишатися типізованим: нові необов’язкові методи, нові необов’язкові поля результату, нові необов’язкові можливості.
- Генерування відео вже відповідає такому самому шаблону:
- ядро володіє контрактом можливості та допоміжним засобом середовища виконання
- Plugin постачальників реєструють
api.registerVideoGenerationProvider(...) - Plugin функцій/каналів використовують
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*є бажаним спільним інтерфейсом для розпізнавання зображень, аудіо та відео.extractStructuredWithModel(...)є доступною для Plugin межею обмеженого видобування даних із пріоритетом зображень, яким керує постачальник. Додайте принаймні одне вхідне зображення; текстові вхідні дані є додатковим контекстом. Plugin продукту володіють своїми маршрутами та схемами, а OpenClaw — межею постачальника/середовища виконання.- Використовує аудіоконфігурацію розпізнавання медіа ядра (
tools.media.audio) і порядок резервного переходу між постачальниками. - Повертає
{ text: undefined }, коли результат транскрибування відсутній (наприклад, для пропущених/непідтримуваних вхідних даних). api.runtime.stt.transcribeAudioFile(...)залишається псевдонімом для сумісності.
api.runtime.subagent:
providerіmodelє необов’язковими перевизначеннями для окремого виконання, а не постійними змінами сеансу.- OpenClaw враховує ці поля перевизначення лише для довірених викликових сторін.
- Для резервних виконань, якими керує Plugin, оператори мають явно дозволити їх за допомогою
plugins.entries.<id>.subagent.allowModelOverride: true. - Використовуйте
plugins.entries.<id>.subagent.allowedModels, щоб обмежити довірені Plugin конкретними канонічними цілямиprovider/model, або"*", щоб явно дозволити будь-яку ціль. - Виконання підагентів від недовірених Plugin і надалі працюють, але запити на перевизначення відхиляються замість непомітного резервного переходу.
- Створені Plugin сеанси підагентів позначаються ідентифікатором Plugin, що їх створив. Резервний
api.runtime.subagent.deleteSession(...)може видаляти лише ці власні сеанси; видалення довільних сеансів і надалі потребує запиту Gateway з областю адміністратора.
api.registerWebSearchProvider(...).
Примітки:
- Зберігайте вибір постачальника, визначення облікових даних і спільну семантику запитів у ядрі.
- Використовуйте постачальників вебпошуку для специфічних для постачальника транспортів пошуку.
api.runtime.webSearch.*є бажаним спільним інтерфейсом для Plugin функцій/каналів, яким потрібна поведінка пошуку без залежності від оболонки інструменту агента.
api.runtime.imageGeneration
generate(...): генерує зображення за допомогою налаштованого ланцюжка постачальників генерування зображень.listProviders(...): перелічує доступних постачальників генерування зображень та їхні можливості.
HTTP-маршрути Gateway
Plugin можуть надавати кінцеві точки HTTP за допомогоюapi.registerHttpRoute(...).
path: шлях маршруту на HTTP-сервері Gateway.auth: обов’язкове поле,"gateway"або"plugin". Використовуйте"gateway", щоб вимагати звичайну автентифікацію Gateway, або"plugin"для автентифікації чи перевірки вебхуків, якими керує плагін.match: необов’язкове поле."exact"(типове значення) або"prefix".handleUpgrade: необов’язковий обробник запитів оновлення WebSocket на тому самому маршруті.replaceExisting: необов’язкове поле. Дає змогу тому самому плагіну замінити власну наявну реєстрацію маршруту.handler: повернітьtrue, коли маршрут обробив запит.
api.registerHttpHandler(...)видалено, і його використання спричинить помилку завантаження плагіна. Натомість використовуйтеapi.registerHttpRoute(...).- Маршрути плагінів мають явно оголошувати
auth. - Конфлікти однакових
path + matchвідхиляються, якщо не вказаноreplaceExisting: true, а один плагін не може замінити маршрут іншого плагіна. - Маршрути, що перекриваються та мають різні рівні
auth, відхиляються. Ланцюжки переходуexact/prefixмають використовувати лише один рівень автентифікації. - Маршрути з
auth: "plugin"не отримують автоматично області дії середовища виконання оператора. Вони призначені для вебхуків і перевірки підписів, якими керує плагін, а не для привілейованих викликів допоміжних функцій Gateway. - Маршрути з
auth: "gateway"виконуються в області середовища виконання запиту Gateway. Типова поверхня (gatewayRuntimeScopeSurface: "write-default") навмисно обмежена:- автентифікація за допомогою спільного секрету в токені носія (
gateway.auth.mode = "token"/"password") і будь-який метод автентифікації, відмінний від довіреного проксі, отримують одну область діїoperator.write, навіть якщо викликач надсилаєx-openclaw-scopes - викликачі
trusted-proxyбез явно заданого заголовкаx-openclaw-scopesтакож зберігають застарілу поверхню лише зoperator.write - викликачі
trusted-proxy, які надсилаютьx-openclaw-scopes, натомість отримують оголошені області дії - маршрут може вибрати
gatewayRuntimeScopeSurface: "trusted-operator", щоб завжди враховуватиx-openclaw-scopesдля режимів автентифікації з ідентичністю (а за відсутності заголовка використовувати повний типовий набір областей дії CLI)
- автентифікація за допомогою спільного секрету в токені носія (
- Практичне правило: не вважайте маршрут плагіна з автентифікацією Gateway неявною адміністративною поверхнею. Якщо маршруту потрібна поведінка лише для адміністраторів, виберіть поверхню областей дії
trusted-operator, вимагайте режим автентифікації з ідентичністю та задокументуйте явний контракт заголовкаx-openclaw-scopes. - Після зіставлення маршруту й автентифікації звичайні обробники беруть участь у допуску кореневої роботи Gateway. Підготовлений Gateway або Gateway, що перезапускається, повертає
503до виклику обробника. Вузьким винятком є дозволений маніфестом маршрут зauth: "gateway", який також вибирає специфічну для маршруту поверхнюtrusted-operator; він залишається доступним, щоб диспетчеризація керування призупиненням не могла залишитися заблокованою, тоді як звичайні споріднені маршрути того самого плагіна залишаються за межею допуску. Володіння WebSockethandleUpgradeвикористовує ту саму атомарну межу допуску; щойно обробник приймає сокет, подальшим життєвим циклом сокета керує плагін, і ця межа його не відстежує.
Шляхи імпорту SDK плагінів
Під час створення нових плагінів використовуйте вузькі підшляхи SDK замість монолітного кореневого модуля реекспортуopenclaw/plugin-sdk. Основні підшляхи:
Плагіни каналів вибирають із сімейства вузьких інтерфейсів —
channel-setup,
setup-runtime, setup-tools, channel-pairing,
channel-contract, channel-feedback, channel-inbound, channel-outbound,
command-auth, secret-input, webhook-ingress,
channel-targets і channel-actions. Поведінку схвалення слід зосередити
в одному контракті approvalCapability, а не розподіляти між не пов’язаними
полями плагіна. Див. Плагіни каналів.
Допоміжні засоби середовища виконання й конфігурації розміщено у відповідних
спеціалізованих підшляхах *-runtime (approval-runtime, agent-runtime,
lazy-runtime, directory-runtime, text-runtime, runtime-store,
system-event-runtime, heartbeat-runtime, channel-activity-runtime тощо).
Віддавайте перевагу config-contracts, plugin-config-runtime,
runtime-config-snapshot і config-mutation замість широкого сумісного
модуля реекспорту config-runtime.
openclaw/plugin-sdk/channel-runtime, openclaw/plugin-sdk/channel-lifecycle,
невеликі фасади допоміжних засобів каналів, openclaw/plugin-sdk/outbound-runtime,
openclaw/plugin-sdk/outbound-send-deps, openclaw/plugin-sdk/config-runtime
і openclaw/plugin-sdk/infra-runtime є застарілими сумісними прошарками для
старіших плагінів. Новий код натомість має імпортувати вужчі загальні примітиви.index.js— точка входу вбудованого плагінаapi.js— модуль реекспорту допоміжних засобів і типівruntime-api.js— модуль реекспорту лише для середовища виконанняsetup-entry.js— точка входу плагіна налаштування
openclaw/plugin-sdk/*. Ніколи
не імпортуйте src/* пакета іншого плагіна з ядра або іншого плагіна.
Точки входу, завантажені через фасад, віддають перевагу активному знімку
конфігурації середовища виконання, якщо він існує, а потім переходять до
визначеного файла конфігурації на диску.
Підшляхи для окремих можливостей, як-от image-generation, media-understanding
і speech, існують, оскільки вбудовані плагіни використовують їх зараз. Вони
не стають автоматично довгостроковими незмінними зовнішніми контрактами —
перевіряйте відповідну довідкову сторінку SDK, якщо покладаєтеся на них.
Схеми інструмента повідомлень
Плагіни мають володіти специфічними для каналів внескамиdescribeMessageTool(...) до схеми для примітивів, що не є повідомленнями,
як-от реакції, прочитання й опитування. Спільне подання надсилання має
використовувати загальний контракт MessagePresentation замість нативних
для постачальника полів кнопок, компонентів, блоків або карток.
Контракт, правила резервного відтворення, зіставлення постачальників і
контрольний список автора плагіна див. у розділі
Подання повідомлень.
Плагіни з можливістю надсилання оголошують, що вони можуть відтворювати,
за допомогою можливостей повідомлень:
presentationдля семантичних блоків подання (text,context,divider,chart,table,buttons,select)delivery-pinдля запитів закріпленої доставки
Визначення цілі каналу
Плагіни каналів мають володіти специфічною для каналів семантикою цілей. Зберігайте спільний хост вихідних повідомлень загальним і використовуйте поверхню адаптера обміну повідомленнями для правил постачальника:messaging.inferTargetChatType({ to })визначає, чи слід вважати нормалізовану цільdirect,groupабоchannelдо пошуку в каталозі.messaging.targetResolver.looksLikeId(raw, normalized)повідомляє ядру, чи слід для введеного значення одразу перейти до визначення за подобою ідентифікатора замість пошуку в каталозі.messaging.targetResolver.reservedLiteralsмістить прості слова, які є посиланнями на канал або сеанс для цього постачальника. Під час визначення спочатку зберігаються налаштовані записи каталогу, а вже потім відхиляються зарезервовані літерали; якщо в каталозі немає збігу, операція безпечно завершується помилкою.messaging.targetResolver.resolveTarget(...)є резервним механізмом плагіна, коли ядру потрібне остаточне визначення, яким керує постачальник, після нормалізації або відсутності збігу в каталозі.messaging.resolveOutboundSessionRoute(...)відповідає за побудову специфічного для постачальника маршруту сеансу після визначення цілі.
- Використовуйте
inferTargetChatTypeдля рішень щодо категорії, які мають відбуватися до пошуку співрозмовників або груп. - Використовуйте
looksLikeIdдля перевірок «вважати це явним або нативним ідентифікатором цілі». - Використовуйте
resolveTargetдля специфічного для постачальника резервного механізму нормалізації, а не для широкого пошуку в каталозі. - Зберігайте нативні ідентифікатори постачальника, як-от ідентифікатори чатів,
потоків, JID, псевдоніми й ідентифікатори кімнат, усередині значень
targetабо специфічних для постачальника параметрів, а не в загальних полях SDK.
Каталоги на основі конфігурації
Плагіни, які формують записи каталогу з конфігурації, мають зберігати цю логіку в плагіні та повторно використовувати спільні допоміжні засоби зopenclaw/plugin-sdk/directory-runtime.
Використовуйте це, коли каналу потрібні визначені конфігурацією співрозмовники
або групи, як-от:
- співрозмовники приватних повідомлень, визначені списком дозволених
- налаштовані зіставлення каналів або груп
- статичні резервні каталоги в межах облікового запису
directory-runtime виконують лише загальні операції:
- фільтрування запитів
- застосування обмежень
- допоміжні засоби усунення дублікатів і нормалізації
- побудову
ChannelDirectoryEntry[]
Каталоги постачальників
Плагіни постачальників можуть визначати каталоги моделей для інференсу за допомогоюregisterProvider({ catalog: { run(...) { ... } } }).
catalog.run(...) повертає ту саму структуру, яку OpenClaw записує в
models.providers:
{ provider }для одного запису постачальника{ providers }для кількох записів постачальників
catalog, коли плагін володіє специфічними для постачальника
ідентифікаторами моделей, типовими базовими URL-адресами або метаданими моделей,
доступ до яких залежить від автентифікації.
catalog.order визначає, коли каталог плагіна об’єднується відносно вбудованих
неявних постачальників OpenClaw:
simple: звичайні постачальники на основі ключа API або змінних середовищаprofile: постачальники, які з’являються за наявності профілів автентифікаціїpaired: постачальники, які синтезують кілька пов’язаних записів постачальниківlate: останній прохід після інших неявних постачальників
api.registerModelCatalogProvider({ provider, kinds, staticCatalog, liveCatalog }). Це перспективний шлях для поверхонь списків, довідки й вибору, який
підтримує рядки text, voice, image_generation, video_generation і
music_generation. Плагіни постачальників і далі відповідають за виклики
активних кінцевих точок, обмін токенами та зіставлення відповідей постачальника;
ядро відповідає за спільну структуру рядків, позначки джерел і форматування
довідки інструментів мультимедіа. Реєстрації постачальників генерації
мультимедіа автоматично синтезують статичні рядки каталогу з defaultModel,
models і capabilities.
Сумісність:
discoveryі далі працює як застарілий псевдонім, але виводить попередження про застарілість- якщо зареєстровано і
catalog, іdiscovery, OpenClaw використовуєcatalogта виводить попередження augmentModelCatalogзастарів; вбудовані постачальники мають публікувати додаткові рядки черезregisterModelCatalogProvider
Перевірка каналу лише для читання
Якщо ваш плагін реєструє канал, бажано реалізуватиplugin.config.inspectAccount(cfg, accountId) разом із resolveAccount(...).
Чому:
resolveAccount(...)є шляхом середовища виконання. Він може припускати, що облікові дані повністю матеріалізовано, і швидко завершуватися помилкою, якщо потрібні секрети відсутні.- Шляхи команд лише для читання, як-от
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolve, а також потоки виправлення doctor або конфігурації не повинні матеріалізувати облікові дані середовища виконання лише для опису конфігурації.
inspectAccount(...):
- Повертайте лише описовий стан облікового запису.
- Зберігайте
enabledіconfigured. - За потреби включайте поля джерела/стану облікових даних, наприклад:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- Щоб повідомити про доступність лише для читання, не потрібно повертати необроблені значення токенів. Для команд перевірки стану достатньо повернути
tokenStatus: "available"(і відповідне поле джерела). - Використовуйте
configured_unavailable, коли облікові дані налаштовано через SecretRef, але вони недоступні в поточному шляху виконання команди.
Пакети розширень
Каталог Plugin може міститиpackage.json із openclaw.extensions:
<manifestOrPackageName>/<fileBase> (за наявності перевагу має ідентифікатор маніфесту; інакше використовується ім’я package.json без області видимості).
Якщо ваш Plugin імпортує залежності npm, установіть їх у цьому каталозі, щоб був доступний node_modules (npm install / pnpm install).
Захисне обмеження: після розв’язання символічних посилань кожен запис openclaw.extensions має залишатися в межах каталогу Plugin. Записи, що виходять за межі каталогу пакета, відхиляються.
Примітка щодо безпеки: openclaw plugins install установлює залежності Plugin за допомогою локальної для проєкту команди npm install --omit=dev --ignore-scripts (без сценаріїв життєвого циклу та без залежностей для розробки під час виконання), ігноруючи успадковані глобальні налаштування встановлення npm. Підтримуйте дерева залежностей Plugin у вигляді «чистого JS/TS» й уникайте пакетів, що потребують складання через postinstall.
Необов’язково: openclaw.setupEntry може вказувати на легкий модуль, призначений лише для налаштування. Коли OpenClaw потрібні поверхні налаштування для вимкненого Plugin каналу або коли Plugin каналу ввімкнено, але ще не налаштовано, він завантажує setupEntry замість повної точки входу Plugin. Це полегшує запуск і налаштування, якщо основна точка входу Plugin також підключає інструменти, перехоплювачі або інший код, потрібний лише під час виконання.
Необов’язково: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen дає змогу Plugin каналу використовувати той самий шлях setupEntry на етапі запуску Gateway до початку прослуховування, навіть якщо канал уже налаштовано.
Використовуйте це лише тоді, коли setupEntry повністю охоплює поверхню запуску, яка має існувати до того, як Gateway почне прослуховування. На практиці це означає, що точка входу налаштування має реєструвати кожну належну каналу можливість, від якої залежить запуск, зокрема:
- саму реєстрацію каналу
- усі HTTP-маршрути, які мають бути доступні до того, як Gateway почне прослуховування
- усі методи Gateway, інструменти або служби, які мають існувати впродовж цього самого проміжку часу
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* без завантаження повної точки входу Plugin. Matrix є поточним вбудованим прикладом: коли іменовані облікові записи вже існують, він переносить до іменованого цільового облікового запису лише ключі автентифікації/початкового налаштування, а також може зберегти налаштований неканонічний ключ типового облікового запису замість того, щоб завжди створювати accounts.default.
Ці адаптери виправлень налаштування зберігають відкладене виявлення вбудованої поверхні контракту. Час імпорту залишається коротким; поверхня перенесення завантажується лише під час першого використання замість повторного запуску вбудованого каналу під час імпорту модуля.
Коли ці поверхні запуску включають методи RPC Gateway, використовуйте для них префікс, специфічний для Plugin. Простори імен адміністрування ядра (config.*, exec.approvals.*, wizard.*, update.*) залишаються зарезервованими та завжди відповідають operator.admin, навіть якщо Plugin запитує вужчу область дозволів.
Приклад:
Метадані каталогу каналів
Plugin каналів можуть оголошувати метадані налаштування/виявлення черезopenclaw.channel, а підказки зі встановлення — через openclaw.install. Завдяки цьому каталог ядра не містить даних.
Приклад:
openclaw.channel, окрім мінімального прикладу:
detailLabel: додаткова мітка для докладніших поверхонь каталогу/стануdocsLabel: перевизначення тексту посилання на документаціюpreferOver: ідентифікатори Plugin/каналів із нижчим пріоритетом, які цей запис каталогу має випереджатиselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: елементи керування текстом поверхні виборуmarkdownCapable: позначає канал як сумісний із Markdown для ухвалення рішень щодо форматування вихідних повідомленьexposure.configured: якщо встановленоfalse, приховує канал із поверхонь переліку налаштованих каналівexposure.setup: якщо встановленоfalse, приховує канал з інтерактивних засобів вибору налаштування/конфігураціїexposure.docs: позначає канал як внутрішній/приватний для поверхонь навігації документацієюshowConfigured/showInSetup: застарілі псевдоніми, які досі приймаються для сумісності; віддавайте перевагуexposurequickstartAllowFrom: долучає канал до стандартного процесу швидкого запускуallowFromforceAccountBinding: вимагає явного прив’язування облікового запису, навіть якщо існує лише один обліковий записpreferSessionLookupForAnnounceTarget: надає перевагу пошуку сеансу під час визначення цілей оголошень
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (чи OPENCLAW_MPM_CATALOG_PATHS) один або кілька файлів JSON (розділених комами, крапками з комою або роздільником PATH). Кожен файл має містити { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }. Синтаксичний аналізатор також приймає "packages" або "plugins" як застарілі псевдоніми ключа "entries".
Згенеровані записи каталогу каналів і записи каталогу встановлення постачальників надають нормалізовані відомості про джерело встановлення поряд із необробленим блоком openclaw.install. Нормалізовані відомості визначають, чи є специфікація npm точною версією або плаваючим селектором, чи наявні очікувані метадані цілісності та чи доступний також локальний шлях до джерела. Коли ідентичність каталогу/пакета відома, нормалізовані відомості попереджають, якщо проаналізоване ім’я пакета npm відрізняється від цієї ідентичності. Вони також попереджають, коли defaultChoice недійсний або вказує на недоступне джерело, а також коли метадані цілісності npm наявні без дійсного джерела npm. Споживачі мають розглядати installSource як додаткове необов’язкове поле, щоб створені вручну записи та адаптери каталогу не мусили його синтезувати.
Завдяки цьому початкове налаштування та діагностика можуть пояснювати стан площини джерел без імпорту середовища виконання Plugin.
Для офіційних зовнішніх записів npm слід віддавати перевагу точному npmSpec разом із expectedIntegrity. Самі імена пакетів і теги розповсюдження досі працюють для сумісності, але вони спричиняють попередження площини джерел, щоб каталог міг перейти до закріплених установлень із перевіркою цілісності без порушення роботи наявних Plugin.
Коли під час початкового налаштування встановлення виконується з локального шляху каталогу, створюється керований запис індексу Plugin із source: "path" і, коли можливо, відносним щодо робочого простору sourcePath. Абсолютний робочий шлях завантаження залишається в plugins.load.paths; запис установлення не дублює шляхи локальної робочої станції в довготривалій конфігурації. Завдяки цьому локальні встановлення для розробки залишаються видимими для діагностики площини джерел без додавання другої поверхні розкриття необроблених шляхів файлової системи. Збережена таблиця SQLite installed_plugin_index є джерелом істини щодо джерел установлення й може оновлюватися без завантаження модулів середовища виконання Plugin. Її мапа installRecords зберігається навіть тоді, коли маніфест Plugin відсутній або недійсний; її вміст plugins є відновлюваним представленням маніфесту.
Plugin рушія контексту
Plugin рушія контексту керують оркестрацією контексту сеансу для приймання, складання та Compaction. Зареєструйте їх зі свого Plugin за допомогоюapi.registerContextEngine(id, factory), а потім виберіть активний рушій через plugins.slots.contextEngine.
Використовуйте це, коли ваш Plugin має замінити або розширити типовий конвеєр контексту, а не лише додати пошук у пам’яті чи перехоплювачі.
ctx надає необов’язкові значення config, agentDir і workspaceDir для ініціалізації під час створення.
assemble() може повертати contextProjection, коли активне середовище має постійний серверний потік. Не вказуйте його для застарілої проєкції на кожен хід. Повертайте { mode: "thread_bootstrap", epoch }, коли зібраний контекст потрібно один раз упровадити в серверний потік і повторно використовувати, доки не зміниться епоха. Змінюйте епоху після зміни семантичного контексту рушія, наприклад після проходу Compaction, яким керує рушій. Хости можуть зберігати метадані викликів інструментів, форму вхідних даних і відредаговані результати інструментів у проєкції початкового завантаження потоку, щоб нові серверні потоки зберігали безперервність роботи інструментів без копіювання необроблених даних, що містять секрети.
Якщо ваш рушій не володіє алгоритмом Compaction, залиште compact() реалізованим і явно делегуйте його:
Додавання нової можливості
Коли Plugin потребує поведінки, яка не вписується в поточний API, не обходьте систему Plugin за допомогою приватного прямого доступу. Додайте відсутню можливість. Рекомендована послідовність:- Визначте контракт ядра. Вирішіть, за яку спільну поведінку має відповідати ядро: політику, резервний варіант, об’єднання конфігурації, життєвий цикл, семантику для каналів і форму допоміжних засобів середовища виконання.
- Додайте типізовані поверхні реєстрації Plugin і середовища виконання. Розширте
OpenClawPluginApiта/абоapi.runtimeнайменшою корисною типізованою поверхнею можливості. - Під’єднайте ядро та споживачів каналів/функцій. Канали й Plugin функцій мають використовувати нову можливість через ядро, а не імпортувати реалізацію постачальника безпосередньо.
- Зареєструйте реалізації постачальників. Потім Plugin постачальників реєструють свої серверні реалізації для цієї можливості.
- Додайте покриття контракту. Додайте тести, щоб структура володіння та реєстрації залишалася явною з часом.
Контрольний список можливості
Коли ви додаєте нову можливість, реалізація зазвичай має одночасно охоплювати такі поверхні:- типи контракту ядра в
src/<capability>/types.ts - засіб виконання ядра або допоміжний засіб середовища виконання в
src/<capability>/runtime.ts - поверхню реєстрації API Plugin у
src/plugins/types.ts - під’єднання реєстру Plugin у
src/plugins/registry.ts - надання середовища виконання Plugin у
src/plugins/runtime/*, коли Plugin функцій або каналів мають його використовувати - допоміжні засоби захоплення/тестування в
src/test-utils/plugin-registration.ts - перевірки володіння/контракту в
src/plugins/contracts/registry.ts - документацію для операторів/Plugin у
docs/
Шаблон можливості
Мінімальний шаблон:src/plugins/contracts/registry.ts надає засоби пошуку
володіння, як-от providerContractPluginIds; тести перевіряють, що список
contracts.videoGenerationProviders Plugin відповідає тому, що він фактично реєструє):
- ядро відповідає за контракт можливості та оркестрацію
- Plugin постачальників відповідають за реалізації постачальників
- Plugin функцій/каналів використовують допоміжні засоби середовища виконання
- тести контрактів зберігають володіння явним
Пов’язані матеріали
- Архітектура Plugin — публічна модель і форми можливостей
- Підшляхи SDK Plugin
- Налаштування SDK Plugin
- Створення Plugin