mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
test: add ACP spawn defaults live Docker test
This commit is contained in:
@@ -249,7 +249,7 @@ openclaw_live_stage_state_dir "$tmp_dir/.openclaw-state"
|
||||
openclaw_live_prepare_staged_config
|
||||
cd "$tmp_dir"
|
||||
export OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND="${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}"
|
||||
node scripts/test-live.mjs -- src/gateway/gateway-acp-bind.live.test.ts
|
||||
node scripts/test-live.mjs -- ${OPENCLAW_LIVE_ACP_BIND_TEST_FILES:-src/gateway/gateway-acp-bind.live.test.ts}
|
||||
EOF
|
||||
|
||||
openclaw_live_acp_bind_append_build_extension acpx
|
||||
@@ -349,6 +349,7 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
|
||||
echo "==> Run ACP bind live test in Docker"
|
||||
echo "==> Agent: $ACP_AGENT"
|
||||
echo "==> Test files: ${OPENCLAW_LIVE_ACP_BIND_TEST_FILES:-src/gateway/gateway-acp-bind.live.test.ts}"
|
||||
echo "==> Profile file: $PROFILE_STATUS"
|
||||
echo "==> Auth dirs: ${AUTH_DIRS_CSV:-none}"
|
||||
echo "==> Auth files: ${AUTH_FILES_CSV:-none}"
|
||||
@@ -365,6 +366,9 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
-e GOOGLE_API_KEY \
|
||||
-e FACTORY_API_KEY \
|
||||
-e OPENAI_API_KEY \
|
||||
-e CODEX_API_KEY \
|
||||
-e ACPX_AUTH_OPENAI_API_KEY \
|
||||
-e ACPX_AUTH_CODEX_API_KEY \
|
||||
-e OPENCODE_API_KEY \
|
||||
-e OPENCODE_ZEN_API_KEY \
|
||||
-e OPENCODE_CONFIG_CONTENT \
|
||||
@@ -381,8 +385,16 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
-e OPENCLAW_LIVE_TEST=1 \
|
||||
-e OPENCLAW_LIVE_ACP_BIND=1 \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_AGENT="$ACP_AGENT" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_TEST_FILES="${OPENCLAW_LIVE_ACP_BIND_TEST_FILES:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL="${OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_SETUP_TIMEOUT_SECONDS="${OPENCLAW_LIVE_ACP_BIND_SETUP_TIMEOUT_SECONDS:-180}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL="${OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL:-opencode/kimi-k2.6}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_AGENT="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_AGENT:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_CONNECT_TIMEOUT_MS="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_CONNECT_TIMEOUT_MS:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_MODEL="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_MODEL:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_TIMEOUT_MS="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_TIMEOUT_MS:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND="$AGENT_COMMAND")
|
||||
openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_HOME_MOUNT
|
||||
openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_TRUSTED_HARNESS_MOUNT
|
||||
|
||||
18
scripts/test-live-acp-spawn-defaults-docker.sh
Executable file
18
scripts/test-live-acp-spawn-defaults-docker.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
if [[ -n "${OPENCLAW_LIVE_ACP_BIND_AGENTS:-}" && "${OPENCLAW_LIVE_ACP_BIND_AGENTS}" != "codex" ]]; then
|
||||
echo "ERROR: ACP spawn defaults Docker test supports only OPENCLAW_LIVE_ACP_BIND_AGENTS=codex." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export OPENCLAW_LIVE_ACP_BIND_AGENTS=codex
|
||||
export OPENCLAW_LIVE_ACP_BIND_TEST_FILES="${OPENCLAW_LIVE_ACP_BIND_TEST_FILES:-src/gateway/gateway-acp-spawn-defaults.live.test.ts}"
|
||||
export OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS=1
|
||||
export OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_MODEL="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_MODEL:-openai/gpt-5.5}"
|
||||
export OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING:-high}"
|
||||
export OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL="${OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL:-gpt-5.5}"
|
||||
|
||||
exec bash "$SCRIPT_DIR/test-live-acp-bind-docker.sh"
|
||||
428
src/gateway/gateway-acp-spawn-defaults.live.test.ts
Normal file
428
src/gateway/gateway-acp-spawn-defaults.live.test.ts
Normal file
@@ -0,0 +1,428 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import net from "node:net";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
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 { resolveStorePath } from "../config/sessions/paths.js";
|
||||
import { loadSessionStore } from "../config/sessions/store.js";
|
||||
import type { SessionEntry } from "../config/sessions/types.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { clearPluginLoaderCache } from "../plugins/loader.js";
|
||||
import { resetPluginRuntimeStateForTest } from "../plugins/runtime.js";
|
||||
import { sleep } from "../utils.js";
|
||||
import { startGatewayServer } from "./server.js";
|
||||
|
||||
const LIVE = isLiveTestEnabled();
|
||||
const ACP_SPAWN_DEFAULTS_LIVE = isTruthyEnvValue(process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS);
|
||||
const describeLive = LIVE && ACP_SPAWN_DEFAULTS_LIVE ? describe : describe.skip;
|
||||
const CONNECT_TIMEOUT_MS = resolvePositiveInteger(
|
||||
process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_CONNECT_TIMEOUT_MS,
|
||||
90_000,
|
||||
);
|
||||
const LIVE_TIMEOUT_MS = resolvePositiveInteger(
|
||||
process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_TIMEOUT_MS,
|
||||
240_000,
|
||||
);
|
||||
|
||||
function resolvePositiveInteger(raw: string | undefined, fallback: number): number {
|
||||
const parsed = raw ? Number(raw) : Number.NaN;
|
||||
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
||||
}
|
||||
|
||||
function resolveSubagentModel(): string {
|
||||
return process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_MODEL?.trim() || "openai/gpt-5.5";
|
||||
}
|
||||
|
||||
function resolveThinking(): string {
|
||||
return process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING?.trim() || "high";
|
||||
}
|
||||
|
||||
function resolveHarnessModel(): string {
|
||||
return process.env.OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL?.trim() || "gpt-5.5";
|
||||
}
|
||||
|
||||
function resolveAcpAgentId(): string {
|
||||
return process.env.OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_AGENT?.trim() || "codex";
|
||||
}
|
||||
|
||||
function resolveAcpAgentCommand(): { command: string; args?: string[] } {
|
||||
const codexHome = process.env.CODEX_HOME?.trim();
|
||||
return {
|
||||
command: "env",
|
||||
args: [
|
||||
...(codexHome ? [`CODEX_HOME=${codexHome}`] : []),
|
||||
process.execPath,
|
||||
path.join(process.cwd(), "node_modules/@zed-industries/codex-acp/bin/codex-acp.js"),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
async function prepareCodexHomeForLiveSpawnDefaultsTest(tempRoot: string): Promise<void> {
|
||||
const home = process.env.HOME?.trim();
|
||||
const sourceCodexHome = process.env.CODEX_HOME?.trim() || (home ? path.join(home, ".codex") : "");
|
||||
const codexHome = path.join(tempRoot, "codex-home");
|
||||
await fs.mkdir(codexHome, { recursive: true });
|
||||
if (sourceCodexHome) {
|
||||
await fs
|
||||
.copyFile(path.join(sourceCodexHome, "auth.json"), path.join(codexHome, "auth.json"))
|
||||
.catch((error) => {
|
||||
if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
const sourceConfigPath = sourceCodexHome ? path.join(sourceCodexHome, "config.toml") : "";
|
||||
const targetConfigPath = path.join(codexHome, "config.toml");
|
||||
let rawConfig = "";
|
||||
try {
|
||||
rawConfig = sourceConfigPath ? await fs.readFile(sourceConfigPath, "utf8") : "";
|
||||
} catch (error) {
|
||||
if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const modelLine = `model = ${JSON.stringify(resolveHarnessModel())}`;
|
||||
const nextConfig = /^model\s*=.*$/m.test(rawConfig)
|
||||
? rawConfig.replace(/^model\s*=.*$/m, modelLine)
|
||||
: `${modelLine}\n${rawConfig}`;
|
||||
await fs.writeFile(targetConfigPath, nextConfig, "utf8");
|
||||
process.env.CODEX_HOME = codexHome;
|
||||
}
|
||||
|
||||
async function waitForGatewayPort(params: {
|
||||
host: string;
|
||||
port: number;
|
||||
timeoutMs?: number;
|
||||
}): Promise<void> {
|
||||
const timeoutMs = params.timeoutMs ?? CONNECT_TIMEOUT_MS;
|
||||
const startedAt = Date.now();
|
||||
|
||||
while (Date.now() - startedAt < timeoutMs) {
|
||||
const connected = await new Promise<boolean>((resolve) => {
|
||||
const socket = net.createConnection({ host: params.host, port: params.port });
|
||||
const finish = (ok: boolean) => {
|
||||
socket.removeAllListeners();
|
||||
socket.destroy();
|
||||
resolve(ok);
|
||||
};
|
||||
socket.once("connect", () => finish(true));
|
||||
socket.once("error", () => finish(false));
|
||||
socket.setTimeout(1_000, () => finish(false));
|
||||
});
|
||||
if (connected) {
|
||||
return;
|
||||
}
|
||||
await sleep(250);
|
||||
}
|
||||
|
||||
throw new Error(`timed out waiting for gateway port ${params.host}:${String(params.port)}`);
|
||||
}
|
||||
|
||||
async function getFreeGatewayPort(): Promise<number> {
|
||||
const { getFreePortBlockWithPermissionFallback } = await import("../test-utils/ports.js");
|
||||
return await getFreePortBlockWithPermissionFallback({
|
||||
offsets: [0, 1, 2, 4],
|
||||
fallbackBase: 42_000,
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForAcpBackendReady(timeoutMs = CONNECT_TIMEOUT_MS): Promise<void> {
|
||||
const startedAt = Date.now();
|
||||
while (Date.now() - startedAt < timeoutMs) {
|
||||
const backend = getAcpRuntimeBackend("acpx");
|
||||
const runtime = backend?.runtime as { probeAvailability?: () => Promise<void> } | undefined;
|
||||
if (backend && (!backend.healthy || backend.healthy())) {
|
||||
return;
|
||||
}
|
||||
await runtime?.probeAvailability?.().catch(() => {});
|
||||
if (backend && (!backend.healthy || backend.healthy())) {
|
||||
return;
|
||||
}
|
||||
await sleep(1_000);
|
||||
}
|
||||
throw new Error("timed out waiting for acpx backend readiness");
|
||||
}
|
||||
|
||||
async function waitForSessionEntry(params: {
|
||||
cfg: OpenClawConfig;
|
||||
sessionKey: string;
|
||||
timeoutMs?: number;
|
||||
}): Promise<SessionEntry> {
|
||||
const timeoutMs = params.timeoutMs ?? 20_000;
|
||||
const storePath = resolveStorePath(params.cfg.session?.store, { agentId: "codex" });
|
||||
const startedAt = Date.now();
|
||||
while (Date.now() - startedAt < timeoutMs) {
|
||||
const entry = loadSessionStore(storePath)[params.sessionKey];
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
await sleep(250);
|
||||
}
|
||||
throw new Error(`timed out waiting for ACP session entry ${params.sessionKey}`);
|
||||
}
|
||||
|
||||
function createConfig(params: {
|
||||
port: number;
|
||||
tempRoot: string;
|
||||
acpAgentId: string;
|
||||
subagentModel?: string;
|
||||
thinking?: string;
|
||||
includePrimaryOnlyAcpAgent?: boolean;
|
||||
}): OpenClawConfig {
|
||||
return {
|
||||
agents: {
|
||||
list: params.includePrimaryOnlyAcpAgent
|
||||
? [
|
||||
{
|
||||
id: "codex-acp-primary-only",
|
||||
runtime: {
|
||||
type: "acp",
|
||||
acp: { agent: params.acpAgentId },
|
||||
},
|
||||
model: "anthropic/claude-sonnet-4-6",
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
defaults: {
|
||||
model: {
|
||||
primary: "openai/gpt-5.5",
|
||||
},
|
||||
subagents: {
|
||||
allowAgents: ["*"],
|
||||
maxSpawnDepth: 2,
|
||||
...(params.subagentModel ? { model: params.subagentModel } : {}),
|
||||
},
|
||||
models: {
|
||||
...(params.subagentModel && params.thinking
|
||||
? {
|
||||
[params.subagentModel]: {
|
||||
params: {
|
||||
thinking: params.thinking,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
gateway: {
|
||||
mode: "local",
|
||||
bind: "loopback",
|
||||
port: params.port,
|
||||
},
|
||||
session: {
|
||||
mainKey: "main",
|
||||
scope: "per-sender",
|
||||
store: path.join(params.tempRoot, "sessions.json"),
|
||||
},
|
||||
acp: {
|
||||
enabled: true,
|
||||
backend: "acpx",
|
||||
defaultAgent: params.acpAgentId,
|
||||
allowedAgents: [params.acpAgentId],
|
||||
},
|
||||
plugins: {
|
||||
enabled: true,
|
||||
allow: ["acpx"],
|
||||
entries: {
|
||||
acpx: {
|
||||
enabled: true,
|
||||
config: {
|
||||
probeAgent: params.acpAgentId,
|
||||
permissionMode: "approve-all",
|
||||
nonInteractivePermissions: "deny",
|
||||
agents: {
|
||||
[params.acpAgentId]: resolveAcpAgentCommand(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describeLive("gateway live (ACP spawn defaults)", () => {
|
||||
it(
|
||||
"applies existing subagent defaults to live ACP spawns without leaking primary agent model",
|
||||
async () => {
|
||||
const previous = {
|
||||
configPath: process.env.OPENCLAW_CONFIG_PATH,
|
||||
stateDir: process.env.OPENCLAW_STATE_DIR,
|
||||
token: process.env.OPENCLAW_GATEWAY_TOKEN,
|
||||
port: process.env.OPENCLAW_GATEWAY_PORT,
|
||||
skipChannels: process.env.OPENCLAW_SKIP_CHANNELS,
|
||||
skipGmail: process.env.OPENCLAW_SKIP_GMAIL_WATCHER,
|
||||
skipCron: process.env.OPENCLAW_SKIP_CRON,
|
||||
skipCanvas: process.env.OPENCLAW_SKIP_CANVAS_HOST,
|
||||
codexHome: process.env.CODEX_HOME,
|
||||
};
|
||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-live-acp-spawn-"));
|
||||
const tempConfigPath = path.join(tempRoot, "openclaw.json");
|
||||
const tempStateDir = path.join(tempRoot, "state");
|
||||
const port = await getFreeGatewayPort();
|
||||
const token = `test-${randomUUID()}`;
|
||||
const acpAgentId = resolveAcpAgentId();
|
||||
const subagentModel = resolveSubagentModel();
|
||||
const thinking = resolveThinking();
|
||||
const sessionKeys: string[] = [];
|
||||
|
||||
process.env.OPENCLAW_CONFIG_PATH = tempConfigPath;
|
||||
process.env.OPENCLAW_STATE_DIR = tempStateDir;
|
||||
process.env.OPENCLAW_SKIP_CHANNELS = "1";
|
||||
process.env.OPENCLAW_SKIP_GMAIL_WATCHER = "1";
|
||||
process.env.OPENCLAW_SKIP_CRON = "1";
|
||||
process.env.OPENCLAW_SKIP_CANVAS_HOST = "1";
|
||||
process.env.OPENCLAW_GATEWAY_TOKEN = token;
|
||||
process.env.OPENCLAW_GATEWAY_PORT = String(port);
|
||||
await prepareCodexHomeForLiveSpawnDefaultsTest(tempRoot);
|
||||
|
||||
const cfg = createConfig({
|
||||
port,
|
||||
tempRoot,
|
||||
acpAgentId,
|
||||
subagentModel,
|
||||
thinking,
|
||||
includePrimaryOnlyAcpAgent: true,
|
||||
});
|
||||
await fs.writeFile(tempConfigPath, `${JSON.stringify(cfg, null, 2)}\n`);
|
||||
clearConfigCache();
|
||||
clearRuntimeConfigSnapshot();
|
||||
clearPluginLoaderCache();
|
||||
resetPluginRuntimeStateForTest();
|
||||
|
||||
const server = await startGatewayServer(port, {
|
||||
bind: "loopback",
|
||||
auth: { mode: "token", token },
|
||||
controlUiEnabled: false,
|
||||
});
|
||||
try {
|
||||
await waitForGatewayPort({ host: "127.0.0.1", port, timeoutMs: CONNECT_TIMEOUT_MS });
|
||||
await waitForAcpBackendReady();
|
||||
const runtimeCfg = getRuntimeConfig();
|
||||
const configuredDefaultResult = await spawnAcpDirect(
|
||||
{
|
||||
task: "Reply with exactly LIVE-ACP-SPAWN-DEFAULTS-OK",
|
||||
agentId: acpAgentId,
|
||||
mode: "run",
|
||||
},
|
||||
{ agentSessionKey: "agent:main:main" },
|
||||
);
|
||||
if (!isSpawnAcpAcceptedResult(configuredDefaultResult)) {
|
||||
throw new Error(
|
||||
`configured default ACP spawn failed (${configuredDefaultResult.errorCode}): ${configuredDefaultResult.error}`,
|
||||
);
|
||||
}
|
||||
expect(isSpawnAcpAcceptedResult(configuredDefaultResult)).toBe(true);
|
||||
sessionKeys.push(configuredDefaultResult.childSessionKey);
|
||||
const configuredDefaultEntry = await waitForSessionEntry({
|
||||
cfg: runtimeCfg,
|
||||
sessionKey: configuredDefaultResult.childSessionKey,
|
||||
});
|
||||
expect(configuredDefaultEntry.acp?.runtimeOptions).toMatchObject({
|
||||
model: subagentModel,
|
||||
thinking,
|
||||
});
|
||||
|
||||
const primaryOnlyResult = await spawnAcpDirect(
|
||||
{
|
||||
task: "Reply with exactly LIVE-ACP-SPAWN-PRIMARY-DEFAULT-OK",
|
||||
agentId: "codex-acp-primary-only",
|
||||
mode: "run",
|
||||
},
|
||||
{ agentSessionKey: "agent:main:main" },
|
||||
);
|
||||
if (!isSpawnAcpAcceptedResult(primaryOnlyResult)) {
|
||||
throw new Error(
|
||||
`primary-only ACP spawn failed (${primaryOnlyResult.errorCode}): ${primaryOnlyResult.error}`,
|
||||
);
|
||||
}
|
||||
expect(isSpawnAcpAcceptedResult(primaryOnlyResult)).toBe(true);
|
||||
sessionKeys.push(primaryOnlyResult.childSessionKey);
|
||||
const primaryOnlyEntry = await waitForSessionEntry({
|
||||
cfg: runtimeCfg,
|
||||
sessionKey: primaryOnlyResult.childSessionKey,
|
||||
});
|
||||
expect(primaryOnlyEntry.acp?.runtimeOptions).toMatchObject({
|
||||
model: subagentModel,
|
||||
thinking,
|
||||
});
|
||||
expect(primaryOnlyEntry.acp?.runtimeOptions?.model).not.toBe("anthropic/claude-sonnet-4-6");
|
||||
} finally {
|
||||
const runtimeCfg = getRuntimeConfig();
|
||||
for (const sessionKey of sessionKeys) {
|
||||
await getAcpSessionManager()
|
||||
.closeSession({
|
||||
cfg: runtimeCfg,
|
||||
sessionKey,
|
||||
reason: "live-acp-spawn-defaults-test-cleanup",
|
||||
discardPersistentState: true,
|
||||
clearMeta: true,
|
||||
requireAcpSession: false,
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
clearConfigCache();
|
||||
clearRuntimeConfigSnapshot();
|
||||
await server.close();
|
||||
await fs.rm(tempRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
||||
if (previous.configPath === undefined) {
|
||||
delete process.env.OPENCLAW_CONFIG_PATH;
|
||||
} else {
|
||||
process.env.OPENCLAW_CONFIG_PATH = previous.configPath;
|
||||
}
|
||||
if (previous.stateDir === undefined) {
|
||||
delete process.env.OPENCLAW_STATE_DIR;
|
||||
} else {
|
||||
process.env.OPENCLAW_STATE_DIR = previous.stateDir;
|
||||
}
|
||||
if (previous.token === undefined) {
|
||||
delete process.env.OPENCLAW_GATEWAY_TOKEN;
|
||||
} else {
|
||||
process.env.OPENCLAW_GATEWAY_TOKEN = previous.token;
|
||||
}
|
||||
if (previous.port === undefined) {
|
||||
delete process.env.OPENCLAW_GATEWAY_PORT;
|
||||
} else {
|
||||
process.env.OPENCLAW_GATEWAY_PORT = previous.port;
|
||||
}
|
||||
if (previous.skipChannels === undefined) {
|
||||
delete process.env.OPENCLAW_SKIP_CHANNELS;
|
||||
} else {
|
||||
process.env.OPENCLAW_SKIP_CHANNELS = previous.skipChannels;
|
||||
}
|
||||
if (previous.skipGmail === undefined) {
|
||||
delete process.env.OPENCLAW_SKIP_GMAIL_WATCHER;
|
||||
} else {
|
||||
process.env.OPENCLAW_SKIP_GMAIL_WATCHER = previous.skipGmail;
|
||||
}
|
||||
if (previous.skipCron === undefined) {
|
||||
delete process.env.OPENCLAW_SKIP_CRON;
|
||||
} else {
|
||||
process.env.OPENCLAW_SKIP_CRON = previous.skipCron;
|
||||
}
|
||||
if (previous.skipCanvas === undefined) {
|
||||
delete process.env.OPENCLAW_SKIP_CANVAS_HOST;
|
||||
} else {
|
||||
process.env.OPENCLAW_SKIP_CANVAS_HOST = previous.skipCanvas;
|
||||
}
|
||||
if (previous.codexHome === undefined) {
|
||||
delete process.env.CODEX_HOME;
|
||||
} else {
|
||||
process.env.CODEX_HOME = previous.codexHome;
|
||||
}
|
||||
}
|
||||
},
|
||||
LIVE_TIMEOUT_MS + 120_000,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user