Skip to content

Commit de1d329

Browse files
vincentkocopenclaw-clownfish[bot]pradeep7127
authored
fix(plugins): allow Dreaming sidecar through restrictive memory allowlists (#93678)
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com> Co-authored-by: pradeep7127 <[email protected]>
1 parent 75cdf22 commit de1d329

4 files changed

Lines changed: 556 additions & 44 deletions

File tree

src/plugins/channel-plugin-ids.test.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,6 +2443,78 @@ describe("resolveGatewayStartupPluginIds", () => {
24432443
});
24442444
});
24452445

2446+
it("includes memory-core as a dreaming sidecar for restrictive selected-memory allowlists", () => {
2447+
expectStartupPluginIdsCase({
2448+
config: {
2449+
channels: {},
2450+
plugins: {
2451+
allow: ["browser", "memory-lancedb"],
2452+
slots: { memory: "memory-lancedb" },
2453+
entries: {
2454+
"memory-lancedb": { enabled: true, config: { dreaming: { enabled: true } } },
2455+
},
2456+
},
2457+
} as OpenClawConfig,
2458+
expected: ["browser", "memory-core", "memory-lancedb"],
2459+
});
2460+
});
2461+
2462+
it("includes memory-core in restrictive dreaming startup metadata scopes", () => {
2463+
const registry = createManifestRegistryFixture();
2464+
const index = createInstalledPluginIndexFixture(registry);
2465+
2466+
expect(
2467+
resolveGatewayStartupMetadataPluginIds({
2468+
config: {
2469+
channels: {},
2470+
plugins: {
2471+
allow: ["browser", "memory-lancedb"],
2472+
slots: { memory: "memory-lancedb" },
2473+
entries: {
2474+
"memory-lancedb": { enabled: true, config: { dreaming: { enabled: true } } },
2475+
},
2476+
},
2477+
} as OpenClawConfig,
2478+
env: createPluginPlanningTestEnv(),
2479+
index,
2480+
}),
2481+
).toEqual(["browser", "memory-core", "memory-lancedb"]);
2482+
});
2483+
2484+
it("does not include denied memory-core as a restrictive dreaming startup sidecar", () => {
2485+
expectStartupPluginIdsCase({
2486+
config: {
2487+
channels: {},
2488+
plugins: {
2489+
allow: ["browser", "memory-lancedb"],
2490+
deny: ["memory-core"],
2491+
slots: { memory: "memory-lancedb" },
2492+
entries: {
2493+
"memory-lancedb": { enabled: true, config: { dreaming: { enabled: true } } },
2494+
},
2495+
},
2496+
} as OpenClawConfig,
2497+
expected: ["browser", "memory-lancedb"],
2498+
});
2499+
});
2500+
2501+
it("does not include explicitly disabled memory-core as a restrictive dreaming startup sidecar", () => {
2502+
expectStartupPluginIdsCase({
2503+
config: {
2504+
channels: {},
2505+
plugins: {
2506+
allow: ["browser", "memory-lancedb"],
2507+
slots: { memory: "memory-lancedb" },
2508+
entries: {
2509+
"memory-core": { enabled: false },
2510+
"memory-lancedb": { enabled: true, config: { dreaming: { enabled: true } } },
2511+
},
2512+
},
2513+
} as OpenClawConfig,
2514+
expected: ["browser", "memory-lancedb"],
2515+
});
2516+
});
2517+
24462518
it("normalizes the raw memory slot id before startup filtering", () => {
24472519
expectStartupPluginIdsCase({
24482520
config: createStartupConfig({

src/plugins/gateway-startup-plugin-ids.ts

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,85 @@ function isGatewayStartupMemoryPlugin(plugin: InstalledPluginIndexRecord): boole
113113
return plugin.startup.memory;
114114
}
115115

116-
function resolveGatewayStartupDreamingPluginIds(config: OpenClawConfig): Set<string> {
116+
function resolveGatewayStartupDreamingEngineId(config: OpenClawConfig): string | undefined {
117117
const dreamingConfig = resolveMemoryDreamingConfig({
118118
pluginConfig: resolveMemoryDreamingPluginConfig(config),
119119
cfg: config,
120120
});
121121
if (!dreamingConfig.enabled) {
122+
return undefined;
123+
}
124+
if (!resolveGatewayStartupDreamingSelectedPluginId(config)) {
125+
return undefined;
126+
}
127+
return DEFAULT_MEMORY_DREAMING_PLUGIN_ID;
128+
}
129+
130+
function resolveGatewayStartupDreamingSelectedPluginId(config: OpenClawConfig): string | undefined {
131+
const selectedPluginId = normalizeOptionalLowercaseString(resolveMemoryDreamingPluginId(config));
132+
return selectedPluginId && selectedPluginId !== DEFAULT_MEMORY_DREAMING_PLUGIN_ID
133+
? selectedPluginId
134+
: undefined;
135+
}
136+
137+
function blocksPluginStartup(params: {
138+
pluginId: string;
139+
pluginsConfig: NormalizedPluginsConfig;
140+
activationSourcePlugins: NormalizedPluginsConfig;
141+
}): boolean {
142+
return (
143+
params.pluginsConfig.deny.includes(params.pluginId) ||
144+
params.activationSourcePlugins.deny.includes(params.pluginId) ||
145+
params.pluginsConfig.entries[params.pluginId]?.enabled === false ||
146+
params.activationSourcePlugins.entries[params.pluginId]?.enabled === false
147+
);
148+
}
149+
150+
function resolveAuthorizedGatewayStartupDreamingPluginIds(params: {
151+
config: OpenClawConfig;
152+
pluginsConfig: NormalizedPluginsConfig;
153+
activationSource: {
154+
plugins: NormalizedPluginsConfig;
155+
rootConfig?: OpenClawConfig;
156+
};
157+
activationSourcePlugins: NormalizedPluginsConfig;
158+
selectedMemoryPluginId?: string;
159+
index: { plugins: readonly InstalledPluginIndexRecord[] };
160+
platform?: NodeJS.Platform;
161+
}): Set<string> {
162+
const engineId = resolveGatewayStartupDreamingEngineId(params.config);
163+
const dreamingSelectedPluginId = resolveGatewayStartupDreamingSelectedPluginId(params.config);
164+
if (!engineId || !params.pluginsConfig.enabled || !params.activationSourcePlugins.enabled) {
165+
return new Set();
166+
}
167+
if (
168+
!params.selectedMemoryPluginId ||
169+
params.selectedMemoryPluginId !== dreamingSelectedPluginId ||
170+
params.selectedMemoryPluginId === engineId ||
171+
blocksPluginStartup({
172+
pluginId: engineId,
173+
pluginsConfig: params.pluginsConfig,
174+
activationSourcePlugins: params.activationSourcePlugins,
175+
})
176+
) {
177+
return new Set();
178+
}
179+
const selectedPlugin = params.index.plugins.find(
180+
(plugin) => plugin.pluginId === params.selectedMemoryPluginId,
181+
);
182+
const sidecarPlugin = params.index.plugins.find((plugin) => plugin.pluginId === engineId);
183+
if (!selectedPlugin?.startup.memory || !sidecarPlugin?.startup.memory) {
122184
return new Set();
123185
}
124-
return new Set([DEFAULT_MEMORY_DREAMING_PLUGIN_ID, resolveMemoryDreamingPluginId(config)]);
186+
const activationState = resolveEffectivePluginActivationState({
187+
id: selectedPlugin.pluginId,
188+
origin: selectedPlugin.origin,
189+
config: params.pluginsConfig,
190+
rootConfig: params.config,
191+
enabledByDefault: isPluginEnabledByDefaultForPlatform(selectedPlugin, params.platform),
192+
activationSource: params.activationSource,
193+
});
194+
return activationState.enabled ? new Set([engineId]) : new Set();
125195
}
126196

127197
function resolveMemorySlotStartupPluginId(params: {
@@ -913,12 +983,28 @@ export function resolveGatewayStartupMetadataPluginIds(params: {
913983
addPluginConfigEntryIds(scope, pluginsConfig);
914984
addPluginConfigEntryIds(scope, activationSourcePlugins);
915985

986+
const memorySlotStartupPluginId = resolveMemorySlotStartupPluginId({
987+
activationSourceConfig,
988+
activationSourcePlugins,
989+
normalizePluginId: lookup.normalizePluginId,
990+
});
916991
addConfiguredSlotPluginIds(scope, {
917992
activationSourceConfig,
918993
activationSourcePlugins,
919994
lookup,
920995
});
921-
for (const pluginId of resolveGatewayStartupDreamingPluginIds(params.config)) {
996+
for (const pluginId of resolveAuthorizedGatewayStartupDreamingPluginIds({
997+
config: params.config,
998+
pluginsConfig,
999+
activationSource: {
1000+
plugins: activationSourcePlugins,
1001+
rootConfig: activationSourceConfig,
1002+
},
1003+
activationSourcePlugins,
1004+
selectedMemoryPluginId: memorySlotStartupPluginId,
1005+
index: params.index,
1006+
platform: params.platform,
1007+
})) {
9221008
scope.add(pluginId);
9231009
}
9241010
if (!lookup.hasCompleteConfigPathActivationMetadata()) {
@@ -1900,7 +1986,6 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: {
19001986
const requiredAgentHarnessRuntimes = new Set(
19011987
collectConfiguredAgentHarnessRuntimes(activationSourceConfig),
19021988
);
1903-
const startupDreamingPluginIds = resolveGatewayStartupDreamingPluginIds(params.config);
19041989
const configuredSpeechProviderIds = collectConfiguredSpeechProviderIds(activationSourceConfig);
19051990
const configuredWebSearchProviderIds =
19061991
collectConfiguredWebSearchProviderIds(activationSourceConfig);
@@ -1921,6 +2006,15 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: {
19212006
activationSourcePlugins,
19222007
normalizePluginId,
19232008
});
2009+
const startupDreamingPluginIds = resolveAuthorizedGatewayStartupDreamingPluginIds({
2010+
config: params.config,
2011+
pluginsConfig,
2012+
activationSource,
2013+
activationSourcePlugins,
2014+
selectedMemoryPluginId: memorySlotStartupPluginId,
2015+
index: params.index,
2016+
platform: params.platform,
2017+
});
19242018
const contextEngineSlotStartupPluginId = resolveContextEngineSlotStartupPluginId({
19252019
activationSourceConfig,
19262020
activationSourcePlugins,
@@ -2116,6 +2210,10 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: {
21162210
) {
21172211
continue;
21182212
}
2213+
if (startupDreamingPluginIds.has(plugin.pluginId)) {
2214+
pluginIds.push(plugin.pluginId);
2215+
continue;
2216+
}
21192217
const activationState = resolveEffectivePluginActivationState({
21202218
id: plugin.pluginId,
21212219
origin: plugin.origin,

0 commit comments

Comments
 (0)