mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:00:43 +00:00
chore(plugins): finish compat registry cleanup
This commit is contained in:
@@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugins/compat: add missing dated compatibility records for legacy extension-api, memory registration, provider hook/type aliases, runtime aliases, channel SDK helpers, and approval/test utility shims. Thanks @vincentkoc.
|
||||
- Plugins/CLI: make plugin install and uninstall config writes conflict-aware, clear stale denylist entries on explicit reinstall/removal, and delete managed plugin files only after config/index commit succeeds. Thanks @codex.
|
||||
- Plugins: fail `plugins update` when tracked plugin or hook updates error, keep bundled runtime-dependency repair behind restrictive allowlists, and reject package installs with unloadable extension entries. Thanks @codex.
|
||||
- Gateway/chat: keep duplicate attachment-backed `chat.send` retries with the same idempotency key on the documented in-flight path so aborts still target the real active run. Fixes #70139. Thanks @Feelw00.
|
||||
|
||||
@@ -84,11 +84,20 @@ Current compatibility records include:
|
||||
- legacy hook-only plugin shapes and `before_agent_start`
|
||||
- legacy `activate(api)` plugin entrypoints while plugins migrate to
|
||||
`register(api)`
|
||||
- legacy SDK aliases such as `openclaw/plugin-sdk/channel-runtime`,
|
||||
`openclaw/plugin-sdk/command-auth` status builders, and the
|
||||
`ClawdbotConfig` type alias
|
||||
- legacy SDK aliases such as `openclaw/extension-api`,
|
||||
`openclaw/plugin-sdk/channel-runtime`, `openclaw/plugin-sdk/command-auth`
|
||||
status builders, `openclaw/plugin-sdk/test-utils`, and the `ClawdbotConfig`
|
||||
type alias
|
||||
- bundled plugin allowlist and enablement behavior
|
||||
- legacy provider/channel env-var manifest metadata
|
||||
- legacy provider plugin hooks and type aliases while providers move to
|
||||
explicit catalog, auth, thinking, replay, and transport hooks
|
||||
- legacy runtime aliases such as `api.runtime.taskFlow`,
|
||||
`api.runtime.subagent.getSession`, and `api.runtime.stt`
|
||||
- legacy memory-plugin split registration while memory plugins move to
|
||||
`registerMemoryCapability`
|
||||
- legacy channel SDK helpers for native message schemas, mention gating,
|
||||
inbound envelope formatting, and approval capability nesting
|
||||
- activation hints that are being replaced by manifest contribution ownership
|
||||
- `setup-api` runtime fallback while setup descriptors move to cold
|
||||
`setup.requiresRuntime: false` metadata
|
||||
|
||||
@@ -9,6 +9,89 @@ import {
|
||||
|
||||
const datePattern = /^\d{4}-\d{2}-\d{2}$/u;
|
||||
|
||||
const knownDeprecatedSurfaceMarkers = [
|
||||
{
|
||||
code: "legacy-extension-api-import",
|
||||
file: "src/extensionAPI.ts",
|
||||
marker: "openclaw/extension-api is deprecated",
|
||||
},
|
||||
{
|
||||
code: "memory-split-registration",
|
||||
file: "src/plugins/memory-state.ts",
|
||||
marker: "registerMemoryPromptSection",
|
||||
},
|
||||
{
|
||||
code: "provider-static-capabilities-bag",
|
||||
file: "src/plugins/types.ts",
|
||||
marker: "Legacy static provider capability bag",
|
||||
},
|
||||
{
|
||||
code: "provider-discovery-type-aliases",
|
||||
file: "src/plugins/types.ts",
|
||||
marker: "ProviderPluginDiscovery = ProviderPluginCatalog",
|
||||
},
|
||||
{
|
||||
code: "provider-thinking-policy-hooks",
|
||||
file: "src/plugins/types.ts",
|
||||
marker: "Prefer `resolveThinkingProfile`",
|
||||
},
|
||||
{
|
||||
code: "provider-external-oauth-profiles-hook",
|
||||
file: "src/plugins/types.ts",
|
||||
marker: "resolveExternalOAuthProfiles",
|
||||
},
|
||||
{
|
||||
code: "agent-tool-result-harness-alias",
|
||||
file: "src/plugins/agent-tool-result-middleware-types.ts",
|
||||
marker: "AgentToolResultMiddlewareHarness",
|
||||
},
|
||||
{
|
||||
code: "runtime-taskflow-legacy-alias",
|
||||
file: "src/plugins/runtime/types-core.ts",
|
||||
marker: "taskFlow",
|
||||
},
|
||||
{
|
||||
code: "runtime-subagent-get-session-alias",
|
||||
file: "src/plugins/runtime/types.ts",
|
||||
marker: "getSessionMessages",
|
||||
},
|
||||
{
|
||||
code: "runtime-stt-alias",
|
||||
file: "src/plugins/runtime/types-core.ts",
|
||||
marker: "stt",
|
||||
},
|
||||
{
|
||||
code: "runtime-inbound-envelope-alias",
|
||||
file: "src/plugins/runtime/types-channel.ts",
|
||||
marker: "formatInboundEnvelope",
|
||||
},
|
||||
{
|
||||
code: "channel-native-message-schema-helpers",
|
||||
file: "src/plugin-sdk/channel-actions.ts",
|
||||
marker: "createMessageToolButtonsSchema",
|
||||
},
|
||||
{
|
||||
code: "channel-mention-gating-legacy-helpers",
|
||||
file: "src/plugin-sdk/channel-inbound.ts",
|
||||
marker: "resolveMentionGatingWithBypass",
|
||||
},
|
||||
{
|
||||
code: "provider-web-search-core-wrapper",
|
||||
file: "src/plugin-sdk/provider-web-search.ts",
|
||||
marker: "createPluginBackedWebSearchProvider",
|
||||
},
|
||||
{
|
||||
code: "approval-capability-approvals-alias",
|
||||
file: "src/plugin-sdk/approval-delivery-helpers.ts",
|
||||
marker: "approvals?: Partial<ChannelApprovalCapabilitySurfaces>",
|
||||
},
|
||||
{
|
||||
code: "plugin-sdk-test-utils-alias",
|
||||
file: "src/plugin-sdk/test-utils.ts",
|
||||
marker: "Deprecated compatibility alias",
|
||||
},
|
||||
] as const;
|
||||
|
||||
function parseDate(date: string): Date {
|
||||
return new Date(`${date}T00:00:00Z`);
|
||||
}
|
||||
@@ -58,4 +141,11 @@ describe("plugin compatibility registry", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("tracks known plugin-facing deprecated surfaces", () => {
|
||||
for (const surface of knownDeprecatedSurfaceMarkers) {
|
||||
expect(isPluginCompatCode(surface.code), surface.code).toBe(true);
|
||||
expect(fs.readFileSync(surface.file, "utf8"), surface.file).toContain(surface.marker);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -361,6 +361,267 @@ export const PLUGIN_COMPAT_RECORDS = [
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "legacy-extension-api-import",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement:
|
||||
"injected `api.runtime.*` helpers or focused `openclaw/plugin-sdk/<subpath>` imports",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: ["openclaw/extension-api"],
|
||||
diagnostics: ["OPENCLAW_EXTENSION_API_DEPRECATED"],
|
||||
tests: ["src/plugins/sdk-alias.test.ts", "src/index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "memory-split-registration",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`api.registerMemoryCapability({ promptBuilder, flushPlanResolver, runtime })`",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: [
|
||||
"api.registerMemoryPromptSection",
|
||||
"api.registerMemoryFlushPlan",
|
||||
"api.registerMemoryRuntime",
|
||||
"src/plugins/memory-state split registration helpers",
|
||||
],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/memory-state.test.ts", "src/plugins/loader.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "provider-static-capabilities-bag",
|
||||
status: "deprecated",
|
||||
owner: "provider",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement:
|
||||
"explicit provider hooks such as `buildReplayPolicy`, `normalizeToolSchemas`, and `wrapStreamFn`",
|
||||
docsPath: "/plugins/sdk-provider-plugins",
|
||||
surfaces: ["ProviderPlugin.capabilities", "ProviderCapabilities"],
|
||||
diagnostics: ["provider validation warning"],
|
||||
tests: [
|
||||
"src/plugins/provider-runtime.test.ts",
|
||||
"src/plugins/contracts/provider-family-plugin-tests.test.ts",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "provider-discovery-type-aliases",
|
||||
status: "deprecated",
|
||||
owner: "provider",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement:
|
||||
"`ProviderCatalogOrder`, `ProviderCatalogContext`, `ProviderCatalogResult`, and `ProviderPluginCatalog`",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: [
|
||||
"ProviderDiscoveryOrder",
|
||||
"ProviderDiscoveryContext",
|
||||
"ProviderDiscoveryResult",
|
||||
"ProviderPluginDiscovery",
|
||||
],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "provider-thinking-policy-hooks",
|
||||
status: "deprecated",
|
||||
owner: "provider",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`resolveThinkingProfile`",
|
||||
docsPath: "/plugins/sdk-provider-plugins",
|
||||
surfaces: [
|
||||
"ProviderPlugin.isBinaryThinking",
|
||||
"ProviderPlugin.supportsXHighThinking",
|
||||
"ProviderPlugin.resolveDefaultThinkingLevel",
|
||||
],
|
||||
diagnostics: ["provider runtime compatibility warning"],
|
||||
tests: ["src/plugins/provider-runtime.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "provider-external-oauth-profiles-hook",
|
||||
status: "deprecated",
|
||||
owner: "provider",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`contracts.externalAuthProviders` plus `resolveExternalAuthProfiles`",
|
||||
docsPath: "/plugins/sdk-provider-plugins",
|
||||
surfaces: ["ProviderPlugin.resolveExternalOAuthProfiles"],
|
||||
diagnostics: ["provider external auth fallback warning"],
|
||||
tests: ["src/plugins/provider-runtime.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "agent-tool-result-harness-alias",
|
||||
status: "deprecated",
|
||||
owner: "agent-runtime",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`runtime` and `runtimes` agent tool-result middleware fields",
|
||||
docsPath: "/plugins/sdk-agent-harness",
|
||||
surfaces: [
|
||||
"AgentToolResultMiddlewareHarness",
|
||||
"AgentToolResultMiddlewareContext.harness",
|
||||
"AgentToolResultMiddlewareOptions.harnesses",
|
||||
"normalizeAgentToolResultMiddlewareHarnesses",
|
||||
],
|
||||
diagnostics: ["agent runtime compatibility warning"],
|
||||
tests: [
|
||||
"src/plugins/captured-registration.test.ts",
|
||||
"src/agents/codex-app-server.extensions.test.ts",
|
||||
],
|
||||
},
|
||||
{
|
||||
code: "runtime-taskflow-legacy-alias",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`api.runtime.tasks.flows`",
|
||||
docsPath: "/plugins/sdk-runtime",
|
||||
surfaces: ["api.runtime.taskFlow", "api.runtime.tasks.flow"],
|
||||
diagnostics: ["plugin runtime compatibility warning"],
|
||||
tests: ["src/plugins/runtime/index.test.ts", "src/plugins/runtime/runtime-tasks.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "runtime-subagent-get-session-alias",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`api.runtime.subagent.getSessionMessages`",
|
||||
docsPath: "/plugins/sdk-runtime",
|
||||
surfaces: ["api.runtime.subagent.getSession"],
|
||||
diagnostics: ["plugin runtime compatibility warning"],
|
||||
tests: ["src/plugins/runtime/index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "runtime-stt-alias",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`api.runtime.mediaUnderstanding.transcribeAudioFile`",
|
||||
docsPath: "/plugins/sdk-runtime",
|
||||
surfaces: ["api.runtime.stt.transcribeAudioFile"],
|
||||
diagnostics: ["plugin runtime compatibility warning"],
|
||||
tests: ["src/plugins/runtime/index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "runtime-inbound-envelope-alias",
|
||||
status: "deprecated",
|
||||
owner: "channel",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`BodyForAgent` plus structured user-context blocks",
|
||||
docsPath: "/plugins/sdk-runtime",
|
||||
surfaces: ["api.runtime.channel.reply.formatInboundEnvelope"],
|
||||
diagnostics: ["channel runtime compatibility warning"],
|
||||
tests: ["src/plugins/runtime/index.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "channel-native-message-schema-helpers",
|
||||
status: "deprecated",
|
||||
owner: "channel",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "semantic `presentation` capabilities",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: [
|
||||
"openclaw/plugin-sdk/channel-actions createMessageToolButtonsSchema",
|
||||
"openclaw/plugin-sdk/channel-actions createMessageToolCardSchema",
|
||||
],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-subpaths.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "channel-mention-gating-legacy-helpers",
|
||||
status: "deprecated",
|
||||
owner: "channel",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`resolveInboundMentionDecision({ facts, policy })`",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: [
|
||||
"openclaw/plugin-sdk/channel-inbound resolveMentionGating",
|
||||
"openclaw/plugin-sdk/channel-inbound resolveMentionGatingWithBypass",
|
||||
"openclaw/plugin-sdk/channel-mention-gating resolveMentionGating",
|
||||
"openclaw/plugin-sdk/channel-mention-gating resolveMentionGatingWithBypass",
|
||||
],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-subpaths.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "provider-web-search-core-wrapper",
|
||||
status: "deprecated",
|
||||
owner: "provider",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "provider-owned `createTool(...)` on the returned `WebSearchProviderPlugin`",
|
||||
docsPath: "/plugins/sdk-provider-plugins",
|
||||
surfaces: ["openclaw/plugin-sdk/provider-web-search createPluginBackedWebSearchProvider"],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-subpaths.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "approval-capability-approvals-alias",
|
||||
status: "deprecated",
|
||||
owner: "channel",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement:
|
||||
"top-level `delivery`, `nativeRuntime`, `render`, and `native` approval capability fields",
|
||||
docsPath: "/plugins/sdk-channel-plugins",
|
||||
surfaces: ["createChannelApprovalCapability({ approvals })"],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugin-sdk/approval-delivery-helpers.test.ts"],
|
||||
},
|
||||
{
|
||||
code: "plugin-sdk-test-utils-alias",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-26",
|
||||
warningStarts: "2026-04-26",
|
||||
removeAfter: "2026-07-26",
|
||||
replacement: "`openclaw/plugin-sdk/testing`",
|
||||
docsPath: "/plugins/sdk-migration",
|
||||
surfaces: ["openclaw/plugin-sdk/test-utils"],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
tests: ["src/plugins/contracts/plugin-sdk-subpaths.test.ts"],
|
||||
},
|
||||
] as const satisfies readonly PluginCompatRecord[];
|
||||
|
||||
export type PluginCompatCode = (typeof PLUGIN_COMPAT_RECORDS)[number]["code"];
|
||||
|
||||
Reference in New Issue
Block a user