Конвейер загрузки
При запуске OpenClaw выполняет примерно следующее:- обнаруживает корневые каталоги потенциальных плагинов
- читает нативные или совместимые манифесты пакетов и метаданные пакетов
- отклоняет небезопасные кандидаты
- нормализует конфигурацию плагинов (
plugins.enabled,allow,deny,entries,slots,load.paths) - определяет, следует ли включить каждого кандидата
- загружает включённые нативные модули: собранные встроенные модули используют нативный загрузчик; сторонний локальный исходный код TypeScript использует аварийный резервный механизм Jiti
- вызывает нативные перехватчики
register(api)и собирает регистрации в реестре плагинов - предоставляет реестр командам и поверхностям среды выполнения
activate — устаревший псевдоним для register: загрузчик разрешает присутствующий вариант (def.register ?? def.activate) и вызывает его в той же точке. Все встроенные плагины используют register; для новых плагинов предпочитайте register.- его разрешённая точка входа находится за пределами корня плагина
- его путь (или корневой каталог) доступен для записи всем пользователям
- для невстроенных плагинов владелец пути не соответствует текущему uid (или root)
chmod (при установке через npm или глобально каталоги
пакетов могут поставляться с правами 0777), после чего проверка выполняется
повторно; для встроенного источника проверка владельца полностью пропускается.
Заблокированные кандидаты всё равно содержат идентификатор плагина в выдаваемой диагностике,
если он известен (включая идентификаторы, полученные из манифеста внутри каталога,
отклонённого по другой причине), поэтому конфигурация, ссылающаяся на такой идентификатор,
получает заблокированный плагин с предупреждением о безопасности пути вместо несвязанной
ошибки «неизвестный плагин».
Приоритет манифеста
Манифест — источник истины уровня управления. OpenClaw использует его, чтобы:- идентифицировать плагин
- обнаруживать объявленные каналы, Skills, схему конфигурации или возможности пакета
- проверять
plugins.entries.<id>.config - дополнять подписи и заполнители Control UI
- показывать метаданные установки и каталога
- сохранять недорогие дескрипторы активации и настройки без загрузки среды выполнения плагина
activation и setup остаются на уровне управления.
Это исключительно метаданные для планирования активации и обнаружения настройки;
они не заменяют регистрацию среды выполнения, register(...) или setupEntry.
Активные потребители активации используют подсказки манифеста о командах, каналах и провайдерах,
чтобы сузить загрузку плагинов до более широкой материализации реестра:
- загрузка CLI ограничивается плагинами, которым принадлежит запрошенная основная команда
- настройка канала и разрешение плагина ограничиваются плагинами, которым принадлежит запрошенный идентификатор канала
- явная настройка провайдера и его разрешение во время выполнения ограничиваются плагинами, которым принадлежит запрошенный идентификатор провайдера
- планирование запуска Gateway использует
activation.onStartupдля явных импортов при запуске; плагины без метаданных запуска загружаются только через более узкие триггеры активации
activation.* от резервного определения по владению из манифеста:
Это разделение причин служит границей совместимости: существующие метаданные плагинов
продолжают работать, а новый код может обнаруживать широкие подсказки или резервное поведение,
не изменяя семантику загрузки среды выполнения.
Предварительные загрузки среды выполнения во время запроса, запрашивающие широкую область
all, всё равно формируют явный эффективный набор идентификаторов плагинов из
конфигурации, планирования запуска, настроенных каналов, слотов и правил автоматического включения
(resolveEffectivePluginIds в src/plugins/effective-plugin-ids.ts). Если этот
производный набор пуст, OpenClaw оставляет область пустой, а не расширяет её
до всех обнаруживаемых плагинов.
Обнаружение настройки предпочитает принадлежащие дескрипторам идентификаторы, такие как
setup.providers и setup.cliBackends, чтобы сузить список плагинов-кандидатов перед переходом
к резервному setup-api для плагинов, которым по-прежнему нужны перехватчики среды
выполнения во время настройки. Списки настройки провайдеров используют providerAuthChoices
из манифеста, полученные из дескрипторов варианты настройки и метаданные каталога установки
без загрузки среды выполнения провайдера. Явный setup.requiresRuntime: false служит порогом только
для дескрипторов; если requiresRuntime отсутствует, для совместимости сохраняется
устаревший резервный механизм setup-api. Если более одного обнаруженного плагина заявляет
один и тот же нормализованный идентификатор провайдера настройки или серверной части CLI,
поиск настройки отклоняет неоднозначного владельца вместо зависимости от порядка обнаружения.
Когда среда выполнения настройки всё же запускается, диагностика реестра сообщает о расхождениях
между setup.providers / setup.cliBackends и провайдерами или серверными частями CLI,
фактически зарегистрированными через setup-api, не блокируя устаревшие плагины.
Граница кеширования плагинов
OpenClaw не кеширует результаты обнаружения плагинов или непосредственные данные реестра манифестов на основе временных окон. Установки, изменения манифестов и путей загрузки должны становиться видимыми при следующем явном чтении метаданных или перестроении снимка. Парсер файла манифеста поддерживает ограниченный кеш сигнатур файлов, ключом которого служат путь к открытому манифесту, устройство и inode, размер, а также mtime/ctime; этот кеш лишь предотвращает повторный разбор неизменённых байтов и не должен кешировать результаты обнаружения, реестр, владельцев или решения политик. Безопасный быстрый путь метаданных основан на явном владении объектами, а не на скрытом кеше. Горячие пути запуска Gateway должны передавать текущийPluginMetadataSnapshot,
производный PluginLookUpTable или явный реестр манифестов по цепочке вызовов.
Проверка конфигурации, автоматическое включение при запуске, начальная загрузка плагинов
и выбор провайдера могут повторно использовать эти объекты, пока они представляют текущую
конфигурацию и набор плагинов. Поиск настройки всё равно воссоздаёт метаданные манифеста
по требованию, если конкретный путь настройки не получает явный реестр манифестов; сохраняйте
это как резервный механизм холодного пути, а не добавляйте скрытые кеши поиска. При изменении
входных данных перестраивайте и заменяйте снимок, не изменяя его на месте и не сохраняя
исторические копии. Представления активного реестра плагинов и вспомогательные средства
начальной загрузки встроенных каналов следует пересчитывать из текущего реестра/корня.
Краткоживущие отображения допустимы внутри одного вызова для устранения повторной работы
или защиты от повторного входа; они не должны превращаться в кеши метаданных процесса.
Для загрузки плагинов постоянным уровнем кеширования служит загрузка среды выполнения.
Он может повторно использовать состояние загрузчика, когда код или установленные артефакты
действительно загружаются, например:
PluginLoaderCacheStateи совместимые активные реестры среды выполнения- кеши jiti/модулей и кеши загрузчика публичных поверхностей, позволяющие избежать повторного импорта одной и той же поверхности среды выполнения
- кеши файловой системы для артефактов установленных плагинов
- краткоживущие отображения на время вызова для нормализации путей или устранения дубликатов
- результатов обнаружения
- непосредственных реестров манифестов
- реестров манифестов, воссозданных из индекса установленных плагинов
- поиска владельца провайдера, подавления моделей, политики провайдера или метаданных публичных артефактов
- любых других ответов, полученных из манифеста, для которых изменённый манифест, индекс установленных компонентов или путь загрузки должен быть виден при следующем чтении метаданных
Модель реестра
Загруженные плагины не изменяют напрямую произвольные глобальные объекты ядра. Они регистрируются в центральном реестре плагинов (PluginRegistry в src/plugins/registry-types.ts),
который отслеживает записи плагинов (идентичность, источник, происхождение, состояние, диагностику),
а также массивы для каждой возможности: инструменты, устаревшие и типизированные перехватчики,
каналы, провайдеры, обработчики RPC Gateway, HTTP-маршруты, регистраторы CLI,
фоновые службы, принадлежащие плагинам команды и множество других типизированных семейств
провайдеров (речь, векторные представления, генерация изображений, видео и музыки,
получение данных и поиск в интернете, среды агентов, действия сеансов и т. д.).
Затем основные функции читают данные из этого реестра, а не взаимодействуют с модулями
плагинов напрямую. Благодаря этому загрузка остаётся однонаправленной:
- модуль плагина -> регистрация в реестре
- среда выполнения ядра -> использование реестра
Обратные вызовы привязки беседы
Плагины, привязывающие беседу, могут реагировать на результат запроса подтверждения. Используйтеapi.onConversationBindingResolved(...), чтобы получить обратный вызов после
одобрения или отклонения запроса на привязку:
status:"approved"или"denied"decision:"allow-once","allow-always"или"deny"binding: разрешённая привязка для одобренных запросовrequest: исходная сводка запроса, подсказка отсоединения, идентификатор отправителя и метаданные беседы
Перехватчики среды выполнения провайдера
Плагины провайдеров состоят из трёх уровней:- Метаданные манифеста для быстрого и нетребовательного поиска до запуска:
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 сначала проверяют
соответствующий плагин провайдера, а затем последовательно обращаются к другим плагинам
провайдеров, поддерживающим хуки, пока один из них фактически не изменит идентификатор модели
или транспорт/конфигурацию. Это позволяет псевдонимам и совместимым адаптерам провайдеров
работать без необходимости для вызывающей стороны знать, какой встроенный плагин отвечает
за преобразование. Если ни один хук провайдера не преобразует поддерживаемую запись
конфигурации семейства Google, встроенный нормализатор конфигурации Google всё равно выполнит
эту очистку для обеспечения совместимости.
Если провайдеру требуется полностью собственный протокол передачи данных или собственный
исполнитель запросов, это другой класс расширения. Эти хуки предназначены для поведения
провайдера, которое по-прежнему выполняется в стандартном цикле инференса OpenClaw.
resolveUsageAuth определяет, должен ли OpenClaw вызвать fetchUsageSnapshot или
перейти к универсальному разрешению учётных данных для поверхностей использования/состояния.
Возвращайте { token, accountId?, subscriptionType?, rateLimitTier? }, когда у провайдера
есть учётные данные для получения сведений об использовании (необязательные метаданные тарифа
передаются в fetchUsageSnapshot); возвращайте
{ handled: true }, когда принадлежащая провайдеру авторизация для получения сведений
об использовании обработала запрос и должна отключить универсальный резервный механизм
API-ключа/OAuth; возвращайте null или undefined,
когда провайдер не обработал авторизацию для получения сведений об использовании.
Объявляйте учётные данные организации или биллинга в манифесте
providerUsageAuthEnvVars. Это позволяет универсальным механизмам обнаружения и удаления секретов
распознавать их, не делая кандидатами на авторизацию инференса.
Пример провайдера
Встроенные примеры
Встроенные плагины провайдеров сочетают приведённые выше хуки с учётом требований каждого поставщика к каталогу, авторизации, рассуждению, повторному воспроизведению и сведениям об использовании. Авторитетный набор хуков находится в каждом плагине в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, вместо того чтобы каждый плагин
заново реализовывал очистку.Провайдеры только с каталогом
Провайдеры только с каталогом
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 плагина Anthropic
(wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier), а не в
универсальном SDK.Вспомогательные средства среды выполнения
Плагины могут обращаться к избранным вспомогательным средствам ядра черезapi.runtime. Для TTS:
textToSpeechвозвращает стандартную полезную нагрузку результата TTS ядра для поверхностей файлов/голосовых заметок.- Использует конфигурацию ядра
messages.ttsи выбор провайдера. - Возвращает буфер аудио PCM и частоту дискретизации. Плагины должны передискретизировать/кодировать данные для провайдеров.
listVoicesявляется необязательным для каждого провайдера. Используйте его для принадлежащих поставщику средств выбора голоса или процессов настройки.- Ядро передаёт рассчитанный крайний срок запроса в хуки провайдера
listVoices; настройки тайм-аута конкретного провайдера могут его переопределить. - Списки голосов могут содержать более подробные метаданные, такие как локаль, пол и теги характера, для средств выбора с учётом провайдера.
- OpenAI и ElevenLabs сейчас поддерживают телефонию. Microsoft — нет.
api.registerSpeechProvider(...).
- Сохраняйте политику TTS, резервный механизм и доставку ответов в ядре.
- Используйте провайдеров синтеза речи для принадлежащего поставщику поведения синтеза.
- Устаревший вход Microsoft
edgeнормализуется в идентификатор провайдераmicrosoft. - Предпочтительная модель владения ориентирована на компанию: один плагин поставщика может управлять провайдерами текста, речи, изображений и будущих типов мультимедиа по мере добавления OpenClaw соответствующих контрактов возможностей.
- Сохраняйте оркестрацию, резервный механизм, конфигурацию и подключение каналов в ядре.
- Сохраняйте поведение поставщика в плагине провайдера.
- Аддитивное расширение должно оставаться типизированным: новые необязательные методы, новые необязательные поля результатов, новые необязательные возможности.
- Генерация видео уже следует тому же шаблону:
- ядро управляет контрактом возможностей и вспомогательным средством среды выполнения
- плагины поставщиков регистрируют
api.registerVideoGenerationProvider(...) - плагины функций/каналов используют
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*— предпочтительная общая поверхность для анализа изображений/аудио/видео.extractStructuredWithModel(...)— доступный плагинам интерфейс для ограниченного извлечения, принадлежащего провайдеру и ориентированного прежде всего на изображения. Включайте хотя бы один вход изображения; текстовые входы служат дополнительным контекстом. Продуктовые плагины управляют своими маршрутами и схемами, а OpenClaw — границей провайдера и среды выполнения.- Использует аудиоконфигурацию анализа мультимедиа ядра (
tools.media.audio) и порядок резервного выбора провайдеров. - Возвращает
{ text: undefined }, если результат транскрибирования не создан (например, вход пропущен/не поддерживается). api.runtime.stt.transcribeAudioFile(...)сохраняется как псевдоним совместимости.
api.runtime.subagent:
providerиmodel— необязательные переопределения для отдельного выполнения, а не постоянные изменения сеанса.- OpenClaw учитывает эти поля переопределения только для доверенных вызывающих сторон.
- Для принадлежащих плагину резервных выполнений операторы должны явно включить их с помощью
plugins.entries.<id>.subagent.allowModelOverride: true. - Используйте
plugins.entries.<id>.subagent.allowedModels, чтобы ограничить доверенные плагины конкретными каноническими целямиprovider/model, либо"*", чтобы явно разрешить любую цель. - Выполнения подагентов недоверенных плагинов по-прежнему работают, но запросы на переопределение отклоняются вместо неявного перехода к резервному варианту.
- Сеансы подагентов, созданные плагином, помечаются идентификатором создавшего их плагина. Резервный механизм
api.runtime.subagent.deleteSession(...)может удалять только эти принадлежащие ему сеансы; для удаления произвольных сеансов по-прежнему требуется запрос к Gateway с областью администратора.
api.registerWebSearchProvider(...).
Примечания:
- Сохраняйте выбор провайдера, разрешение учётных данных и общую семантику запросов в ядре.
- Используйте провайдеров веб-поиска для специфичных для поставщика транспортов поиска.
api.runtime.webSearch.*— предпочтительная общая поверхность для плагинов функций/каналов, которым требуется поведение поиска без зависимости от оболочки инструмента агента.
api.runtime.imageGeneration
generate(...): создать изображение с помощью настроенной цепочки провайдеров генерации изображений.listProviders(...): вывести список доступных провайдеров генерации изображений и их возможностей.
HTTP-маршруты Gateway
Плагины могут предоставлять HTTP-конечные точки с помощьюapi.registerHttpRoute(...).
path: путь маршрута на HTTP-сервере Gateway.auth: обязательное поле,"gateway"или"plugin". Используйте"gateway", чтобы требовать обычную аутентификацию Gateway, или"plugin"для управляемой плагином аутентификации либо проверки Webhook.match: необязательное поле."exact"(по умолчанию) или"prefix".handleUpgrade: необязательный обработчик запросов обновления соединения до WebSocket на том же маршруте.replaceExisting: необязательное поле. Позволяет тому же плагину заменить собственную существующую регистрацию маршрута.handler: вернитеtrue, если маршрут обработал запрос.
api.registerHttpHandler(...)удалён и вызовет ошибку загрузки плагина. Вместо него используйтеapi.registerHttpRoute(...).- Маршруты плагина должны явно объявлять
auth. - Конфликты точных значений
path + matchотклоняются, если не заданоreplaceExisting: true; один плагин не может заменить маршрут другого плагина. - Перекрывающиеся маршруты с разными уровнями
authотклоняются. Цепочки переходаexact/prefixдолжны использовать только один уровень аутентификации. - Маршруты
auth: "plugin"не получают области доступа среды выполнения оператора автоматически. Они предназначены для управляемых плагином Webhook и проверки подписей, а не для привилегированных вызовов вспомогательных функций 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 возвращает
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/config, не должны материализовывать учётные данные среды выполнения только для того, чтобы описать конфигурацию.
inspectAccount(...):
- Возвращайте только описательное состояние учётной записи.
- Сохраняйте
enabledиconfigured. - При необходимости включайте поля источника и состояния учётных данных, например:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- Для сообщения о доступности в режиме только для чтения не нужно возвращать необработанные значения токенов.
Для команд, отображающих состояние, достаточно вернуть
tokenStatus: "available"(и соответствующее поле источника). - Используйте
configured_unavailable, когда учётные данные настроены через SecretRef, но недоступны в текущем пути команды.
Пакеты плагинов
Каталог плагина может содержатьpackage.json с openclaw.extensions:
<manifestOrPackageName>/<fileBase> (при наличии приоритет имеет идентификатор манифеста;
в противном случае используется имя package.json без области).
Если ваш плагин импортирует зависимости npm, установите их в этом каталоге, чтобы
node_modules был доступен (npm install / pnpm install).
Ограничение безопасности: после разрешения символических ссылок каждая запись openclaw.extensions должна оставаться внутри каталога
плагина. Записи, выходящие за пределы каталога пакета,
отклоняются.
Примечание по безопасности: openclaw plugins install устанавливает зависимости плагина с помощью
локального для проекта npm install --omit=dev --ignore-scripts (без сценариев жизненного цикла
и без зависимостей для разработки во время выполнения), игнорируя унаследованные глобальные настройки установки npm.
Поддерживайте деревья зависимостей плагина в виде «чистого JS/TS» и избегайте пакетов, которым требуются
сборки postinstall.
Необязательно: openclaw.setupEntry может указывать на облегчённый модуль только для настройки.
Когда OpenClaw требуются поверхности настройки для отключённого плагина канала или
когда плагин канала включён, но ещё не настроен, загружается setupEntry
вместо полной точки входа плагина. Это снижает нагрузку при запуске и настройке,
если основная точка входа плагина также подключает инструменты, хуки или другой код,
используемый только во время выполнения.
Необязательно: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
может включить для плагина канала тот же путь setupEntry на этапе запуска Gateway
до начала прослушивания, даже если канал уже настроен.
Используйте это только тогда, когда setupEntry полностью покрывает поверхность запуска, которая должна существовать
до того, как Gateway начнёт прослушивание. На практике это означает, что точка входа настройки
должна регистрировать все принадлежащие каналу возможности, от которых зависит запуск, например:
- саму регистрацию канала
- все HTTP-маршруты, которые должны быть доступны до начала прослушивания Gateway
- все методы Gateway, инструменты или службы, которые должны существовать в течение того же периода
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.*, не загружая полную точку входа плагина.
Текущим встроенным примером служит Matrix: при наличии именованных учётных записей он переносит
в именованную преобразованную учётную запись только ключи аутентификации и начальной загрузки, а также может сохранить
настроенный неканонический ключ учётной записи по умолчанию вместо безусловного создания
accounts.default.
Эти адаптеры исправлений настройки сохраняют ленивое обнаружение встроенной поверхности контракта.
Импорт остаётся лёгким; поверхность преобразования загружается только при первом использовании,
а не повторно запускает встроенный канал при импорте модуля.
Если эти поверхности запуска включают RPC-методы Gateway, используйте для них
префикс конкретного плагина. Административные пространства имён ядра (config.*,
exec.approvals.*, wizard.*, update.*) остаются зарезервированными и всегда разрешаются
в operator.admin, даже если плагин запрашивает более узкую область.
Пример:
Метаданные каталога каналов
Плагины каналов могут публиковать метаданные настройки и обнаружения черезopenclaw.channel,
а подсказки по установке — через openclaw.install. Благодаря этому каталог ядра не содержит данных.
Пример:
openclaw.channel помимо минимального примера:
detailLabel: дополнительная метка для более информативных поверхностей каталога и состоянияdocsLabel: переопределение текста ссылки на документациюpreferOver: идентификаторы плагинов или каналов с более низким приоритетом, которые эта запись каталога должна опережатьselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: параметры текста поверхности выбораmarkdownCapable: отмечает, что канал поддерживает Markdown, для принятия решений о форматировании исходящих сообщенийexposure.configured: скрывает канал из поверхностей списка настроенных каналов, если задано значениеfalseexposure.setup: скрывает канал из интерактивных списков выбора при настройке и конфигурировании, если задано значениеfalseexposure.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 как добавочное необязательное поле, чтобы
созданным вручную записям и адаптерам каталога не требовалось его синтезировать.
Это позволяет процессам первичной настройки и диагностики объяснять состояние уровня источников,
не импортируя среду выполнения плагина.
Официальным внешним записям npm следует предпочитать точный npmSpec вместе с
expectedIntegrity. Простые имена пакетов и dist-tags по-прежнему работают для
совместимости, но вызывают предупреждения уровня источников, чтобы каталог мог перейти
к закреплённым установкам с проверкой целостности без нарушения работы существующих плагинов.
При установке в процессе первичной настройки из локального пути каталога создаётся управляемая запись
индекса плагинов с source: "path" и, когда это возможно, относительным к рабочей области
sourcePath. Абсолютный рабочий путь загрузки остаётся в
plugins.load.paths; запись установки не дублирует пути локальной рабочей станции
в долгоживущей конфигурации. Благодаря этому локальные установки для разработки остаются видимыми
диагностике уровня источников без добавления второй поверхности раскрытия необработанного пути файловой системы.
Сохранённая таблица SQLite installed_plugin_index является источником истины для установки
и может обновляться без загрузки модулей среды выполнения плагина.
Её карта installRecords сохраняется, даже если манифест плагина отсутствует или
недействителен; её содержимое plugins представляет собой восстанавливаемое представление манифеста.
Плагины движка контекста
Плагины движка контекста управляют оркестрацией контекста сеанса для приёма, сборки и Compaction. Зарегистрируйте их из своего плагина с помощьюapi.registerContextEngine(id, factory), затем выберите активный движок с помощью
plugins.slots.contextEngine.
Используйте это, когда вашему плагину требуется заменить или расширить стандартный конвейер
контекста, а не просто добавить поиск по памяти или хуки.
ctx предоставляет необязательные значения config, agentDir и workspaceDir
для инициализации во время создания.
assemble() может возвращать contextProjection, когда активная среда выполнения использует
постоянный серверный поток. Не указывайте его для устаревшей проекции на каждый ход. Возвращайте
{ mode: "thread_bootstrap", epoch }, когда собранный контекст следует
однократно внедрить в серверный поток и повторно использовать до изменения эпохи. Изменяйте
эпоху после изменения семантического контекста движка, например после
прохода Compaction, выполняемого движком. Хосты могут сохранять метаданные вызовов инструментов, форму
ввода и отредактированные результаты инструментов в проекции инициализации потока, чтобы новые
серверные потоки сохраняли непрерывность работы с инструментами без копирования исходных полезных
нагрузок, содержащих секреты.
Если ваш движок не владеет алгоритмом Compaction, оставьте compact()
реализованным и явно делегируйте его:
Добавление новой возможности
Когда плагину требуется поведение, не соответствующее текущему API, не обходите систему плагинов через приватный прямой доступ. Добавьте недостающую возможность. Рекомендуемая последовательность:- Определите контракт ядра. Решите, за какое общее поведение должно отвечать ядро: политики, резервное поведение, объединение конфигурации, жизненный цикл, семантику для каналов и форму вспомогательных функций среды выполнения.
- Добавьте типизированные поверхности регистрации и среды выполнения плагинов. Расширьте
OpenClawPluginApiи/илиapi.runtimeминимальной полезной типизированной поверхностью возможности. - Подключите ядро и потребителей в каналах и функциональных плагинах. Каналы и функциональные плагины должны использовать новую возможность через ядро, а не импортировать реализацию поставщика напрямую.
- Зарегистрируйте реализации поставщиков. Затем плагины поставщиков регистрируют свои серверные реализации для этой возможности.
- Добавьте проверку контракта. Добавьте тесты, чтобы принадлежность и форма регистрации со временем оставались явными.
Контрольный список возможности
При добавлении новой возможности реализация обычно должна одновременно затрагивать следующие поверхности:- типы контракта ядра в
src/<capability>/types.ts - исполнитель или вспомогательную функцию среды выполнения ядра в
src/<capability>/runtime.ts - поверхность регистрации API плагина в
src/plugins/types.ts - подключение реестра плагинов в
src/plugins/registry.ts - предоставление среды выполнения плагина в
src/plugins/runtime/*, когда функциональным или канальным плагинам необходимо её использовать - вспомогательные средства захвата и тестирования в
src/test-utils/plugin-registration.ts - проверки принадлежности и контракта в
src/plugins/contracts/registry.ts - документацию для операторов и разработчиков плагинов в
docs/
Шаблон возможности
Минимальный шаблон:src/plugins/contracts/registry.ts предоставляет средства поиска
принадлежности, такие как providerContractPluginIds; тесты проверяют, что список
contracts.videoGenerationProviders плагина соответствует тому, что он фактически регистрирует):
- ядро отвечает за контракт возможности и оркестрацию
- плагины поставщиков отвечают за реализации поставщиков
- функциональные и канальные плагины используют вспомогательные функции среды выполнения
- тесты контрактов явно фиксируют принадлежность
Связанные материалы
- Архитектура плагинов — общедоступная модель возможностей и структуры
- Подпути SDK плагинов
- Настройка SDK плагинов
- Разработка плагинов