Skip to content

Commit 5be66ca

Browse files
committed
fix(agents): avoid secrets snapshot clones in plugin tool prep
1 parent 45cfe1d commit 5be66ca

3 files changed

Lines changed: 73 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Docs: https://docs.openclaw.ai
4545
- Release validation: install the cross-OS TypeScript harness through Windows-safe Node/npm shims so native Windows package checks reach the OpenClaw smoke suites instead of exiting before artifact capture. Thanks @vincentkoc.
4646
- Release validation: let Windows packaged-upgrade checks continue after the shipped 2026.5.2 updater hits its native-module swap cleanup fallback, verifying the fallback-installed candidate through package metadata and downstream smoke instead of crashing on the immediate update-status probe. Thanks @vincentkoc.
4747
- Doctor/plugins: skip channel-derived official plugin installs when another configured plugin is the effective owner for the same channel, so `doctor --repair` does not reinstall `feishu` while `openclaw-lark` handles `channels.feishu`. Fixes #76623. Thanks @fuyizheng3120.
48+
- Agents/tools: use config-only runtime snapshots for plugin tool registration and live runtime config getters, avoiding expensive full secrets snapshot clones on the core-plugin-tools prep path. Fixes #76295.
4849
- Agents/bootstrap: keep pending `BOOTSTRAP.md` and bootstrap truncation notices in system-prompt Project Context instead of copying setup text or raw warning diagnostics into WebChat user/runtime context. Fixes #76946.
4950
- Channels/WhatsApp: allow `@whiskeysockets/libsignal-node` in `onlyBuiltDependencies` so pnpm v9+ `blockExoticSubdeps` no longer rejects the baileys git-tarball subdep and silences all inbound agent replies. Fixes #76539. Thanks @ottodeng and @vincentkoc.
5051
- Gateway/install: keep `.env`-managed values in the macOS LaunchAgent env file while still tracking `OPENCLAW_SERVICE_MANAGED_ENV_KEYS`, so regenerated services do not boot without managed auth/provider keys. Fixes #75374.

src/agents/openclaw-plugin-tools.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { selectApplicableRuntimeConfig } from "../config/config.js";
2+
import {
3+
getRuntimeConfigSnapshot,
4+
getRuntimeConfigSourceSnapshot,
5+
} from "../config/runtime-snapshot.js";
26
import type { OpenClawConfig } from "../config/types.openclaw.js";
37
import { resolvePluginTools } from "../plugins/tools.js";
4-
import { getActiveSecretsRuntimeSnapshot } from "../secrets/runtime.js";
58
import { normalizeDeliveryContext } from "../utils/delivery-context.js";
69
import { listProfilesForProvider } from "./auth-profiles.js";
710
import type { AuthProfileStore } from "./auth-profiles/types.js";
@@ -28,6 +31,27 @@ type ResolveOpenClawPluginToolsOptions = OpenClawPluginToolOptions & {
2831
authProfileStore?: AuthProfileStore;
2932
};
3033

34+
function resolveApplicablePluginRuntimeConfig(
35+
inputConfig?: OpenClawConfig,
36+
): OpenClawConfig | undefined {
37+
const runtimeConfig = getRuntimeConfigSnapshot() ?? undefined;
38+
if (!runtimeConfig) {
39+
return inputConfig;
40+
}
41+
if (!inputConfig || inputConfig === runtimeConfig) {
42+
return runtimeConfig;
43+
}
44+
const runtimeSourceConfig = getRuntimeConfigSourceSnapshot() ?? undefined;
45+
if (!runtimeSourceConfig) {
46+
return inputConfig;
47+
}
48+
return selectApplicableRuntimeConfig({
49+
inputConfig,
50+
runtimeConfig,
51+
runtimeSourceConfig,
52+
});
53+
}
54+
3155
export function resolveOpenClawPluginToolsForOptions(params: {
3256
options?: ResolveOpenClawPluginToolsOptions;
3357
resolvedConfig?: OpenClawConfig;
@@ -45,12 +69,7 @@ export function resolveOpenClawPluginToolsForOptions(params: {
4569
});
4670

4771
const resolveCurrentRuntimeConfig = () => {
48-
const currentRuntimeSnapshot = getActiveSecretsRuntimeSnapshot();
49-
return selectApplicableRuntimeConfig({
50-
inputConfig: params.resolvedConfig ?? params.options?.config,
51-
runtimeConfig: currentRuntimeSnapshot?.config,
52-
runtimeSourceConfig: currentRuntimeSnapshot?.sourceConfig,
53-
});
72+
return resolveApplicablePluginRuntimeConfig(params.resolvedConfig ?? params.options?.config);
5473
};
5574
const authProfileStore = params.options?.authProfileStore;
5675
const pluginTools = resolvePluginTools({

src/agents/openclaw-tools.browser-plugin.integration.test.ts

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { afterEach, describe, expect, it, vi } from "vitest";
22
import type { OpenClawConfig } from "../config/config.js";
3+
import { resetConfigRuntimeState, setRuntimeConfigSnapshot } from "../config/config.js";
34
import { activateSecretsRuntimeSnapshot, clearSecretsRuntimeSnapshot } from "../secrets/runtime.js";
45
import { resolveOpenClawPluginToolsForOptions } from "./openclaw-plugin-tools.js";
56

@@ -15,6 +16,7 @@ describe("createOpenClawTools browser plugin integration", () => {
1516
afterEach(() => {
1617
hoisted.resolvePluginTools.mockReset();
1718
clearSecretsRuntimeSnapshot();
19+
resetConfigRuntimeState();
1820
});
1921

2022
it("keeps the browser tool returned by plugin resolution", () => {
@@ -193,6 +195,48 @@ describe("createOpenClawTools browser plugin integration", () => {
193195
expect(capturedRuntimeConfig).toBe(resolvedRunConfig);
194196
});
195197

198+
it("does not let a source-less pinned config snapshot override explicit plugin tool config", () => {
199+
const pinnedRuntimeConfig = {
200+
plugins: {
201+
allow: ["old-plugin"],
202+
},
203+
} as OpenClawConfig;
204+
const explicitConfig = {
205+
plugins: {
206+
allow: ["browser"],
207+
},
208+
tools: {
209+
experimental: {
210+
planTool: true,
211+
},
212+
},
213+
} as OpenClawConfig;
214+
let capturedRuntimeConfig: OpenClawConfig | undefined;
215+
let getRuntimeConfig: (() => OpenClawConfig | undefined) | undefined;
216+
hoisted.resolvePluginTools.mockImplementation((params: unknown) => {
217+
const context = (
218+
params as {
219+
context?: {
220+
runtimeConfig?: OpenClawConfig;
221+
getRuntimeConfig?: () => OpenClawConfig | undefined;
222+
};
223+
}
224+
).context;
225+
capturedRuntimeConfig = context?.runtimeConfig;
226+
getRuntimeConfig = context?.getRuntimeConfig;
227+
return [];
228+
});
229+
setRuntimeConfigSnapshot(pinnedRuntimeConfig);
230+
231+
resolveOpenClawPluginToolsForOptions({
232+
options: { config: explicitConfig },
233+
resolvedConfig: explicitConfig,
234+
});
235+
236+
expect(capturedRuntimeConfig).toBe(explicitConfig);
237+
expect(getRuntimeConfig?.()).toBe(explicitConfig);
238+
});
239+
196240
it("exposes a live runtime config getter to plugin tool factories", () => {
197241
const sourceConfig = {
198242
plugins: {
@@ -218,23 +262,7 @@ describe("createOpenClawTools browser plugin integration", () => {
218262
).context?.getRuntimeConfig;
219263
return [];
220264
});
221-
activateSecretsRuntimeSnapshot({
222-
sourceConfig,
223-
config: firstRuntimeConfig,
224-
authStores: [],
225-
warnings: [],
226-
webTools: {
227-
search: {
228-
providerSource: "none",
229-
diagnostics: [],
230-
},
231-
fetch: {
232-
providerSource: "none",
233-
diagnostics: [],
234-
},
235-
diagnostics: [],
236-
},
237-
});
265+
setRuntimeConfigSnapshot(firstRuntimeConfig, sourceConfig);
238266

239267
resolveOpenClawPluginToolsForOptions({
240268
options: { config: sourceConfig },
@@ -243,23 +271,7 @@ describe("createOpenClawTools browser plugin integration", () => {
243271

244272
expect(getRuntimeConfig?.()).toStrictEqual(firstRuntimeConfig);
245273

246-
activateSecretsRuntimeSnapshot({
247-
sourceConfig,
248-
config: nextRuntimeConfig,
249-
authStores: [],
250-
warnings: [],
251-
webTools: {
252-
search: {
253-
providerSource: "none",
254-
diagnostics: [],
255-
},
256-
fetch: {
257-
providerSource: "none",
258-
diagnostics: [],
259-
},
260-
diagnostics: [],
261-
},
262-
});
274+
setRuntimeConfigSnapshot(nextRuntimeConfig, sourceConfig);
263275

264276
expect(getRuntimeConfig?.()).toStrictEqual(nextRuntimeConfig);
265277
expect(getRuntimeConfig?.()?.plugins?.entries?.["memory-core"]?.enabled).toBe(false);

0 commit comments

Comments
 (0)