perf(cli): avoid runtime config loads in gateway discover

This commit is contained in:
Vincent Koc
2026-04-14 17:47:28 +01:00
parent 4d6eeebda2
commit e31dfa9897
6 changed files with 80 additions and 4 deletions

View File

@@ -72,6 +72,7 @@ vi.mock("../../commands/health.js", () => ({
vi.mock("../../config/read-best-effort-config.runtime.js", () => ({
readBestEffortConfig: async () => ({}),
readSourceConfigBestEffort: async () => ({}),
}));
vi.mock("../../infra/bonjour-discovery.js", () => ({

View File

@@ -265,7 +265,7 @@ export function registerGatewayCli(program: Command) {
.action(async (opts: GatewayDiscoverOpts) => {
await runGatewayCommand(async () => {
const [
{ readBestEffortConfig },
{ readSourceConfigBestEffort },
{ discoverGatewayBeacons },
{ resolveWideAreaDiscoveryDomain },
] = await Promise.all([
@@ -273,7 +273,7 @@ export function registerGatewayCli(program: Command) {
loadBonjourDiscoveryModule(),
loadWideAreaDnsModule(),
]);
const cfg = await readBestEffortConfig();
const cfg = await readSourceConfigBestEffort();
const wideAreaDomain = resolveWideAreaDiscoveryDomain({
configDomain: cfg.discovery?.wideArea?.domain,
});

View File

@@ -10,6 +10,7 @@ export {
projectConfigOntoRuntimeSourceSnapshot,
loadConfig,
readBestEffortConfig,
readSourceConfigBestEffort,
parseConfigJson5,
readConfigFileSnapshot,
readConfigFileSnapshotForWrite,

View File

@@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { readBestEffortConfig, readConfigFileSnapshot } from "./config.js";
import {
readBestEffortConfig,
readConfigFileSnapshot,
readSourceConfigBestEffort,
} from "./config.js";
import { withTempHome, writeOpenClawConfig } from "./test-helpers.js";
describe("readBestEffortConfig", () => {
@@ -33,3 +37,29 @@ describe("readBestEffortConfig", () => {
});
});
});
describe("readSourceConfigBestEffort", () => {
it("preserves the authored source config without 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 sourceBestEffort = await readSourceConfigBestEffort();
expect(sourceBestEffort).toEqual(snapshot.resolved);
expect(sourceBestEffort.agents?.defaults?.contextPruning?.mode).toBeUndefined();
expect(sourceBestEffort.agents?.defaults?.compaction?.mode).toBeUndefined();
});
});
});

View File

@@ -1413,6 +1413,45 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
);
}
async function readSourceConfigBestEffort(): Promise<OpenClawConfig> {
maybeLoadDotEnvForConfig(deps.env);
const exists = deps.fs.existsSync(configPath);
if (!exists) {
return {};
}
try {
const raw = deps.fs.readFileSync(configPath, "utf-8");
const parsedRes = parseConfigJson5(raw, deps.json5);
if (!parsedRes.ok) {
return {};
}
const recovered = await maybeRecoverSuspiciousConfigRead({
deps,
configPath,
raw,
parsed: parsedRes.parsed,
});
let resolved: unknown;
try {
resolved = resolveConfigIncludesForRead(recovered.parsed, configPath, deps);
} catch {
return coerceConfig(recovered.parsed);
}
const readResolution = resolveConfigForRead(resolved, deps.env);
const legacyResolution = resolveLegacyConfigForRead(
readResolution.resolvedConfigRaw,
recovered.parsed,
);
return coerceConfig(legacyResolution.effectiveConfigRaw);
} catch {
return {};
}
}
async function writeConfigFile(
cfg: OpenClawConfig,
options: ConfigWriteOptions = {},
@@ -1674,6 +1713,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
configPath,
loadConfig,
readBestEffortConfig,
readSourceConfigBestEffort,
readConfigFileSnapshot,
readConfigFileSnapshotForWrite,
writeConfigFile,
@@ -1768,6 +1808,10 @@ export async function readBestEffortConfig(): Promise<OpenClawConfig> {
return await createConfigIO().readBestEffortConfig();
}
export async function readSourceConfigBestEffort(): Promise<OpenClawConfig> {
return await createConfigIO().readSourceConfigBestEffort();
}
export async function readConfigFileSnapshot(): Promise<ConfigFileSnapshot> {
return await createConfigIO().readConfigFileSnapshot();
}

View File

@@ -1 +1 @@
export { readBestEffortConfig } from "./io.js";
export { readBestEffortConfig, readSourceConfigBestEffort } from "./io.js";