From 8820547a0716fcda4f72e24f49837f8dc7ee8e51 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 13 Apr 2026 16:12:09 +0100 Subject: [PATCH] perf(config): reuse validated best-effort snapshots --- src/config/io.best-effort.test.ts | 35 +++++++++++ src/config/io.ts | 99 +++++++++++++++++-------------- 2 files changed, 91 insertions(+), 43 deletions(-) create mode 100644 src/config/io.best-effort.test.ts diff --git a/src/config/io.best-effort.test.ts b/src/config/io.best-effort.test.ts new file mode 100644 index 00000000000..accd9440c16 --- /dev/null +++ b/src/config/io.best-effort.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "vitest"; +import { readBestEffortConfig, readConfigFileSnapshot } from "./config.js"; +import { withTempHome, writeOpenClawConfig } from "./test-helpers.js"; + +describe("readBestEffortConfig", () => { + it("reuses valid snapshots while preserving load-time defaults", async () => { + await withTempHome(async (home) => { + await writeOpenClawConfig(home, { + auth: { + profiles: { + "anthropic:api": { provider: "anthropic", mode: "api_key" }, + }, + }, + agents: { + defaults: { + model: { primary: "anthropic/claude-opus-4-6" }, + }, + }, + }); + + const snapshot = await readConfigFileSnapshot(); + const bestEffort = await readBestEffortConfig(); + + expect(snapshot.config.agents?.defaults?.contextPruning?.mode).toBeUndefined(); + expect(snapshot.config.agents?.defaults?.compaction?.mode).toBeUndefined(); + + expect(bestEffort.agents?.defaults?.contextPruning?.mode).toBe("cache-ttl"); + expect(bestEffort.agents?.defaults?.contextPruning?.ttl).toBe("1h"); + expect(bestEffort.agents?.defaults?.compaction?.mode).toBe("safeguard"); + expect( + bestEffort.agents?.defaults?.models?.["anthropic/claude-opus-4-6"]?.params?.cacheRetention, + ).toBe("short"); + }); + }); +}); diff --git a/src/config/io.ts b/src/config/io.ts index 165a6b33d93..8690ed7ba6d 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -1030,6 +1030,49 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { return snapshot; } + function finalizeLoadedRuntimeConfig(cfg: OpenClawConfig): OpenClawConfig { + const duplicates = findDuplicateAgentDirs(cfg, { + env: deps.env, + homedir: deps.homedir, + }); + if (duplicates.length > 0) { + throw new DuplicateAgentDirError(duplicates); + } + + applyConfigEnvVars(cfg, deps.env); + + const enabled = shouldEnableShellEnvFallback(deps.env) || cfg.env?.shellEnv?.enabled === true; + if (enabled && !shouldDeferShellEnvFallback(deps.env)) { + loadShellEnvFallback({ + enabled: true, + env: deps.env, + expectedKeys: resolveShellEnvExpectedKeys(deps.env), + logger: deps.logger, + timeoutMs: cfg.env?.shellEnv?.timeoutMs ?? resolveShellEnvFallbackTimeoutMs(deps.env), + }); + } + + const pendingSecret = AUTO_OWNER_DISPLAY_SECRET_BY_PATH.get(configPath); + const ownerDisplaySecretResolution = ensureOwnerDisplaySecret( + cfg, + () => pendingSecret ?? crypto.randomBytes(32).toString("hex"), + ); + const cfgWithOwnerDisplaySecret = persistGeneratedOwnerDisplaySecret({ + config: ownerDisplaySecretResolution.config, + configPath, + generatedSecret: ownerDisplaySecretResolution.generatedSecret, + logger: deps.logger, + state: { + pendingByPath: AUTO_OWNER_DISPLAY_SECRET_BY_PATH, + persistInFlight: AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT, + persistWarned: AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED, + }, + persistConfig: (nextConfig, options) => writeConfigFile(nextConfig, options), + }); + + return applyConfigOverrides(cfgWithOwnerDisplaySecret); + } + function loadConfig(): OpenClawConfig { try { maybeLoadDotEnvForConfig(deps.env); @@ -1144,47 +1187,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { legacyIssues: legacyResolution.sourceLegacyIssues, }), }); - - const duplicates = findDuplicateAgentDirs(cfg, { - env: deps.env, - homedir: deps.homedir, - }); - if (duplicates.length > 0) { - throw new DuplicateAgentDirError(duplicates); - } - - applyConfigEnvVars(cfg, deps.env); - - const enabled = shouldEnableShellEnvFallback(deps.env) || cfg.env?.shellEnv?.enabled === true; - if (enabled && !shouldDeferShellEnvFallback(deps.env)) { - loadShellEnvFallback({ - enabled: true, - env: deps.env, - expectedKeys: resolveShellEnvExpectedKeys(deps.env), - logger: deps.logger, - timeoutMs: cfg.env?.shellEnv?.timeoutMs ?? resolveShellEnvFallbackTimeoutMs(deps.env), - }); - } - - const pendingSecret = AUTO_OWNER_DISPLAY_SECRET_BY_PATH.get(configPath); - const ownerDisplaySecretResolution = ensureOwnerDisplaySecret( - cfg, - () => pendingSecret ?? crypto.randomBytes(32).toString("hex"), - ); - const cfgWithOwnerDisplaySecret = persistGeneratedOwnerDisplaySecret({ - config: ownerDisplaySecretResolution.config, - configPath, - generatedSecret: ownerDisplaySecretResolution.generatedSecret, - logger: deps.logger, - state: { - pendingByPath: AUTO_OWNER_DISPLAY_SECRET_BY_PATH, - persistInFlight: AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT, - persistWarned: AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED, - }, - persistConfig: (nextConfig, options) => writeConfigFile(nextConfig, options), - }); - - return applyConfigOverrides(cfgWithOwnerDisplaySecret); + return finalizeLoadedRuntimeConfig(cfg); } catch (err) { if (err instanceof DuplicateAgentDirError) { deps.logger.error(err.message); @@ -1389,6 +1392,16 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { }; } + async function readBestEffortConfig(): Promise { + const result = await readConfigFileSnapshotInternal(); + if (!result.snapshot.valid) { + return result.snapshot.config; + } + return finalizeLoadedRuntimeConfig( + materializeRuntimeConfig(result.snapshot.sourceConfig, "load"), + ); + } + async function writeConfigFile( cfg: OpenClawConfig, options: ConfigWriteOptions = {}, @@ -1649,6 +1662,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { return { configPath, loadConfig, + readBestEffortConfig, readConfigFileSnapshot, readConfigFileSnapshotForWrite, writeConfigFile, @@ -1740,8 +1754,7 @@ export function getRuntimeConfig(): OpenClawConfig { } export async function readBestEffortConfig(): Promise { - const snapshot = await readConfigFileSnapshot(); - return snapshot.valid ? loadConfig() : snapshot.config; + return await createConfigIO().readBestEffortConfig(); } export async function readConfigFileSnapshot(): Promise {