Skip to content

Commit 7f3f108

Browse files
committed
refactor(config): migrate plugin config access
1 parent 48ebed3 commit 7f3f108

531 files changed

Lines changed: 3501 additions & 1645 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
3546f416ff22ead14952cd105c7b88e3b7b76d5ddc10269e73f69ed1950f0603 config-baseline.json
2-
b29ade2d1d2415b030b4d5ec36097a93ab4ea943b7d2a52da95829be1c28fc2a config-baseline.core.json
1+
5027142b42acd038bb3cd15e53a0d45293103448a3aee1072500352095e14242 config-baseline.json
2+
ecb702eee54bcb697916944440e13208ac7a640a8e07f44072bb79e9284ca994 config-baseline.core.json
33
07963db49502132f26db396c56b36e018b110e6c55a68b3cb012d3ec96f43901 config-baseline.channel.json
44
ed65cefbef96f034ce2b73069d9d5bacc341a43489ff9b20a34d40956b877f79 config-baseline.plugin.json
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
6eabbe9e1e568fa1bc02539bd21bb6cd463d609f2ad4573d0cbf116ce39a28f9 plugin-sdk-api-baseline.json
2-
c5a5ba7c051ab741b1cdfb36b23f13e6aad9fbe17ba3fa92c4833c0490a35181 plugin-sdk-api-baseline.jsonl
1+
74344f185b3149695443bf8815c9dd784daf9c0b8118ecc54129dc57899e9564 plugin-sdk-api-baseline.json
2+
7b84c2f1e5743dac9c764fdee6d3b23e64553516c409f4a24f009a36c40d64e8 plugin-sdk-api-baseline.jsonl

extensions/active-memory/index.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,13 @@ describe("active-memory plugin", () => {
9090
resolveStateDir: () => stateDir,
9191
},
9292
config: {
93+
current: () => configFile,
9394
loadConfig: () => configFile,
95+
replaceConfigFile: vi.fn(
96+
async ({ nextConfig }: { nextConfig: Record<string, unknown> }) => {
97+
configFile = nextConfig;
98+
},
99+
),
94100
writeConfigFile: vi.fn(async (nextConfig: Record<string, unknown>) => {
95101
configFile = nextConfig;
96102
}),
@@ -275,7 +281,7 @@ describe("active-memory plugin", () => {
275281
});
276282

277283
expect(offResult.text).toBe("Active Memory: off globally.");
278-
expect(api.runtime.config.writeConfigFile).toHaveBeenCalledTimes(1);
284+
expect(api.runtime.config.replaceConfigFile).toHaveBeenCalledTimes(1);
279285
expect(configFile).toMatchObject({
280286
plugins: {
281287
entries: {

extensions/active-memory/index.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,7 +1932,9 @@ export default definePluginEntry({
19321932
warnDeprecatedModelFallbackPolicy(api.pluginConfig);
19331933
const refreshLiveConfigFromRuntime = () => {
19341934
const livePluginConfig = resolveLivePluginConfigObject(
1935-
api.runtime.config?.loadConfig,
1935+
api.runtime.config?.current
1936+
? () => api.runtime.config.current() as OpenClawConfig
1937+
: undefined,
19361938
"active-memory",
19371939
api.pluginConfig as Record<string, unknown>,
19381940
);
@@ -1953,21 +1955,27 @@ export default definePluginEntry({
19531955
return { text: formatActiveMemoryCommandHelp() };
19541956
}
19551957
if (isGlobal) {
1956-
const currentConfig = api.runtime.config.loadConfig();
1958+
const currentConfig = api.runtime.config.current() as OpenClawConfig;
19571959
if (action === "status") {
19581960
return {
19591961
text: `Active Memory: ${isActiveMemoryGloballyEnabled(currentConfig) ? "on" : "off"} globally.`,
19601962
};
19611963
}
19621964
if (action === "on" || action === "enable" || action === "enabled") {
19631965
const nextConfig = updateActiveMemoryGlobalEnabledInConfig(currentConfig, true);
1964-
await api.runtime.config.writeConfigFile(nextConfig);
1966+
await api.runtime.config.replaceConfigFile({
1967+
nextConfig,
1968+
afterWrite: { mode: "auto" },
1969+
});
19651970
refreshLiveConfigFromRuntime();
19661971
return { text: "Active Memory: on globally." };
19671972
}
19681973
if (action === "off" || action === "disable" || action === "disabled") {
19691974
const nextConfig = updateActiveMemoryGlobalEnabledInConfig(currentConfig, false);
1970-
await api.runtime.config.writeConfigFile(nextConfig);
1975+
await api.runtime.config.replaceConfigFile({
1976+
nextConfig,
1977+
afterWrite: { mode: "auto" },
1978+
});
19711979
refreshLiveConfigFromRuntime();
19721980
return { text: "Active Memory: off globally." };
19731981
}

extensions/bluebubbles/src/actions.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,24 @@ const { bluebubblesMessageActions } = await importFreshModule<typeof import("./a
5050
"./actions.js?actions-test",
5151
);
5252

53+
function requireDefined<T>(value: T | undefined, name: string): T {
54+
if (value === undefined) {
55+
throw new Error(`${name} is not registered`);
56+
}
57+
return value;
58+
}
59+
5360
describe("bluebubblesMessageActions", () => {
54-
const describeMessageTool = bluebubblesMessageActions.describeMessageTool!;
55-
const supportsAction = bluebubblesMessageActions.supportsAction!;
56-
const extractToolSend = bluebubblesMessageActions.extractToolSend!;
57-
const handleAction = bluebubblesMessageActions.handleAction!;
61+
const describeMessageTool = requireDefined(
62+
bluebubblesMessageActions.describeMessageTool,
63+
"describeMessageTool",
64+
);
65+
const supportsAction = requireDefined(bluebubblesMessageActions.supportsAction, "supportsAction");
66+
const extractToolSend = requireDefined(
67+
bluebubblesMessageActions.extractToolSend,
68+
"extractToolSend",
69+
);
70+
const handleAction = requireDefined(bluebubblesMessageActions.handleAction, "handleAction");
5871
const callHandleAction = (ctx: Omit<Parameters<typeof handleAction>[0], "channel">) =>
5972
handleAction({ channel: "bluebubbles", ...ctx });
6073
const blueBubblesConfig = (): OpenClawConfig => ({

extensions/browser/src/browser-tool.actions.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import {
66
browserSnapshot,
77
browserTabs,
88
getBrowserProfileCapabilities,
9+
getRuntimeConfig,
910
imageResultFromFile,
1011
jsonResult,
11-
loadConfig,
1212
normalizeOptionalString,
1313
readStringValue,
1414
resolveBrowserConfig,
@@ -22,8 +22,8 @@ const browserToolActionDeps = {
2222
browserConsoleMessages,
2323
browserSnapshot,
2424
browserTabs,
25+
getRuntimeConfig,
2526
imageResultFromFile,
26-
loadConfig,
2727
};
2828

2929
const BROWSER_ACT_REQUEST_TIMEOUT_SLACK_MS = 5_000;
@@ -70,7 +70,7 @@ function existingSessionRejectsActTimeout(request: BrowserActRequest): boolean {
7070
}
7171

7272
function usesExistingSessionProfile(profileName: string | undefined): boolean {
73-
const cfg = browserToolActionDeps.loadConfig();
73+
const cfg = browserToolActionDeps.getRuntimeConfig();
7474
const resolved = resolveBrowserConfig(cfg.browser, cfg);
7575
const profile = resolveProfile(resolved, profileName ?? resolved.defaultProfile);
7676
return profile ? getBrowserProfileCapabilities(profile).usesChromeMcp : false;
@@ -91,7 +91,7 @@ function withConfiguredActTimeout(
9191
return request;
9292
}
9393

94-
const cfg = browserToolActionDeps.loadConfig();
94+
const cfg = browserToolActionDeps.getRuntimeConfig();
9595
const configuredTimeout =
9696
normalizePositiveTimeoutMs(cfg.browser?.actionTimeoutMs) ?? DEFAULT_BROWSER_ACTION_TIMEOUT_MS;
9797
return { ...typedRequest, timeoutMs: configuredTimeout } as BrowserActRequest;
@@ -122,7 +122,7 @@ export const __testing = {
122122
browserSnapshot: typeof browserSnapshot;
123123
browserTabs: typeof browserTabs;
124124
imageResultFromFile: typeof imageResultFromFile;
125-
loadConfig: typeof loadConfig;
125+
getRuntimeConfig: typeof getRuntimeConfig;
126126
}> | null,
127127
) {
128128
browserToolActionDeps.browserAct = overrides?.browserAct ?? browserAct;
@@ -132,7 +132,7 @@ export const __testing = {
132132
browserToolActionDeps.browserTabs = overrides?.browserTabs ?? browserTabs;
133133
browserToolActionDeps.imageResultFromFile =
134134
overrides?.imageResultFromFile ?? imageResultFromFile;
135-
browserToolActionDeps.loadConfig = overrides?.loadConfig ?? loadConfig;
135+
browserToolActionDeps.getRuntimeConfig = overrides?.getRuntimeConfig ?? getRuntimeConfig;
136136
},
137137
};
138138

@@ -250,7 +250,7 @@ function isChromeStaleTargetError(profile: string | undefined, err: unknown): bo
250250
const msg = String(err);
251251
return msg.includes("404:") && msg.includes("tab not found");
252252
}
253-
const cfg = browserToolActionDeps.loadConfig();
253+
const cfg = browserToolActionDeps.getRuntimeConfig();
254254
const resolved = resolveBrowserConfig(cfg.browser, cfg);
255255
const browserProfile = resolveProfile(resolved, profile);
256256
if (!browserProfile || !getBrowserProfileCapabilities(browserProfile).usesChromeMcp) {
@@ -326,7 +326,7 @@ export async function executeSnapshotAction(params: {
326326
onTabActivity?: (targetId: string | undefined) => void;
327327
}): Promise<AgentToolResult<unknown>> {
328328
const { input, baseUrl, profile, proxyRequest } = params;
329-
const snapshotDefaults = browserToolActionDeps.loadConfig().browser?.snapshotDefaults;
329+
const snapshotDefaults = browserToolActionDeps.getRuntimeConfig().browser?.snapshotDefaults;
330330
const format: "ai" | "aria" | undefined =
331331
input.snapshotFormat === "ai" ? "ai" : input.snapshotFormat === "aria" ? "aria" : undefined;
332332
const formatExplicit = format !== undefined;

extensions/browser/src/browser-tool.runtime.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { loadConfig } from "openclaw/plugin-sdk/browser-config-runtime";
1+
export { getRuntimeConfig } from "openclaw/plugin-sdk/browser-config-runtime";
22
export {
33
callGatewayTool,
44
imageResultFromFile,

extensions/browser/src/browser-tool.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ vi.mock("openclaw/plugin-sdk/config-runtime", async () => {
142142
);
143143
return {
144144
...actual,
145-
loadConfig: configMocks.loadConfig,
145+
getRuntimeConfig: configMocks.loadConfig,
146146
};
147147
});
148148

@@ -193,6 +193,7 @@ vi.mock("./browser-tool.runtime.js", () => {
193193
...configMocks,
194194
...gatewayMocks,
195195
...sessionTabRegistryMocks,
196+
getRuntimeConfig: configMocks.loadConfig,
196197
applyBrowserProxyPaths: vi.fn(),
197198
getBrowserProfileCapabilities: (profile: Record<string, unknown>) => ({
198199
usesChromeMcp: profile.driver === "existing-session",
@@ -269,7 +270,7 @@ function resetBrowserToolMocks() {
269270
browserStatus: browserClientMocks.browserStatus as never,
270271
browserStop: browserClientMocks.browserStop as never,
271272
imageResultFromFile: toolCommonMocks.imageResultFromFile as never,
272-
loadConfig: configMocks.loadConfig as never,
273+
getRuntimeConfig: configMocks.loadConfig as never,
273274
listNodes: nodesUtilsMocks.listNodes as never,
274275
callGatewayTool: gatewayMocks.callGatewayTool as never,
275276
trackSessionBrowserTab: sessionTabRegistryMocks.trackSessionBrowserTab as never,
@@ -280,7 +281,7 @@ function resetBrowserToolMocks() {
280281
browserConsoleMessages: browserActionsMocks.browserConsoleMessages as never,
281282
browserSnapshot: browserClientMocks.browserSnapshot as never,
282283
browserTabs: browserClientMocks.browserTabs as never,
283-
loadConfig: configMocks.loadConfig as never,
284+
getRuntimeConfig: configMocks.loadConfig as never,
284285
imageResultFromFile: toolCommonMocks.imageResultFromFile as never,
285286
});
286287
}

extensions/browser/src/browser-tool.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import {
2626
browserStatus,
2727
browserStop,
2828
callGatewayTool,
29+
getRuntimeConfig,
2930
getBrowserProfileCapabilities,
3031
imageResultFromFile,
3132
jsonResult,
3233
listNodes,
33-
loadConfig,
3434
normalizeOptionalString,
3535
persistBrowserProxyFiles,
3636
readStringParam,
@@ -61,8 +61,8 @@ const browserToolDeps = {
6161
browserStart,
6262
browserStatus,
6363
browserStop,
64+
getRuntimeConfig,
6465
imageResultFromFile,
65-
loadConfig,
6666
listNodes,
6767
callGatewayTool,
6868
touchSessionBrowserTab,
@@ -88,7 +88,7 @@ export const __testing = {
8888
browserStatus: typeof browserStatus;
8989
browserStop: typeof browserStop;
9090
imageResultFromFile: typeof imageResultFromFile;
91-
loadConfig: typeof loadConfig;
91+
getRuntimeConfig: typeof getRuntimeConfig;
9292
listNodes: typeof listNodes;
9393
callGatewayTool: typeof callGatewayTool;
9494
touchSessionBrowserTab: typeof touchSessionBrowserTab;
@@ -113,7 +113,7 @@ export const __testing = {
113113
browserToolDeps.browserStatus = overrides?.browserStatus ?? browserStatus;
114114
browserToolDeps.browserStop = overrides?.browserStop ?? browserStop;
115115
browserToolDeps.imageResultFromFile = overrides?.imageResultFromFile ?? imageResultFromFile;
116-
browserToolDeps.loadConfig = overrides?.loadConfig ?? loadConfig;
116+
browserToolDeps.getRuntimeConfig = overrides?.getRuntimeConfig ?? getRuntimeConfig;
117117
browserToolDeps.listNodes = overrides?.listNodes ?? listNodes;
118118
browserToolDeps.callGatewayTool = overrides?.callGatewayTool ?? callGatewayTool;
119119
browserToolDeps.touchSessionBrowserTab =
@@ -220,7 +220,7 @@ async function resolveBrowserNodeTarget(params: {
220220
target?: "sandbox" | "host" | "node";
221221
sandboxBridgeUrl?: string;
222222
}): Promise<BrowserNodeTarget | null> {
223-
const cfg = browserToolDeps.loadConfig();
223+
const cfg = browserToolDeps.getRuntimeConfig();
224224
const policy = cfg.gateway?.nodes?.browser;
225225
const mode = policy?.mode ?? "auto";
226226
if (mode === "off") {
@@ -340,7 +340,7 @@ function resolveBrowserBaseUrl(params: {
340340
sandboxBridgeUrl?: string;
341341
allowHostControl?: boolean;
342342
}): string | undefined {
343-
const cfg = loadConfig();
343+
const cfg = getRuntimeConfig();
344344
const resolved = resolveBrowserConfig(cfg.browser, cfg);
345345
const normalizedSandbox = params.sandboxBridgeUrl?.trim() ?? "";
346346
const target = params.target ?? (normalizedSandbox ? "sandbox" : "host");
@@ -369,7 +369,7 @@ function shouldPreferHostForProfile(profileName: string | undefined) {
369369
if (!profileName) {
370370
return false;
371371
}
372-
const cfg = browserToolDeps.loadConfig();
372+
const cfg = browserToolDeps.getRuntimeConfig();
373373
const resolved = resolveBrowserConfig(cfg.browser, cfg);
374374
const profile = resolveProfile(resolved, profileName);
375375
if (!profile) {
@@ -395,7 +395,7 @@ function usesExistingSessionManageFlow(params: { action: string; profileName?: s
395395
if (!EXISTING_SESSION_MANAGE_ACTIONS.has(params.action)) {
396396
return false;
397397
}
398-
const cfg = browserToolDeps.loadConfig();
398+
const cfg = browserToolDeps.getRuntimeConfig();
399399
const resolved = resolveBrowserConfig(cfg.browser, cfg);
400400
const profile = resolveProfile(resolved, params.profileName ?? resolved.defaultProfile);
401401
if (profile && getBrowserProfileCapabilities(profile).usesChromeMcp) {
@@ -448,7 +448,9 @@ export function createBrowserTool(opts?: {
448448
const requestedNode = readStringParam(params, "node");
449449
const requestedTimeoutMs = readToolTimeoutMs(params);
450450
let target = readStringParam(params, "target") as "sandbox" | "host" | "node" | undefined;
451-
const configuredNode = browserToolDeps.loadConfig().gateway?.nodes?.browser?.node?.trim();
451+
const configuredNode = browserToolDeps
452+
.getRuntimeConfig()
453+
.gateway?.nodes?.browser?.node?.trim();
452454

453455
if (requestedNode && target && target !== "node") {
454456
throw new Error('node is only supported with target="node".');

extensions/browser/src/browser/browser-utils.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe("fetchBrowserJson loopback auth (bridge auth registry)", () => {
217217
candidate === port ? { token: "registry-token" } : undefined,
218218
);
219219
const init = __test.withLoopbackBrowserAuth(`http://127.0.0.1:${port}/`, undefined, {
220-
loadConfig: () => ({}),
220+
getRuntimeConfig: () => ({}),
221221
resolveBrowserControlAuth: () => ({}),
222222
getBridgeAuthForPort,
223223
});

0 commit comments

Comments
 (0)