# Removed surfaces and replacements

> Removed SDK surfaces and the replacement for each removed or deprecated API

- 网址：https://funcoding.ai/agents/openclaw/plugins/sdk-migration/removed-surfaces/
- 来源：OpenClaw 官方文档原文（英文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/plugins/sdk-migration/removed-surfaces

---
What the July 2026 sweep removed, plus the per-API replacement mappings for removed surfaces and later-window deprecations. Part of the [Plugin SDK migration](https://funcoding.ai/agents/openclaw/plugins/sdk-migration/) guide.

## Removed compatibility surfaces

The July 2026 sweep removed the root SDK and compat barrels, the extension API
bridge, the expired SDK subpath aliases, unused SDK subpaths, and typed-public
access to bundled-only SDK modules. Private-local build mappings remain for
repository owners, and production-private JavaScript exports support official
plugin runtimes. Neither provides typed third-party SDK access.

### Channel, config, and infrastructure compatibility facades

`channel-lifecycle`, `channel-message`, `channel-reply-pipeline`,
`config-runtime`, and `infra-runtime` were removed with SDK-owner approval on
September 30, 2026. Channel imports move to focused outbound and inbound
contracts; config access uses supplied config, snapshots, and mutation helpers;
infrastructure imports move to the matching focused runtime or injected API.
System-event snapshot inspection and consumption use `system-event-runtime`.

Some legacy helpers and named types require caller changes rather than an
import-path substitution. See the [channel mappings](https://funcoding.ai/agents/openclaw/plugins/sdk-migration/import-paths/#retained-channel-facade-mappings)
and [config and infrastructure migration steps](https://funcoding.ai/agents/openclaw/plugins/sdk-migration/how-to-migrate/).

### Command, Discord, and Telegram account facades

`command-auth`, `discord`, and `telegram-account` were removed with explicit
SDK-owner approval on October 2, 2026. Move sender authorization to
`channel-ingress-runtime`, native command helpers to `command-auth-native`, and
help builders to `command-status`. Discord and Telegram behavior remains owned
by their plugins; use generic channel contracts and injected runtime helpers
from external plugins, and the owning plugin's `api.ts` / `runtime-api.ts`
barrels for repository consumers.

These are breaking removals for third-party plugins that still import the old
subpaths, including older published `@openclaw/discord` packages. Upgrade affected
plugins before upgrading the host. Not every export has a path-only replacement;
see the [per-surface mappings](https://funcoding.ai/agents/openclaw/plugins/sdk-migration/import-paths/#removed-command-and-channel-facades).

### Retroactively recorded shipped exports

The following exports shipped in `v2026.9.8` and were removed without a
compatibility window. Their removals were recorded retroactively on October 7,
2026 when the shipped-surface guard was introduced; the exports remain removed.
The registry's `removeAfter` is the UTC day before the removing commit landed,
not a compatibility window that was offered to plugin authors.

| Removed export (`openclaw/plugin-sdk/` prefix)                 | Landed (UTC) | `removeAfter` | Replacement                                                                                           |
| -------------------------------------------------------------- | ------------ | ------------- | ----------------------------------------------------------------------------------------------------- |
| `allow-from.mapBasicAllowlistResolutionEntries`                | 2026-10-05   | 2026-10-04    | None; project `BasicAllowlistResolutionEntry` fields in the consuming plugin.                         |
| `computer-use.compileComputerUseValidator`                     | 2026-10-05   | 2026-10-04    | `Compile(schema).Check` from `typebox/compile`, using the exported Computer Use schemas.              |
| `extension-shared.runStoppablePassiveMonitor`                  | 2026-10-05   | 2026-10-04    | `channel-outbound.runPassiveAccountLifecycle` with `stop: (monitor) => monitor.stop()`.               |
| `gateway-runtime.resolveAdvertisedLanHost`                     | 2026-10-05   | 2026-10-04    | None; advertised LAN host discovery is host-owned.                                                    |
| `json-store.readJsonFileWithFallback`                          | 2026-10-05   | 2026-10-04    | None; own JSON artifact parsing, fallback, and file-existence handling in the plugin.                 |
| `provider-auth.normalizeSecretInputModeInput`                  | 2026-10-05   | 2026-10-04    | None; validate plugin-owned input as the exported `SecretInputMode` values `plaintext` or `ref`.      |
| `persistent-dedupe.PersistentDedupeLegacyJsonMigrationOptions` | 2026-10-05   | 2026-10-04    | None; the legacy JSON migration was retired.                                                          |
| `persistent-dedupe.PersistentDedupeLegacyJsonMigrationResult`  | 2026-10-05   | 2026-10-04    | None; the legacy JSON migration was retired.                                                          |
| `persistent-dedupe.listPersistentDedupeLegacyJsonFileEntries`  | 2026-10-05   | 2026-10-04    | None; the legacy JSON migration was retired.                                                          |
| `persistent-dedupe.migratePersistentDedupeLegacyJsonFile`      | 2026-10-05   | 2026-10-04    | None; the legacy JSON migration was retired. Runtime dedupe continues through the SQLite-backed APIs. |
| `provider-auth.CachedCopilotToken`                             | 2026-10-02   | 2026-10-01    | Provider-local GitHub Copilot auth APIs; none in the public SDK.                                      |
| `provider-auth.DEFAULT_COPILOT_API_BASE_URL`                   | 2026-10-02   | 2026-10-01    | Provider-local GitHub Copilot auth APIs; none in the public SDK.                                      |
| `provider-auth.deriveCopilotApiBaseUrlFromToken`               | 2026-10-02   | 2026-10-01    | Provider-local GitHub Copilot auth APIs; none in the public SDK.                                      |
| `provider-auth.resolveCopilotApiToken`                         | 2026-10-02   | 2026-10-01    | Provider-local GitHub Copilot auth APIs; none in the public SDK.                                      |

The first six exports were removed in
[`2fec39f57319be5b6e0b20b5305665ed1ff5e685`](https://github.com/openclaw/openclaw/commit/2fec39f57319be5b6e0b20b5305665ed1ff5e685).
The four legacy JSON migration exports were removed in
[`bd64d93ff1ae704d13813f6580c4809ba0e76606`](https://github.com/openclaw/openclaw/commit/bd64d93ff1ae704d13813f6580c4809ba0e76606).
The four Copilot exports and their earlier deprecation entries were removed in
[`f2de06b38de710854aacd19218327358445816c8`](https://github.com/openclaw/openclaw/commit/f2de06b38de710854aacd19218327358445816c8);
third-party plugins must own their provider-specific token exchange and caching.

### Process-global API-provider publication

`registerApiProvider(...)` and `unregisterApiProviders(...)` were removed from
`openclaw/plugin-sdk/llm`. They published API transports into process-global
state, which lifecycle-owned model runtimes then had to copy into each prepared
registry.

Provider plugins should register text-inference providers through
`api.registerProvider(...)`. Host-owned code and tests that construct an
`ApiRegistry` should register directly on that registry so provider ownership
and teardown stay scoped to the prepared runtime.

### Deactivate hook alias

The `api.on("deactivate", handler)` compatibility alias was removed. Register
the same shutdown cleanup with `gateway_stop`:

```typescript
// Before
api.on("deactivate", async (event, ctx) => {
  await stopPluginService(ctx);
});

// After
api.on("gateway_stop", async (event, ctx) => {
  await stopPluginService(ctx);
});
```

### Skill Workshop proposal hooks

The `skill_proposal_evaluate` and `skill_proposal_changed` hooks were removed
together with Skill Workshop proposals. Workshop now applies each change
immediately and keeps a restorable version, so there is no pending draft to
evaluate and no proposal lifecycle to observe. The hook runner methods
`runSkillProposalEvaluate` and `runSkillProposalChanged` were removed, and
`openclaw/plugin-sdk/plugin-entry` no longer exports
`PluginHookSkillProposalEvaluateEvent`, `PluginHookSkillProposalEvaluateResult`,
`PluginHookSkillProposalEvaluationOutcome`, `PluginHookSkillProposalChangedEvent`,
`PluginHookSkillProposalKind`, `PluginHookSkillEvaluationFinding`,
`PluginHookSkillBundleFile`, or `PluginHookSkillBundleSnapshot`. The optional
`proposal` field on `PluginHookSkillChangedEvent` was removed too.

To observe committed Workshop skill writes, register `skill_changed` and filter
on `source: "workshop"`. There is no replacement for pre-apply evaluation.
Registering a removed hook name logs an `unknown typed hook` warning and the
handler never runs.

### Private testing barrel

`openclaw/plugin-sdk/testing` was repo-local and excluded from shipped package
artifacts, so it was removed before its 2026-07-28 `removeAfter` date. Repository
tests use focused 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`.

### Credential prompt builder

`buildCredentialSafetyPrompt` remains available from
`openclaw/plugin-sdk/agent-harness-runtime`. With an options object whose
`controlToolsAvailable` is set from the callable `openclaw` and `gateway` tools, it
returns guidance to use or store user-shared credentials as asked, complete the
task, and briefly acknowledge their use or storage in the final reply without
repeating their values. The acknowledgment stays factual and non-alarming. It also
returns the private login-code handoff guidance and the terminal setup route when
neither control tool is available.

The legacy string argument is deprecated from 2026-09-09 and remains supported
through 2026-11-30. It is accepted and ignored: availability is unknown, so the
helper returns only the private handoff line. Replace strings with
`{ controlToolsAvailable }`; the string form is eligible for removal starting
2026-12-01. The helper itself is not deprecated.

## Migration reference

These mappings cover both removed July 2026 surfaces and later-window active
deprecations. A mapping is migration guidance, not evidence that the old
surface remains available; consult the compatibility registry and removal
timeline for current status.

<details>
<summary>command-auth help builders -> command-status</summary>

**Old (`openclaw/plugin-sdk/command-auth`)**: `buildCommandsMessage`,
`buildCommandsMessagePaginated`, `buildHelpMessage`.

**New (`openclaw/plugin-sdk/command-status`)**: same signatures, imported
from the narrower subpath. The `command-auth` compatibility re-exports
have been removed.

```typescript
// Before
import { buildHelpMessage } from "openclaw/plugin-sdk/command-auth";

// After
import { buildHelpMessage } from "openclaw/plugin-sdk/command-status";
```

</details>

<details>
<summary>Mention gating helpers -> resolveInboundMentionDecision</summary>

**Old**: `resolveMentionGating(params)` and
`resolveMentionGatingWithBypass(params)` from
`openclaw/plugin-sdk/channel-inbound` or
`openclaw/plugin-sdk/channel-mention-gating`.

**New**: `resolveInboundMentionDecision({ facts, policy })` - one decision
object instead of two split call shapes.

Adopted across Discord, iMessage, Matrix, MS Teams, QQBot, Signal,
Telegram, WhatsApp, and Zalo. Slack's own `app_mention` event model does
not use this helper.

</details>

<details>
<summary>Channel runtime shim and channel actions helpers</summary>

`openclaw/plugin-sdk/channel-runtime` has been removed. Use
`openclaw/plugin-sdk/channel-runtime-context` for registering runtime
objects.

The native message schema helpers in `openclaw/plugin-sdk/channel-actions`
were removed 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.

</details>

<details>
<summary>Web search provider tool() helper -> createTool() on the plugin</summary>

**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.

</details>

<details>
<summary>Plaintext channel envelopes -> BodyForAgent</summary>

**Old**: `api.runtime.channel.reply.formatInboundEnvelope(...)` (and the
`channelEnvelope` field on inbound message objects) 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 the old envelope text.

</details>

<details>
<summary>subagent_spawning hook -> core thread binding</summary>

**Old**: `api.on("subagent_spawning", handler)` returning
`threadBindingReady` or `deliveryOrigin`.

**New**: let core prepare `thread: true` subagent bindings through the
channel session-binding adapter. Use `api.on("subagent_spawned", handler)`
only for post-launch observation.

```typescript
// Before
api.on("subagent_spawning", async () => ({
  status: "ok",
  threadBindingReady: true,
  deliveryOrigin: { channel: "discord", to: "channel:123", threadId: "456" },
}));

// After
api.on("subagent_spawned", async (event) => {
  await observeSubagentLaunch(event);
});
```

The `subagent_spawning` hook and its event/result types were removed in
August 2026 after thread binding moved to the core session-binding path.

</details>

<details>
<summary>Provider discovery types -> provider catalog types</summary>

Four discovery type aliases are now thin wrappers over the catalog-era
types:

| Old alias                 | New type                  |
| ------------------------- | ------------------------- |
| `ProviderDiscoveryOrder`  | `ProviderCatalogOrder`    |
| `ProviderDiscoveryContext`| `ProviderCatalogContext`  |
| `ProviderDiscoveryResult` | `ProviderCatalogResult`   |
| `ProviderPluginDiscovery` | `ProviderPluginCatalog`   |

The aliases and legacy `ProviderCapabilities` static bag have been
removed. Provider plugins
should use explicit provider hooks such as `buildReplayPolicy`,
`normalizeToolSchemas`, and `wrapStreamFn` rather than a static object.

</details>

<details>
<summary>Thinking policy hooks -> resolveThinkingProfile</summary>

**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 a
ranked level list. OpenClaw downgrades stale stored values by profile rank
automatically.

The context includes `provider`, `modelId`, optional merged `reasoning`,
and optional merged model `compat` facts. Provider plugins can use those
catalog facts to expose a model-specific profile only when the configured
request contract supports it.

Implement one hook instead of three. The legacy hooks have been removed.

</details>

<details>
<summary>External auth providers -> contracts.externalAuthProviders</summary>

**Old**: implementing external auth hooks without declaring the provider
in the plugin manifest.

**New**: declare `contracts.externalAuthProviders` in the plugin manifest
**and** implement `resolveExternalAuthProfiles(...)`.

```json
{
  "contracts": {
    "externalAuthProviders": ["anthropic", "openai"]
  }
}
```

</details>

<details>
<summary>Provider env-var lookup -> setup.providers[].envVars</summary>

**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` is no longer accepted.

</details>

<details>
<summary>Memory plugin registration -> registerMemoryCapability</summary>

**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 prompt and corpus helpers
(`registerMemoryPromptSupplement`, `registerMemoryCorpusSupplement`) are
not affected.

</details>

<details>
<summary>Memory embedding provider API</summary>

**Old**: `api.registerMemoryEmbeddingProvider(...)` plus
`contracts.memoryEmbeddingProviders`.

**New**: `api.registerEmbeddingProvider(...)` plus
`contracts.embeddingProviders`.

The generic embedding provider contract is reusable outside memory and is
the supported path for every provider. The memory-specific registration API
and manifest contract were removed after the **2026-08-21** migration
deadline.

</details>

<details>
<summary>Raw channel send results -> OutboundDeliveryResult</summary>

**Old**: return `{ ok, messageId, error }` through
`ChannelSendRawResult` and normalize it with
`createRawChannelSendResultAdapter(...)`.

**New**: return `OutboundDeliveryResult` fields and attach the channel with
`createAttachedChannelResultAdapter(...)`. Failed sends should throw instead
of returning an error string. Put the platform destination in
`target: { kind: "chat" | "channel" | "room" | "conversation", id }`;
the old parallel `chatId`, `channelId`, `roomId`, and `conversationId`
result fields are no longer accepted. The raw result type remains available
until the next plugin-SDK major release.

</details>

<details>
<summary>Subagent session messages types renamed</summary>

Two legacy type aliases still exported from `src/plugins/runtime/types.ts`:

| Old                           | New                             |
| ----------------------------- | ------------------------------- |
| `SubagentReadSessionParams`   | `SubagentGetSessionMessagesParams` |
| `SubagentReadSessionResult`   | `SubagentGetSessionMessagesResult` |

The runtime method `readSession` is deprecated in favor of
`getSessionMessages`. Same signature; the old method calls through to the
new one.

</details>

<details>
<summary>Removed session and transcript file APIs</summary>

The SQLite session/transcript flip removes or deprecates plugin-facing APIs
that exposed active `sessions.json` stores, JSONL transcript paths, or lists
of session files. Runtime plugins should use session identity and SDK runtime
helpers instead of resolving or mutating active files.

| Migrating surface | Replacement |
| ----------------- | ----------- |
| Removed `loadSessionStore(...)` and `resolveSessionStoreEntry(...)`, including package-root `loadSessionStore(...)` | `getSessionEntry(...)` for one scoped row or `listSessionEntries(...)` for scoped iteration from `openclaw/plugin-sdk/session-store-runtime`. |
| Removed `updateSessionStore(...)`, package-root `saveSessionStore(...)`, and SDK file-store writes | `patchSessionEntry(...)`, `upsertSessionEntry(...)`, and `deleteSessionEntry(...)` from `openclaw/plugin-sdk/session-store-runtime`; mutate only the intended rows instead of replacing a detached whole-store snapshot. |
| Removed `LoadSessionStoreOptions` and `UpdateSessionStoreOptions` | Parameters accepted by the scoped row APIs; the whole-store cache and callback options no longer apply. |
| Removed `resolveSessionFilePath(...)` | Session identity (`agentId`, `sessionKey`, and `sessionId`) with `openclaw/plugin-sdk/session-transcript-runtime`, or Gateway methods that operate on the current session. |
| Removed `resolveSessionTranscriptPathInDir(...)` and `resolveAndPersistSessionFile(...)` | Session identity and Gateway methods that operate on the current session. |
| `readLatestAssistantTextFromSessionTranscript(...)` | Identity-backed transcript readers exposed by the current runtime context, or Gateway history/session methods when the plugin is outside the transcript owner path. |
| `SessionTranscriptUpdate.sessionFile` | `SessionTranscriptUpdate.target` with `agentId`, `sessionKey`, and `sessionId`. |
| Memory sync inputs such as `sessionFiles` | Identity-backed transcript/session sources provided by the host; do not crawl active JSONL files for live sessions. |
| Runtime options named `transcriptPath` or `sessionFile` for active sessions | `sessionTarget`/runtime target objects that carry storage-neutral session identity. |

Legacy JSONL transcript files remain valid as import, archive, export, and
support artifacts. They are no longer the steady-state runtime contract for
active sessions.

The official `@openclaw/codex` and `@openclaw/feishu` plugins released with
`v2026.7.1-beta.5` imported the retired bridge. SDK-owner approval on
September 30, 2026 closed its compatibility window early, replacing the
former October 12 deadline. The supported-plugin cutoff excludes that
release and any other package still importing the
bridge. Upgrade affected plugins to versions using the replacements before
upgrading OpenClaw. A newer version number alone is not evidence of migration.

`openclaw/plugin-sdk/session-store-runtime` and `resolveStorePath(...)`
remain supported. Pass the selected `agentId` explicitly to scoped row
operations; resolving a path no longer records an agent selection for a
later whole-store call. This removal does not change SQLite schemas or
legacy-state import and Doctor migrations.

`openclaw plugins inspect --all --runtime` reports non-bundled plugins whose
load errors or diagnostics still reference these removed file APIs. The
`@openclaw/plugin-inspector` advisory sweep must use version `0.3.17` or
newer so external package scans also flag whole-store session helpers,
session file-path helpers, legacy transcript file targets, and low-level
transcript helpers before release.

</details>

<details>
<summary>Agent harness attempt params -> V2 host-capability contract</summary>

New or updated harness plugins should implement `AgentHarnessV2` and use
`AgentHarnessAttemptParamsV2`, `EmbeddedRunAttemptParamsV2`, or
`AgentHarnessSideQuestionParamsV2`. The V2 parameter types require
`hostCapabilities`, matching what core supplies at the selected-harness
boundary. A plugin that adopts these V2 contracts must declare
`openclaw.compat.pluginApi: ">=2026.8.1"` (or a newer floor) in its package
manifest so an older host rejects the plugin before loading it.

Existing plugins may continue implementing `AgentHarness` and constructing
the legacy `AgentHarnessAttemptParams`, `EmbeddedRunAttemptParams`, or
`AgentHarnessSideQuestionParams` types without that field through
2026-10-12. Those contracts keep the capability optional only for source
compatibility; they do not create a capability-free runtime path. Migrate
by changing the imported type name and binding tool or native-action surfaces through
`params.hostCapabilities`.

</details>

<details>
<summary>Tasks and TaskFlow APIs removed</summary>

The Tasks registry and TaskFlow orchestration APIs have been removed,
including `api.runtime.tasks`, `registerDetachedTaskRuntime`, and the
`agent-harness-task-runtime` SDK subpath. No compatibility facade remains.
Use native subagent launch/wait/history APIs, cron run history, and the
ordinary Lobster runner for their respective operations. Harness completion
routing uses the completion-only `agent-harness-completion` subpath.
This removal does not change the physical database schemas. Existing
`task_runs`, `task_delivery_state`, and `flow_runs` tables, columns, and indexes
remain unchanged. Cron reads and writes only its `runtime = 'cron'` history
rows in `task_runs`; non-Cron Task and TaskFlow rows remain untouched and
unused by the runtime. The Codex plugin's
[Doctor migration](https://funcoding.ai/agents/openclaw/gateway/doctor/config-migrations/#native-codex-recovery-after-tasks-removal)
preserves eligible owner-stamped native recovery facts in existing parent
binding metadata, leaving source rows byte-identical. It adds no runtime Task
reader or replacement SDK surface; current requester authority still governs
completion delivery. See the [versioning contract](https://funcoding.ai/agents/openclaw/reference/database-schemas/versioning/).

</details>

<details>
<summary>Embedded extension factories -> agent tool-result middleware</summary>

Covered in [How to migrate](https://funcoding.ai/agents/openclaw/plugins/sdk-migration/how-to-migrate/#how-to-migrate). Included here for
completeness: the removed embedded-runner-only
`api.registerEmbeddedExtensionFactory(...)` path is replaced by
`api.registerAgentToolResultMiddleware(...)` with an explicit runtime list
in `contracts.agentToolResultMiddleware`.

</details>

<details>
<summary>OpenClawSchemaType alias -> OpenClawConfig</summary>

The `OpenClawSchemaType` root-SDK alias was removed. Use the canonical
`OpenClawConfig` name.

```typescript
// Before
import type { OpenClawSchemaType } from "openclaw/plugin-sdk";
// After
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
```

</details>

<div class="callout callout-note">

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.

</div>
