mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-05 19:31:40 +00:00
refactor: correct SDK compatibility removal metadata (#115862)
* refactor(plugin-sdk): correct compat removal metadata * test(plugins): align boundary report compat counts
This commit is contained in:
committed by
GitHub
parent
edf4aca7bc
commit
5de970c1cc
@@ -129,55 +129,56 @@ export const DEPRECATED_PLUGIN_SDK_SUBPATH_RECORDS = DEPRECATED_PLUGIN_SDK_SUBPA
|
||||
}) satisfies PluginCompatRecord,
|
||||
) satisfies readonly PluginCompatRecord[];
|
||||
|
||||
const BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATHS = [
|
||||
"media-understanding",
|
||||
"memory-host-core",
|
||||
"plugin-config-runtime",
|
||||
"tool-plugin",
|
||||
] as const;
|
||||
|
||||
type SdkReplacement = { replacement: string; docsPath: string };
|
||||
const DOCUMENTED_PUBLIC_PLUGIN_SDK_REPLACEMENTS: Record<string, SdkReplacement> = {
|
||||
"media-understanding": {
|
||||
const BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_SEEDS = [
|
||||
{
|
||||
subpath: "media-understanding",
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-09-30",
|
||||
replacement:
|
||||
"`api.registerMediaUnderstandingProvider(...)` with provider-owned request helpers and types from `openclaw/plugin-sdk/plugin-entry`",
|
||||
"`api.registerMediaUnderstandingProvider(...)` with provider-owned request helpers and types from `openclaw/plugin-sdk/plugin-entry`; retain the public subpath through the 2026-09-30 window while official plugin consumers migrate",
|
||||
docsPath: "/plugins/architecture",
|
||||
},
|
||||
"memory-host-core": {
|
||||
{
|
||||
subpath: "memory-host-core",
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-09-30",
|
||||
replacement:
|
||||
"host-prepared memory prompts via `openclaw/plugin-sdk/core` and memory capability registration through the injected plugin API; retain the facade for companion-plugin public-artifact discovery until a focused read seam exists",
|
||||
"host-prepared memory prompts via `openclaw/plugin-sdk/core` and memory capability registration through the injected plugin API; retain the facade through the 2026-09-30 window and until a focused public-artifact read seam exists",
|
||||
docsPath: "/plugins/architecture-internals#context-engine-plugins",
|
||||
},
|
||||
"plugin-config-runtime": {
|
||||
{
|
||||
subpath: "plugin-config-runtime",
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-12-01",
|
||||
replacement:
|
||||
"`api.pluginConfig`, runtime tool context config, and focused `config-contracts`, `runtime-config-snapshot`, or `config-mutation` subpaths",
|
||||
"`api.pluginConfig`, runtime tool context config, and focused `config-contracts`, `runtime-config-snapshot`, or `config-mutation` subpaths; retain the public subpath through the 2026-12-01 window while official plugin consumers migrate",
|
||||
docsPath: "/plugins/sdk-runtime",
|
||||
},
|
||||
};
|
||||
{
|
||||
subpath: "tool-plugin",
|
||||
status: "deprecated",
|
||||
replacement:
|
||||
"retain the public subpath until plugin authoring has a nonexecuting static metadata replacement for `defineToolPlugin`; `getToolPluginMetadata` currently reads metadata only from an already-executed entry",
|
||||
docsPath: "/plugins/tool-plugins",
|
||||
},
|
||||
] as const;
|
||||
|
||||
function buildPublicSdkSubpathRecord({
|
||||
subpath,
|
||||
...compat
|
||||
}: (typeof BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_SEEDS)[number]) {
|
||||
return {
|
||||
code: `plugin-sdk-${subpath}-public-demotion` as const,
|
||||
owner: "sdk" as const,
|
||||
introduced: "2026-07-15",
|
||||
deprecated: "2026-07-15",
|
||||
warningStarts: "2026-07-15",
|
||||
...compat,
|
||||
surfaces: [`openclaw/plugin-sdk/${subpath}`],
|
||||
diagnostics: ["registry-backed public SDK demotion window; no external runtime import warning"],
|
||||
tests: ["src/plugins/compat/registry.test.ts"],
|
||||
} satisfies PluginCompatRecord;
|
||||
}
|
||||
|
||||
export const BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_RECORDS =
|
||||
BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATHS.map((subpath) => {
|
||||
const documented = DOCUMENTED_PUBLIC_PLUGIN_SDK_REPLACEMENTS[subpath];
|
||||
return {
|
||||
code: `plugin-sdk-${subpath}-public-demotion` as const,
|
||||
status: "removal-pending" as const,
|
||||
owner: "sdk" as const,
|
||||
introduced: "2026-07-15",
|
||||
deprecated: "2026-07-15",
|
||||
warningStarts: "2026-07-15",
|
||||
removeAfter: "2026-07-30",
|
||||
replacement:
|
||||
subpath === "tool-plugin"
|
||||
? "retain the public subpath until plugin authoring has a nonexecuting static metadata replacement for `defineToolPlugin`"
|
||||
: `${documented?.replacement ?? "define and document a public replacement"}; retain the public subpath until the 2026-07-30 window closes and official plugin consumers migrate`,
|
||||
docsPath:
|
||||
subpath === "tool-plugin"
|
||||
? "/plugins/tool-plugins"
|
||||
: (documented?.docsPath ?? "/plugins/sdk-migration"),
|
||||
surfaces: [`openclaw/plugin-sdk/${subpath}`],
|
||||
diagnostics: [
|
||||
"registry-backed public SDK demotion window; no external runtime import warning",
|
||||
],
|
||||
tests: ["src/plugins/compat/registry.test.ts"],
|
||||
} satisfies PluginCompatRecord;
|
||||
}) satisfies readonly PluginCompatRecord[];
|
||||
BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_SEEDS.map(buildPublicSdkSubpathRecord);
|
||||
|
||||
@@ -440,14 +440,12 @@ export const PLUGIN_COMPAT_RECORDS = [
|
||||
},
|
||||
{
|
||||
code: "agent-harness-sdk-alias",
|
||||
status: "removal-pending",
|
||||
status: "deprecated",
|
||||
owner: "agent-runtime",
|
||||
introduced: "2026-04-24",
|
||||
deprecated: "2026-04-25",
|
||||
warningStarts: "2026-04-25",
|
||||
removeAfter: "2026-07-25",
|
||||
replacement:
|
||||
"`openclaw/plugin-sdk/agent-runtime`; retain the public aliases until the shipped SDK contract has a replacement window backed by external-usage proof",
|
||||
replacement: "none yet; retain until a harness subpath ships and external migration is proven",
|
||||
docsPath: "/plugins/sdk-agent-harness",
|
||||
surfaces: ["openclaw/plugin-sdk/agent-harness", "openclaw/plugin-sdk/agent-harness-runtime"],
|
||||
diagnostics: ["plugin SDK compatibility warning"],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import fs from "node:fs";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { listGitTrackedFiles } from "../../test-utils/repo-files.js";
|
||||
import { listPluginCompatRecords } from "./registry.js";
|
||||
import { listPluginCompatRecords, type PluginCompatCode } from "./registry.js";
|
||||
|
||||
const datePattern = /^\d{4}-\d{2}-\d{2}$/u;
|
||||
const sourceRootsForDeprecatedCallGuard = [
|
||||
@@ -21,7 +21,10 @@ const deprecatedTargetParserCompatFiles = new Set([
|
||||
"src/infra/outbound/outbound-session.test-helpers.ts",
|
||||
"src/plugins/compat/registry.test.ts",
|
||||
]);
|
||||
const removalDatePendingCompatCodes = new Set<string>();
|
||||
const removalDatePendingCompatCodes = new Set<PluginCompatCode>([
|
||||
"plugin-sdk-tool-plugin-public-demotion",
|
||||
"agent-harness-sdk-alias",
|
||||
]);
|
||||
const deprecationMarkingCodes = [
|
||||
"plugin-sdk-channel-setup-input-fields",
|
||||
"plugin-sdk-broad-runtime-barrels",
|
||||
@@ -91,25 +94,37 @@ describe("plugin compatibility registry", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps shipped public contracts pending until their runtime blockers clear", () => {
|
||||
const records = listPluginCompatRecords().filter(
|
||||
it("keeps blocked public SDK removals aligned with their actual gates", () => {
|
||||
const records = new Map(listPluginCompatRecords().map((record) => [record.code, record]));
|
||||
const staleRemovalWindows = [...records.values()].filter(
|
||||
(record) =>
|
||||
record.status === "removal-pending" &&
|
||||
record.removeAfter !== undefined &&
|
||||
record.removeAfter <= "2026-07-30",
|
||||
);
|
||||
|
||||
expect(records.map((record) => record.code)).toEqual([
|
||||
"plugin-sdk-media-understanding-public-demotion",
|
||||
"plugin-sdk-memory-host-core-public-demotion",
|
||||
"plugin-sdk-plugin-config-runtime-public-demotion",
|
||||
"plugin-sdk-tool-plugin-public-demotion",
|
||||
"agent-harness-sdk-alias",
|
||||
]);
|
||||
for (const record of records) {
|
||||
expect(record.replacement).toMatch(/retain the public/u);
|
||||
expect(record.releaseNote).toBeUndefined();
|
||||
expect(staleRemovalWindows).toEqual([]);
|
||||
expect(records.get("plugin-sdk-media-understanding-public-demotion")).toMatchObject({
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-09-30",
|
||||
});
|
||||
expect(records.get("plugin-sdk-memory-host-core-public-demotion")).toMatchObject({
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-09-30",
|
||||
});
|
||||
expect(records.get("plugin-sdk-plugin-config-runtime-public-demotion")).toMatchObject({
|
||||
status: "removal-pending",
|
||||
removeAfter: "2026-12-01",
|
||||
});
|
||||
for (const code of removalDatePendingCompatCodes) {
|
||||
expect(records.get(code)).toMatchObject({ status: "deprecated" });
|
||||
expect(records.get(code)?.removeAfter).toBeUndefined();
|
||||
expect(records.get(code)?.replacement).toMatch(/retain/u);
|
||||
}
|
||||
expect(records.get("agent-harness-sdk-alias")?.surfaces).toEqual([
|
||||
"openclaw/plugin-sdk/agent-harness",
|
||||
"openclaw/plugin-sdk/agent-harness-runtime",
|
||||
]);
|
||||
});
|
||||
|
||||
it("tracks the deprecation-marking families through the approved window", () => {
|
||||
|
||||
@@ -1232,6 +1232,8 @@ describe("plugin-sdk subpath exports", () => {
|
||||
]);
|
||||
expectSourceMentions("setup-tools", ["formatCliCommand", "detectBinary", "formatDocsLink"]);
|
||||
expectSourceMentions("lazy-runtime", ["createLazyRuntimeSurface", "createLazyRuntimeModule"]);
|
||||
expectSourceMentions("agent-harness", ["./agent-harness-runtime.js"]);
|
||||
expectSourceMentions("agent-harness-runtime", ["AgentHarness", "EmbeddedPiCompactResult"]);
|
||||
expectSourceOmitsSnippet("agent-runtime", "./sglang.js");
|
||||
expectSourceOmitsSnippet("agent-runtime", "./vllm.js");
|
||||
expectSourceOmitsSnippet("agent-runtime", "../../extensions/");
|
||||
|
||||
@@ -54,14 +54,12 @@ describe("plugin-boundary-report", () => {
|
||||
|
||||
expect(summaryResult.exitCode).toBe(0);
|
||||
expect(summaryResult.stderr).toBe("");
|
||||
expect(summary.compat?.removalPendingCount).toBe(5);
|
||||
expect(summary.compat?.removalPendingCount).toBe(3);
|
||||
expect(summary.compat?.removalPendingDueCount).toEqual(expect.any(Number));
|
||||
expect(summary.compat?.removalPending?.map((record) => record.code)).toEqual([
|
||||
"agent-harness-sdk-alias",
|
||||
"plugin-sdk-media-understanding-public-demotion",
|
||||
"plugin-sdk-memory-host-core-public-demotion",
|
||||
"plugin-sdk-plugin-config-runtime-public-demotion",
|
||||
"plugin-sdk-tool-plugin-public-demotion",
|
||||
]);
|
||||
for (const record of summary.compat?.removalPending ?? []) {
|
||||
expect(record.removeAfter).toMatch(/^\d{4}-\d{2}-\d{2}$/u);
|
||||
@@ -84,8 +82,8 @@ describe("plugin-boundary-report", () => {
|
||||
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.stderr).toBe("");
|
||||
expect(result.stdout).toContain("removalPending=5");
|
||||
expect(result.stdout).toContain("removal-pending 2026-07-25 agent-harness-sdk-alias");
|
||||
expect(result.stdout).toContain("removalPending=3");
|
||||
expect(result.stdout).not.toContain("agent-harness-sdk-alias");
|
||||
expect(result.stdout).toMatch(/blocker=.*retain the public/iu);
|
||||
expect(result.stdout).toMatch(/readerRefs=\d+ readers=/u);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user