mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:50:43 +00:00
fix(channels): defer setup runtime deps until login
This commit is contained in:
@@ -71,6 +71,7 @@ function loadChannelSetupPluginRegistry(params: {
|
||||
workspaceDir?: string;
|
||||
onlyPluginIds?: string[];
|
||||
activate?: boolean;
|
||||
installRuntimeDeps?: boolean;
|
||||
}): PluginRegistry {
|
||||
clearPluginDiscoveryCache();
|
||||
const autoEnabled = applyPluginAutoEnable({ config: params.cfg, env: process.env });
|
||||
@@ -88,7 +89,9 @@ function loadChannelSetupPluginRegistry(params: {
|
||||
logger: createPluginLoaderLogger(log),
|
||||
onlyPluginIds: params.onlyPluginIds,
|
||||
includeSetupOnlyChannelPlugins: true,
|
||||
forceSetupOnlyChannelPlugins: params.installRuntimeDeps === false,
|
||||
activate: params.activate,
|
||||
installBundledRuntimeDeps: params.installRuntimeDeps !== false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -156,6 +159,7 @@ export function loadChannelSetupPluginRegistrySnapshotForChannel(params: {
|
||||
channel: string;
|
||||
pluginId?: string;
|
||||
workspaceDir?: string;
|
||||
installRuntimeDeps?: boolean;
|
||||
}): PluginRegistry {
|
||||
const scopedPluginId = resolveScopedChannelPluginId({
|
||||
cfg: params.cfg,
|
||||
|
||||
@@ -327,6 +327,9 @@ describe("channelsAddCommand", () => {
|
||||
expect.objectContaining({ entry: catalogEntry }),
|
||||
);
|
||||
expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledTimes(1);
|
||||
expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ installRuntimeDeps: false }),
|
||||
);
|
||||
expectExternalChatEnabledConfigWrite();
|
||||
expect(runtime.error).not.toHaveBeenCalled();
|
||||
expect(runtime.exit).not.toHaveBeenCalled();
|
||||
@@ -348,6 +351,9 @@ describe("channelsAddCommand", () => {
|
||||
|
||||
expect(ensureChannelSetupPluginInstalled).not.toHaveBeenCalled();
|
||||
expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledTimes(1);
|
||||
expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ installRuntimeDeps: false }),
|
||||
);
|
||||
expectExternalChatEnabledConfigWrite();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
||||
import { parseOptionalDelimitedEntries } from "../../channels/plugins/helpers.js";
|
||||
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
||||
import { getLoadedChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
||||
import { moveSingleAccountChannelSectionToDefaultAccount } from "../../channels/plugins/setup-helpers.js";
|
||||
import type { ChannelSetupPlugin } from "../../channels/plugins/setup-wizard-types.js";
|
||||
import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js";
|
||||
@@ -141,7 +141,7 @@ export async function channelsAddCommand(
|
||||
if (wantsNames) {
|
||||
for (const channel of selection) {
|
||||
const accountId = accountIds[channel] ?? DEFAULT_ACCOUNT_ID;
|
||||
const plugin = resolvedPlugins.get(channel) ?? getChannelPlugin(channel);
|
||||
const plugin = resolvedPlugins.get(channel) ?? getLoadedChannelPlugin(channel);
|
||||
const account = plugin?.config.resolveAccount(nextConfig, accountId) as
|
||||
| { name?: string }
|
||||
| undefined;
|
||||
@@ -248,7 +248,7 @@ export async function channelsAddCommand(
|
||||
channelId: ChannelId,
|
||||
pluginId?: string,
|
||||
): Promise<ChannelPlugin | undefined> => {
|
||||
const existing = getChannelPlugin(channelId);
|
||||
const existing = getLoadedChannelPlugin(channelId);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
@@ -260,10 +260,11 @@ export async function channelsAddCommand(
|
||||
channel: channelId,
|
||||
...(pluginId ? { pluginId } : {}),
|
||||
workspaceDir: resolveWorkspaceDir(),
|
||||
installRuntimeDeps: false,
|
||||
});
|
||||
return (
|
||||
snapshot.channels.find((entry) => entry.plugin.id === channelId)?.plugin ??
|
||||
snapshot.channelSetups.find((entry) => entry.plugin.id === channelId)?.plugin
|
||||
snapshot.channelSetups.find((entry) => entry.plugin.id === channelId)?.plugin ??
|
||||
snapshot.channels.find((entry) => entry.plugin.id === channelId)?.plugin
|
||||
);
|
||||
};
|
||||
|
||||
@@ -359,7 +360,7 @@ export async function channelsAddCommand(
|
||||
nextConfig,
|
||||
...(baseHash !== undefined ? { baseHash } : {}),
|
||||
});
|
||||
runtime.log(`Added ${channelLabel(channel)} account "${accountId}".`);
|
||||
runtime.log(`Added ${plugin.meta.label ?? channelLabel(channel)} account "${accountId}".`);
|
||||
const afterAccountConfigWritten = plugin.setup?.afterAccountConfigWritten;
|
||||
if (afterAccountConfigWritten) {
|
||||
const { runCollectedChannelOnboardingPostWriteHooks } = await loadOnboardChannels();
|
||||
|
||||
@@ -174,10 +174,11 @@ export async function setupChannels(
|
||||
channel,
|
||||
...(pluginId ? { pluginId } : {}),
|
||||
workspaceDir: resolveWorkspaceDir(),
|
||||
installRuntimeDeps: false,
|
||||
});
|
||||
const plugin =
|
||||
snapshot.channels.find((entry) => entry.plugin.id === channel)?.plugin ??
|
||||
snapshot.channelSetups.find((entry) => entry.plugin.id === channel)?.plugin;
|
||||
snapshot.channelSetups.find((entry) => entry.plugin.id === channel)?.plugin ??
|
||||
snapshot.channels.find((entry) => entry.plugin.id === channel)?.plugin;
|
||||
if (plugin) {
|
||||
rememberScopedPlugin(plugin);
|
||||
return plugin;
|
||||
|
||||
@@ -145,6 +145,7 @@ export type PluginLoadOptions = {
|
||||
preferSetupRuntimeForChannelPlugins?: boolean;
|
||||
activate?: boolean;
|
||||
loadModules?: boolean;
|
||||
installBundledRuntimeDeps?: boolean;
|
||||
throwOnLoadError?: boolean;
|
||||
bundledRuntimeDepsInstaller?: (params: BundledRuntimeDepsInstallParams) => void;
|
||||
};
|
||||
@@ -780,6 +781,7 @@ function buildCacheKey(params: {
|
||||
requireSetupEntryForSetupOnlyChannelPlugins?: boolean;
|
||||
preferSetupRuntimeForChannelPlugins?: boolean;
|
||||
loadModules?: boolean;
|
||||
installBundledRuntimeDeps?: boolean;
|
||||
runtimeSubagentMode?: "default" | "explicit" | "gateway-bindable";
|
||||
pluginSdkResolution?: PluginSdkResolutionPreference;
|
||||
coreGatewayMethodNames?: string[];
|
||||
@@ -816,6 +818,8 @@ function buildCacheKey(params: {
|
||||
const startupChannelMode =
|
||||
params.preferSetupRuntimeForChannelPlugins === true ? "prefer-setup" : "full";
|
||||
const moduleLoadMode = params.loadModules === false ? "manifest-only" : "load-modules";
|
||||
const bundledRuntimeDepsMode =
|
||||
params.installBundledRuntimeDeps === false ? "skip-runtime-deps" : "install-runtime-deps";
|
||||
const runtimeSubagentMode = params.runtimeSubagentMode ?? "default";
|
||||
const gatewayMethodsKey = JSON.stringify(params.coreGatewayMethodNames ?? []);
|
||||
return `${roots.workspace ?? ""}::${roots.global ?? ""}::${roots.stock ?? ""}::${JSON.stringify({
|
||||
@@ -823,7 +827,7 @@ function buildCacheKey(params: {
|
||||
installs,
|
||||
loadPaths,
|
||||
activationMetadataKey: params.activationMetadataKey ?? "",
|
||||
})}::${scopeKey}::${setupOnlyKey}::${setupOnlyModeKey}::${setupOnlyRequirementKey}::${startupChannelMode}::${moduleLoadMode}::${runtimeSubagentMode}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}`;
|
||||
})}::${scopeKey}::${setupOnlyKey}::${setupOnlyModeKey}::${setupOnlyRequirementKey}::${startupChannelMode}::${moduleLoadMode}::${bundledRuntimeDepsMode}::${runtimeSubagentMode}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}`;
|
||||
}
|
||||
|
||||
function matchesScopedPluginRequest(params: {
|
||||
@@ -901,6 +905,7 @@ function hasExplicitCompatibilityInputs(options: PluginLoadOptions): boolean {
|
||||
options.forceSetupOnlyChannelPlugins === true ||
|
||||
options.requireSetupEntryForSetupOnlyChannelPlugins === true ||
|
||||
options.preferSetupRuntimeForChannelPlugins === true ||
|
||||
options.installBundledRuntimeDeps === false ||
|
||||
options.loadModules === false
|
||||
);
|
||||
}
|
||||
@@ -926,6 +931,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
|
||||
const requireSetupEntryForSetupOnlyChannelPlugins =
|
||||
options.requireSetupEntryForSetupOnlyChannelPlugins === true;
|
||||
const preferSetupRuntimeForChannelPlugins = options.preferSetupRuntimeForChannelPlugins === true;
|
||||
const shouldInstallBundledRuntimeDeps = options.installBundledRuntimeDeps !== false;
|
||||
const runtimeSubagentMode = resolveRuntimeSubagentMode(options.runtimeOptions);
|
||||
const coreGatewayMethodNames = Object.keys(options.coreGatewayHandlers ?? {}).toSorted();
|
||||
const cacheKey = buildCacheKey({
|
||||
@@ -943,6 +949,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
|
||||
requireSetupEntryForSetupOnlyChannelPlugins,
|
||||
preferSetupRuntimeForChannelPlugins,
|
||||
loadModules: options.loadModules,
|
||||
installBundledRuntimeDeps: options.installBundledRuntimeDeps,
|
||||
runtimeSubagentMode,
|
||||
pluginSdkResolution: options.pluginSdkResolution,
|
||||
coreGatewayMethodNames,
|
||||
@@ -961,6 +968,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
|
||||
preferSetupRuntimeForChannelPlugins,
|
||||
shouldActivate: options.activate !== false,
|
||||
shouldLoadModules: options.loadModules !== false,
|
||||
shouldInstallBundledRuntimeDeps,
|
||||
runtimeSubagentMode,
|
||||
cacheKey,
|
||||
};
|
||||
@@ -1839,6 +1847,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
preferSetupRuntimeForChannelPlugins,
|
||||
shouldActivate,
|
||||
shouldLoadModules,
|
||||
shouldInstallBundledRuntimeDeps,
|
||||
cacheKey,
|
||||
runtimeSubagentMode,
|
||||
} = resolvePluginLoadCacheContext(options);
|
||||
@@ -2183,7 +2192,12 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
markPluginActivationDisabled(record, enableState.reason);
|
||||
}
|
||||
|
||||
if (shouldLoadModules && candidate.origin === "bundled" && enableState.enabled) {
|
||||
if (
|
||||
shouldLoadModules &&
|
||||
shouldInstallBundledRuntimeDeps &&
|
||||
candidate.origin === "bundled" &&
|
||||
enableState.enabled
|
||||
) {
|
||||
try {
|
||||
const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginRoot, { env });
|
||||
const retainSpecs = bundledRuntimeDepsRetainSpecsByInstallRoot.get(installRoot) ?? [];
|
||||
@@ -2426,7 +2440,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
manifestRecord.setupSource
|
||||
) {
|
||||
const setupRegistration = resolveSetupChannelRegistration(mod, {
|
||||
installRuntimeDeps: enableState.enabled,
|
||||
installRuntimeDeps: shouldInstallBundledRuntimeDeps && enableState.enabled,
|
||||
});
|
||||
if (setupRegistration.loadError) {
|
||||
recordPluginError({
|
||||
|
||||
Reference in New Issue
Block a user