test: isolate live test config reads (#114024)

This commit is contained in:
Peter Steinberger
2026-07-25 21:51:47 -07:00
committed by GitHub
parent 08493c51d8
commit dfcd3b9e0b
18 changed files with 121 additions and 64 deletions
+2 -3
View File
@@ -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({
@@ -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[] = [];
@@ -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<void> {
const cfg = withPluginsEnabled(getRuntimeConfig());
const cfg = withPluginsEnabled(await readLiveTestConfig());
const configuredModels = resolveConfiguredLiveVideoModels(cfg);
const agentDir = resolveDefaultAgentDir(cfg as never);
const attempted: string[] = [];
+2 -7
View File
@@ -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 {
@@ -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<TokenSource> {
};
}
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);
+62
View File
@@ -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([]);
});
});
+10
View File
@@ -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<OpenClawConfig> {
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[] = [],
+1
View File
@@ -9,6 +9,7 @@ export {
extractNonEmptyAssistantText,
isLiveProfileKeyModeEnabled,
isLiveTestEnabled,
readLiveTestConfig,
} from "./live-test-config.js";
export type CompleteSimpleContent<TApi extends Api = Api> = Awaited<
+2 -2
View File
@@ -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();
@@ -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);
@@ -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" });
+3 -7
View File
@@ -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 }),
+3 -3
View File
@@ -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);
@@ -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<string, CommandProfile> = {
},
};
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<typeof buildGatewayConnectionDetails>;
loadLocalConfig?: () => OpenClawConfig;
loadLocalConfig?: () => OpenClawConfig | Promise<OpenClawConfig>;
}): Promise<OpenClawConfig> {
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<string, CommandResult>();
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", {});
+3 -7
View File
@@ -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<string, { command?: string }> =
typeof acpxEntry?.config === "object" &&
@@ -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({
@@ -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);
+1
View File
@@ -5,6 +5,7 @@ export {
extractNonEmptyAssistantText,
isLiveProfileKeyModeEnabled,
isLiveTestEnabled,
readLiveTestConfig,
} from "../agents/live-test-config.js";
export { isModelNotFoundErrorMessage } from "../agents/live-model-errors.js";
export {