fix: defer bundled plugin runtime deps until enabled

This commit is contained in:
Peter Steinberger
2026-04-23 03:16:44 +01:00
parent 4479d4d437
commit 90696bffff
7 changed files with 309 additions and 61 deletions

View File

@@ -1232,7 +1232,10 @@ function loadBundledRuntimeChannelPlugin(params: {
}
}
function resolveSetupChannelRegistration(moduleExport: unknown): {
function resolveSetupChannelRegistration(
moduleExport: unknown,
params: { installRuntimeDeps?: boolean } = {},
): {
plugin?: ChannelPlugin;
setChannelRuntime?: (runtime: PluginRuntime) => void;
usesBundledSetupContract?: boolean;
@@ -1253,10 +1256,14 @@ function resolveSetupChannelRegistration(moduleExport: unknown): {
typeof setupEntryRecord.loadSetupPlugin === "function"
) {
try {
const loadedPlugin = setupEntryRecord.loadSetupPlugin();
const setupLoadOptions =
params.installRuntimeDeps === false ? { installRuntimeDeps: false } : undefined;
const loadedPlugin = setupEntryRecord.loadSetupPlugin(setupLoadOptions);
const loadedSecrets =
typeof setupEntryRecord.loadSetupSecrets === "function"
? (setupEntryRecord.loadSetupSecrets() as ChannelPlugin["secrets"] | undefined)
? (setupEntryRecord.loadSetupSecrets(setupLoadOptions) as
| ChannelPlugin["secrets"]
| undefined)
: undefined;
if (loadedPlugin && typeof loadedPlugin === "object") {
const mergedSecrets = mergeChannelPluginSection(
@@ -2062,6 +2069,49 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
let runtimeCandidateSource = candidate.source;
let runtimeSetupSource = manifestRecord.setupSource;
const scopedSetupOnlyChannelPluginRequested =
includeSetupOnlyChannelPlugins &&
!validateOnly &&
onlyPluginIdSet &&
manifestRecord.channels.length > 0 &&
(!enableState.enabled || forceSetupOnlyChannelPlugins);
const canLoadScopedSetupOnlyChannelPlugin =
scopedSetupOnlyChannelPluginRequested &&
(!requireSetupEntryForSetupOnlyChannelPlugins || Boolean(manifestRecord.setupSource));
const registrationMode = canLoadScopedSetupOnlyChannelPlugin
? "setup-only"
: scopedSetupOnlyChannelPluginRequested && requireSetupEntryForSetupOnlyChannelPlugins
? null
: enableState.enabled
? shouldLoadModules &&
!validateOnly &&
shouldLoadChannelPluginInSetupRuntime({
manifestChannels: manifestRecord.channels,
setupSource: manifestRecord.setupSource,
startupDeferConfiguredChannelFullLoadUntilAfterListen:
manifestRecord.startupDeferConfiguredChannelFullLoadUntilAfterListen,
cfg,
env,
preferSetupRuntimeForChannelPlugins,
})
? "setup-runtime"
: "full"
: null;
if (!registrationMode) {
record.status = "disabled";
record.error = enableState.reason;
markPluginActivationDisabled(record, enableState.reason);
registry.plugins.push(record);
seenIds.set(pluginId, candidate.origin);
continue;
}
if (!enableState.enabled) {
record.status = "disabled";
record.error = enableState.reason;
markPluginActivationDisabled(record, enableState.reason);
}
if (shouldLoadModules && candidate.origin === "bundled" && enableState.enabled) {
try {
const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginRoot, { env });
@@ -2112,49 +2162,6 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
}
}
const scopedSetupOnlyChannelPluginRequested =
includeSetupOnlyChannelPlugins &&
!validateOnly &&
onlyPluginIdSet &&
manifestRecord.channels.length > 0 &&
(!enableState.enabled || forceSetupOnlyChannelPlugins);
const canLoadScopedSetupOnlyChannelPlugin =
scopedSetupOnlyChannelPluginRequested &&
(!requireSetupEntryForSetupOnlyChannelPlugins || Boolean(manifestRecord.setupSource));
const registrationMode = canLoadScopedSetupOnlyChannelPlugin
? "setup-only"
: scopedSetupOnlyChannelPluginRequested && requireSetupEntryForSetupOnlyChannelPlugins
? null
: enableState.enabled
? shouldLoadModules &&
!validateOnly &&
shouldLoadChannelPluginInSetupRuntime({
manifestChannels: manifestRecord.channels,
setupSource: manifestRecord.setupSource,
startupDeferConfiguredChannelFullLoadUntilAfterListen:
manifestRecord.startupDeferConfiguredChannelFullLoadUntilAfterListen,
cfg,
env,
preferSetupRuntimeForChannelPlugins,
})
? "setup-runtime"
: "full"
: null;
if (!registrationMode) {
record.status = "disabled";
record.error = enableState.reason;
markPluginActivationDisabled(record, enableState.reason);
registry.plugins.push(record);
seenIds.set(pluginId, candidate.origin);
continue;
}
if (!enableState.enabled) {
record.status = "disabled";
record.error = enableState.reason;
markPluginActivationDisabled(record, enableState.reason);
}
if (record.format === "bundle") {
const unsupportedCapabilities = (record.bundleCapabilities ?? []).filter(
(capability) =>
@@ -2345,7 +2352,9 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
(registrationMode === "setup-only" || registrationMode === "setup-runtime") &&
manifestRecord.setupSource
) {
const setupRegistration = resolveSetupChannelRegistration(mod);
const setupRegistration = resolveSetupChannelRegistration(mod, {
installRuntimeDeps: enableState.enabled,
});
if (setupRegistration.loadError) {
recordPluginError({
logger,