refactor(plugins): split activation snapshot and compat flow

This commit is contained in:
Peter Steinberger
2026-04-04 00:42:01 +09:00
parent eb3481fca9
commit 41ce3269f4
8 changed files with 275 additions and 108 deletions

View File

@@ -18,6 +18,12 @@ export type PluginActivationCompatConfig = {
vitestPluginIds?: readonly string[];
};
export type PluginActivationBundledCompatMode = {
allowlist?: boolean;
enablement?: "always" | "allowlist";
vitest?: boolean;
};
export type PluginActivationInputs = {
rawConfig?: OpenClawConfig;
config?: OpenClawConfig;
@@ -27,7 +33,21 @@ export type PluginActivationInputs = {
autoEnabledReasons: Record<string, string[]>;
};
function applyPluginActivationCompat(params: {
export type PluginActivationSnapshot = Pick<
PluginActivationInputs,
| "rawConfig"
| "config"
| "normalized"
| "activationSourceConfig"
| "activationSource"
| "autoEnabledReasons"
>;
export type BundledPluginCompatibleActivationInputs = PluginActivationInputs & {
compatPluginIds: string[];
};
export function applyPluginCompatibilityOverrides(params: {
config?: OpenClawConfig;
compat?: PluginActivationCompatConfig;
env: NodeJS.ProcessEnv;
@@ -54,14 +74,13 @@ function applyPluginActivationCompat(params: {
return vitestCompat;
}
export function resolvePluginActivationInputs(params: {
export function resolvePluginActivationSnapshot(params: {
rawConfig?: OpenClawConfig;
resolvedConfig?: OpenClawConfig;
autoEnabledReasons?: Record<string, string[]>;
env?: NodeJS.ProcessEnv;
compat?: PluginActivationCompatConfig;
applyAutoEnable?: boolean;
}): PluginActivationInputs {
}): PluginActivationSnapshot {
const env = params.env ?? process.env;
const rawConfig = params.rawConfig ?? params.resolvedConfig;
let resolvedConfig = params.resolvedConfig ?? params.rawConfig;
@@ -76,16 +95,10 @@ export function resolvePluginActivationInputs(params: {
autoEnabledReasons = autoEnabled.autoEnabledReasons;
}
const config = applyPluginActivationCompat({
config: resolvedConfig,
compat: params.compat,
env,
});
return {
rawConfig,
config,
normalized: normalizePluginsConfig(config?.plugins),
config: resolvedConfig,
normalized: normalizePluginsConfig(resolvedConfig?.plugins),
activationSourceConfig: rawConfig,
activationSource: createPluginActivationSource({
config: rawConfig,
@@ -93,3 +106,94 @@ export function resolvePluginActivationInputs(params: {
autoEnabledReasons: autoEnabledReasons ?? {},
};
}
export function resolvePluginActivationInputs(params: {
rawConfig?: OpenClawConfig;
resolvedConfig?: OpenClawConfig;
autoEnabledReasons?: Record<string, string[]>;
env?: NodeJS.ProcessEnv;
compat?: PluginActivationCompatConfig;
applyAutoEnable?: boolean;
}): PluginActivationInputs {
const env = params.env ?? process.env;
const snapshot = resolvePluginActivationSnapshot({
rawConfig: params.rawConfig,
resolvedConfig: params.resolvedConfig,
autoEnabledReasons: params.autoEnabledReasons,
env,
applyAutoEnable: params.applyAutoEnable,
});
const config = applyPluginCompatibilityOverrides({
config: snapshot.config,
compat: params.compat,
env,
});
return {
rawConfig: snapshot.rawConfig,
config,
normalized: normalizePluginsConfig(config?.plugins),
activationSourceConfig: snapshot.activationSourceConfig,
activationSource: snapshot.activationSource,
autoEnabledReasons: snapshot.autoEnabledReasons,
};
}
export function resolveBundledPluginCompatibleActivationInputs(params: {
rawConfig?: OpenClawConfig;
resolvedConfig?: OpenClawConfig;
autoEnabledReasons?: Record<string, string[]>;
env?: NodeJS.ProcessEnv;
workspaceDir?: string;
onlyPluginIds?: readonly string[];
applyAutoEnable?: boolean;
compatMode: PluginActivationBundledCompatMode;
resolveCompatPluginIds: (params: {
config?: OpenClawConfig;
workspaceDir?: string;
env?: NodeJS.ProcessEnv;
onlyPluginIds?: readonly string[];
}) => string[];
}): BundledPluginCompatibleActivationInputs {
const snapshot = resolvePluginActivationSnapshot({
rawConfig: params.rawConfig,
resolvedConfig: params.resolvedConfig,
autoEnabledReasons: params.autoEnabledReasons,
env: params.env,
applyAutoEnable: params.applyAutoEnable,
});
const allowlistCompatEnabled = params.compatMode.allowlist === true;
const shouldResolveCompatPluginIds =
allowlistCompatEnabled ||
params.compatMode.enablement === "always" ||
(params.compatMode.enablement === "allowlist" && allowlistCompatEnabled) ||
params.compatMode.vitest === true;
const compatPluginIds = shouldResolveCompatPluginIds
? params.resolveCompatPluginIds({
config: snapshot.config,
workspaceDir: params.workspaceDir,
env: params.env,
onlyPluginIds: params.onlyPluginIds,
})
: [];
const activation = resolvePluginActivationInputs({
rawConfig: snapshot.rawConfig,
resolvedConfig: snapshot.config,
autoEnabledReasons: snapshot.autoEnabledReasons,
env: params.env,
compat: {
allowlistPluginIds: allowlistCompatEnabled ? compatPluginIds : undefined,
enablementPluginIds:
params.compatMode.enablement === "always" ||
(params.compatMode.enablement === "allowlist" && allowlistCompatEnabled)
? compatPluginIds
: undefined,
vitestPluginIds: params.compatMode.vitest ? compatPluginIds : undefined,
},
});
return {
...activation,
compatPluginIds,
};
}

View File

@@ -1,5 +1,5 @@
import { createSubsystemLogger } from "../logging/subsystem.js";
import { resolvePluginActivationInputs } from "./activation-context.js";
import { resolveBundledPluginCompatibleActivationInputs } from "./activation-context.js";
import { resolveRuntimePluginRegistry, type PluginLoadOptions } from "./loader.js";
import { createPluginLoaderLogger } from "./logger.js";
import {
@@ -24,41 +24,23 @@ export function resolvePluginProviders(params: {
pluginSdkResolution?: PluginLoadOptions["pluginSdkResolution"];
}): ProviderPlugin[] {
const env = params.env ?? process.env;
const autoEnabled = resolvePluginActivationInputs({
const activation = resolveBundledPluginCompatibleActivationInputs({
rawConfig: params.config,
env,
workspaceDir: params.workspaceDir,
onlyPluginIds: params.onlyPluginIds,
applyAutoEnable: true,
});
const bundledProviderCompatPluginIds =
params.bundledProviderAllowlistCompat || params.bundledProviderVitestCompat
? resolveBundledProviderCompatPluginIds({
config: autoEnabled.config,
workspaceDir: params.workspaceDir,
env,
onlyPluginIds: params.onlyPluginIds,
})
: [];
const activation = resolvePluginActivationInputs({
rawConfig: params.config,
resolvedConfig: autoEnabled.config,
autoEnabledReasons: autoEnabled.autoEnabledReasons,
env,
compat: {
allowlistPluginIds: params.bundledProviderAllowlistCompat
? bundledProviderCompatPluginIds
: undefined,
enablementPluginIds: params.bundledProviderAllowlistCompat
? bundledProviderCompatPluginIds
: undefined,
vitestPluginIds: params.bundledProviderVitestCompat
? bundledProviderCompatPluginIds
: undefined,
compatMode: {
allowlist: params.bundledProviderAllowlistCompat,
enablement: "allowlist",
vitest: params.bundledProviderVitestCompat,
},
resolveCompatPluginIds: resolveBundledProviderCompatPluginIds,
});
const config = params.bundledProviderVitestCompat
? withBundledProviderVitestCompat({
config: activation.config,
pluginIds: bundledProviderCompatPluginIds,
pluginIds: activation.compatPluginIds,
env,
})
: activation.config;

View File

@@ -16,7 +16,7 @@ export function resolveBundledProviderCompatPluginIds(params: {
config?: PluginLoadOptions["config"];
workspaceDir?: string;
env?: PluginLoadOptions["env"];
onlyPluginIds?: string[];
onlyPluginIds?: readonly string[];
}): string[] {
const onlyPluginIdSet = params.onlyPluginIds ? new Set(params.onlyPluginIds) : null;
const registry = loadPluginManifestRegistry({
@@ -39,7 +39,7 @@ export function resolveEnabledProviderPluginIds(params: {
config?: PluginLoadOptions["config"];
workspaceDir?: string;
env?: PluginLoadOptions["env"];
onlyPluginIds?: string[];
onlyPluginIds?: readonly string[];
}): string[] {
const onlyPluginIdSet = params.onlyPluginIds ? new Set(params.onlyPluginIds) : null;
const registry = loadPluginManifestRegistry({

View File

@@ -1,4 +1,4 @@
import { resolvePluginActivationInputs } from "./activation-context.js";
import { resolveBundledPluginCompatibleActivationInputs } from "./activation-context.js";
import { resolveBundledWebFetchPluginIds } from "./bundled-web-fetch.js";
import { type NormalizedPluginsConfig } from "./config-state.js";
import type { PluginLoadOptions } from "./loader.js";
@@ -53,26 +53,17 @@ export function resolveBundledWebFetchResolutionConfig(params: {
activationSourceConfig?: PluginLoadOptions["config"];
autoEnabledReasons: Record<string, string[]>;
} {
const autoEnabled = resolvePluginActivationInputs({
const activation = resolveBundledPluginCompatibleActivationInputs({
rawConfig: params.config,
env: params.env,
applyAutoEnable: true,
});
const bundledCompatPluginIds = resolveBundledWebFetchCompatPluginIds({
config: autoEnabled.config,
workspaceDir: params.workspaceDir,
env: params.env,
});
const activation = resolvePluginActivationInputs({
rawConfig: params.config,
resolvedConfig: autoEnabled.config,
autoEnabledReasons: autoEnabled.autoEnabledReasons,
env: params.env,
compat: {
allowlistPluginIds: params.bundledAllowlistCompat ? bundledCompatPluginIds : undefined,
enablementPluginIds: bundledCompatPluginIds,
vitestPluginIds: bundledCompatPluginIds,
applyAutoEnable: true,
compatMode: {
allowlist: params.bundledAllowlistCompat,
enablement: "always",
vitest: true,
},
resolveCompatPluginIds: resolveBundledWebFetchCompatPluginIds,
});
return {

View File

@@ -1,4 +1,4 @@
import { resolvePluginActivationInputs } from "./activation-context.js";
import { resolveBundledPluginCompatibleActivationInputs } from "./activation-context.js";
import { resolveBundledWebSearchPluginIds } from "./bundled-web-search.js";
import { type NormalizedPluginsConfig } from "./config-state.js";
import type { PluginLoadOptions } from "./loader.js";
@@ -53,26 +53,17 @@ export function resolveBundledWebSearchResolutionConfig(params: {
activationSourceConfig?: PluginLoadOptions["config"];
autoEnabledReasons: Record<string, string[]>;
} {
const autoEnabled = resolvePluginActivationInputs({
const activation = resolveBundledPluginCompatibleActivationInputs({
rawConfig: params.config,
env: params.env,
applyAutoEnable: true,
});
const bundledCompatPluginIds = resolveBundledWebSearchCompatPluginIds({
config: autoEnabled.config,
workspaceDir: params.workspaceDir,
env: params.env,
});
const activation = resolvePluginActivationInputs({
rawConfig: params.config,
resolvedConfig: autoEnabled.config,
autoEnabledReasons: autoEnabled.autoEnabledReasons,
env: params.env,
compat: {
allowlistPluginIds: params.bundledAllowlistCompat ? bundledCompatPluginIds : undefined,
enablementPluginIds: bundledCompatPluginIds,
vitestPluginIds: bundledCompatPluginIds,
applyAutoEnable: true,
compatMode: {
allowlist: params.bundledAllowlistCompat,
enablement: "always",
vitest: true,
},
resolveCompatPluginIds: resolveBundledWebSearchCompatPluginIds,
});
return {