mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:20:43 +00:00
fix(agents): avoid secrets snapshot clones in plugin tool prep
This commit is contained in:
@@ -45,6 +45,7 @@ Docs: https://docs.openclaw.ai
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { selectApplicableRuntimeConfig } from "../config/config.js";
|
||||
import {
|
||||
getRuntimeConfigSnapshot,
|
||||
getRuntimeConfigSourceSnapshot,
|
||||
} from "../config/runtime-snapshot.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { resolvePluginTools } from "../plugins/tools.js";
|
||||
import { getActiveSecretsRuntimeSnapshot } from "../secrets/runtime.js";
|
||||
import { normalizeDeliveryContext } from "../utils/delivery-context.js";
|
||||
import { listProfilesForProvider } from "./auth-profiles.js";
|
||||
import type { AuthProfileStore } from "./auth-profiles/types.js";
|
||||
@@ -28,6 +31,27 @@ type ResolveOpenClawPluginToolsOptions = OpenClawPluginToolOptions & {
|
||||
authProfileStore?: AuthProfileStore;
|
||||
};
|
||||
|
||||
function resolveApplicablePluginRuntimeConfig(
|
||||
inputConfig?: OpenClawConfig,
|
||||
): OpenClawConfig | undefined {
|
||||
const runtimeConfig = getRuntimeConfigSnapshot() ?? undefined;
|
||||
if (!runtimeConfig) {
|
||||
return inputConfig;
|
||||
}
|
||||
if (!inputConfig || inputConfig === runtimeConfig) {
|
||||
return runtimeConfig;
|
||||
}
|
||||
const runtimeSourceConfig = getRuntimeConfigSourceSnapshot() ?? undefined;
|
||||
if (!runtimeSourceConfig) {
|
||||
return inputConfig;
|
||||
}
|
||||
return selectApplicableRuntimeConfig({
|
||||
inputConfig,
|
||||
runtimeConfig,
|
||||
runtimeSourceConfig,
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveOpenClawPluginToolsForOptions(params: {
|
||||
options?: ResolveOpenClawPluginToolsOptions;
|
||||
resolvedConfig?: OpenClawConfig;
|
||||
@@ -45,12 +69,7 @@ export function resolveOpenClawPluginToolsForOptions(params: {
|
||||
});
|
||||
|
||||
const resolveCurrentRuntimeConfig = () => {
|
||||
const currentRuntimeSnapshot = getActiveSecretsRuntimeSnapshot();
|
||||
return selectApplicableRuntimeConfig({
|
||||
inputConfig: params.resolvedConfig ?? params.options?.config,
|
||||
runtimeConfig: currentRuntimeSnapshot?.config,
|
||||
runtimeSourceConfig: currentRuntimeSnapshot?.sourceConfig,
|
||||
});
|
||||
return resolveApplicablePluginRuntimeConfig(params.resolvedConfig ?? params.options?.config);
|
||||
};
|
||||
const authProfileStore = params.options?.authProfileStore;
|
||||
const pluginTools = resolvePluginTools({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resetConfigRuntimeState, setRuntimeConfigSnapshot } from "../config/config.js";
|
||||
import { activateSecretsRuntimeSnapshot, clearSecretsRuntimeSnapshot } from "../secrets/runtime.js";
|
||||
import { resolveOpenClawPluginToolsForOptions } from "./openclaw-plugin-tools.js";
|
||||
|
||||
@@ -15,6 +16,7 @@ describe("createOpenClawTools browser plugin integration", () => {
|
||||
afterEach(() => {
|
||||
hoisted.resolvePluginTools.mockReset();
|
||||
clearSecretsRuntimeSnapshot();
|
||||
resetConfigRuntimeState();
|
||||
});
|
||||
|
||||
it("keeps the browser tool returned by plugin resolution", () => {
|
||||
@@ -193,6 +195,48 @@ describe("createOpenClawTools browser plugin integration", () => {
|
||||
expect(capturedRuntimeConfig).toBe(resolvedRunConfig);
|
||||
});
|
||||
|
||||
it("does not let a source-less pinned config snapshot override explicit plugin tool config", () => {
|
||||
const pinnedRuntimeConfig = {
|
||||
plugins: {
|
||||
allow: ["old-plugin"],
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const explicitConfig = {
|
||||
plugins: {
|
||||
allow: ["browser"],
|
||||
},
|
||||
tools: {
|
||||
experimental: {
|
||||
planTool: true,
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
let capturedRuntimeConfig: OpenClawConfig | undefined;
|
||||
let getRuntimeConfig: (() => OpenClawConfig | undefined) | undefined;
|
||||
hoisted.resolvePluginTools.mockImplementation((params: unknown) => {
|
||||
const context = (
|
||||
params as {
|
||||
context?: {
|
||||
runtimeConfig?: OpenClawConfig;
|
||||
getRuntimeConfig?: () => OpenClawConfig | undefined;
|
||||
};
|
||||
}
|
||||
).context;
|
||||
capturedRuntimeConfig = context?.runtimeConfig;
|
||||
getRuntimeConfig = context?.getRuntimeConfig;
|
||||
return [];
|
||||
});
|
||||
setRuntimeConfigSnapshot(pinnedRuntimeConfig);
|
||||
|
||||
resolveOpenClawPluginToolsForOptions({
|
||||
options: { config: explicitConfig },
|
||||
resolvedConfig: explicitConfig,
|
||||
});
|
||||
|
||||
expect(capturedRuntimeConfig).toBe(explicitConfig);
|
||||
expect(getRuntimeConfig?.()).toBe(explicitConfig);
|
||||
});
|
||||
|
||||
it("exposes a live runtime config getter to plugin tool factories", () => {
|
||||
const sourceConfig = {
|
||||
plugins: {
|
||||
@@ -218,23 +262,7 @@ describe("createOpenClawTools browser plugin integration", () => {
|
||||
).context?.getRuntimeConfig;
|
||||
return [];
|
||||
});
|
||||
activateSecretsRuntimeSnapshot({
|
||||
sourceConfig,
|
||||
config: firstRuntimeConfig,
|
||||
authStores: [],
|
||||
warnings: [],
|
||||
webTools: {
|
||||
search: {
|
||||
providerSource: "none",
|
||||
diagnostics: [],
|
||||
},
|
||||
fetch: {
|
||||
providerSource: "none",
|
||||
diagnostics: [],
|
||||
},
|
||||
diagnostics: [],
|
||||
},
|
||||
});
|
||||
setRuntimeConfigSnapshot(firstRuntimeConfig, sourceConfig);
|
||||
|
||||
resolveOpenClawPluginToolsForOptions({
|
||||
options: { config: sourceConfig },
|
||||
@@ -243,23 +271,7 @@ describe("createOpenClawTools browser plugin integration", () => {
|
||||
|
||||
expect(getRuntimeConfig?.()).toStrictEqual(firstRuntimeConfig);
|
||||
|
||||
activateSecretsRuntimeSnapshot({
|
||||
sourceConfig,
|
||||
config: nextRuntimeConfig,
|
||||
authStores: [],
|
||||
warnings: [],
|
||||
webTools: {
|
||||
search: {
|
||||
providerSource: "none",
|
||||
diagnostics: [],
|
||||
},
|
||||
fetch: {
|
||||
providerSource: "none",
|
||||
diagnostics: [],
|
||||
},
|
||||
diagnostics: [],
|
||||
},
|
||||
});
|
||||
setRuntimeConfigSnapshot(nextRuntimeConfig, sourceConfig);
|
||||
|
||||
expect(getRuntimeConfig?.()).toStrictEqual(nextRuntimeConfig);
|
||||
expect(getRuntimeConfig?.()?.plugins?.entries?.["memory-core"]?.enabled).toBe(false);
|
||||
|
||||
Reference in New Issue
Block a user