diff --git a/extensions/comfy/comfy.live.test.ts b/extensions/comfy/comfy.live.test.ts index 42ab85c85678..dc9ec3d55cd8 100644 --- a/extensions/comfy/comfy.live.test.ts +++ b/extensions/comfy/comfy.live.test.ts @@ -2,8 +2,7 @@ import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-runtime"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api"; -import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot"; -import { isLiveTestEnabled } from "openclaw/plugin-sdk/test-live"; +import { isLiveTestEnabled, readLiveTestConfig } from "openclaw/plugin-sdk/test-live"; import { beforeAll, describe, expect, it } from "vitest"; import plugin from "./index.js"; import { getComfyConfigForTesting } from "./test-support.js"; @@ -51,7 +50,7 @@ describeLive("comfy live", () => { []; beforeAll(async () => { - cfg = withPluginsEnabled(getRuntimeConfig()); + cfg = withPluginsEnabled(await readLiveTestConfig()); agentDir = resolveDefaultAgentDir(cfg as never); plugin.register( createTestPluginApi({ diff --git a/extensions/music-generation-providers.live.test.ts b/extensions/music-generation-providers.live.test.ts index 40b1b2ddd4bf..48f08dbc18a9 100644 --- a/extensions/music-generation-providers.live.test.ts +++ b/extensions/music-generation-providers.live.test.ts @@ -8,7 +8,6 @@ import { registerProviderPlugin, requireRegisteredProvider, } from "openclaw/plugin-sdk/plugin-test-runtime"; -import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot"; import { isAuthErrorMessage, isBillingErrorMessage, @@ -19,6 +18,7 @@ import { isServerErrorMessage, isTimeoutErrorMessage, isTruthyEnvValue, + readLiveTestConfig, } from "openclaw/plugin-sdk/test-live"; import { collectProviderApiKeys, getShellEnvAppliedKeys } from "openclaw/plugin-sdk/test-live-auth"; import { @@ -196,7 +196,7 @@ describeLive("music generation provider live", () => { it( "covers generate plus declared edit paths with shell/profile auth", async () => { - const cfg = withPluginsEnabled(getRuntimeConfig()); + const cfg = withPluginsEnabled(await readLiveTestConfig()); const configuredModels = resolveConfiguredLiveMusicModels(cfg); const agentDir = resolveDefaultAgentDir(cfg as never); const attempted: string[] = []; diff --git a/extensions/video-generation-providers.live.test.ts b/extensions/video-generation-providers.live.test.ts index 1e2bbd80f154..37f833906936 100644 --- a/extensions/video-generation-providers.live.test.ts +++ b/extensions/video-generation-providers.live.test.ts @@ -8,7 +8,6 @@ import { registerProviderPlugin, requireRegisteredProvider, } from "openclaw/plugin-sdk/plugin-test-runtime"; -import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot"; import { isAuthErrorMessage, isBillingErrorMessage, @@ -19,6 +18,7 @@ import { isServerErrorMessage, isTimeoutErrorMessage, isTruthyEnvValue, + readLiveTestConfig, } from "openclaw/plugin-sdk/test-live"; import { collectProviderApiKeys, getShellEnvAppliedKeys } from "openclaw/plugin-sdk/test-live-auth"; import { @@ -401,7 +401,7 @@ function resolveLiveSmokeDurationSeconds(params: { } async function runLiveVideoProviderCase(testCase: LiveProviderCase): Promise { - const cfg = withPluginsEnabled(getRuntimeConfig()); + const cfg = withPluginsEnabled(await readLiveTestConfig()); const configuredModels = resolveConfiguredLiveVideoModels(cfg); const agentDir = resolveDefaultAgentDir(cfg as never); const attempted: string[] = []; diff --git a/extensions/xai/xai.live.test.ts b/extensions/xai/xai.live.test.ts index d0c904a5aff9..fd6c7f490ebc 100644 --- a/extensions/xai/xai.live.test.ts +++ b/extensions/xai/xai.live.test.ts @@ -20,7 +20,6 @@ import { type RealtimeVoiceBridge, type RealtimeVoiceBridgeEvent, } from "openclaw/plugin-sdk/realtime-voice"; -import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot"; import { isBillingErrorMessage } from "openclaw/plugin-sdk/test-live"; import { describe, expect, it } from "vitest"; import { createCodeExecutionTool } from "./code-execution.js"; @@ -34,21 +33,17 @@ const describeLive = liveEnabled ? describe : describe.skip; const EMPTY_AUTH_STORE = { version: 1, profiles: {} } as const; function createLiveConfig(): OpenClawConfig { - const cfg = getRuntimeConfig(); return { - ...cfg, models: { - ...cfg.models, providers: { - ...cfg.models?.providers, xai: { - ...cfg.models?.providers?.xai, apiKey: XAI_API_KEY, baseUrl: "https://api.x.ai/v1", + models: [], }, }, }, - } as OpenClawConfig; + }; } function createReferencePng(): Buffer { diff --git a/src/agents/anthropic.setup-token.live.test.ts b/src/agents/anthropic.setup-token.live.test.ts index d9ec1ef65f39..f53beebd0a31 100644 --- a/src/agents/anthropic.setup-token.live.test.ts +++ b/src/agents/anthropic.setup-token.live.test.ts @@ -10,7 +10,6 @@ import path from "node:path"; import { completeSimple, type Model } from "openclaw/plugin-sdk/llm"; import { describe, expect, it } from "vitest"; import { validateAnthropicSetupToken } from "../commands/auth-token.js"; -import { getRuntimeConfig } from "../config/config.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveDefaultAgentDir } from "./agent-scope.js"; import { @@ -18,7 +17,7 @@ import { ensureAuthProfileStore, saveAuthProfileStore, } from "./auth-profiles.js"; -import { isLiveTestEnabled } from "./live-test-helpers.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "./live-test-helpers.js"; import { getApiKeyForModel, requireApiKey } from "./model-auth.js"; import { normalizeProviderId, parseModelRef } from "./model-selection.js"; import { ensureOpenClawModelsJson } from "./models-config.js"; @@ -97,7 +96,7 @@ async function resolveTokenSource(): Promise { }; } - const agentDir = resolveDefaultAgentDir(getRuntimeConfig()); + const agentDir = resolveDefaultAgentDir(await readLiveTestConfig()); const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false, }); @@ -186,7 +185,7 @@ describeLive("live anthropic setup-token", () => { async () => { const tokenSource = await resolveTokenSource(); try { - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg, tokenSource.agentDir); const authStorage = discoverAuthStorage(tokenSource.agentDir); diff --git a/src/agents/live-test-config.test.ts b/src/agents/live-test-config.test.ts new file mode 100644 index 000000000000..3dd12c0859d4 --- /dev/null +++ b/src/agents/live-test-config.test.ts @@ -0,0 +1,62 @@ +import fs from "node:fs"; +import path from "node:path"; +import { describe, expect, it } from "vitest"; +import { withTempHome } from "../config/test-helpers.js"; +import { withEnvAsync } from "../test-utils/env.js"; +import { readLiveTestConfig } from "./live-test-config.js"; + +function listLiveTestFiles(root: string): string[] { + const files: string[] = []; + const pending = [root]; + while (pending.length > 0) { + const current = pending.pop(); + if (!current) { + continue; + } + for (const entry of fs.readdirSync(current, { withFileTypes: true })) { + const entryPath = path.join(current, entry.name); + if (entry.isDirectory()) { + pending.push(entryPath); + } else if (entry.name.endsWith(".live.test.ts")) { + files.push(entryPath); + } + } + } + return files; +} + +describe("readLiveTestConfig", () => { + it("tolerates retired config keys without mutating process env", async () => { + await withTempHome(async (home) => { + const envKey = "OPENCLAW_LIVE_CONFIG_ISOLATION_TEST"; + const configDir = path.join(home, ".openclaw"); + await fs.promises.mkdir(configDir, { recursive: true }); + await fs.promises.writeFile( + path.join(configDir, "openclaw.json"), + `${JSON.stringify({ + meta: { lastTouchedAt: "2026-07-25T00:00:00.000Z" }, + env: { vars: { [envKey]: "from-config" } }, + gateway: { mode: "local" }, + })}\n`, + ); + + await withEnvAsync({ [envKey]: undefined }, async () => { + await expect(readLiveTestConfig()).resolves.toMatchObject({ + gateway: { mode: "local" }, + }); + expect(process.env[envKey]).toBeUndefined(); + }); + }); + }); + + it("keeps live tests off the strict runtime config loader", () => { + const roots = [path.join(process.cwd(), "extensions"), path.join(process.cwd(), "src")]; + const offenders = roots + .flatMap(listLiveTestFiles) + .filter((file) => /\bgetRuntimeConfig\s*\(/u.test(fs.readFileSync(file, "utf8"))) + .map((file) => path.relative(process.cwd(), file)) + .toSorted(); + + expect(offenders).toStrictEqual([]); + }); +}); diff --git a/src/agents/live-test-config.ts b/src/agents/live-test-config.ts index 0c9178c92295..4c73246feadf 100644 --- a/src/agents/live-test-config.ts +++ b/src/agents/live-test-config.ts @@ -1,7 +1,17 @@ +import type { OpenClawConfig } from "../config/types.js"; import { isTruthyEnvValue } from "../infra/env.js"; const LIVE_OK_PROMPT = "Reply with the word ok."; +/** + * Read the active host or test config without letting invalid legacy keys or + * config-owned env vars mutate the live-test process. + */ +export async function readLiveTestConfig(): Promise { + const { readBestEffortConfig } = await import("../config/io.js"); + return await readBestEffortConfig({ isolateEnv: true, observe: false }); +} + /** Return whether live tests are enabled by standard or caller-specific env flags. */ export function isLiveTestEnabled( extraEnvVars: readonly string[] = [], diff --git a/src/agents/live-test-helpers.ts b/src/agents/live-test-helpers.ts index b7335f035b5f..2ed1bcd8f9ff 100644 --- a/src/agents/live-test-helpers.ts +++ b/src/agents/live-test-helpers.ts @@ -9,6 +9,7 @@ export { extractNonEmptyAssistantText, isLiveProfileKeyModeEnabled, isLiveTestEnabled, + readLiveTestConfig, } from "./live-test-config.js"; export type CompleteSimpleContent = Awaited< diff --git a/src/agents/models.profiles.live.test.ts b/src/agents/models.profiles.live.test.ts index 5e4dda90a6d6..7c8cf9aa4b60 100644 --- a/src/agents/models.profiles.live.test.ts +++ b/src/agents/models.profiles.live.test.ts @@ -7,7 +7,6 @@ import { expectDefined } from "@openclaw/normalization-core"; import { type Api, completeSimple, type Model } from "openclaw/plugin-sdk/llm"; import { Type } from "typebox"; import { describe, expect, it, vi } from "vitest"; -import { getRuntimeConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { coerceSecretRef, type SecretInput } from "../config/types.secrets.js"; import { parseLiveCsvFilter } from "../media-generation/live-test-helpers.js"; @@ -57,6 +56,7 @@ import { createLiveTargetMatcher } from "./live-target-matcher.js"; import { isLiveProfileKeyModeEnabled, isLiveTestEnabled, + readLiveTestConfig, requiresLiveProfileCredential, resolveLiveCredentialPrecedence, } from "./live-test-helpers.js"; @@ -1704,7 +1704,7 @@ describeLive("live models (profile keys)", () => { async () => { logProgress("[live-models] loading config"); const loadedCfg = await withLiveStageTimeout( - Promise.resolve().then(() => getRuntimeConfig()), + readLiveTestConfig(), "[live-models] load config", ); const rawModels = process.env.OPENCLAW_LIVE_MODELS?.trim(); diff --git a/src/agents/openai-reasoning-compat.live.test.ts b/src/agents/openai-reasoning-compat.live.test.ts index 5122ab5563d7..27a8057984fd 100644 --- a/src/agents/openai-reasoning-compat.live.test.ts +++ b/src/agents/openai-reasoning-compat.live.test.ts @@ -4,7 +4,6 @@ import { SessionManager } from "openclaw/plugin-sdk/agent-sessions"; import type { Model } from "openclaw/plugin-sdk/llm"; import { Type } from "typebox"; import { describe, expect, it } from "vitest"; -import { getRuntimeConfig } from "../config/config.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveDefaultAgentDir } from "./agent-scope.js"; import { sanitizeSessionHistory } from "./embedded-agent-runner/replay-history.js"; @@ -14,6 +13,7 @@ import { isLiveTestEnabled, logLiveProgress, requiresLiveProfileCredential, + readLiveTestConfig, resolveLiveCredentialPrecedence, } from "./live-test-helpers.js"; import { getApiKeyForModel, requireApiKey } from "./model-auth.js"; @@ -103,7 +103,7 @@ describeLive("openai reasoning compat live", () => { "remaps low reasoning for the configured OpenAI mini target", async () => { const { provider, modelId } = resolveTargetModelRef(); - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg); const agentDir = resolveDefaultAgentDir(cfg); @@ -163,7 +163,7 @@ describeLive("openai reasoning compat live", () => { "accepts repaired OpenAI Codex parallel tool replay with aborted missing results", async () => { const { provider, modelId } = resolveTargetModelRef(); - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg); const agentDir = resolveDefaultAgentDir(cfg); diff --git a/src/agents/sessions/agent-session.live.test.ts b/src/agents/sessions/agent-session.live.test.ts index 0b327e31c64e..99a7129cb386 100644 --- a/src/agents/sessions/agent-session.live.test.ts +++ b/src/agents/sessions/agent-session.live.test.ts @@ -5,9 +5,8 @@ import { join } from "node:path"; import type { Model } from "openclaw/plugin-sdk/llm"; import { Type } from "typebox"; import { afterEach, describe, expect, it } from "vitest"; -import { getRuntimeConfig } from "../../config/config.js"; import { discoverModels } from "../agent-model-discovery.js"; -import { isLiveTestEnabled } from "../live-test-helpers.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "../live-test-helpers.js"; import { ensureOpenClawModelsJson } from "../models-config.js"; import type { AgentMessage } from "../runtime/index.js"; import { AgentSession } from "./agent-session.js"; @@ -73,7 +72,7 @@ async function resolveLiveModel( agentDir: string, authStorage: AuthStorage, ): Promise<{ model: Model; modelRegistry: ModelRegistry }> { - await ensureOpenClawModelsJson(getRuntimeConfig(), agentDir, { + await ensureOpenClawModelsJson(await readLiveTestConfig(), agentDir, { providerDiscoveryProviderIds: ["anthropic"], }); const modelRegistry = discoverModels(authStorage, agentDir, { providerFilter: "anthropic" }); diff --git a/src/agents/subagent-announce.live.test.ts b/src/agents/subagent-announce.live.test.ts index 9484b3d18d8d..6b520b589023 100644 --- a/src/agents/subagent-announce.live.test.ts +++ b/src/agents/subagent-announce.live.test.ts @@ -4,11 +4,7 @@ import { randomBytes, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; -import { - clearRuntimeConfigSnapshot, - getRuntimeConfig, - type OpenClawConfig, -} from "../config/config.js"; +import { clearRuntimeConfigSnapshot, type OpenClawConfig } from "../config/config.js"; import { callGateway as realCallGateway } from "../gateway/call.js"; import { GatewayClient } from "../gateway/client.js"; import { dispatchGatewayMethodInProcess as realDispatchGatewayMethodInProcess } from "../gateway/server-plugins.js"; @@ -22,7 +18,7 @@ import { type OpenClawTestState, } from "../test-utils/openclaw-test-state.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; -import { isLiveTestEnabled } from "./live-test-helpers.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "./live-test-helpers.js"; import { testing as subagentAnnounceDeliveryTesting } from "./subagent-announce-delivery.test-support.js"; import { testing as subagentAnnounceTesting } from "./subagent-announce.js"; import { resolveSubagentController, steerControlledSubagentRun } from "./subagent-control.js"; @@ -577,7 +573,7 @@ describeLive("subagent announce live", () => { expect(runBeforeSteer.completion?.resultText, runStateBeforeSteer).toBeUndefined(); console.log(`[subagent-steer] steering active child run; runs=${runStateBeforeSteer}`); - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); const steerResult = await steerControlledSubagentRun({ cfg, controller: resolveSubagentController({ cfg, agentSessionKey: sessionKey }), diff --git a/src/agents/tool-replay-repair.live.test.ts b/src/agents/tool-replay-repair.live.test.ts index 4050226cc6b5..75ce744da845 100644 --- a/src/agents/tool-replay-repair.live.test.ts +++ b/src/agents/tool-replay-repair.live.test.ts @@ -7,7 +7,6 @@ import { SessionManager } from "openclaw/plugin-sdk/agent-sessions"; import type { Context, Model } from "openclaw/plugin-sdk/llm"; import { Type } from "typebox"; import { describe, expect, it } from "vitest"; -import { getRuntimeConfig } from "../config/config.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveDefaultAgentDir } from "./agent-scope.js"; import { sanitizeSessionHistory } from "./embedded-agent-runner/replay-history.js"; @@ -17,6 +16,7 @@ import { isLiveTestEnabled, logLiveProgress, requiresLiveProfileCredential, + readLiveTestConfig, resolveLiveCredentialPrecedence, type CompleteSimpleContent, } from "./live-test-helpers.js"; @@ -244,7 +244,7 @@ describeLive("tool replay repair live", () => { it( `accepts repaired displaced and missing tool results with ${target.ref}`, async () => { - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg); const agentDir = resolveDefaultAgentDir(cfg); @@ -357,7 +357,7 @@ describeLive("tool replay repair live", () => { it( `accepts transport replay after dropping aborted assistant tool calls with ${target.ref}`, async () => { - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg); const agentDir = resolveDefaultAgentDir(cfg); diff --git a/src/gateway/android-node.capabilities.live.test.ts b/src/gateway/android-node.capabilities.live.test.ts index d5851fe9b3a3..a1aff1b05a2e 100644 --- a/src/gateway/android-node.capabilities.live.test.ts +++ b/src/gateway/android-node.capabilities.live.test.ts @@ -8,8 +8,7 @@ import { ANDROID_NODE_REQUIRED_NON_INTERACTIVE_COMMANDS, findMissingRequiredAndroidNodeCommands, } from "../../test/helpers/gateway/android-node-capabilities-required-commands.js"; -import { isLiveTestEnabled } from "../agents/live-test-helpers.js"; -import { getRuntimeConfig } from "../config/config.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "../agents/live-test-helpers.js"; import type { OpenClawConfig } from "../config/config.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { parseNodeList, parsePairingList } from "../shared/node-list-parse.js"; @@ -323,8 +322,8 @@ const COMMAND_PROFILES: Record = { }, }; -function resolveGatewayConnection() { - const cfg = getRuntimeConfig(); +async function resolveGatewayConnection() { + const cfg = await readLiveTestConfig(); const urlOverride = readString(process.env.OPENCLAW_ANDROID_GATEWAY_URL); const details = buildGatewayConnectionDetails({ config: cfg, @@ -350,15 +349,15 @@ function resolveGatewayConnection() { async function resolvePolicyConfigForRun(params: { client: GatewayClient; connectionDetails: ReturnType; - loadLocalConfig?: () => OpenClawConfig; + loadLocalConfig?: () => OpenClawConfig | Promise; }): Promise { if (shouldFetchRemotePolicyConfig(params.connectionDetails)) { const raw = await params.client.request("config.get", {}); return unwrapRemoteConfigSnapshot(raw); } - const loadLocalConfig = params.loadLocalConfig ?? getRuntimeConfig; - return loadLocalConfig(); + const loadLocalConfig = params.loadLocalConfig ?? readLiveTestConfig; + return await loadLocalConfig(); } describe("resolvePolicyConfigForRun", () => { @@ -565,7 +564,7 @@ describeLive("android node capability integration (preconditioned)", () => { const results = new Map(); beforeAll(async () => { - const { details, url, token, password } = resolveGatewayConnection(); + const { details, url, token, password } = await resolveGatewayConnection(); client = await connectGatewayClient({ url, token, password }); const listRaw = await client.request("node.list", {}); diff --git a/src/gateway/gateway-acp-bind.live.test.ts b/src/gateway/gateway-acp-bind.live.test.ts index 8556dfbc15ba..5f7ca20a656c 100644 --- a/src/gateway/gateway-acp-bind.live.test.ts +++ b/src/gateway/gateway-acp-bind.live.test.ts @@ -7,12 +7,8 @@ import path from "node:path"; import { describe, expect, it } from "vitest"; import { renderCatFacePngBase64 } from "../../test/helpers/live-image-probe.js"; import { getAcpRuntimeBackend } from "../acp/runtime/registry.js"; -import { isLiveTestEnabled } from "../agents/live-test-helpers.js"; -import { - clearConfigCache, - clearRuntimeConfigSnapshot, - getRuntimeConfig, -} from "../config/config.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "../agents/live-test-helpers.js"; +import { clearConfigCache, clearRuntimeConfigSnapshot } from "../config/config.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { clearPluginLoaderCache } from "../plugins/loader.test-fixtures.js"; import { @@ -611,7 +607,7 @@ describeLive("gateway live (ACP bind)", () => { await prepareCodexHomeForLiveBindTest(tempRoot); } - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); const acpxEntry = cfg.plugins?.entries?.acpx; const existingAgentOverrides: Record = typeof acpxEntry?.config === "object" && diff --git a/src/gateway/gateway-acp-spawn-defaults.live.test.ts b/src/gateway/gateway-acp-spawn-defaults.live.test.ts index 74b2580d711f..4f2ae4e6e09c 100644 --- a/src/gateway/gateway-acp-spawn-defaults.live.test.ts +++ b/src/gateway/gateway-acp-spawn-defaults.live.test.ts @@ -11,12 +11,8 @@ import { describe, expect, it } from "vitest"; import { getAcpSessionManager } from "../acp/control-plane/manager.js"; import { getAcpRuntimeBackend } from "../acp/runtime/registry.js"; import { isSpawnAcpAcceptedResult, spawnAcpDirect } from "../agents/acp-spawn.js"; -import { isLiveTestEnabled } from "../agents/live-test-helpers.js"; -import { - clearConfigCache, - clearRuntimeConfigSnapshot, - getRuntimeConfig, -} from "../config/config.js"; +import { isLiveTestEnabled, readLiveTestConfig } from "../agents/live-test-helpers.js"; +import { clearConfigCache, clearRuntimeConfigSnapshot } from "../config/config.js"; import { resolveStorePath } from "../config/sessions/paths.js"; import { loadSessionEntry } from "../config/sessions/session-accessor.js"; import type { SessionEntry } from "../config/sessions/types.js"; @@ -484,7 +480,7 @@ describeLive("gateway live (ACP spawn defaults)", () => { }); await waitForGatewayPort({ host: "127.0.0.1", port, timeoutMs: CONNECT_TIMEOUT_MS }); await waitForAcpBackendReady(); - const runtimeCfg = getRuntimeConfig(); + const runtimeCfg = await readLiveTestConfig(); if (ACP_THINKING_CONTROLS_LIVE) { const runProof = acpAgentId === "opencode" @@ -542,7 +538,7 @@ describeLive("gateway live (ACP spawn defaults)", () => { expect(primaryOnlyEntry.acp?.runtimeOptions?.model).not.toBe("anthropic/claude-sonnet-4-6"); } finally { try { - const runtimeCfg = getRuntimeConfig(); + const runtimeCfg = await readLiveTestConfig(); for (const sessionKey of sessionKeys) { await getAcpSessionManager() .closeSession({ diff --git a/src/gateway/gateway-models.profiles.live.test.ts b/src/gateway/gateway-models.profiles.live.test.ts index 00a0f1bc9bc8..9985d2e8fb78 100644 --- a/src/gateway/gateway-models.profiles.live.test.ts +++ b/src/gateway/gateway-models.profiles.live.test.ts @@ -45,7 +45,11 @@ import { shouldExcludeProviderFromDefaultHighSignalLiveSweep, } from "../agents/live-model-filter.js"; import { createLiveTargetMatcher } from "../agents/live-target-matcher.js"; -import { isLiveProfileKeyModeEnabled, isLiveTestEnabled } from "../agents/live-test-helpers.js"; +import { + isLiveProfileKeyModeEnabled, + isLiveTestEnabled, + readLiveTestConfig, +} from "../agents/live-test-helpers.js"; import { shouldSkipLiveProviderDrift } from "../agents/live-test-provider-drift.js"; import { isLiveBillingDrift, @@ -56,7 +60,7 @@ import { normalizeProviderId } from "../agents/model-selection.js"; import { shouldSuppressBuiltInModel } from "../agents/model-suppression.js"; import { ensureOpenClawModelsJson } from "../agents/models-config.js"; import { STREAM_ERROR_FALLBACK_TEXT } from "../agents/stream-message-shared.js"; -import { clearRuntimeConfigSnapshot, getRuntimeConfig } from "../config/io.js"; +import { clearRuntimeConfigSnapshot } from "../config/io.js"; import type { ModelsConfig, ModelProviderConfig, OpenClawConfig } from "../config/types.js"; import { isTruthyEnvValue } from "../infra/env.js"; import type { ModelRegistry } from "../llm/model-registry.js"; @@ -4522,7 +4526,7 @@ async function runGatewayModelSuite(params: GatewayModelSuiteParams) { process.env.OPENCLAW_GATEWAY_TOKEN = token; const agentId = GATEWAY_LIVE_AGENT_ID; - const hostAgentDir = resolveDefaultAgentDir(getRuntimeConfig()); + const hostAgentDir = resolveDefaultAgentDir(await readLiveTestConfig()); const hostStore = ensureAuthProfileStore(hostAgentDir, { allowKeychainPrompt: false, }); @@ -5434,7 +5438,7 @@ describeLive("gateway live (dev agent, profile keys)", () => { logProgress("[all-models] loading config"); clearRuntimeConfigSnapshot(); const cfg = await withGatewayLiveSetupTimeout( - Promise.resolve().then(() => getRuntimeConfig()), + readLiveTestConfig(), "[all-models] load config", ); const workspaceDir = resolveAgentWorkspaceDir(cfg, DEFAULT_AGENT_ID); @@ -5699,7 +5703,7 @@ describeLive("gateway live (dev agent, profile keys)", () => { let tempDir: string | undefined; let tempStateDir: string | undefined; try { - const cfg = getRuntimeConfig(); + const cfg = await readLiveTestConfig(); await ensureOpenClawModelsJson(cfg); const agentDir = resolveDefaultAgentDir(cfg); diff --git a/src/plugin-sdk/test-live.ts b/src/plugin-sdk/test-live.ts index bdc509a41154..f6aba8a08ad1 100644 --- a/src/plugin-sdk/test-live.ts +++ b/src/plugin-sdk/test-live.ts @@ -5,6 +5,7 @@ export { extractNonEmptyAssistantText, isLiveProfileKeyModeEnabled, isLiveTestEnabled, + readLiveTestConfig, } from "../agents/live-test-config.js"; export { isModelNotFoundErrorMessage } from "../agents/live-model-errors.js"; export {