refactor: keep manifest contracts on plugin index

This commit is contained in:
Shakker
2026-04-26 04:55:05 +01:00
parent 948c32dd33
commit d251932fcf
6 changed files with 8 additions and 124 deletions

View File

@@ -1,9 +1,7 @@
import { mergeMissing } from "../../../config/legacy.shared.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import {
loadPluginManifestRegistry,
resolveManifestContractOwnerPluginId,
} from "../../../plugins/manifest-registry.js";
import { loadPluginManifestRegistry } from "../../../plugins/manifest-registry.js";
import { resolveManifestContractOwnerPluginId } from "../../../plugins/plugin-registry.js";
import {
cloneRecord,
ensureRecord,

View File

@@ -1,7 +1,7 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { uniqueSortedStrings } from "../../../test/helpers/plugins/contracts-testkit.js";
import { withBundledPluginAllowlistCompat } from "../bundled-compat.js";
import { resolveManifestContractPluginIds } from "../manifest-registry.js";
import { resolveManifestContractPluginIds } from "../plugin-registry.js";
import { __testing as providerTesting } from "../providers.js";
import { resolveBundledContractSnapshotPluginIds } from "./inventory/bundled-capability-metadata.js";
import { providerContractCompatPluginIds } from "./registry.js";

View File

@@ -1,9 +1,7 @@
import { describe, expect, it } from "vitest";
import { uniqueSortedStrings } from "../../../test/helpers/plugins/contracts-testkit.js";
import {
loadPluginManifestRegistry,
resolveManifestContractPluginIds,
} from "../manifest-registry.js";
import { loadPluginManifestRegistry } from "../manifest-registry.js";
import { resolveManifestContractPluginIds } from "../plugin-registry.js";
import {
pluginRegistrationContractRegistry,
providerContractLoadError,

View File

@@ -1,10 +1,8 @@
import { normalizeProviderId } from "../../agents/provider-id.js";
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
import { loadBundledCapabilityRuntimeRegistry } from "../bundled-capability-runtime.js";
import {
loadPluginManifestRegistry,
resolveManifestContractPluginIds,
} from "../manifest-registry.js";
import { loadPluginManifestRegistry } from "../manifest-registry.js";
import { resolveManifestContractPluginIds } from "../plugin-registry.js";
import { resolveBundledExplicitProviderContractsFromPublicArtifacts } from "../provider-contract-public-artifacts.js";
import type {
ImageGenerationProviderPlugin,

View File

@@ -3,10 +3,7 @@ import path from "node:path";
import type { OpenClawConfig } from "../config/types.js";
import type { PluginInstallRecord } from "../config/types.plugins.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import {
normalizeOptionalLowercaseString,
normalizeOptionalString,
} from "../shared/string-coerce.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { normalizeOptionalTrimmedStringList } from "../shared/string-normalization.js";
import { sanitizeForLog } from "../terminal/ansi.js";
import { resolveUserPath } from "../utils.js";
@@ -169,90 +166,6 @@ const DEFAULT_MANIFEST_CACHE_MS = 1000;
export { clearPluginManifestRegistryCache } from "./manifest-registry-state.js";
function listContractValues(
plugin: PluginManifestRecord,
contract: PluginManifestContractListKey,
): readonly string[] {
return plugin.contracts?.[contract] ?? [];
}
export function resolveManifestContractPluginIds(params: {
contract: PluginManifestContractListKey;
origin?: PluginOrigin;
config?: OpenClawConfig;
workspaceDir?: string;
env?: NodeJS.ProcessEnv;
onlyPluginIds?: readonly string[];
}): string[] {
const onlyPluginIdSet =
params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null;
return loadPluginManifestRegistry({
config: params.config,
workspaceDir: params.workspaceDir,
env: params.env,
})
.plugins.filter(
(plugin) =>
(!params.origin || plugin.origin === params.origin) &&
(!onlyPluginIdSet || onlyPluginIdSet.has(plugin.id)) &&
listContractValues(plugin, params.contract).length > 0,
)
.map((plugin) => plugin.id)
.toSorted((left, right) => left.localeCompare(right));
}
export function resolveManifestContractPluginIdsByCompatibilityRuntimePath(params: {
contract: PluginManifestContractListKey;
path: string | undefined;
origin?: PluginOrigin;
config?: OpenClawConfig;
workspaceDir?: string;
env?: NodeJS.ProcessEnv;
}): string[] {
const normalizedPath = params.path?.trim();
if (!normalizedPath) {
return [];
}
return loadPluginManifestRegistry({
config: params.config,
workspaceDir: params.workspaceDir,
env: params.env,
})
.plugins.filter(
(plugin) =>
(!params.origin || plugin.origin === params.origin) &&
listContractValues(plugin, params.contract).length > 0 &&
(plugin.configContracts?.compatibilityRuntimePaths ?? []).includes(normalizedPath),
)
.map((plugin) => plugin.id)
.toSorted((left, right) => left.localeCompare(right));
}
export function resolveManifestContractOwnerPluginId(params: {
contract: PluginManifestContractListKey;
value: string | undefined;
origin?: PluginOrigin;
config?: OpenClawConfig;
workspaceDir?: string;
env?: NodeJS.ProcessEnv;
}): string | undefined {
const normalizedValue = normalizeOptionalLowercaseString(params.value);
if (!normalizedValue) {
return undefined;
}
return loadPluginManifestRegistry({
config: params.config,
workspaceDir: params.workspaceDir,
env: params.env,
}).plugins.find(
(plugin) =>
(!params.origin || plugin.origin === params.origin) &&
listContractValues(plugin, params.contract).some(
(candidate) => normalizeOptionalLowercaseString(candidate) === normalizedValue,
),
)?.id;
}
function resolveManifestCacheMs(env: NodeJS.ProcessEnv): number {
const raw = env.OPENCLAW_PLUGIN_MANIFEST_CACHE_MS?.trim();
if (raw === "" || raw === "0") {

View File

@@ -10,8 +10,6 @@ type LoadOpenClawPlugins = typeof import("./loader.js").loadOpenClawPlugins;
type IsPluginRegistryLoadInFlight = typeof import("./loader.js").isPluginRegistryLoadInFlight;
type LoadPluginManifestRegistry =
typeof import("./manifest-registry.js").loadPluginManifestRegistry;
type ResolveManifestContractPluginIds =
typeof import("./manifest-registry.js").resolveManifestContractPluginIds;
type ApplyPluginAutoEnable = typeof import("../config/plugin-auto-enable.js").applyPluginAutoEnable;
type SetActivePluginRegistry = typeof import("./runtime.js").setActivePluginRegistry;
@@ -19,23 +17,6 @@ const resolveRuntimePluginRegistryMock = vi.fn<ResolveRuntimePluginRegistry>();
const loadOpenClawPluginsMock = vi.fn<LoadOpenClawPlugins>();
const isPluginRegistryLoadInFlightMock = vi.fn<IsPluginRegistryLoadInFlight>((_) => false);
const loadPluginManifestRegistryMock = vi.fn<LoadPluginManifestRegistry>();
const resolveManifestContractPluginIdsMock = vi.fn<ResolveManifestContractPluginIds>((params) => {
const onlyPluginIds =
params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null;
return loadPluginManifestRegistryMock({
config: params.config,
workspaceDir: params.workspaceDir,
env: params.env,
})
.plugins.filter(
(plugin) =>
(!params.origin || plugin.origin === params.origin) &&
(!onlyPluginIds || onlyPluginIds.has(plugin.id)) &&
(plugin.contracts?.[params.contract] ?? []).length > 0,
)
.map((plugin) => plugin.id)
.toSorted((left, right) => left.localeCompare(right));
});
const applyPluginAutoEnableMock = vi.fn<ApplyPluginAutoEnable>();
let resolveOwningPluginIdsForProvider: typeof import("./providers.js").resolveOwningPluginIdsForProvider;
@@ -308,8 +289,6 @@ describe("resolvePluginProviders", () => {
vi.doMock("./manifest-registry.js", () => ({
loadPluginManifestRegistry: (...args: Parameters<LoadPluginManifestRegistry>) =>
loadPluginManifestRegistryMock(...args),
resolveManifestContractPluginIds: (...args: Parameters<ResolveManifestContractPluginIds>) =>
resolveManifestContractPluginIdsMock(...args),
}));
vi.doMock("./installed-plugin-index-store.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./installed-plugin-index-store.js")>();
@@ -355,7 +334,6 @@ describe("resolvePluginProviders", () => {
resolveRuntimePluginRegistryMock.mockReturnValue(registry);
loadOpenClawPluginsMock.mockReturnValue(registry);
loadPluginManifestRegistryMock.mockReset();
resolveManifestContractPluginIdsMock.mockClear();
applyPluginAutoEnableMock.mockReset();
applyPluginAutoEnableMock.mockImplementation(
(params): PluginAutoEnableResult => ({
@@ -474,7 +452,6 @@ describe("resolvePluginProviders", () => {
declaredPluginIds,
}),
).toEqual(["legacy-auth-owner"]);
expect(resolveManifestContractPluginIdsMock).not.toHaveBeenCalled();
});
it("treats explicit empty provider scopes as scoped-empty in provider helpers", () => {