mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 16:34:45 +00:00
fix(plugins): deprecate deactivate hook alias
This commit is contained in:
@@ -20,7 +20,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Telegram: persist polling updates through restart replay so queued same-topic messages resume in order instead of losing context after a gateway restart. (#82256) Thanks @VACInc.
|
||||
- Gateway/Gmail: abort in-flight Gmail watcher startup and hot-reload restarts before shutdown so reloads cannot spawn `gog serve` after the Gateway is closing. Thanks @frankekn.
|
||||
- MCP plugin tools: forward host MCP `tools/call` `AbortSignal` through `createPluginToolsMcpHandlers().callTool` into plugin `tool.execute`, so host cancellation actually cancels in-flight plugin tool calls instead of letting them run to completion. Fixes #82424. (#82443) Thanks @joshavant.
|
||||
- Plugins: accept `api.on("deactivate")` as a compatibility alias for `gateway_stop`, so external plugin cleanup handlers run on Gateway shutdown instead of being ignored as unknown hooks.
|
||||
- Plugins: accept deprecated `api.on("deactivate")` registrations as a dated compatibility alias for `gateway_stop`, so external plugin cleanup handlers run on Gateway shutdown while authors get migration guidance.
|
||||
- Media: ignore image MIME and filename hints when bytes sniff as generic containers, so zip/octet-stream payloads mislabeled as images do not become local image media or keep image file extensions when staged.
|
||||
- Update/doctor: avoid materializing `groupAllowFrom` for channel schemas that reject it, so package-swap doctor repairs do not fail on externalized Slack configs.
|
||||
- Gateway/media: prevent image filenames from overriding generic non-image byte sniffing, so zip/octet-stream payloads mislabeled as images are offloaded or rejected before they become inline image attachments.
|
||||
|
||||
@@ -112,6 +112,8 @@ Current compatibility records include:
|
||||
|
||||
- legacy broad SDK imports such as `openclaw/plugin-sdk/compat`
|
||||
- legacy hook-only plugin shapes and `before_agent_start`
|
||||
- legacy `api.on("deactivate", ...)` cleanup hook names while plugins migrate to
|
||||
`gateway_stop`
|
||||
- legacy `activate(api)` plugin entrypoints while plugins migrate to
|
||||
`register(api)`
|
||||
- legacy SDK aliases such as `openclaw/extension-api`,
|
||||
|
||||
@@ -145,7 +145,7 @@ observation-only.
|
||||
**Lifecycle**
|
||||
|
||||
- `gateway_start` / `gateway_stop` - start or stop plugin-owned services with the Gateway
|
||||
- `deactivate` - compatibility alias for `gateway_stop`; prefer `gateway_stop` in new plugins
|
||||
- `deactivate` - deprecated compatibility alias for `gateway_stop`; use `gateway_stop` in new plugins
|
||||
- `cron_changed` - observe gateway-owned cron lifecycle changes (added, updated, removed, started, finished, scheduled)
|
||||
- **`before_install`** - inspect skill or plugin install scans and optionally block
|
||||
|
||||
@@ -438,8 +438,8 @@ before the next major release:
|
||||
- **`before_agent_start`** remains for compatibility. New plugins should use
|
||||
`before_model_resolve` and `before_prompt_build` instead of the combined
|
||||
phase.
|
||||
- **`deactivate`** remains as a cleanup compatibility alias. New plugins should
|
||||
use `gateway_stop`.
|
||||
- **`deactivate`** remains as a deprecated cleanup compatibility alias until
|
||||
after 2026-08-16. New plugins should use `gateway_stop`.
|
||||
- **`onResolution` in `before_tool_call`** now uses the typed
|
||||
`PluginApprovalResolution` union (`allow-once` / `allow-always` / `deny` /
|
||||
`timeout` / `cancelled`) instead of a free-form `string`.
|
||||
|
||||
@@ -757,6 +757,29 @@ canonical replacement.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="deactivate hook → gateway_stop">
|
||||
**Old**: `api.on("deactivate", handler)`.
|
||||
|
||||
**New**: `api.on("gateway_stop", handler)`. The event and context are the
|
||||
same shutdown cleanup contract; only the hook name changes.
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
api.on("deactivate", async (event, ctx) => {
|
||||
await stopPluginService(ctx);
|
||||
});
|
||||
|
||||
// After
|
||||
api.on("gateway_stop", async (event, ctx) => {
|
||||
await stopPluginService(ctx);
|
||||
});
|
||||
```
|
||||
|
||||
`deactivate` remains wired as a deprecated compatibility alias until after
|
||||
2026-08-16.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Provider discovery types → provider catalog types">
|
||||
Four discovery type aliases are now thin wrappers over the
|
||||
catalog-era types:
|
||||
|
||||
@@ -135,6 +135,11 @@ const knownDeprecatedSurfaceMarkers = [
|
||||
file: "src/plugin-sdk/compat.ts",
|
||||
marker: "@deprecated Use `openclaw/plugin-sdk/channel-message`.",
|
||||
},
|
||||
{
|
||||
code: "legacy-deactivate-hook-alias",
|
||||
file: "src/plugins/hook-types.ts",
|
||||
marker: "@deprecated Use gateway_stop",
|
||||
},
|
||||
{
|
||||
code: "channel-route-key-aliases",
|
||||
file: "src/plugin-sdk/channel-route.ts",
|
||||
|
||||
@@ -23,6 +23,22 @@ export const PLUGIN_COMPAT_RECORDS = [
|
||||
releaseNote:
|
||||
"Legacy `before_agent_start` hook compatibility remains wired while plugins migrate to modern hook stages.",
|
||||
},
|
||||
{
|
||||
code: "legacy-deactivate-hook-alias",
|
||||
status: "deprecated",
|
||||
owner: "sdk",
|
||||
introduced: "2026-05-16",
|
||||
deprecated: "2026-05-16",
|
||||
warningStarts: "2026-05-16",
|
||||
removeAfter: "2026-08-16",
|
||||
replacement: "`gateway_stop` hook",
|
||||
docsPath: "/plugins/hooks#upcoming-deprecations",
|
||||
surfaces: ["api.on(\"deactivate\", ...)", "plugin typed hook registration"],
|
||||
diagnostics: ["plugin runtime compatibility warning"],
|
||||
tests: ["src/plugins/loader.test.ts"],
|
||||
releaseNote:
|
||||
"`api.on(\"deactivate\", ...)` remains wired as a deprecated compatibility alias while plugins migrate to `gateway_stop`.",
|
||||
},
|
||||
{
|
||||
code: "hook-only-plugin-shape",
|
||||
status: "active",
|
||||
|
||||
@@ -94,6 +94,7 @@ export type PluginHookName =
|
||||
| "subagent_delivery_target"
|
||||
| "subagent_spawned"
|
||||
| "subagent_ended"
|
||||
/** @deprecated Use gateway_stop. */
|
||||
| "deactivate"
|
||||
| "gateway_start"
|
||||
| "gateway_stop"
|
||||
@@ -1003,11 +1004,13 @@ export type PluginHookHandlerMap = {
|
||||
ctx: PluginHookSubagentContext,
|
||||
) => Promise<void> | void;
|
||||
/**
|
||||
* Compatibility alias for gateway_stop.
|
||||
* Deprecated compatibility alias for gateway_stop.
|
||||
*
|
||||
* New plugins should register gateway_stop directly; the loader normalizes
|
||||
* deactivate registrations onto gateway_stop so cleanup handlers still run
|
||||
* during Gateway shutdown.
|
||||
*
|
||||
* @deprecated Use gateway_stop.
|
||||
*/
|
||||
deactivate: (
|
||||
event: PluginHookGatewayStopEvent,
|
||||
|
||||
@@ -5939,7 +5939,8 @@ module.exports = {
|
||||
registry.diagnostics.some(
|
||||
(diag) =>
|
||||
diag.pluginId === "legacy-deactivate-hook" &&
|
||||
diag.message === 'typed hook "deactivate" is a compatibility alias for "gateway_stop"',
|
||||
diag.message ===
|
||||
'typed hook "deactivate" is deprecated (legacy-deactivate-hook-alias); use "gateway_stop". This compatibility alias will be removed after 2026-08-16.',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
import { buildPluginApi } from "./api-builder.js";
|
||||
import { normalizeRegisteredChannelPlugin } from "./channel-validation.js";
|
||||
import { CODEX_APP_SERVER_EXTENSION_RUNTIME_ID } from "./codex-app-server-extension-factory.js";
|
||||
import { getPluginCompatRecord } from "./compat/registry.js";
|
||||
import type { CodexAppServerExtensionFactory } from "./codex-app-server-extension-types.js";
|
||||
import {
|
||||
isReservedCommandName,
|
||||
@@ -187,6 +188,16 @@ export type PluginHttpRouteRegistration = RegistryTypesPluginHttpRouteRegistrati
|
||||
};
|
||||
|
||||
const GATEWAY_METHOD_DISPATCH_CONTRACT = "authenticated-request";
|
||||
const LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT = getPluginCompatRecord("legacy-deactivate-hook-alias");
|
||||
|
||||
function formatLegacyDeactivateHookAliasDiagnostic(): string {
|
||||
const removeAfter =
|
||||
LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT.removeAfter ?? "a future breaking release";
|
||||
return (
|
||||
`typed hook "deactivate" is deprecated (${LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT.code}); ` +
|
||||
`use "gateway_stop". This compatibility alias will be removed after ${removeAfter}.`
|
||||
);
|
||||
}
|
||||
|
||||
type PluginOwnedProviderRegistration<T extends { id: string }> = {
|
||||
pluginId: string;
|
||||
@@ -2304,7 +2315,7 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: 'typed hook "deactivate" is a compatibility alias for "gateway_stop"',
|
||||
message: formatLegacyDeactivateHookAliasDiagnostic(),
|
||||
});
|
||||
}
|
||||
let effectiveHandler = handler;
|
||||
|
||||
Reference in New Issue
Block a user