Plugin internals
Plugin SDK migration
OpenClaw replaced a broad backwards-compatibility layer with a modern plugin architecture built from small, focused imports. If your plugin predates that change, this guide gets it onto the current contracts.
What changed
Several wide-open import surfaces used to let plugins reach almost anything from a single entry point:
openclaw/plugin-sdkandopenclaw/plugin-sdk/compat- re-exported dozens of helpers while the focused SDK was being built. Both roots are now removed. Import a documented subpath instead.openclaw/plugin-sdk/infra-runtime- a broad barrel mixing system events, heartbeat state, delivery queues, fetch/proxy helpers, file helpers, approval types, and unrelated utilities.openclaw/plugin-sdk/config-runtime- a broad config barrel retained for compatibility, including deprecated directloadConfigandwriteConfigFileexports. Those methods were removed from the injected plugin runtime, not from this retained barrel.openclaw/extension-api- a removed bridge that gave plugins direct access to host-side helpers like the embedded agent runner.api.registerEmbeddedExtensionFactory(...)- a removed embedded-runner-only hook that observed embedded-runner events such astool_result. Use agent tool-result middleware instead (see Migrate embedded tool-result extensions to middleware).
The root SDK, compat barrel, extension bridge, and embedded extension factory
have been removed. infra-runtime and config-runtime remain only for their
separately recorded later windows. New plugins should use focused subpaths.
OpenClaw does not remove or reinterpret documented plugin behavior in the same change that introduces a replacement. Breaking contract changes go through a compatibility adapter, diagnostics, docs, and a deprecation window first. That applies to SDK imports, manifest fields, setup APIs, hooks, and runtime registration behavior.
ChatCommandDefinition.category retains the "docks" value accepted by the
2026.8.1 SDK. Command lists display these legacy definitions under Tools.
The category does not enable channel docking or restore retired docking commands.
New definitions should use "tools".
Why
- Slow startup - importing one helper loaded dozens of unrelated modules.
- Circular dependencies - broad re-exports made import cycles easy to create.
- Unclear API surface - no way to tell stable exports from internal ones.
The typed public SDK is organized into focused subpaths with documented contracts. Not every SDK build entrypoint is a public plugin API.
Legacy provider convenience seams for bundled channels are gone too -
channel-branded helper shortcuts were private mono-repo conveniences, not
stable plugin contracts. Use narrow generic SDK subpaths instead. Inside the
bundled plugin workspace, keep provider-owned helpers in that plugin's own
api.ts or runtime-api.ts:
- Anthropic keeps Claude-specific stream helpers in its own
api.ts/contract-api.tsseam. - OpenAI keeps provider builders, default-model helpers, and realtime provider
builders in its own
api.ts. - OpenRouter keeps provider builder and onboarding/config helpers in its own
api.ts.
Where each topic lives
Every section of the single-page version lives on one of the six pages below. The anchors from the single-page version still resolve here.
Migration steps
How to migrate a plugin — the ordered migration steps.
- How to migrate
- Migrate runtime config load/write helpers
- Migrate embedded tool-result extensions to middleware
- Migrate approval-native handlers to capability facts
- Audit Windows wrapper fallback behavior
- Find deprecated imports
- Replace with focused imports
- Replace broad
infra-runtimeimports - Migrate channel route helpers
- Build and test
Import paths
Import path reference — which typed-public subpath replaces each legacy import.
Removed surfaces and replacements
Removed surfaces and replacements — what was removed, and the replacement for each legacy API.
- Removed compatibility surfaces
- Process-global API-provider publication
- Deactivate hook alias
- Private testing barrel
- Migration reference
command-authhelp builders ->command-status- Mention gating helpers ->
resolveInboundMentionDecision - Channel runtime shim and channel actions helpers
- Web search provider
tool()helper ->createTool()on the plugin - Plaintext channel envelopes ->
BodyForAgent subagent_spawninghook -> core thread binding- Provider discovery types -> provider catalog types
- Thinking policy hooks ->
resolveThinkingProfile - External auth providers ->
contracts.externalAuthProviders - Provider env-var lookup ->
setup.providers[].envVars - Memory plugin registration ->
registerMemoryCapability - Memory embedding provider API
- Raw channel send results ->
OutboundDeliveryResult - Subagent session messages types renamed
- Removed session and transcript file APIs
- Agent harness attempt params -> V2 host-capability contract
runtime.tasks.flow->runtime.tasks.managedFlows- Embedded extension factories -> agent tool-result middleware
OpenClawSchemaTypealias ->OpenClawConfig
Talk and voice
Talk and realtime voice migration — the unified Talk session API and its method map.
Compatibility records
Compatibility policy and records — what is retained, why, and on what condition it can be removed.
- Compatibility policy
- Retained helper contracts
- Harness attempt result migration
- Model-provider result compatibility
- Memory read missing results
- Config record migrations
- Plugin state migration declarations
- AuthStorage SQLite migration
- Published channel setup compatibility
- Channel setup input field compatibility
- Verifying readers
- Media legacy projection
Timeline
Removal timeline — when deprecated surfaces become eligible for removal.
Related
- Getting Started - build your first plugin
- SDK Overview - full subpath import reference
- Channel Plugins - building channel plugins
- Provider Plugins - building provider plugins
- Plugin Internals - architecture deep dive
- Plugin Manifest - manifest schema reference
- Plugin hooks - typed and custom hook surfaces