mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-27 09:21:35 +07:00
11 KiB
11 KiB
title, sidebarTitle, summary, read_when
| title | sidebarTitle | summary | read_when | |||
|---|---|---|---|---|---|---|
| Plugin SDK Overview | SDK Overview | Import map, registration API reference, and SDK architecture |
|
Plugin SDK Overview
The plugin SDK is the typed contract between plugins and core. This page is the reference for what to import and what you can register.
**Looking for a how-to guide?** - First plugin? Start with [Getting Started](/plugins/building-plugins) - Channel plugin? See [Channel Plugins](/plugins/sdk-channel-plugins) - Provider plugin? See [Provider Plugins](/plugins/sdk-provider-plugins)Import convention
Always import from a specific subpath:
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
Each subpath is a small, self-contained module. This keeps startup fast and prevents circular dependency issues.
Subpath reference
The most commonly used subpaths, grouped by purpose. The full list of 100+
subpaths is in scripts/lib/plugin-sdk-entrypoints.json.
Plugin entry
| Subpath | Key exports |
|---|---|
plugin-sdk/plugin-entry |
definePluginEntry |
plugin-sdk/core |
defineChannelPluginEntry, createChatChannelPlugin, createChannelPluginBase, defineSetupPluginEntry, buildChannelConfigSchema |
Registration API
The register(api) callback receives an OpenClawPluginApi object with these
methods:
Capability registration
| Method | What it registers |
|---|---|
api.registerProvider(...) |
Text inference (LLM) |
api.registerCliBackend(...) |
Local CLI inference backend |
api.registerChannel(...) |
Messaging channel |
api.registerSpeechProvider(...) |
Text-to-speech / STT synthesis |
api.registerMediaUnderstandingProvider(...) |
Image/audio/video analysis |
api.registerImageGenerationProvider(...) |
Image generation |
api.registerWebSearchProvider(...) |
Web search |
Tools and commands
| Method | What it registers |
|---|---|
api.registerTool(tool, opts?) |
Agent tool (required or { optional: true }) |
api.registerCommand(def) |
Custom command (bypasses the LLM) |
Infrastructure
| Method | What it registers |
|---|---|
api.registerHook(events, handler, opts?) |
Event hook |
api.registerHttpRoute(params) |
Gateway HTTP endpoint |
api.registerGatewayMethod(name, handler) |
Gateway RPC method |
api.registerCli(registrar, opts?) |
CLI subcommand |
api.registerService(service) |
Background service |
api.registerInteractiveHandler(registration) |
Interactive handler |
CLI backend registration
api.registerCliBackend(...) lets a plugin own the default config for a local
AI CLI backend such as claude-cli or codex-cli.
- The backend
idbecomes the provider prefix in model refs likeclaude-cli/opus. - The backend
configuses the same shape asagents.defaults.cliBackends.<id>. - User config still wins. OpenClaw merges
agents.defaults.cliBackends.<id>over the plugin default before running the CLI. - Use
normalizeConfigwhen a backend needs compatibility rewrites after merge (for example normalizing old flag shapes).
Exclusive slots
| Method | What it registers |
|---|---|
api.registerContextEngine(id, factory) |
Context engine (one active at a time) |
api.registerMemoryPromptSection(builder) |
Memory prompt section builder |
Events and lifecycle
| Method | What it does |
|---|---|
api.on(hookName, handler, opts?) |
Typed lifecycle hook |
api.onConversationBindingResolved(handler) |
Conversation binding callback |
Hook decision semantics
before_tool_call: returning{ block: true }is terminal. Once any handler sets it, lower-priority handlers are skipped.before_tool_call: returning{ block: false }is treated as no decision (same as omittingblock), not as an override.message_sending: returning{ cancel: true }is terminal. Once any handler sets it, lower-priority handlers are skipped.message_sending: returning{ cancel: false }is treated as no decision (same as omittingcancel), not as an override.
API object fields
| Field | Type | Description |
|---|---|---|
api.id |
string |
Plugin id |
api.name |
string |
Display name |
api.version |
string? |
Plugin version (optional) |
api.description |
string? |
Plugin description (optional) |
api.source |
string |
Plugin source path |
api.rootDir |
string? |
Plugin root directory (optional) |
api.config |
OpenClawConfig |
Current config snapshot |
api.pluginConfig |
Record<string, unknown> |
Plugin-specific config from plugins.entries.<id>.config |
api.runtime |
PluginRuntime |
Runtime helpers |
api.logger |
PluginLogger |
Scoped logger (debug, info, warn, error) |
api.registrationMode |
PluginRegistrationMode |
"full", "setup-only", or "setup-runtime" |
api.resolvePath(input) |
(string) => string |
Resolve path relative to plugin root |
Internal module convention
Within your plugin, use local barrel files for internal imports:
my-plugin/
api.ts # Public exports for external consumers
runtime-api.ts # Internal-only runtime exports
index.ts # Plugin entry point
setup-entry.ts # Lightweight setup-only entry (optional)
Related
- Entry Points —
definePluginEntryanddefineChannelPluginEntryoptions - Runtime Helpers — full
api.runtimenamespace reference - Setup and Config — packaging, manifests, config schemas
- Testing — test utilities and lint rules
- SDK Migration — migrating from deprecated surfaces
- Plugin Internals — deep architecture and capability model