Plugin SDK Migration
OpenClaw has moved from a broad backwards-compatibility layer to a modern plugin architecture with focused, documented imports. If your plugin was built before the new architecture, this guide helps you migrate.What is changing
The old plugin system provided two wide-open surfaces that let plugins import anything they needed from a single entry point:openclaw/plugin-sdk/compat— a single import that re-exported dozens of helpers. It was introduced to keep older hook-based plugins working while the new plugin architecture was being built.openclaw/extension-api— a bridge that gave plugins direct access to host-side helpers like the embedded agent runner.
Why this changed
The old approach caused problems:- Slow startup — importing one helper loaded dozens of unrelated modules
- Circular dependencies — broad re-exports made it easy to create import cycles
- Unclear API surface — no way to tell which exports were stable vs internal
openclaw/plugin-sdk/\<subpath\>)
is a small, self-contained module with a clear purpose and documented contract.
How to migrate
Replace with focused imports
Each export from the old surface maps to a specific modern import path:For host-side helpers, use the injected plugin runtime instead of importing
directly:The same pattern applies to other legacy bridge helpers:
| Old import | Modern equivalent |
|---|---|
resolveAgentDir | api.runtime.agent.resolveAgentDir |
resolveAgentWorkspaceDir | api.runtime.agent.resolveAgentWorkspaceDir |
resolveAgentIdentity | api.runtime.agent.resolveAgentIdentity |
resolveThinkingDefault | api.runtime.agent.resolveThinkingDefault |
resolveAgentTimeoutMs | api.runtime.agent.resolveAgentTimeoutMs |
ensureAgentWorkspace | api.runtime.agent.ensureAgentWorkspace |
| session store helpers | api.runtime.agent.session.* |
Import path reference
Full import path table
Full import path table
| Import path | Purpose | Key exports |
|---|---|---|
plugin-sdk/core | Plugin entry definitions, base types | defineChannelPluginEntry, definePluginEntry |
plugin-sdk/channel-setup | Setup wizard adapters | createOptionalChannelSetupSurface |
plugin-sdk/channel-pairing | DM pairing primitives | createChannelPairingController |
plugin-sdk/channel-reply-pipeline | Reply prefix + typing wiring | createChannelReplyPipeline |
plugin-sdk/channel-config-helpers | Config adapter factories | createHybridChannelConfigAdapter |
plugin-sdk/channel-config-schema | Config schema builders | Channel config schema types |
plugin-sdk/channel-policy | Group/DM policy resolution | resolveChannelGroupRequireMention |
plugin-sdk/channel-lifecycle | Account status tracking | createAccountStatusSink |
plugin-sdk/channel-runtime | Runtime wiring helpers | Channel runtime utilities |
plugin-sdk/channel-send-result | Send result types | Reply result types |
plugin-sdk/runtime-store | Persistent plugin storage | createPluginRuntimeStore |
plugin-sdk/allow-from | Allowlist formatting | formatAllowFromLowercase |
plugin-sdk/allowlist-resolution | Allowlist input mapping | mapAllowlistResolutionInputs |
plugin-sdk/command-auth | Command gating | resolveControlCommandGate |
plugin-sdk/secret-input | Secret input parsing | Secret input helpers |
plugin-sdk/webhook-ingress | Webhook request helpers | Webhook target utilities |
plugin-sdk/reply-payload | Message reply types | Reply payload types |
plugin-sdk/provider-onboard | Provider onboarding patches | Onboarding config helpers |
plugin-sdk/keyed-async-queue | Ordered async queue | KeyedAsyncQueue |
plugin-sdk/testing | Test utilities | Test helpers and mocks |
src/plugin-sdk/ or ask in Discord.
Removal timeline
| When | What happens |
|---|---|
| Now | Deprecated surfaces emit runtime warnings |
| Next major release | Deprecated surfaces will be removed; plugins still using them will fail |