refactor(config): migrate plugin config access

This commit is contained in:
Peter Steinberger
2026-04-27 12:16:48 +01:00
parent 48ebed3ed3
commit 7f3f108521
531 changed files with 3502 additions and 1646 deletions

View File

@@ -1,4 +1,3 @@
import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/config-runtime";
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { registerMemoryCli } from "./src/cli.js";
import { registerDreamingCommand } from "./src/dreaming-command.js";
@@ -41,23 +40,27 @@ export default definePluginEntry({
});
api.registerTool(
(ctx) =>
createMemorySearchTool({
config: ctx.runtimeConfig ?? ctx.config,
getConfig: () => getRuntimeConfigSnapshot() ?? ctx.runtimeConfig ?? ctx.config,
(ctx) => {
const getConfig = () => ctx.getRuntimeConfig?.() ?? ctx.runtimeConfig ?? ctx.config;
return createMemorySearchTool({
config: getConfig(),
getConfig,
agentSessionKey: ctx.sessionKey,
sandboxed: ctx.sandboxed,
}),
});
},
{ names: ["memory_search"] },
);
api.registerTool(
(ctx) =>
createMemoryGetTool({
config: ctx.runtimeConfig ?? ctx.config,
getConfig: () => getRuntimeConfigSnapshot() ?? ctx.runtimeConfig ?? ctx.config,
(ctx) => {
const getConfig = () => ctx.getRuntimeConfig?.() ?? ctx.runtimeConfig ?? ctx.config;
return createMemoryGetTool({
config: getConfig(),
getConfig,
agentSessionKey: ctx.sessionKey,
}),
});
},
{ names: ["memory_get"] },
);

View File

@@ -13,7 +13,7 @@ export {
withProgressTotals,
} from "openclaw/plugin-sdk/memory-core-host-runtime-cli";
export {
loadConfig,
getRuntimeConfig,
resolveDefaultAgentId,
resolveSessionTranscriptsDirForAgent,
resolveStateDir,

View File

@@ -9,10 +9,10 @@ import {
colorize,
defaultRuntime,
formatErrorMessage,
getRuntimeConfig,
getMemorySearchManager,
isRich,
listMemoryFiles,
loadConfig,
normalizeExtraMemoryPaths,
resolveCommandSecretRefsViaGateway,
resolveDefaultAgentId,
@@ -92,7 +92,7 @@ function getMemoryCommandSecretTargetIds(): Set<string> {
async function loadMemoryCommandConfig(commandName: string): Promise<LoadedMemoryCommandConfig> {
const { resolvedConfig, diagnostics } = await resolveCommandSecretRefsViaGateway({
config: loadConfig(),
config: getRuntimeConfig(),
commandName,
targetIds: getMemoryCommandSecretTargetIds(),
});

View File

@@ -12,7 +12,7 @@ import {
import { readShortTermRecallEntries, recordShortTermRecalls } from "./short-term-promotion.js";
const getMemorySearchManager = vi.hoisted(() => vi.fn());
const loadConfig = vi.hoisted(() => vi.fn(() => ({})));
const getRuntimeConfig = vi.hoisted(() => vi.fn(() => ({})));
const resolveDefaultAgentId = vi.hoisted(() => vi.fn(() => "main"));
const resolveCommandSecretRefsViaGateway = vi.hoisted(() =>
vi.fn(async ({ config }: { config: unknown }) => ({
@@ -34,7 +34,7 @@ vi.mock("./cli.host.runtime.js", async () => {
getMemorySearchManager,
isRich: runtimeCli.isRich,
listMemoryFiles: runtimeFiles.listMemoryFiles,
loadConfig,
getRuntimeConfig,
normalizeExtraMemoryPaths: runtimeFiles.normalizeExtraMemoryPaths,
resolveCommandSecretRefsViaGateway,
resolveDefaultAgentId,
@@ -73,7 +73,7 @@ beforeAll(async () => {
beforeEach(() => {
getMemorySearchManager.mockReset();
loadConfig.mockReset().mockReturnValue({});
getRuntimeConfig.mockReset().mockReturnValue({});
resolveDefaultAgentId.mockReset().mockReturnValue("main");
resolveCommandSecretRefsViaGateway.mockReset().mockImplementation(async ({ config }) => ({
resolvedConfig: config,
@@ -247,7 +247,7 @@ describe("memory cli", () => {
});
it("resolves configured memory SecretRefs through gateway snapshot", async () => {
loadConfig.mockReturnValue({
getRuntimeConfig.mockReturnValue({
agents: {
defaults: {
memorySearch: {

View File

@@ -25,7 +25,11 @@ function createHarness(initialConfig: OpenClawConfig = {}) {
const runtime = {
config: {
current: vi.fn(() => runtimeConfig),
loadConfig: vi.fn(() => runtimeConfig),
replaceConfigFile: vi.fn(async ({ nextConfig }: { nextConfig: OpenClawConfig }) => {
runtimeConfig = nextConfig;
}),
writeConfigFile: vi.fn(async (nextConfig: OpenClawConfig) => {
runtimeConfig = nextConfig;
}),
@@ -111,7 +115,7 @@ describe("memory-core /dreaming command", () => {
const result = await command.handler(createCommandContext("off"));
expect(runtime.config.writeConfigFile).toHaveBeenCalledTimes(1);
expect(runtime.config.replaceConfigFile).toHaveBeenCalledTimes(1);
expect(resolveStoredDreaming(getRuntimeConfig())).toMatchObject({
enabled: false,
frequency: "0 */6 * * *",
@@ -129,7 +133,7 @@ describe("memory-core /dreaming command", () => {
);
expect(result.text).toContain("requires operator.admin");
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
expect(runtime.config.replaceConfigFile).not.toHaveBeenCalled();
});
it("blocks write-scoped gateway callers from persisting dreaming config", async () => {
@@ -142,7 +146,7 @@ describe("memory-core /dreaming command", () => {
);
expect(result.text).toContain("requires operator.admin");
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
expect(runtime.config.replaceConfigFile).not.toHaveBeenCalled();
});
it("allows admin-scoped gateway callers to persist dreaming config", async () => {
@@ -154,7 +158,7 @@ describe("memory-core /dreaming command", () => {
}),
);
expect(runtime.config.writeConfigFile).toHaveBeenCalledTimes(1);
expect(runtime.config.replaceConfigFile).toHaveBeenCalledTimes(1);
expect(resolveStoredDreaming(getRuntimeConfig())).toMatchObject({
enabled: true,
});
@@ -187,7 +191,7 @@ describe("memory-core /dreaming command", () => {
expect(result.text).toContain("- enabled: off (America/Los_Angeles)");
expect(result.text).toContain("- sweep cadence: 15 */8 * * *");
expect(result.text).toContain("- promotion policy: score>=0.8, recalls>=3, uniqueQueries>=3");
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
expect(runtime.config.replaceConfigFile).not.toHaveBeenCalled();
});
it("shows usage for invalid args and does not mutate config", async () => {
@@ -195,6 +199,6 @@ describe("memory-core /dreaming command", () => {
const result = await command.handler(createCommandContext("unknown-mode"));
expect(result.text).toContain("Usage: /dreaming status");
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
expect(runtime.config.replaceConfigFile).not.toHaveBeenCalled();
});
});

View File

@@ -90,7 +90,7 @@ export function registerDreamingCommand(api: OpenClawPluginApi): void {
.split(/\s+/)
.filter(Boolean)
.map((token) => normalizeLowercaseStringOrEmpty(token));
const currentConfig = api.runtime.config.loadConfig();
const currentConfig = api.runtime.config.current() as OpenClawConfig;
if (
!firstToken ||
@@ -111,7 +111,10 @@ export function registerDreamingCommand(api: OpenClawPluginApi): void {
}
const enabled = firstToken === "on";
const nextConfig = updateDreamingEnabledInConfig(currentConfig, enabled);
await api.runtime.config.writeConfigFile(nextConfig);
await api.runtime.config.replaceConfigFile({
nextConfig,
afterWrite: { mode: "auto" },
});
return {
text: [
`Dreaming ${enabled ? "enabled" : "disabled"}.`,

View File

@@ -3,7 +3,7 @@ import type { Dirent } from "node:fs";
import fs from "node:fs/promises";
import path from "node:path";
import {
loadConfig,
getRuntimeConfig,
loadSessionStore,
resolveStorePath,
updateSessionStore,
@@ -717,7 +717,7 @@ async function normalizeSessionEntryPathForComparison(params: {
}
async function scrubDreamingNarrativeArtifacts(logger: Logger): Promise<void> {
const cfg = loadConfig();
const cfg = getRuntimeConfig();
const agentsDir = path.join(resolveStateDir(), "agents");
let agentEntries: Dirent[] = [];
try {

View File

@@ -1334,7 +1334,7 @@ describe("gateway startup reconciliation", () => {
const logger = createLogger();
const harness = createCronHarness();
const onMock = vi.fn();
const runtimeLoadConfig = vi.fn(
const runtimeCurrentConfig = vi.fn(
() =>
({
plugins: {
@@ -1370,7 +1370,7 @@ describe("gateway startup reconciliation", () => {
logger,
runtime: {
config: {
loadConfig: runtimeLoadConfig,
current: runtimeCurrentConfig,
},
},
on: onMock,
@@ -1395,7 +1395,7 @@ describe("gateway startup reconciliation", () => {
{ trigger: "heartbeat", workspaceDir: ".", sessionKey },
);
expect(runtimeLoadConfig).toHaveBeenCalled();
expect(runtimeCurrentConfig).toHaveBeenCalled();
expect(result).toEqual({
handled: true,
reason: "memory-core: short-term dreaming disabled",
@@ -1411,7 +1411,7 @@ describe("gateway startup reconciliation", () => {
const harness = createCronHarness();
const onMock = vi.fn();
const workspaceDir = await createTempWorkspace("memory-dreaming-live-config-workspace-");
const runtimeLoadConfig = vi.fn(
const runtimeCurrentConfig = vi.fn(
() =>
({
agents: {
@@ -1454,7 +1454,7 @@ describe("gateway startup reconciliation", () => {
logger,
runtime: {
config: {
loadConfig: runtimeLoadConfig,
current: runtimeCurrentConfig,
},
},
on: onMock,
@@ -1483,7 +1483,7 @@ describe("gateway startup reconciliation", () => {
handled: true,
reason: "memory-core: short-term dreaming processed",
});
expect(runtimeLoadConfig).toHaveBeenCalled();
expect(runtimeCurrentConfig).toHaveBeenCalled();
expect(logger.warn).not.toHaveBeenCalledWith(
"memory-core: dreaming promotion skipped because no memory workspace is available.",
);
@@ -1497,7 +1497,7 @@ describe("gateway startup reconciliation", () => {
const logger = createLogger();
const harness = createCronHarness();
const onMock = vi.fn();
const runtimeLoadConfig = vi.fn(
const runtimeCurrentConfig = vi.fn(
() =>
({
agents: {
@@ -1525,7 +1525,7 @@ describe("gateway startup reconciliation", () => {
logger,
runtime: {
config: {
loadConfig: runtimeLoadConfig,
current: runtimeCurrentConfig,
},
},
on: onMock,
@@ -1550,7 +1550,7 @@ describe("gateway startup reconciliation", () => {
{ trigger: "heartbeat", workspaceDir: ".", sessionKey },
);
expect(runtimeLoadConfig).toHaveBeenCalled();
expect(runtimeCurrentConfig).toHaveBeenCalled();
expect(result).toEqual({
handled: true,
reason: "memory-core: short-term dreaming disabled",

View File

@@ -681,7 +681,7 @@ export function registerShortTermPromotionDreaming(api: OpenClawPluginApi): void
let lastRuntimeCronRef: CronServiceLike | null = null;
const resolveCurrentConfig = (): OpenClawConfig =>
api.runtime.config?.loadConfig?.() ?? api.config;
(api.runtime.config?.current?.() ?? api.config) as OpenClawConfig;
const runtimeConfigKey = (config: ShortTermPromotionDreamingConfig): string =>
[