Якщо ви ще не створювали жодного Plugin OpenClaw, спочатку прочитайте
Початок роботи, щоб дізнатися базову структуру
пакета й налаштування маніфесту.
Покроковий огляд
Пакет і маніфест
Крок 1: Пакет і маніфест
setup.providers[].envVars, щоб OpenClaw міг виявляти
облікові дані без завантаження середовища виконання вашого Plugin. Додайте providerAuthAliases,
коли варіант провайдера має повторно використовувати автентифікацію іншого ідентифікатора провайдера. modelSupport
необов’язковий і дає OpenClaw змогу автоматично завантажувати ваш Plugin провайдера зі скорочених
ідентифікаторів моделей на кшталт acme-large до появи хуків середовища виконання. Якщо ви публікуєте
провайдера в ClawHub, ці поля openclaw.compat і openclaw.build
обов’язкові в package.json.Зареєструйте провайдера
Мінімальному текстовому провайдеру потрібні Використовуйте
id, label, auth і catalog.
catalog — це хук середовища виконання/конфігурації, яким володіє провайдер; він може викликати живі
API постачальника й повертає записи models.providers.index.ts
registerModelCatalogProvider — це новіша поверхня каталогу площини керування
для списку/довідки/інтерфейсу вибору. Використовуйте її для рядків тексту, генерації зображень,
генерації відео й генерації музики. Тримайте виклики кінцевих точок постачальника та
зіставлення відповідей у Plugin; OpenClaw володіє спільною формою рядків, мітками
джерел і рендерингом довідки.Це вже робочий провайдер. Тепер користувачі можуть виконати
openclaw onboard --acme-ai-api-key <key> і вибрати
acme-ai/acme-large як свою модель.Виявлення живих моделей
Якщо ваш провайдер надає API у стилі/models, тримайте специфічну для провайдера
кінцеву точку та проєкцію рядків у вашому Plugin і використовуйте
openclaw/plugin-sdk/provider-catalog-live-runtime для спільного життєвого циклу
отримання даних. Помічник дає захищені HTTP-запити, заголовки автентифікації провайдера,
структуровані HTTP-помилки, кешування TTL і статичну резервну поведінку без
розміщення політик провайдера в ядрі OpenClaw.Використовуйте buildLiveModelProviderConfig, коли живий API лише повідомляє, які
статичні рядки каталогу, якими володіє провайдер, наразі доступні:index.ts
getCachedLiveProviderModelRows, коли API провайдера повертає багатші
метадані, а Plugin має самостійно проєктувати рядки у визначення моделей
OpenClaw:index.ts
run має залишатися захищеним автентифікацією і повертати null, коли немає придатних
облікових даних. Залиште офлайн-staticRun або статичний резервний варіант, щоб налаштування, документація,
тести й поверхні вибору не залежали від доступу до живої мережі. Використовуйте TTL,
доречний для актуальності списку моделей, уникайте опитування файлової системи під час запиту
й передавайте специфічні для провайдера readRows / readModelId лише тоді, коли
відповідь upstream не має OpenAI-сумісної форми { data: [{ id, object }] }.Якщо upstream-провайдер використовує інші керівні токени, ніж OpenClaw, додайте
невелике двонапрямне текстове перетворення замість заміни шляху потоку:input переписує фінальний системний промпт і текстовий вміст повідомлення перед
транспортуванням. output переписує текстові дельти асистента й фінальний текст перед тим,
як OpenClaw розбере власні керівні маркери або доставку каналом.Для вбудованих провайдерів, які реєструють лише одного текстового провайдера з автентифікацією
через API-ключ плюс одне середовище виконання на основі каталогу, віддавайте перевагу вужчому
помічнику defineSingleProviderPluginEntry(...):buildProvider - це шлях живого каталогу, який використовується, коли OpenClaw може визначити справжню
автентифікацію постачальника. Він може виконувати специфічне для постачальника виявлення. Використовуйте
buildStaticProvider лише для офлайн-рядків, які безпечно показувати до налаштування автентифікації;
він не повинен вимагати облікових даних або виконувати мережеві запити.
Відображення models list --all в OpenClaw наразі виконує статичні каталоги
лише для вбудованих плагінів постачальників, із порожньою конфігурацією, порожнім env і без
шляхів агента/робочого простору.Якщо ваш потік автентифікації також має виправляти models.providers.*, псевдоніми та
модель агента за замовчуванням під час онбордингу, використовуйте preset-помічники з
openclaw/plugin-sdk/provider-onboard. Найвужчі помічники:
createDefaultModelPresetAppliers(...),
createDefaultModelsPresetAppliers(...) і
createModelCatalogPresetAppliers(...).Коли нативний endpoint постачальника підтримує потокові блоки використання у
звичайному транспорті openai-completions, віддавайте перевагу спільним помічникам каталогу в
openclaw/plugin-sdk/provider-catalog-shared замість жорстко закодованих
перевірок provider-id. supportsNativeStreamingUsageCompat(...) і
applyProviderNativeStreamingUsageCompat(...) визначають підтримку з
мапи можливостей endpoint, тож нативні endpoint у стилі Moonshot/DashScope все одно
вмикаються, навіть коли плагін використовує власний provider id.Наведені вище приклади живого виявлення охоплюють provider API у стилі /models. Тримайте
це виявлення всередині catalog.run, обмеженим придатною автентифікацією, і залишайте
staticRun без мережевих запитів для офлайн-генерації каталогу.Додайте динамічне визначення моделей
Якщо ваш постачальник приймає довільні model ID (як проксі або router),
додайте Якщо визначення потребує мережевого виклику, використовуйте
resolveDynamicModel:prepareDynamicModel для асинхронного
прогріву - resolveDynamicModel запускається знову після його завершення.Додайте runtime hooks (за потреби)
Більшості постачальників потрібні лише Доступні сьогодні replay-сімейства:
Доступні сьогодні stream-сімейства:
catalog + resolveDynamicModel. Додавайте hooks
поступово, коли ваш постачальник їх потребуватиме.Спільні builder-помічники тепер охоплюють найпоширеніші сімейства replay/tool-compat,
тому плагінам зазвичай не потрібно під’єднувати кожен hook вручну по одному:| Сімейство | Що воно під’єднує | Вбудовані приклади |
|---|---|---|
openai-compatible | Спільна replay-політика у стилі OpenAI для OpenAI-compatible транспортів, включно з очищенням tool-call-id, виправленнями порядку assistant-first і загальною валідацією Gemini-turn там, де це потрібно транспорту | moonshot, ollama, xai, zai |
anthropic-by-model | Replay-політика з урахуванням Claude, вибрана за modelId, тому транспорти Anthropic-message отримують специфічне для Claude очищення thinking-block лише тоді, коли визначена модель справді має Claude id | amazon-bedrock, anthropic-vertex |
google-gemini | Нативна replay-політика Gemini плюс bootstrap-очищення replay. Спільне сімейство залишає text-output Gemini CLI на tagged reasoning; прямий постачальник google перевизначає resolveReasoningOutputMode на native, оскільки thinking Gemini API надходить як нативні thought parts. | google, google-gemini-cli |
passthrough-gemini | Очищення thought-signature Gemini для моделей Gemini, що працюють через OpenAI-compatible проксі-транспорти; не вмикає нативну replay-валідацію Gemini або bootstrap-переписування | openrouter, kilocode, opencode, opencode-go |
hybrid-anthropic-openai | Гібридна політика для постачальників, які поєднують поверхні моделей Anthropic-message та OpenAI-compatible в одному плагіні; необов’язкове видалення thinking-block лише для Claude залишається обмеженим стороною Anthropic | minimax |
| Сімейство | Що воно під’єднує | Вбудовані приклади |
|---|---|---|
google-thinking | Нормалізація thinking payload Gemini на спільному stream-шляху | google, google-gemini-cli |
kilocode-thinking | Обгортка reasoning Kilo на спільному proxy stream-шляху, де kilo/auto і непідтримувані proxy reasoning id пропускають injected thinking | kilocode |
moonshot-thinking | Мапінг бінарного native-thinking payload Moonshot з конфігурації + рівня /think | moonshot |
minimax-fast-mode | Переписування моделі MiniMax fast-mode на спільному stream-шляху | minimax, minimax-portal |
openai-responses-defaults | Спільні нативні обгортки OpenAI/Codex Responses: attribution headers, /fast/serviceTier, text verbosity, нативний вебпошук Codex, формування reasoning-compat payload і керування контекстом Responses | openai |
openrouter-thinking | Обгортка reasoning OpenRouter для proxy routes, з централізованою обробкою пропусків unsupported-model/auto | openrouter |
tool-stream-default-on | Обгортка tool_stream, увімкнена за замовчуванням, для постачальників на кшталт Z.AI, яким потрібен tool streaming, якщо його явно не вимкнено | zai |
SDK-шви, що живлять family builders
SDK-шви, що живлять family builders
Кожен family builder складено з низькорівневих публічних помічників, експортованих із того самого пакета; до них можна звернутися, коли постачальнику потрібно відійти від спільного шаблону:
openclaw/plugin-sdk/provider-model-shared-ProviderReplayFamily,buildProviderReplayFamilyHooks(...)і сирі replay builders (buildOpenAICompatibleReplayPolicy,buildAnthropicReplayPolicyForModel,buildGoogleGeminiReplayPolicy,buildHybridAnthropicOrOpenAIReplayPolicy). Також експортує replay-помічники Gemini (sanitizeGoogleGeminiReplayHistory,resolveTaggedReasoningOutputMode) і помічники endpoint/model (resolveProviderEndpoint,normalizeProviderId,normalizeGooglePreviewModelId).openclaw/plugin-sdk/provider-stream-ProviderStreamFamily,buildProviderStreamFamilyHooks(...),composeProviderStreamWrappers(...), а також спільні обгортки OpenAI/Codex (createOpenAIAttributionHeadersWrapper,createOpenAIFastModeWrapper,createOpenAIServiceTierWrapper,createOpenAIResponsesContextManagementWrapper,createCodexNativeWebSearchWrapper), OpenAI-compatible обгортка DeepSeek V4 (createDeepSeekV4OpenAICompatibleThinkingWrapper), очищення Anthropic Messages thinking prefill (createAnthropicThinkingPrefillPayloadWrapper), plain-text tool-call compat (createPlainTextToolCallCompatWrapper) і спільні proxy/provider обгортки (createOpenRouterWrapper,createToolStreamWrapper,createMinimaxFastModeWrapper).openclaw/plugin-sdk/provider-stream-shared- легкі payload- та event-обгортки для гарячих provider paths, включно зcreateOpenAICompatibleCompletionsThinkingOffWrapper,createPayloadPatchStreamWrapper,createPlainTextToolCallCompatWrapper,normalizeOpenAICompatibleReasoningPayload(...)іsetQwenChatTemplateThinking(...).openclaw/plugin-sdk/provider-tools-ProviderToolCompatFamily,buildProviderToolCompatFamilyHooks("deepseek" | "gemini" | "openai")і базові помічники provider schema.
native
reasoning output, щоб OpenClaw споживав нативні thought parts без додавання
prompt-директив <think> / <final>. Text-only бекенди в стилі Gemini CLI,
які парсять фінальну JSON/text-відповідь, можуть зберігати спільний
tagged-контракт google-gemini.Деякі stream-помічники навмисно залишаються локальними для постачальника. @openclaw/anthropic-provider тримає wrapAnthropicProviderStream, resolveAnthropicBetas, resolveAnthropicFastMode, resolveAnthropicServiceTier і нижчорівневі Anthropic wrapper builders у власному публічному шві api.ts / contract-api.ts, бо вони кодують обробку Claude OAuth beta та gating context1m. Плагін xAI аналогічно тримає нативне формування xAI Responses у власному wrapStreamFn (псевдоніми /fast, стандартний tool_stream, очищення unsupported strict-tool, специфічне для xAI вилучення reasoning-payload).Та сама package-root схема також підтримує @openclaw/openai-provider (provider builders, помічники default-model, realtime provider builders) і @openclaw/openrouter-provider (provider builder плюс onboarding/config helpers).- Обмін токена
- Власні заголовки
- Нативна транспортна ідентичність
- Використання та білінг
Для постачальників, яким потрібен обмін токена перед кожним inference-викликом:
Усі доступні хуки провайдера
Усі доступні хуки провайдера
OpenClaw викликає хуки в такому порядку. Більшість провайдерів використовують лише 2-3:
Поля провайдера лише для сумісності, які OpenClaw більше не викликає, як-от
Примітки щодо runtime fallback:
ProviderPlugin.capabilities і suppressBuiltInModel, тут не наведені.| # | Хук | Коли використовувати |
|---|---|---|
| 1 | catalog | Каталог моделей або типові значення базового URL |
| 2 | applyConfigDefaults | Глобальні типові значення, що належать провайдеру, під час матеріалізації конфігурації |
| 3 | normalizeModelId | Очищення застарілих/preview псевдонімів model-id перед пошуком |
| 4 | normalizeTransport | Очищення api / baseUrl сімейства провайдера перед універсальним складанням моделі |
| 5 | normalizeConfig | Нормалізація конфігурації models.providers.<id> |
| 6 | applyNativeStreamingUsageCompat | Перезаписи сумісності native streaming-usage для провайдерів конфігурації |
| 7 | resolveConfigApiKey | Розв’язання auth env-маркерів, що належить провайдеру |
| 8 | resolveSyntheticAuth | Локальний/self-hosted або підкріплений конфігурацією synthetic auth |
| 9 | shouldDeferSyntheticProfileAuth | Зниження пріоритету synthetic placeholders збереженого профілю після env/config auth |
| 10 | resolveDynamicModel | Прийняття довільних upstream ID моделей |
| 11 | prepareDynamicModel | Асинхронне отримання метаданих перед розв’язанням |
| 12 | normalizeResolvedModel | Перезаписи транспорту перед runner |
| 13 | normalizeToolSchemas | Очищення tool-schema, що належить провайдеру, перед реєстрацією |
| 14 | inspectToolSchemas | Діагностика tool-schema, що належить провайдеру |
| 15 | resolveReasoningOutputMode | Контракт reasoning-output з тегами або native |
| 16 | prepareExtraParams | Типові параметри запиту |
| 17 | createStreamFn | Повністю кастомний транспорт StreamFn |
| 19 | wrapStreamFn | Кастомні обгортки headers/body на звичайному stream-шляху |
| 20 | resolveTransportTurnState | Native headers/metadata для кожного turn |
| 21 | resolveWebSocketSessionPolicy | Native WS session headers/cool-down |
| 22 | formatApiKey | Кастомна форма runtime token |
| 23 | refreshOAuth | Кастомне оновлення OAuth |
| 24 | buildAuthDoctorHint | Поради з виправлення auth |
| 25 | matchesContextOverflowError | Виявлення overflow, що належить провайдеру |
| 26 | classifyFailoverReason | Класифікація rate-limit/overload, що належить провайдеру |
| 27 | isCacheTtlEligible | Обмеження TTL кешу prompt |
| 28 | buildMissingAuthMessage | Кастомна підказка щодо відсутнього auth |
| 29 | augmentModelCatalog | Synthetic forward-compat рядки |
| 30 | resolveThinkingProfile | Набір опцій /think для конкретної моделі |
| 31 | isBinaryThinking | Сумісність увімкнення/вимкнення binary thinking |
| 32 | supportsXHighThinking | Сумісність підтримки reasoning xhigh |
| 33 | resolveDefaultThinkingLevel | Сумісність типової політики /think |
| 34 | isModernModelRef | Зіставлення live/smoke моделей |
| 35 | prepareRuntimeAuth | Обмін токена перед inference |
| 36 | resolveUsageAuth | Кастомний розбір облікових даних використання |
| 37 | fetchUsageSnapshot | Кастомний endpoint використання |
| 38 | createEmbeddingProvider | Адаптер embedding, що належить провайдеру, для memory/search |
| 39 | buildReplayPolicy | Кастомна політика replay/compaction транскрипту |
| 40 | sanitizeReplayHistory | Перезаписи replay, специфічні для провайдера, після універсального очищення |
| 41 | validateReplayTurns | Сувора валідація replay-turn перед embedded runner |
| 42 | onModelSelected | Callback після вибору (наприклад, telemetry) |
normalizeConfigспочатку перевіряє зіставленого провайдера, а потім інші provider plugins із підтримкою hooks, доки один із них фактично не змінить конфігурацію. Якщо жоден хук провайдера не переписує підтримуваний запис конфігурації сімейства Google, все одно застосовується вбудований нормалізатор конфігурації Google.resolveConfigApiKeyвикористовує хук провайдера, коли він наданий. Amazon Bedrock тримає розв’язання AWS env-маркерів у своєму provider plugin; сам runtime auth і далі використовує стандартний ланцюжок AWS SDK, коли налаштований зauth: "aws-sdk".resolveThinkingProfile(ctx)отримує вибраніprovider,modelId, необов’язкову об’єднану підказку каталогуreasoningі необов’язкові об’єднані фактиcompatмоделі. Використовуйтеcompatлише для вибору thinking UI/profile провайдера.resolveSystemPromptContributionдає провайдеру змогу впроваджувати cache-aware guidance для system-prompt для сімейства моделей. Надавайте йому перевагу надbefore_prompt_build, коли поведінка належить одному провайдеру/сімейству моделей і має зберігати стабільний/динамічний поділ кешу.
Додайте додаткові можливості (необов’язково)
Крок 5: Додайте додаткові можливості
Provider plugin може реєструвати embeddings, speech, realtime transcription, realtime voice, media understanding, image generation, video generation, web fetch і web search поряд із text inference. OpenClaw класифікує це як hybrid-capability plugin - рекомендований шаблон для plugin компаній (один plugin на вендора). Див. Внутрішні механізми: володіння можливостями.Реєструйте кожну можливість усерединіregister(api) поряд з вашим наявним
викликом api.registerProvider(...). Вибирайте лише потрібні вкладки:- Speech (TTS)
- Realtime transcription
- Realtime voice
- Розуміння медіа
- Embeddings
- Генерування зображень і відео
- Веботримання та пошук
assertOkOrThrowProviderError(...) для HTTP-збоїв провайдера, щоб
plugins спільно використовували обмежене читання тіла помилки, розбір JSON-помилок і
суфікси request-id.Тестування
Крок 6: Тестування
src/provider.test.ts
Публікація в ClawHub
Плагіни провайдерів публікуються так само, як і будь-який інший зовнішній кодовий плагін:clawhub package publish.
Структура файлів
Довідник порядку каталогу
catalog.order керує тим, коли ваш каталог об’єднується відносно вбудованих
провайдерів:
| Порядок | Коли | Сценарій використання |
|---|---|---|
simple | Перший прохід | Звичайні провайдери API-ключів |
profile | Після simple | Провайдери, обмежені профілями автентифікації |
paired | Після profile | Синтез кількох пов’язаних записів |
late | Останній прохід | Перевизначення наявних провайдерів (перемагає в разі колізії) |
Наступні кроки
- Плагіни каналів - якщо ваш плагін також надає канал
- SDK Runtime - допоміжні засоби
api.runtime(TTS, пошук, субагент) - Огляд SDK - повний довідник імпорту підшляхів
- Внутрішня архітектура плагінів - подробиці хуків і вбудовані приклади