Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

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/plugin-sdk/infra-runtime - a broad runtime helper barrel that mixed system events, heartbeat state, delivery queues, fetch/proxy helpers, file helpers, approval types, and unrelated utilities.
  • openclaw/plugin-sdk/config-runtime - a broad config compatibility barrel that still carries deprecated direct load/write helpers during the migration window.
  • openclaw/extension-api - a bridge that gave plugins direct access to host-side helpers like the embedded agent runner.
  • api.registerEmbeddedExtensionFactory(...) - a removed Pi-only bundled extension hook that could observe embedded-runner events such as tool_result.
The broad import surfaces are now deprecated. They still work at runtime, but new plugins must not use them, and existing plugins should migrate before the next major release removes them. The Pi-only embedded extension factory registration API has been removed; use tool-result middleware instead. OpenClaw does not remove or reinterpret documented plugin behavior in the same change that introduces a replacement. Breaking contract changes must first go through a compatibility adapter, diagnostics, docs, and a deprecation window. That applies to SDK imports, manifest fields, setup APIs, hooks, and runtime registration behavior.
The backwards-compatibility layer will be removed in a future major release. Plugins that still import from these surfaces will break when that happens. Pi-only embedded extension factory registrations already no longer load.

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
The modern plugin SDK fixes this: each import path (openclaw/plugin-sdk/\<subpath\>) is a small, self-contained module with a clear purpose and documented contract. Legacy provider convenience seams for bundled channels are also gone. Channel-branded helper seams were private mono-repo shortcuts, 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. Current bundled provider examples:
  • Anthropic keeps Claude-specific stream helpers in its own api.ts / contract-api.ts seam
  • 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

Talk and realtime voice migration plan

Realtime voice, telephony, meeting, and browser Talk code is moving from surface-local turn bookkeeping to a shared Talk session controller exported by openclaw/plugin-sdk/realtime-voice. The new controller owns the common Talk event envelope, active turn state, capture state, output-audio state, recent event history, and stale-turn rejection. Provider plugins should keep owning vendor-specific realtime sessions; surface plugins should keep owning capture, playback, telephony, and meeting quirks. This Talk migration is intentionally breaking-clean:
  1. Keep the shared controller/runtime primitives in plugin-sdk/realtime-voice.
  2. Move bundled surfaces onto the shared controller: browser relay, managed-room handoff, voice-call realtime, voice-call streaming STT, Google Meet realtime, and native push-to-talk.
  3. Replace old Talk RPC families with the final talk.session.* and talk.client.* API.
  4. Advertise one live Talk event channel in Gateway hello-ok.features.events: talk.event.
  5. Delete the old realtime HTTP endpoint and any request-time instruction override path.
New code should not call createTalkEventSequencer(...) directly unless it is implementing a low-level adapter or test fixture. Prefer the shared controller so turn-scoped events cannot be emitted without a turn id, stale turnEnd / turnCancel calls cannot clear a newer active turn, and output-audio lifecycle events stay consistent across telephony, meetings, browser relay, managed-room handoff, and native Talk clients. The target public API shape is:
// Gateway-owned Talk session API.
await gateway.request("talk.session.create", {
  mode: "realtime",
  transport: "gateway-relay",
  brain: "agent-consult",
  sessionKey: "main",
});
await gateway.request("talk.session.appendAudio", { sessionId, audioBase64 });
await gateway.request("talk.session.cancelOutput", { sessionId, reason: "barge-in" });
await gateway.request("talk.session.submitToolResult", { sessionId, callId, result });
await gateway.request("talk.session.close", { sessionId });

// Client-owned provider session API.
await gateway.request("talk.client.create", {
  mode: "realtime",
  transport: "webrtc",
  brain: "agent-consult",
  sessionKey: "main",
});
await gateway.request("talk.client.toolCall", { sessionKey, callId, name, args });
Browser-owned WebRTC/provider-websocket sessions use talk.client.create, because the browser owns the provider negotiation and media transport while the Gateway owns credentials, instructions, and tool policy. talk.session.* is the common Gateway-managed surface for gateway-relay realtime, gateway-relay transcription, and managed-room native STT/TTS sessions. Legacy configs that placed realtime selectors beside talk.provider / talk.providers should be repaired with openclaw doctor --fix; runtime Talk does not reinterpret speech/TTS provider config as realtime provider config. The supported talk.session.create combinations are intentionally small:
ModeTransportBrainOwnerNotes
realtimegateway-relayagent-consultGatewayFull-duplex provider audio bridged through the Gateway; tool calls are routed through the agent-consult tool.
transcriptiongateway-relaynoneGatewayStreaming STT only; callers send input audio and receive transcript events.
stt-ttsmanaged-roomagent-consultNative/client roomPush-to-talk and walkie-talkie style rooms where the client owns capture/playback and the Gateway owns turn state.
stt-ttsmanaged-roomdirect-toolsNative/client roomAdmin-only room mode for trusted first-party surfaces that execute Gateway tool actions directly.
Removed method map:
OldNew
talk.realtime.sessiontalk.client.create
talk.realtime.toolCalltalk.client.toolCall
talk.realtime.relayAudiotalk.session.appendAudio
talk.realtime.relayCanceltalk.session.cancelOutput or talk.session.cancelTurn
talk.realtime.relayToolResulttalk.session.submitToolResult
talk.realtime.relayStoptalk.session.close
talk.transcription.sessiontalk.session.create({ mode: "transcription" })
talk.transcription.relayAudiotalk.session.appendAudio
talk.transcription.relayCanceltalk.session.cancelTurn
talk.transcription.relayStoptalk.session.close
talk.handoff.createtalk.session.create({ transport: "managed-room" })
talk.handoff.jointalk.session.join
talk.handoff.revoketalk.session.close
The unified control vocabulary is also deliberately narrow:
MethodApplies toContract
talk.session.appendAudiorealtime/gateway-relay, transcription/gateway-relayAppend a base64 PCM audio chunk to the provider session owned by the same Gateway connection.
talk.session.startTurnstt-tts/managed-roomStart a managed-room user turn.
talk.session.endTurnstt-tts/managed-roomEnd the active turn after stale-turn validation.
talk.session.cancelTurnall Gateway-owned sessionsCancel active capture/provider/agent/TTS work for a turn.
talk.session.cancelOutputrealtime/gateway-relayStop assistant audio output without necessarily ending the user turn.
talk.session.submitToolResultrealtime/gateway-relayComplete a provider tool call emitted by the relay.
talk.session.closeall unified sessionsStop relay sessions or revoke managed-room state, then forget the unified session id.
Do not introduce provider or platform special cases in core to make this work. Core owns Talk session semantics. Provider plugins own vendor session setup. Voice-call and Google Meet own telephony/meeting adapters. Browser and native apps own device capture/playback UX.

Compatibility policy

For external plugins, compatibility work follows this order:
  1. add the new contract
  2. keep the old behavior wired through a compatibility adapter
  3. emit a diagnostic or warning that names the old path and replacement
  4. cover both paths in tests
  5. document the deprecation and migration path
  6. remove only after the announced migration window, usually in a major release
Maintainers can audit the current migration queue with pnpm plugins:boundary-report. Use pnpm plugins:boundary-report:summary for compact counts, --owner <id> for one plugin or compatibility owner, and pnpm plugins:boundary-report:ci when a CI gate should fail on due compatibility records, cross-owner reserved SDK imports, or unused reserved SDK subpaths. The report groups deprecated compatibility records by removal date, counts local code/docs references, surfaces cross-owner reserved SDK imports, and summarizes the private memory-host SDK bridge so compatibility cleanup stays explicit instead of relying on ad hoc searches. Reserved SDK subpaths must have tracked owner usage; unused reserved helper exports should be removed from the public SDK. If a manifest field is still accepted, plugin authors can keep using it until the docs and diagnostics say otherwise. New code should prefer the documented replacement, but existing plugins should not break during ordinary minor releases.

How to migrate

1

Migrate runtime config load/write helpers

Bundled plugins should stop calling api.runtime.config.loadConfig() and api.runtime.config.writeConfigFile(...) directly. Prefer config that was already passed into the active call path. Long-lived handlers that need the current process snapshot can use api.runtime.config.current(). Long-lived agent tools should use the tool context’s ctx.getRuntimeConfig() inside execute so a tool created before a config write still sees the refreshed runtime config.Config writes must go through the transactional helpers and choose an after-write policy:
await api.runtime.config.mutateConfigFile({
  afterWrite: { mode: "auto" },
  mutate(draft) {
    draft.plugins ??= {};
  },
});
Use afterWrite: { mode: "restart", reason: "..." } when the caller knows the change requires a clean gateway restart, and afterWrite: { mode: "none", reason: "..." } only when the caller owns the follow-up and deliberately wants to suppress the reload planner. Mutation results include a typed followUp summary for tests and logging; the gateway remains responsible for applying or scheduling the restart. loadConfig and writeConfigFile remain as deprecated compatibility helpers for external plugins during the migration window and warn once with the runtime-config-load-write compatibility code. Bundled plugins and repo runtime code are protected by scanner guardrails in pnpm check:deprecated-internal-config-api and pnpm check:no-runtime-action-load-config: new production plugin usage fails outright, direct config writes fail, gateway server methods must use the request runtime snapshot, runtime channel send/action/client helpers must receive config from their boundary, and long-lived runtime modules have zero allowed ambient loadConfig() calls.New plugin code should also avoid importing the broad openclaw/plugin-sdk/config-runtime compatibility barrel. Use the narrow SDK subpath that matches the job:
NeedImport
Config types such as OpenClawConfigopenclaw/plugin-sdk/config-types
Already-loaded config assertions and plugin-entry config lookupopenclaw/plugin-sdk/plugin-config-runtime
Current runtime snapshot readsopenclaw/plugin-sdk/runtime-config-snapshot
Config writesopenclaw/plugin-sdk/config-mutation
Session store helpersopenclaw/plugin-sdk/session-store-runtime
Markdown table configopenclaw/plugin-sdk/markdown-table-runtime
Group policy runtime helpersopenclaw/plugin-sdk/runtime-group-policy
Secret input resolutionopenclaw/plugin-sdk/secret-input-runtime
Model/session overridesopenclaw/plugin-sdk/model-session-runtime
Bundled plugins and their tests are scanner-guarded against the broad barrel so imports and mocks stay local to the behavior they need. The broad barrel still exists for external compatibility, but new code should not depend on it.
2

Migrate Pi tool-result extensions to middleware

Bundled plugins must replace Pi-only api.registerEmbeddedExtensionFactory(...) tool-result handlers with runtime-neutral middleware.
// Pi and Codex runtime dynamic tools
api.registerAgentToolResultMiddleware(async (event) => {
  return compactToolResult(event);
}, {
  runtimes: ["pi", "codex"],
});
Update the plugin manifest at the same time:
{
  "contracts": {
    "agentToolResultMiddleware": ["pi", "codex"]
  }
}
External plugins cannot register tool-result middleware because it can rewrite high-trust tool output before the model sees it.
3

Migrate approval-native handlers to capability facts

Approval-capable channel plugins now expose native approval behavior through approvalCapability.nativeRuntime plus the shared runtime-context registry.Key changes:
  • Replace approvalCapability.handler.loadRuntime(...) with approvalCapability.nativeRuntime
  • Move approval-specific auth/delivery off legacy plugin.auth / plugin.approvals wiring and onto approvalCapability
  • ChannelPlugin.approvals has been removed from the public channel-plugin contract; move delivery/native/render fields onto approvalCapability
  • plugin.auth remains for channel login/logout flows only; approval auth hooks there are no longer read by core
  • Register channel-owned runtime objects such as clients, tokens, or Bolt apps through openclaw/plugin-sdk/channel-runtime-context
  • Do not send plugin-owned reroute notices from native approval handlers; core now owns routed-elsewhere notices from actual delivery results
  • When passing channelRuntime into createChannelManager(...), provide a real createPluginRuntime().channel surface. Partial stubs are rejected.
See /plugins/sdk-channel-plugins for the current approval capability layout.
4

Audit Windows wrapper fallback behavior

If your plugin uses openclaw/plugin-sdk/windows-spawn, unresolved Windows .cmd/.bat wrappers now fail closed unless you explicitly pass allowShellFallback: true.
// Before
const program = applyWindowsSpawnProgramPolicy({ candidate });

// After
const program = applyWindowsSpawnProgramPolicy({
  candidate,
  // Only set this for trusted compatibility callers that intentionally
  // accept shell-mediated fallback.
  allowShellFallback: true,
});
If your caller does not intentionally rely on shell fallback, do not set allowShellFallback and handle the thrown error instead.
5

Find deprecated imports

Search your plugin for imports from either deprecated surface:
grep -r "plugin-sdk/compat" my-plugin/
grep -r "plugin-sdk/infra-runtime" my-plugin/
grep -r "plugin-sdk/config-runtime" my-plugin/
grep -r "openclaw/extension-api" my-plugin/
6

Replace with focused imports

Each export from the old surface maps to a specific modern import path:
// Before (deprecated backwards-compatibility layer)
import {
  createChannelReplyPipeline,
  createPluginRuntimeStore,
  resolveControlCommandGate,
} from "openclaw/plugin-sdk/compat";

// After (modern focused imports)
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
For host-side helpers, use the injected plugin runtime instead of importing directly:
// Before (deprecated extension-api bridge)
import { runEmbeddedPiAgent } from "openclaw/extension-api";
const result = await runEmbeddedPiAgent({ sessionId, prompt });

// After (injected runtime)
const result = await api.runtime.agent.runEmbeddedPiAgent({ sessionId, prompt });
The same pattern applies to other legacy bridge helpers:
Old importModern equivalent
resolveAgentDirapi.runtime.agent.resolveAgentDir
resolveAgentWorkspaceDirapi.runtime.agent.resolveAgentWorkspaceDir
resolveAgentIdentityapi.runtime.agent.resolveAgentIdentity
resolveThinkingDefaultapi.runtime.agent.resolveThinkingDefault
resolveAgentTimeoutMsapi.runtime.agent.resolveAgentTimeoutMs
ensureAgentWorkspaceapi.runtime.agent.ensureAgentWorkspace
session store helpersapi.runtime.agent.session.*
7

Replace broad infra-runtime imports

openclaw/plugin-sdk/infra-runtime still exists for external compatibility, but new code should import the focused helper surface it actually needs:
NeedImport
System event queue helpersopenclaw/plugin-sdk/system-event-runtime
Heartbeat event and visibility helpersopenclaw/plugin-sdk/heartbeat-runtime
Pending delivery queue drainopenclaw/plugin-sdk/delivery-queue-runtime
Channel activity telemetryopenclaw/plugin-sdk/channel-activity-runtime
In-memory dedupe cachesopenclaw/plugin-sdk/dedupe-runtime
Safe local-file/media path helpersopenclaw/plugin-sdk/file-access-runtime
Dispatcher-aware fetchopenclaw/plugin-sdk/runtime-fetch
Proxy and guarded fetch helpersopenclaw/plugin-sdk/fetch-runtime
SSRF dispatcher policy typesopenclaw/plugin-sdk/ssrf-dispatcher
Approval request/resolution typesopenclaw/plugin-sdk/approval-runtime
Approval reply payload and command helpersopenclaw/plugin-sdk/approval-reply-runtime
Error formatting helpersopenclaw/plugin-sdk/error-runtime
Transport readiness waitsopenclaw/plugin-sdk/transport-ready-runtime
Secure token helpersopenclaw/plugin-sdk/secure-random-runtime
Bounded async task concurrencyopenclaw/plugin-sdk/concurrency-runtime
Numeric coercionopenclaw/plugin-sdk/number-runtime
Process-local async lockopenclaw/plugin-sdk/async-lock-runtime
File locksopenclaw/plugin-sdk/file-lock
Bundled plugins are scanner-guarded against infra-runtime, so repo code cannot regress to the broad barrel.
8

Migrate channel route helpers

New channel route code should use openclaw/plugin-sdk/channel-route. The older route-key and comparable-target names remain as compatibility aliases during the migration window, but new plugins should use the route names that describe the behavior directly:
Old helperModern helper
channelRouteIdentityKey(...)channelRouteDedupeKey(...)
channelRouteKey(...)channelRouteCompactKey(...)
ComparableChannelTargetChannelRouteParsedTarget
resolveComparableTargetForChannel(...)resolveRouteTargetForChannel(...)
resolveComparableTargetForLoadedChannel(...)resolveRouteTargetForLoadedChannel(...)
comparableChannelTargetsMatch(...)channelRouteTargetsMatchExact(...)
comparableChannelTargetsShareRoute(...)channelRouteTargetsShareConversation(...)
The modern route helpers normalize { channel, to, accountId, threadId } consistently across native approvals, reply suppression, inbound dedupe, cron delivery, and session routing. If your plugin owns custom target grammar, use resolveChannelRouteTargetWithParser(...) to adapt that parser into the same route target contract.
9

Build and test

pnpm build
pnpm test -- my-plugin/

Import path reference

Import pathPurposeKey exports
plugin-sdk/plugin-entryCanonical plugin entry helperdefinePluginEntry
plugin-sdk/coreLegacy umbrella re-export for channel entry definitions/buildersdefineChannelPluginEntry, createChatChannelPlugin
plugin-sdk/config-schemaRoot config schema exportOpenClawSchema
plugin-sdk/provider-entrySingle-provider entry helperdefineSingleProviderPluginEntry
plugin-sdk/channel-coreFocused channel entry definitions and buildersdefineChannelPluginEntry, defineSetupPluginEntry, createChatChannelPlugin, createChannelPluginBase
plugin-sdk/setupShared setup wizard helpersAllowlist prompts, setup status builders
plugin-sdk/setup-runtimeSetup-time runtime helpersImport-safe setup patch adapters, lookup-note helpers, promptResolvedAllowFrom, splitSetupEntries, delegated setup proxies
plugin-sdk/setup-adapter-runtimeSetup adapter helperscreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolsSetup tooling helpersformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR
plugin-sdk/account-coreMulti-account helpersAccount list/config/action-gate helpers
plugin-sdk/account-idAccount-id helpersDEFAULT_ACCOUNT_ID, account-id normalization
plugin-sdk/account-resolutionAccount lookup helpersAccount lookup + default-fallback helpers
plugin-sdk/account-helpersNarrow account helpersAccount list/account-action helpers
plugin-sdk/channel-setupSetup wizard adapterscreateOptionalChannelSetupSurface, createOptionalChannelSetupAdapter, createOptionalChannelSetupWizard, plus DEFAULT_ACCOUNT_ID, createTopLevelChannelDmPolicy, setSetupChannelEnabled, splitSetupEntries
plugin-sdk/channel-pairingDM pairing primitivescreateChannelPairingController
plugin-sdk/channel-reply-pipelineReply prefix, typing, and source-delivery wiringcreateChannelReplyPipeline, resolveChannelSourceReplyDeliveryMode
plugin-sdk/channel-config-helpersConfig adapter factories and DM access helperscreateHybridChannelConfigAdapter, resolveChannelDmAccess, resolveChannelDmAllowFrom, resolveChannelDmPolicy, normalizeChannelDmPolicy, normalizeLegacyDmAliases
plugin-sdk/channel-config-schemaConfig schema buildersShared channel config schema primitives and the generic builder only
plugin-sdk/bundled-channel-config-schemaBundled config schemasOpenClaw-maintained bundled plugins only; new plugins must define plugin-local schemas
plugin-sdk/channel-config-schema-legacyDeprecated bundled config schemasCompatibility alias only; use plugin-sdk/bundled-channel-config-schema for maintained bundled plugins
plugin-sdk/telegram-command-configTelegram command config helpersCommand-name normalization, description trimming, duplicate/conflict validation
plugin-sdk/channel-policyGroup/DM policy resolutionresolveChannelGroupRequireMention
plugin-sdk/channel-lifecycleAccount status and draft stream lifecycle helperscreateAccountStatusSink, draft preview finalization helpers
plugin-sdk/inbound-envelopeInbound envelope helpersShared route + envelope builder helpers
plugin-sdk/inbound-reply-dispatchInbound reply helpersShared record-and-dispatch helpers
plugin-sdk/messaging-targetsMessaging target parsingTarget parsing/matching helpers
plugin-sdk/outbound-mediaOutbound media helpersShared outbound media loading
plugin-sdk/outbound-send-depsOutbound send dependency helpersLightweight resolveOutboundSendDep lookup without importing the full outbound runtime
plugin-sdk/outbound-runtimeOutbound runtime helpersOutbound delivery, identity/send delegate, session, formatting, and payload planning helpers
plugin-sdk/thread-bindings-runtimeThread-binding helpersThread-binding lifecycle and adapter helpers
plugin-sdk/agent-media-payloadLegacy media payload helpersAgent media payload builder for legacy field layouts
plugin-sdk/channel-runtimeDeprecated compatibility shimLegacy channel runtime utilities only
plugin-sdk/channel-send-resultSend result typesReply result types
plugin-sdk/runtime-storePersistent plugin storagecreatePluginRuntimeStore
plugin-sdk/runtimeBroad runtime helpersRuntime/logging/backup/plugin-install helpers
plugin-sdk/runtime-envNarrow runtime env helpersLogger/runtime env, timeout, retry, and backoff helpers
plugin-sdk/plugin-runtimeShared plugin runtime helpersPlugin commands/hooks/http/interactive helpers
plugin-sdk/hook-runtimeHook pipeline helpersShared webhook/internal hook pipeline helpers
plugin-sdk/lazy-runtimeLazy runtime helperscreateLazyRuntimeModule, createLazyRuntimeMethod, createLazyRuntimeMethodBinder, createLazyRuntimeNamedExport, createLazyRuntimeSurface
plugin-sdk/process-runtimeProcess helpersShared exec helpers
plugin-sdk/cli-runtimeCLI runtime helpersCommand formatting, waits, version helpers
plugin-sdk/gateway-runtimeGateway helpersGateway client, event-loop-ready start helper, and channel-status patch helpers
plugin-sdk/config-runtimeDeprecated config compatibility shimPrefer config-types, plugin-config-runtime, runtime-config-snapshot, and config-mutation
plugin-sdk/telegram-command-configTelegram command helpersFallback-stable Telegram command validation helpers when the bundled Telegram contract surface is unavailable
plugin-sdk/approval-runtimeApproval prompt helpersExec/plugin approval payload, approval capability/profile helpers, native approval routing/runtime helpers, and structured approval display path formatting
plugin-sdk/approval-auth-runtimeApproval auth helpersApprover resolution, same-chat action auth
plugin-sdk/approval-client-runtimeApproval client helpersNative exec approval profile/filter helpers
plugin-sdk/approval-delivery-runtimeApproval delivery helpersNative approval capability/delivery adapters
plugin-sdk/approval-gateway-runtimeApproval gateway helpersShared approval gateway-resolution helper
plugin-sdk/approval-handler-adapter-runtimeApproval adapter helpersLightweight native approval adapter loading helpers for hot channel entrypoints
plugin-sdk/approval-handler-runtimeApproval handler helpersBroader approval handler runtime helpers; prefer the narrower adapter/gateway seams when they are enough
plugin-sdk/approval-native-runtimeApproval target helpersNative approval target/account binding helpers
plugin-sdk/approval-reply-runtimeApproval reply helpersExec/plugin approval reply payload helpers
plugin-sdk/channel-runtime-contextChannel runtime-context helpersGeneric channel runtime-context register/get/watch helpers
plugin-sdk/security-runtimeSecurity helpersShared trust, DM gating, root-bounded file/path helpers, external-content, and secret-collection helpers
plugin-sdk/ssrf-policySSRF policy helpersHost allowlist and private-network policy helpers
plugin-sdk/ssrf-runtimeSSRF runtime helpersPinned-dispatcher, guarded fetch, SSRF policy helpers
plugin-sdk/system-event-runtimeSystem event helpersenqueueSystemEvent, peekSystemEventEntries
plugin-sdk/heartbeat-runtimeHeartbeat helpersHeartbeat event and visibility helpers
plugin-sdk/delivery-queue-runtimeDelivery queue helpersdrainPendingDeliveries
plugin-sdk/channel-activity-runtimeChannel activity helpersrecordChannelActivity
plugin-sdk/dedupe-runtimeDedupe helpersIn-memory dedupe caches
plugin-sdk/file-access-runtimeFile access helpersSafe local-file/media path helpers
plugin-sdk/transport-ready-runtimeTransport readiness helperswaitForTransportReady
plugin-sdk/collection-runtimeBounded cache helperspruneMapToMaxSize
plugin-sdk/diagnostic-runtimeDiagnostic gating helpersisDiagnosticFlagEnabled, isDiagnosticsEnabled
plugin-sdk/error-runtimeError formatting helpersformatUncaughtError, isApprovalNotFoundError, error graph helpers
plugin-sdk/fetch-runtimeWrapped fetch/proxy helpersresolveFetch, proxy helpers, EnvHttpProxyAgent option helpers
plugin-sdk/host-runtimeHost normalization helpersnormalizeHostname, normalizeScpRemoteHost
plugin-sdk/retry-runtimeRetry helpersRetryConfig, retryAsync, policy runners
plugin-sdk/allow-fromAllowlist formattingformatAllowFromLowercase
plugin-sdk/allowlist-resolutionAllowlist input mappingmapAllowlistResolutionInputs
plugin-sdk/command-authCommand gating and command-surface helpersresolveControlCommandGate, sender-authorization helpers, command registry helpers including dynamic argument menu formatting
plugin-sdk/command-statusCommand status/help renderersbuildCommandsMessage, buildCommandsMessagePaginated, buildHelpMessage
plugin-sdk/secret-inputSecret input parsingSecret input helpers
plugin-sdk/webhook-ingressWebhook request helpersWebhook target utilities
plugin-sdk/webhook-request-guardsWebhook body guard helpersRequest body read/limit helpers
plugin-sdk/reply-runtimeShared reply runtimeInbound dispatch, heartbeat, reply planner, chunking
plugin-sdk/reply-dispatch-runtimeNarrow reply dispatch helpersFinalize, provider dispatch, and conversation-label helpers
plugin-sdk/reply-historyReply-history helpersbuildHistoryContext, buildPendingHistoryContextFromMap, recordPendingHistoryEntry, clearHistoryEntriesIfEnabled
plugin-sdk/reply-referenceReply reference planningcreateReplyReferencePlanner
plugin-sdk/reply-chunkingReply chunk helpersText/markdown chunking helpers
plugin-sdk/session-store-runtimeSession store helpersStore path + updated-at helpers
plugin-sdk/state-pathsState path helpersState and OAuth dir helpers
plugin-sdk/routingRouting/session-key helpersresolveAgentRoute, buildAgentSessionKey, resolveDefaultAgentBoundAccountId, session-key normalization helpers
plugin-sdk/status-helpersChannel status helpersChannel/account status summary builders, runtime-state defaults, issue metadata helpers
plugin-sdk/target-resolver-runtimeTarget resolver helpersShared target resolver helpers
plugin-sdk/string-normalization-runtimeString normalization helpersSlug/string normalization helpers
plugin-sdk/request-urlRequest URL helpersExtract string URLs from request-like inputs
plugin-sdk/run-commandTimed command helpersTimed command runner with normalized stdout/stderr
plugin-sdk/param-readersParam readersCommon tool/CLI param readers
plugin-sdk/tool-payloadTool payload extractionExtract normalized payloads from tool result objects
plugin-sdk/tool-sendTool send extractionExtract canonical send target fields from tool args
plugin-sdk/temp-pathTemp path helpersShared temp-download path helpers
plugin-sdk/logging-coreLogging helpersSubsystem logger and redaction helpers
plugin-sdk/markdown-table-runtimeMarkdown-table helpersMarkdown table mode helpers
plugin-sdk/reply-payloadMessage reply typesReply payload types
plugin-sdk/provider-setupCurated local/self-hosted provider setup helpersSelf-hosted provider discovery/config helpers
plugin-sdk/self-hosted-provider-setupFocused OpenAI-compatible self-hosted provider setup helpersSame self-hosted provider discovery/config helpers
plugin-sdk/provider-auth-runtimeProvider runtime auth helpersRuntime API-key resolution helpers
plugin-sdk/provider-auth-api-keyProvider API-key setup helpersAPI-key onboarding/profile-write helpers
plugin-sdk/provider-auth-resultProvider auth-result helpersStandard OAuth auth-result builder
plugin-sdk/provider-auth-loginProvider interactive login helpersShared interactive login helpers
plugin-sdk/provider-selection-runtimeProvider selection helpersConfigured-or-auto provider selection and raw provider config merging
plugin-sdk/provider-env-varsProvider env-var helpersProvider auth env-var lookup helpers
plugin-sdk/provider-model-sharedShared provider model/replay helpersProviderReplayFamily, buildProviderReplayFamilyHooks, normalizeModelCompat, shared replay-policy builders, provider-endpoint helpers, and model-id normalization helpers
plugin-sdk/provider-catalog-sharedShared provider catalog helpersfindCatalogTemplate, buildSingleProviderApiKeyCatalog, buildManifestModelProviderConfig, supportsNativeStreamingUsageCompat, applyProviderNativeStreamingUsageCompat
plugin-sdk/provider-onboardProvider onboarding patchesOnboarding config helpers
plugin-sdk/provider-httpProvider HTTP helpersGeneric provider HTTP/endpoint capability helpers, including audio transcription multipart form helpers
plugin-sdk/provider-web-fetchProvider web-fetch helpersWeb-fetch provider registration/cache helpers
plugin-sdk/provider-web-search-config-contractProvider web-search config helpersNarrow web-search config/credential helpers for providers that do not need plugin-enable wiring
plugin-sdk/provider-web-search-contractProvider web-search contract helpersNarrow web-search config/credential contract helpers such as createWebSearchProviderContractFields, enablePluginInConfig, resolveProviderWebSearchPluginConfig, and scoped credential setters/getters
plugin-sdk/provider-web-searchProvider web-search helpersWeb-search provider registration/cache/runtime helpers
plugin-sdk/provider-toolsProvider tool/schema compat helpersProviderToolCompatFamily, buildProviderToolCompatFamilyHooks, Gemini schema cleanup + diagnostics, and xAI compat helpers such as resolveXaiModelCompatPatch / applyXaiModelCompat
plugin-sdk/provider-usageProvider usage helpersfetchClaudeUsage, fetchGeminiUsage, fetchGithubCopilotUsage, and other provider usage helpers
plugin-sdk/provider-streamProvider stream wrapper helpersProviderStreamFamily, buildProviderStreamFamilyHooks, composeProviderStreamWrappers, stream wrapper types, and shared Anthropic/Bedrock/DeepSeek V4/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot wrapper helpers
plugin-sdk/provider-transport-runtimeProvider transport helpersNative provider transport helpers such as guarded fetch, transport message transforms, and writable transport event streams
plugin-sdk/keyed-async-queueOrdered async queueKeyedAsyncQueue
plugin-sdk/media-runtimeShared media helpersMedia fetch/transform/store helpers, ffprobe-backed video dimension probing, and media payload builders
plugin-sdk/media-generation-runtimeShared media-generation helpersShared failover helpers, candidate selection, and missing-model messaging for image/video/music generation
plugin-sdk/media-understandingMedia-understanding helpersMedia understanding provider types plus provider-facing image/audio helper exports
plugin-sdk/text-runtimeShared text helpersAssistant-visible-text stripping, markdown render/chunking/table helpers, redaction helpers, directive-tag helpers, safe-text utilities, and related text/logging helpers
plugin-sdk/text-chunkingText chunking helpersOutbound text chunking helper
plugin-sdk/speechSpeech helpersSpeech provider types plus provider-facing directive, registry, validation helpers, and OpenAI-compatible TTS builder
plugin-sdk/speech-coreShared speech coreSpeech provider types, registry, directives, normalization
plugin-sdk/realtime-transcriptionRealtime transcription helpersProvider types, registry helpers, and shared WebSocket session helper
plugin-sdk/realtime-voiceRealtime voice helpersProvider types, registry/resolution helpers, bridge session helpers, shared agent talk-back queues, transcript/event health, echo suppression, and fast context consult helpers
plugin-sdk/image-generationImage-generation helpersImage generation provider types plus image asset/data URL helpers and the OpenAI-compatible image provider builder
plugin-sdk/image-generation-coreShared image-generation coreImage-generation types, failover, auth, and registry helpers
plugin-sdk/music-generationMusic-generation helpersMusic-generation provider/request/result types
plugin-sdk/music-generation-coreShared music-generation coreMusic-generation types, failover helpers, provider lookup, and model-ref parsing
plugin-sdk/video-generationVideo-generation helpersVideo-generation provider/request/result types
plugin-sdk/video-generation-coreShared video-generation coreVideo-generation types, failover helpers, provider lookup, and model-ref parsing
plugin-sdk/interactive-runtimeInteractive reply helpersInteractive reply payload normalization/reduction
plugin-sdk/channel-config-primitivesChannel config primitivesNarrow channel config-schema primitives
plugin-sdk/channel-config-writesChannel config-write helpersChannel config-write authorization helpers
plugin-sdk/channel-plugin-commonShared channel preludeShared channel plugin prelude exports
plugin-sdk/channel-statusChannel status helpersShared channel status snapshot/summary helpers
plugin-sdk/allowlist-config-editAllowlist config helpersAllowlist config edit/read helpers
plugin-sdk/group-accessGroup access helpersShared group-access decision helpers
plugin-sdk/direct-dmDirect-DM helpersShared direct-DM auth/guard helpers
plugin-sdk/extension-sharedShared extension helpersPassive-channel/status and ambient proxy helper primitives
plugin-sdk/webhook-targetsWebhook target helpersWebhook target registry and route-install helpers
plugin-sdk/webhook-pathWebhook path helpersWebhook path normalization helpers
plugin-sdk/web-mediaShared web media helpersRemote/local media loading helpers
plugin-sdk/zodZod re-exportRe-exported zod for plugin SDK consumers
plugin-sdk/memory-coreBundled memory-core helpersMemory manager/config/file/CLI helper surface
plugin-sdk/memory-core-engine-runtimeMemory engine runtime facadeMemory index/search runtime facade
plugin-sdk/memory-core-host-engine-foundationMemory host foundation engineMemory host foundation engine exports
plugin-sdk/memory-core-host-engine-embeddingsMemory host embedding engineMemory embedding contracts, registry access, local provider, and generic batch/remote helpers; concrete remote providers live in their owning plugins
plugin-sdk/memory-core-host-engine-qmdMemory host QMD engineMemory host QMD engine exports
plugin-sdk/memory-core-host-engine-storageMemory host storage engineMemory host storage engine exports
plugin-sdk/memory-core-host-multimodalMemory host multimodal helpersMemory host multimodal helpers
plugin-sdk/memory-core-host-queryMemory host query helpersMemory host query helpers
plugin-sdk/memory-core-host-secretMemory host secret helpersMemory host secret helpers
plugin-sdk/memory-core-host-eventsMemory host event journal helpersMemory host event journal helpers
plugin-sdk/memory-core-host-statusMemory host status helpersMemory host status helpers
plugin-sdk/memory-core-host-runtime-cliMemory host CLI runtimeMemory host CLI runtime helpers
plugin-sdk/memory-core-host-runtime-coreMemory host core runtimeMemory host core runtime helpers
plugin-sdk/memory-core-host-runtime-filesMemory host file/runtime helpersMemory host file/runtime helpers
plugin-sdk/memory-host-coreMemory host core runtime aliasVendor-neutral alias for memory host core runtime helpers
plugin-sdk/memory-host-eventsMemory host event journal aliasVendor-neutral alias for memory host event journal helpers
plugin-sdk/memory-host-filesMemory host file/runtime aliasVendor-neutral alias for memory host file/runtime helpers
plugin-sdk/memory-host-markdownManaged markdown helpersShared managed-markdown helpers for memory-adjacent plugins
plugin-sdk/memory-host-searchActive memory search facadeLazy active-memory search-manager runtime facade
plugin-sdk/memory-host-statusMemory host status aliasVendor-neutral alias for memory host status helpers
plugin-sdk/testingTest utilitiesLegacy broad compatibility barrel; prefer focused test subpaths such as plugin-sdk/plugin-test-runtime, plugin-sdk/channel-test-helpers, plugin-sdk/channel-target-testing, plugin-sdk/test-env, and plugin-sdk/test-fixtures
This table is intentionally the common migration subset, not the full SDK surface. The full list of 200+ entrypoints lives in scripts/lib/plugin-sdk-entrypoints.json. Reserved bundled-plugin helper seams have been retired from the public SDK export map except for explicitly documented compatibility facades such as the deprecated plugin-sdk/discord shim retained for the published @openclaw/discord@2026.3.13 package. Owner-specific helpers live inside the owning plugin package; shared host behavior should move through generic SDK contracts such as plugin-sdk/gateway-runtime, plugin-sdk/security-runtime, and plugin-sdk/plugin-config-runtime. Use the narrowest import that matches the job. If you cannot find an export, check the source at src/plugin-sdk/ or ask maintainers which generic contract should own it.

Active deprecations

Narrower deprecations that apply across the plugin SDK, provider contract, runtime surface, and manifest. Each one still works today but will be removed in a future major release. The entry below every item maps the old API to its canonical replacement.
Old (openclaw/plugin-sdk/command-auth): buildCommandsMessage, buildCommandsMessagePaginated, buildHelpMessage.New (openclaw/plugin-sdk/command-status): same signatures, same exports - just imported from the narrower subpath. command-auth re-exports them as compat stubs.
// Before
import { buildHelpMessage } from "openclaw/plugin-sdk/command-auth";

// After
import { buildHelpMessage } from "openclaw/plugin-sdk/command-status";
Old: resolveInboundMentionRequirement({ facts, policy }) and shouldDropInboundForMention(...) from openclaw/plugin-sdk/channel-inbound or openclaw/plugin-sdk/channel-mention-gating.New: resolveInboundMentionDecision({ facts, policy }) - returns a single decision object instead of two split calls.Downstream channel plugins (Slack, Discord, Matrix, MS Teams) have already switched.
openclaw/plugin-sdk/channel-runtime is a compatibility shim for older channel plugins. Do not import it from new code; use openclaw/plugin-sdk/channel-runtime-context for registering runtime objects.channelActions* helpers in openclaw/plugin-sdk/channel-actions are deprecated alongside raw “actions” channel exports. Expose capabilities through the semantic presentation surface instead - channel plugins declare what they render (cards, buttons, selects) rather than which raw action names they accept.
Old: tool() factory from openclaw/plugin-sdk/provider-web-search.New: implement createTool(...) directly on the provider plugin. OpenClaw no longer needs the SDK helper to register the tool wrapper.
Old: formatInboundEnvelope(...) (and ChannelMessageForAgent.channelEnvelope) to build a flat plaintext prompt envelope from inbound channel messages.New: BodyForAgent plus structured user-context blocks. Channel plugins attach routing metadata (thread, topic, reply-to, reactions) as typed fields instead of concatenating them into a prompt string. The formatAgentEnvelope(...) helper is still supported for synthesized assistant-facing envelopes, but inbound plaintext envelopes are on the way out.Affected areas: inbound_claim, message_received, and any custom channel plugin that post-processed channelEnvelope text.
Four discovery type aliases are now thin wrappers over the catalog-era types:
Old aliasNew type
ProviderDiscoveryOrderProviderCatalogOrder
ProviderDiscoveryContextProviderCatalogContext
ProviderDiscoveryResultProviderCatalogResult
ProviderPluginDiscoveryProviderPluginCatalog
Plus the legacy ProviderCapabilities static bag - provider plugins should use explicit provider hooks such as buildReplayPolicy, normalizeToolSchemas, and wrapStreamFn rather than a static object.
Old (three separate hooks on ProviderThinkingPolicy): isBinaryThinking(ctx), supportsXHighThinking(ctx), and resolveDefaultThinkingLevel(ctx).New: a single resolveThinkingProfile(ctx) that returns a ProviderThinkingProfile with the canonical id, optional label, and ranked level list. OpenClaw downgrades stale stored values by profile rank automatically.Implement one hook instead of three. The legacy hooks keep working during the deprecation window but are not composed with the profile result.
Old: implementing resolveExternalOAuthProfiles(...) without declaring the provider in the plugin manifest.New: declare contracts.externalAuthProviders in the plugin manifest and implement resolveExternalAuthProfiles(...). The old “auth fallback” path emits a warning at runtime and will be removed.
{
  "contracts": {
    "externalAuthProviders": ["anthropic", "openai"]
  }
}
Old manifest field: providerAuthEnvVars: { anthropic: ["ANTHROPIC_API_KEY"] }.New: mirror the same env-var lookup into setup.providers[].envVars on the manifest. This consolidates setup/status env metadata in one place and avoids booting the plugin runtime just to answer env-var lookups.providerAuthEnvVars remains supported through a compatibility adapter until the deprecation window closes.
Old: three separate calls - api.registerMemoryPromptSection(...), api.registerMemoryFlushPlan(...), api.registerMemoryRuntime(...).New: one call on the memory-state API - registerMemoryCapability(pluginId, { promptBuilder, flushPlanResolver, runtime }).Same slots, single registration call. Additive memory helpers (registerMemoryPromptSupplement, registerMemoryCorpusSupplement, registerMemoryEmbeddingProvider) are not affected.
Two legacy type aliases still exported from src/plugins/runtime/types.ts:
OldNew
SubagentReadSessionParamsSubagentGetSessionMessagesParams
SubagentReadSessionResultSubagentGetSessionMessagesResult
The runtime method readSession is deprecated in favor of getSessionMessages. Same signature; the old method calls through to the new one.
Old: runtime.tasks.flow (singular) returned a live task-flow accessor.New: runtime.tasks.managedFlows keeps the managed TaskFlow mutation runtime for plugins that create, update, cancel, or run child tasks from a flow. Use runtime.tasks.flows when the plugin only needs DTO-based reads.
// Before
const flow = api.runtime.tasks.flow.fromToolContext(ctx);
// After
const flow = api.runtime.tasks.managedFlows.fromToolContext(ctx);
Covered in “How to migrate → Migrate Pi tool-result extensions to middleware” above. Included here for completeness: the removed Pi-only api.registerEmbeddedExtensionFactory(...) path is replaced by api.registerAgentToolResultMiddleware(...) with an explicit runtime list in contracts.agentToolResultMiddleware.
OpenClawSchemaType re-exported from openclaw/plugin-sdk is now a one-line alias for OpenClawConfig. Prefer the canonical name.
// Before
import type { OpenClawSchemaType } from "openclaw/plugin-sdk";
// After
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-schema";
Extension-level deprecations (inside bundled channel/provider plugins under extensions/) are tracked inside their own api.ts and runtime-api.ts barrels. They do not affect third-party plugin contracts and are not listed here. If you consume a bundled plugin’s local barrel directly, read the deprecation comments in that barrel before upgrading.

Removal timeline

WhenWhat happens
NowDeprecated surfaces emit runtime warnings
Next major releaseDeprecated surfaces will be removed; plugins still using them will fail
All core plugins have already been migrated. External plugins should migrate before the next major release.

Suppressing the warnings temporarily

Set these environment variables while you work on migrating:
OPENCLAW_SUPPRESS_PLUGIN_SDK_COMPAT_WARNING=1 openclaw gateway run
OPENCLAW_SUPPRESS_EXTENSION_API_WARNING=1 openclaw gateway run
This is a temporary escape hatch, not a permanent solution.