fix: avoid eager channel setup loading

This commit is contained in:
Peter Steinberger 2026-04-26 10:27:19 +01:00
parent 6bc5fe6952
commit 0b301e9af4
No known key found for this signature in database
2 changed files with 17 additions and 27 deletions

View file

@ -496,6 +496,7 @@ describe("setupChannels", () => {
({ setupChannels } = await import("./onboard-channels.js"));
setMinimalOnboardingRegistryForTests();
catalogMocks.listChannelPluginCatalogEntries.mockReset();
catalogMocks.listChannelPluginCatalogEntries.mockReturnValue([]);
manifestRegistryMocks.loadPluginManifestRegistry.mockReset();
manifestRegistryMocks.loadPluginManifestRegistry.mockReturnValue({
plugins: [],

View file

@ -1,10 +1,7 @@
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { getBundledChannelSetupPlugin } from "../channels/plugins/bundled.js";
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
import {
getChannelSetupPlugin,
listActiveChannelSetupPlugins,
listChannelSetupPlugins,
} from "../channels/plugins/setup-registry.js";
import { listActiveChannelSetupPlugins } from "../channels/plugins/setup-registry.js";
import type {
ChannelSetupPlugin,
ChannelSetupWizardAdapter,
@ -113,7 +110,6 @@ export async function setupChannels(
): Promise<OpenClawConfig> {
let next = cfg;
const deferStatusUntilSelection = options?.deferStatusUntilSelection === true;
const includeRegistryBeforeSelection = !deferStatusUntilSelection;
const forceAllowFromChannels = new Set(options?.forceAllowFromChannels ?? []);
const accountOverrides: Partial<Record<ChannelChoice, string>> = {
...options?.accountIds,
@ -131,17 +127,10 @@ export async function setupChannels(
return plugin;
};
const getVisibleChannelPlugin = (channel: ChannelChoice): ChannelSetupPlugin | undefined =>
scopedPluginsById.get(channel) ??
activePluginsById.get(channel) ??
(deferStatusUntilSelection ? undefined : getChannelSetupPlugin(channel));
const listVisibleInstalledPlugins = (params?: {
includeRegistry?: boolean;
}): ChannelSetupPlugin[] => {
const includeRegistry = params?.includeRegistry ?? includeRegistryBeforeSelection;
scopedPluginsById.get(channel) ?? activePluginsById.get(channel);
const listVisibleInstalledPlugins = (): ChannelSetupPlugin[] => {
const merged = new Map<string, ChannelSetupPlugin>();
const registryPlugins = includeRegistry
? listChannelSetupPlugins()
: listActiveChannelSetupPlugins().map(rememberActivePlugin);
const registryPlugins = listActiveChannelSetupPlugins().map(rememberActivePlugin);
for (const plugin of registryPlugins) {
if (shouldShowChannelInSetup(plugin.meta)) {
merged.set(plugin.id, plugin);
@ -154,10 +143,10 @@ export async function setupChannels(
}
return Array.from(merged.values());
};
const resolveVisibleChannelEntries = (params?: { includeRegistry?: boolean }) =>
const resolveVisibleChannelEntries = () =>
resolveChannelSetupEntries({
cfg: next,
installedPlugins: listVisibleInstalledPlugins(params),
installedPlugins: listVisibleInstalledPlugins(),
workspaceDir: resolveWorkspaceDir(),
});
const loadScopedChannelPlugin = async (
@ -189,6 +178,11 @@ export async function setupChannels(
rememberScopedPlugin(plugin);
return plugin;
}
const bundledPlugin = getBundledChannelSetupPlugin(channel);
if (bundledPlugin) {
rememberScopedPlugin(bundledPlugin);
return bundledPlugin;
}
return undefined;
};
const getVisibleSetupFlowAdapter = (channel: ChannelChoice) => {
@ -200,6 +194,7 @@ export async function setupChannels(
};
const preloadConfiguredExternalPlugins = async () => {
// Keep setup memory bounded by snapshot-loading only configured external plugins.
listVisibleInstalledPlugins();
const workspaceDir = resolveWorkspaceDir();
const preloadTasks: Promise<unknown>[] = [];
// Security: keep trusted workspace overrides eligible during setup while
@ -246,9 +241,7 @@ export async function setupChannels(
return cfg;
}
const primerChannels = resolveVisibleChannelEntries({
includeRegistry: includeRegistryBeforeSelection,
}).entries.map((entry) => ({
const primerChannels = resolveVisibleChannelEntries().entries.map((entry) => ({
id: entry.id,
label: entry.meta.label,
blurb: entry.meta.blurb,
@ -314,9 +307,7 @@ export async function setupChannels(
};
const getChannelEntries = () => {
const resolved = resolveVisibleChannelEntries({
includeRegistry: includeRegistryBeforeSelection,
});
const resolved = resolveVisibleChannelEntries();
return {
entries: resolved.entries,
catalogById: resolved.installableCatalogById,
@ -657,9 +648,7 @@ export async function setupChannels(
const selectedLines = resolveChannelSelectionNoteLines({
cfg: next,
installedPlugins: listVisibleInstalledPlugins({
includeRegistry: includeRegistryBeforeSelection,
}),
installedPlugins: listVisibleInstalledPlugins(),
selection,
});
if (selectedLines.length > 0) {