mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-23 16:01:17 +00:00
7.0 KiB
7.0 KiB
title, sidebarTitle, summary, read_when
| title | sidebarTitle | summary | read_when | |||
|---|---|---|---|---|---|---|
| Plugin SDK Overview | SDK Overview | How the OpenClaw plugin SDK is organized, which subpaths are stable, and how to choose the right import |
|
Plugin SDK Overview
The OpenClaw plugin SDK is split into small public subpaths under
openclaw/plugin-sdk/<subpath>.
Use the narrowest import that matches the job. That keeps plugin dependencies small, avoids circular imports, and makes it clear which contract you depend on.
Rules first
- Use focused imports such as
openclaw/plugin-sdk/plugin-entry. - Do not import the root
openclaw/plugin-sdkbarrel in new code. - Do not import
openclaw/extension-apiin new code. - Do not import
src/**from plugin packages. - Inside a plugin package, route internal imports through local files such as
./api.tsor./runtime-api.ts, not through the published SDK path for that same plugin.
SDK map
| Job | Subpath | Next page |
|---|---|---|
| Define plugin entry modules | plugin-sdk/plugin-entry, plugin-sdk/core |
Plugin Entry Points |
| Use injected runtime helpers | plugin-sdk/runtime, plugin-sdk/runtime-store |
Plugin Runtime |
| Build setup/configure flows | plugin-sdk/setup, plugin-sdk/channel-setup, plugin-sdk/secret-input |
Plugin Setup |
| Build channel plugins | plugin-sdk/core, plugin-sdk/channel-contract, plugin-sdk/channel-actions, plugin-sdk/channel-pairing |
Channel Plugin SDK |
| Build provider plugins | plugin-sdk/plugin-entry, plugin-sdk/provider-auth, plugin-sdk/provider-onboard, plugin-sdk/provider-models, plugin-sdk/provider-usage |
Provider Plugin SDK |
| Test plugin code | plugin-sdk/testing |
Plugin SDK Testing |
Typical plugin layout
my-plugin/
├── package.json
├── openclaw.plugin.json
├── index.ts
├── setup-entry.ts
├── api.ts
├── runtime-api.ts
└── src/
├── provider.ts
├── setup.ts
└── provider.test.ts
// api.ts
export {
definePluginEntry,
type OpenClawPluginApi,
type ProviderAuthContext,
type ProviderAuthResult,
} from "openclaw/plugin-sdk/plugin-entry";
What belongs where
Entry helpers
plugin-sdk/plugin-entryis the default entry surface for providers, tools, commands, services, memory plugins, and context engines.plugin-sdk/coreadds channel-focused helpers such asdefineChannelPluginEntry(...).
Runtime helpers
- Use
api.runtime.*for trusted in-process helpers that OpenClaw injects at registration time. - Use
plugin-sdk/runtime-storewhen plugin modules need a mutable runtime slot that is initialized later.
Setup helpers
plugin-sdk/setupcontains shared setup-wizard helpers and config patch helpers.plugin-sdk/channel-setupcontains channel-specific setup adapters.plugin-sdk/secret-inputexposes the shared secret-input schema helpers.
Channel helpers
plugin-sdk/channel-contractexports pure channel types.plugin-sdk/channel-actionscovers sharedmessagetool schema helpers.plugin-sdk/channel-pairingcovers pairing approval flows.plugin-sdk/webhook-ingresscovers plugin-owned webhook routes.
Provider helpers
plugin-sdk/provider-authcovers auth flows and credential helpers.plugin-sdk/provider-onboardcovers config patches after auth/setup.plugin-sdk/provider-modelscovers catalog and model-definition helpers.plugin-sdk/provider-usagecovers usage snapshot helpers.plugin-sdk/provider-setupandplugin-sdk/self-hosted-provider-setupcover self-hosted and local-model onboarding.
Example: mixing subpaths in one plugin
import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
import { applyProviderConfigWithDefaultModel } from "openclaw/plugin-sdk/provider-onboard";
import { buildSecretInputSchema } from "openclaw/plugin-sdk/secret-input";
export default definePluginEntry({
id: "example-provider",
name: "Example Provider",
description: "Small provider plugin example",
configSchema: {
jsonSchema: {
type: "object",
additionalProperties: false,
properties: {
apiKey: { type: "string" },
},
},
safeParse(value) {
return buildSecretInputSchema().safeParse((value as { apiKey?: unknown })?.apiKey);
},
},
register(api: OpenClawPluginApi) {
api.registerProvider({
id: "example",
label: "Example",
auth: [
createProviderApiKeyAuthMethod({
providerId: "example",
methodId: "api-key",
label: "Example API key",
optionKey: "exampleApiKey",
flagName: "--example-api-key",
envVar: "EXAMPLE_API_KEY",
promptMessage: "Enter Example API key",
profileId: "example:default",
defaultModel: "example/default",
applyConfig: (cfg) =>
applyProviderConfigWithDefaultModel(cfg, "example", {
id: "default",
name: "Default",
}),
}),
],
});
},
});
Choose the smallest public seam
If a helper exists on a focused subpath, prefer that over a broader runtime surface.
- Prefer
plugin-sdk/provider-authover reaching into unrelated provider files. - Prefer
plugin-sdk/channel-contractfor types in tests and helper modules. - Prefer
plugin-sdk/runtime-storeover custom mutable globals. - Prefer
plugin-sdk/testingfor shared test fixtures.