diff --git a/src/plugins/channel-plugin-ids.test.ts b/src/plugins/channel-plugin-ids.test.ts index 965c8302329..3571c3552bc 100644 --- a/src/plugins/channel-plugin-ids.test.ts +++ b/src/plugins/channel-plugin-ids.test.ts @@ -1996,6 +1996,32 @@ describe("resolveGatewayStartupPluginIds", () => { expect(plan.configuredDeferredChannelPluginIds).toStrictEqual([]); }); + it("carries deferred configured channel ids through the startup plan", () => { + const registry = createManifestRegistryFixtureWithWorkspaceDemoChannel(); + const index = createInstalledPluginIndexFixture(registry); + + const plan = resolveGatewayStartupPluginPlanFromRegistry({ + config: { + channels: { + "demo-channel": { + token: "configured", + }, + }, + plugins: { + allow: ["workspace-demo-channel-plugin"], + }, + } as OpenClawConfig, + env: createPluginPlanningTestEnv(), + index, + manifestRegistry: registry, + }); + + expect(plan.pluginIds).toContain("workspace-demo-channel-plugin"); + expect(plan.configuredDeferredChannelPluginIds).toStrictEqual([ + "workspace-demo-channel-plugin", + ]); + }); + it("does not treat explicitly disabled stale channel config as deferred startup intent", () => { useManifestRegistryFixture(createManifestRegistryFixtureWithWorkspaceDemoChannel()); diff --git a/src/plugins/gateway-startup-plugin-ids.ts b/src/plugins/gateway-startup-plugin-ids.ts index 2f3fcb25951..4e99703276c 100644 --- a/src/plugins/gateway-startup-plugin-ids.ts +++ b/src/plugins/gateway-startup-plugin-ids.ts @@ -1581,18 +1581,7 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: { rootConfig: activationSourceConfig, }; const manifestLookup = createManifestRegistryLookup(params.manifestRegistry); - const configuredDeferredChannelPluginIds = resolveConfiguredDeferredChannelPluginIdsFromPrepared({ - config: params.config, - index: params.index, - configuredChannelIds, - pluginsConfig, - activationSource: { - plugins: pluginsConfig, - rootConfig: params.config, - }, - manifestLookup, - platform: params.platform, - }); + const configuredDeferredChannelPluginIds: string[] = []; const requiredAgentHarnessRuntimes = new Set( collectConfiguredAgentHarnessRuntimes(activationSourceConfig), ); @@ -1620,154 +1609,171 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: { activationSourcePlugins, normalizePluginId, }); - const pluginIds = params.index.plugins - .filter((plugin) => { - const manifest = findManifestPlugin(manifestLookup, plugin.pluginId); - if ( - hasConfiguredStartupChannel({ - plugin, - manifestLookup, - configuredChannelIds, - }) - ) { - return canStartConfiguredChannelPlugin({ - plugin, - config: params.config, - pluginsConfig, - activationSource, - manifestLookup, - platform: params.platform, - }); - } - if ( - canStartRequiredAgentHarnessPlugin({ - plugin, - pluginsConfig, - activationSource, - config: params.config, - requiredAgentHarnessRuntimes, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartConfiguredRootPlugin({ - plugin, - manifest, - config: activationSourceConfig, - pluginsConfig, - activationSourcePlugins, - }) - ) { - return true; - } - if ( - canStartConfiguredSpeechProviderPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - configuredSpeechProviderIds, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartConfiguredWebSearchProviderPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - configuredWebSearchProviderIds, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartConfiguredModelProviderPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - configuredModelProviderIds, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartConfiguredGenerationProviderPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - configuredGenerationProviderIds, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartConfiguredVoiceProviderPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - configuredVoiceProviderIds, - platform: params.platform, - }) - ) { - return true; - } - if ( - canStartExplicitHookPlugin({ - plugin, - manifest, - config: params.config, - pluginsConfig, - activationSource, - activationSourcePlugins, - platform: params.platform, - }) - ) { - return true; - } - if ( - !shouldConsiderForGatewayStartup({ - plugin, - manifest, - startupDreamingPluginIds, - memorySlotStartupPluginId, - contextEngineSlotStartupPluginId, - }) - ) { - return false; - } - const activationState = resolveEffectivePluginActivationState({ - id: plugin.pluginId, - origin: plugin.origin, - config: pluginsConfig, - rootConfig: params.config, - enabledByDefault: isPluginEnabledByDefaultForPlatform(plugin, params.platform), + const pluginIds: string[] = []; + for (const plugin of params.index.plugins) { + const manifest = findManifestPlugin(manifestLookup, plugin.pluginId); + if ( + hasConfiguredStartupChannel({ + plugin, + manifestLookup, + configuredChannelIds, + }) + ) { + const canStartConfiguredChannel = canStartConfiguredChannelPlugin({ + plugin, + config: params.config, + pluginsConfig, activationSource, + manifestLookup, + platform: params.platform, }); - if (!activationState.enabled) { - return false; + if (canStartConfiguredChannel) { + pluginIds.push(plugin.pluginId); + if (plugin.startup.deferConfiguredChannelFullLoadUntilAfterListen) { + configuredDeferredChannelPluginIds.push(plugin.pluginId); + } } - if (plugin.origin !== "bundled") { - return activationState.explicitlyEnabled; - } - return activationState.source === "explicit" || activationState.source === "default"; - }) - .map((plugin) => plugin.pluginId); + continue; + } + if ( + canStartRequiredAgentHarnessPlugin({ + plugin, + pluginsConfig, + activationSource, + config: params.config, + requiredAgentHarnessRuntimes, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredRootPlugin({ + plugin, + manifest, + config: activationSourceConfig, + pluginsConfig, + activationSourcePlugins, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredSpeechProviderPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + configuredSpeechProviderIds, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredWebSearchProviderPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + configuredWebSearchProviderIds, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredModelProviderPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + configuredModelProviderIds, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredGenerationProviderPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + configuredGenerationProviderIds, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartConfiguredVoiceProviderPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + configuredVoiceProviderIds, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + canStartExplicitHookPlugin({ + plugin, + manifest, + config: params.config, + pluginsConfig, + activationSource, + activationSourcePlugins, + platform: params.platform, + }) + ) { + pluginIds.push(plugin.pluginId); + continue; + } + if ( + !shouldConsiderForGatewayStartup({ + plugin, + manifest, + startupDreamingPluginIds, + memorySlotStartupPluginId, + contextEngineSlotStartupPluginId, + }) + ) { + continue; + } + const activationState = resolveEffectivePluginActivationState({ + id: plugin.pluginId, + origin: plugin.origin, + config: pluginsConfig, + rootConfig: params.config, + enabledByDefault: isPluginEnabledByDefaultForPlatform(plugin, params.platform), + activationSource, + }); + if (!activationState.enabled) { + continue; + } + if ( + plugin.origin !== "bundled" + ? activationState.explicitlyEnabled + : activationState.source === "explicit" || activationState.source === "default" + ) { + pluginIds.push(plugin.pluginId); + } + } return { channelPluginIds, configuredDeferredChannelPluginIds, diff --git a/src/plugins/plugin-lookup-table.ts b/src/plugins/plugin-lookup-table.ts index f2cfadcdc2c..49a2d3f6fc2 100644 --- a/src/plugins/plugin-lookup-table.ts +++ b/src/plugins/plugin-lookup-table.ts @@ -31,7 +31,6 @@ export type PluginLookUpTableMetrics = { }; export type PluginLookUpTable = PluginMetadataSnapshot & { - key: string; startup: PluginLookUpTableStartupPlan; metrics: PluginMetadataSnapshot["metrics"] & Pick< @@ -141,16 +140,6 @@ export function loadPluginLookUpTable(params: LoadPluginLookUpTableParams): Plug const table: PluginLookUpTable = { ...metadataSnapshot, - key: hashJson({ - policyHash: index.policyHash, - generatedAtMs: index.generatedAtMs, - plugins: index.plugins.map((plugin) => [ - plugin.pluginId, - plugin.manifestHash, - plugin.installRecordHash, - ]), - startup, - }), startup, metrics: { ...metadataSnapshot.metrics,