Building provider plugins
기준일: 2026-07-26
공식 기준: Building provider plugins
Building provider plugins 문서는 OpenClaw 공식 문서(plugins/sdk-provider-plugins)를 한국어로 정리한 가이드입니다. Step-by-step guide to building a model provider plugin for OpenClaw 명령·설정 키·코드 예시는 공식 문서를 그대로 보존하며, 해석과 절차 안내는 한국어로 제공합니다. 최종 동작은 설치된 CLI 버전과 공식 원문을 확인하세요.
핵심 요약
Step-by-step guide to building a model provider plugin for OpenClaw
한국어 가이드 범위: plugins/sdk-provider-plugins 경로의 설정·명령·제약·예시를 학습용으로 재구성합니다.
문서 구성
공식 문서의 주요 섹션은 다음과 같습니다.
- Walkthrough
- Publish to ClawHub
- File structure
- Catalog order reference
- 다음 단계
- 관련 문서
상세 내용
본문
Build a provider plugin to add a model provider (LLM) to OpenClaw: a model catalog, API-key auth, and dynamic model resolution.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Walkthrough
setup.providers[].envVars lets OpenClaw detect credentials without loading your plugin runtime. Add providerAuthAliases when a provider variant should reuse another provider id's auth. modelSupport is optional and lets OpenClaw auto-load your provider plugin from shorthand model ids like acme-large before runtime hooks exist. openclaw.compat and openclaw.build in package.json are required for ClawHub publishing (openclaw.compat.pluginApi and openclaw.build.openclawVersion are the two required fields; minGatewayVersion falls back to openclaw.install.minHostVersion when omitted).
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
openclaw/plugin-sdk/provider-model-shared-ProviderReplayFamily,buildProviderReplayFamilyHooks(...), and the raw replay builders (buildOpenAICompatibleReplayPolicy,buildAnthropicReplayPolicyForModel,buildGoogleGeminiReplayPolicy,buildHybridAnthropicOrOpenAIReplayPolicy). Also exports Gemini replay helpers (sanitizeGoogleGeminiReplayHistory,resolveTaggedReasoningOutputMode) and endpoint/model helpers (resolveProviderEndpoint,normalizeProviderId,normalizeGooglePreviewModelId).openclaw/plugin-sdk/provider-stream-ProviderStreamFamily,buildProviderStreamFamilyHooks(...),composeProviderStreamWrappers(...), plus the shared OpenAI/Codex wrappers (createOpenAIAttributionHeadersWrapper,createOpenAIFastModeWrapper,createOpenAIServiceTierWrapper,createOpenAIResponsesContextManagementWrapper,createCodexNativeWebSearchWrapper), DeepSeek V4 OpenAI-compatible wrapper (createDeepSeekV4OpenAICompatibleThinkingWrapper), Anthropic Messages thinking prefill cleanup (createAnthropicThinkingPrefillPayloadWrapper), plain-text tool-call compat (createPlainTextToolCallCompatWrapper), and shared proxy/provider wrappers (createOpenRouterWrapper,createToolStreamWrapper,createMinimaxFastModeWrapper).openclaw/plugin-sdk/provider-stream-shared- lightweight payload and event wrappers for hot provider paths, includingcreateOpenAICompatibleCompletionsThinkingOffWrapper,createPayloadPatchStreamWrapper,createPlainTextToolCallCompatWrapper,normalizeOpenAICompatibleReasoningPayload(...), andsetQwenChatTemplateThinking(...).openclaw/plugin-sdk/provider-tools-ProviderToolCompatFamily,buildProviderToolCompatFamilyHooks("deepseek" | "gemini" | "openai"), and underlying provider schema helpers.plan: provider-reported subscription or key labelwindows: resettable quota windows as used percentagesbilling: typedbalance,spend, orbudgetentries;unitcan besummary: compact provider-specific context that does not fit thosenormalizeConfigresolves one owning plugin per provider id (bundled providers first, then the matched runtime plugin) and calls only that hook - there is no scan across other providers. Google's ownnormalizeConfighook is what normalizesgoogle/google-vertex/google-antigravityconfig entries; it is not a separate core fallback.resolveConfigApiKeyuses the provider hook when exposed. Amazon Bedrock keeps AWS env-marker resolution in its provider plugin; runtime auth itself still uses the AWS SDK default chain when configured withauth: "aws-sdk".resolveThinkingProfile(ctx)receives the selectedprovider,modelId, optional mergedreasoningcatalog hint, and optional merged modelcompatfacts. Usecompatonly to select the provider's thinking UI/profile.resolveSystemPromptContributionlets a provider inject cache-aware system-prompt guidance for a model family. Prefer it over the legacy plugin-widebefore_prompt_buildhook when the behavior belongs to one provider/model family and should preserve the stable/dynamic cache split.
`setup.providers[].envVars` lets OpenClaw detect credentials without
loading your plugin runtime. Add `providerAuthAliases` when a provider
variant should reuse another provider id's auth. `modelSupport` is
optional and lets OpenClaw auto-load your provider plugin from shorthand
model ids like `acme-large` before runtime hooks exist. `openclaw.compat`
and `openclaw.build` in `package.json` are required for ClawHub
publishing (`openclaw.compat.pluginApi` and `openclaw.build.openclawVersion`
are the two required fields; `minGatewayVersion` falls back to
`openclaw.install.minHostVersion` when omitted).
A minimal text provider needs an `id`, `label`, `auth`, and `catalog`.
`catalog` is the provider-owned runtime/config hook; it can call live
vendor APIs and returns `models.providers` entries.
`registerModelCatalogProvider` is the newer control-plane catalog surface
for list/help/picker UI, covering `text`, `voice`, `image_generation`,
`video_generation`, and `music_generation` rows. Keep vendor endpoint
calls and response mapping in the plugin; OpenClaw owns the shared row
shape, source labels, and help rendering.
That is a working provider. Users can now run
`openclaw onboard --acme-ai-api-key <key>` and select
`acme-ai/acme-large` as their model.
### Live model discovery
If your provider exposes an OpenAI-compatible `/models` API, opt the
single-provider helper into shared discovery:
`liveModelDiscovery: true` is a public Plugin SDK contract with these
behaviors:
| Area | Contract |
| --- | --- |
| Credentials | Discovery uses the catalog's resolved provider credential, preferring `discoveryApiKey` when auth supplies one. Secret-reference markers are never sent as tokens. The default request uses `Authorization: Bearer <token>`; use `buildRequestHeaders` for another vendor auth scheme. |
| Endpoint | The default URL is `models` relative to the effective provider `baseUrl`, including an operator override when `allowExplicitBaseUrl` is enabled. Use `endpointPath` for another relative path. Use `endpointUrl: { url, requireBaseUrl }` only for a fixed vendor URL; discovery is skipped unless the effective base URL still equals `requireBaseUrl`, so a custom proxy credential is not sent to the vendor. |
| Network limits | Fetches use OpenClaw's SSRF guard, one 5-second timeout budget across pagination, a 4 MiB response limit per page, and a 50-page limit. Cross-origin pagination links are rejected; credentials are removed after a cross-origin redirect. |
| Cache | Successful, non-empty catalogs are cached for 60 seconds by provider, endpoint, and resolved credential. Empty or unusable results are not cached. |
| Filtering | Exact live IDs keep their trusted static metadata. New rows are projected conservatively as text/chat models. Disabled, archived, deprecated, explicitly non-chat, embedding, reranking, moderation, speech, image-only, and video-only rows are excluded. Use `readRows` only to select rows from a nonstandard response envelope; provider-specific model semantics still belong in a custom catalog. |
| Failure | Live discovery is advisory. Auth, network, timeout, pagination, parsing, empty-catalog, and filtering failures return the provider-owned static seed instead of removing the provider. |
For a non-Bearer or nonstandard list endpoint, pass options instead of
`true`:
Publish to ClawHub
Provider plugins publish the same way as any other external code plugin:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
File structure
<bundled-plugin-root>/acme-ai/
├── package.json # openclaw.providers metadata
├── openclaw.plugin.json # Manifest with provider auth metadata
├── index.ts # definePluginEntry + registerProvider
└── src/
├── provider.test.ts # Tests
└── usage.ts # Usage endpoint (optional)
Catalog order reference
catalog.order controls when your catalog merges relative to built-in providers:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Order | When | Use case |
|---|---|---|
simple |
First pass | Plain API-key providers |
profile |
After simple | Providers gated on auth profiles |
paired |
After profile | Synthesize multiple related entries |
late |
Last pass | Override existing providers (wins on collision) |
다음 단계
주요 항목:
- Channel Plugins - if your plugin also provides a channel
- SDK Runtime -
api.runtimehelpers (TTS, search, subagent) - SDK Overview - full subpath import reference
- Plugin Internals - hook details and bundled examples
관련 문서
주요 항목:
- Plugin SDK setup
- Building plugins
- Building channel plugins
실습 체크리스트
- 공식 문서와 로컬 버전을 대조합니다:
https://docs.openclaw.ai/plugins/sdk-provider-plugins - 관련 CLI는
openclaw --help및 하위 명령--help로 옵션을 확인합니다. - 설정 변경 시
openclaw config/openclaw doctor로 유효성을 검사합니다. - Gateway·채널·플러그인 변경 후에는 필요 시 Gateway를 재시작합니다.
자주 쓰는 명령·설정 예시
`setup.providers[].envVars` lets OpenClaw detect credentials without
loading your plugin runtime. Add `providerAuthAliases` when a provider
variant should reuse another provider id's auth. `modelSupport` is
optional and lets OpenClaw auto-load your provider plugin from shorthand
model ids like `acme-large` before runtime hooks exist. `openclaw.compat`
and `openclaw.build` in `package.json` are required for ClawHub
publishing (`openclaw.compat.pluginApi` and `openclaw.build.openclawVersion`
are the two required fields; `minGatewayVersion` falls back to
`openclaw.install.minHostVersion` when omitted).
A minimal text provider needs an `id`, `label`, `auth`, and `catalog`.
`catalog` is the provider-owned runtime/config hook; it can call live
vendor APIs and returns `models.providers` entries.
`registerModelCatalogProvider` is the newer control-plane catalog surface
for list/help/picker UI, covering `text`, `voice`, `image_generation`,
`video_generation`, and `music_generation` rows. Keep vendor endpoint
calls and response mapping in the plugin; OpenClaw owns the shared row
shape, source labels, and help rendering.
That is a working provider. Users can now run
`openclaw onboard --acme-ai-api-key <key>` and select
`acme-ai/acme-large` as their model.
### Live model discovery
If your provider exposes an OpenAI-compatible `/models` API, opt the
single-provider helper into shared discovery:
`liveModelDiscovery: true` is a public Plugin SDK contract with these
behaviors:
| Area | Contract |
| --- | --- |
| Credentials | Discovery uses the catalog's resolved provider credential, preferring `discoveryApiKey` when auth supplies one. Secret-reference markers are never sent as tokens. The default request uses `Authorization: Bearer <token>`; use `buildRequestHeaders` for another vendor auth scheme. |
| Endpoint | The default URL is `models` relative to the effective provider `baseUrl`, including an operator override when `allowExplicitBaseUrl` is enabled. Use `endpointPath` for another relative path. Use `endpointUrl: { url, requireBaseUrl }` only for a fixed vendor URL; discovery is skipped unless the effective base URL still equals `requireBaseUrl`, so a custom proxy credential is not sent to the vendor. |
| Network limits | Fetches use OpenClaw's SSRF guard, one 5-second timeout budget across pagination, a 4 MiB response limit per page, and a 50-page limit. Cross-origin pagination links are rejected; credentials are removed after a cross-origin redirect. |
| Cache | Successful, non-empty catalogs are cached for 60 seconds by provider, endpoint, and resolved credential. Empty or unusable results are not cached. |
| Filtering | Exact live IDs keep their trusted static metadata. New rows are projected conservatively as text/chat models. Disabled, archived, deprecated, explicitly non-chat, embedding, reranking, moderation, speech, image-only, and video-only rows are excluded. Use `readRows` only to select rows from a nonstandard response envelope; provider-specific model semantics still belong in a custom catalog. |
| Failure | Live discovery is advisory. Auth, network, timeout, pagination, parsing, empty-catalog, and filtering failures return the provider-owned static seed instead of removing the provider. |
For a non-Bearer or nonstandard list endpoint, pass options instead of
`true`:
Do not use `endpointUrl` as an unconditional alternate host. Its
`requireBaseUrl` check is the credential-isolation boundary for providers
whose model-list host differs from their inference host.
If the provider needs custom model semantics rather than the conservative
OpenAI-compatible projection, keep that projection in the plugin and use
`openclaw/plugin-sdk/provider-catalog-live-runtime` for the shared fetch
lifecycle. The helper gives you guarded HTTP fetches, provider-auth headers,
structured HTTP errors, TTL caching, and static fallback behavior without
putting provider policy in OpenClaw core.
Use `buildLiveModelProviderConfig` when the live API only tells you which
provider-owned static catalog rows are currently available:
Use `getCachedLiveProviderModelRows` when the provider API returns richer
metadata and the plugin needs to project rows into OpenClaw model
definitions itself:
관련 링크
이 가이드는 공식 문서를 한국어 학습용으로 재구성한 것입니다. 옵션 기본값·플래그 이름은 설치 버전에 따라 달라질 수 있습니다.