diff --git a/src/auto-reply/reply/commands-status.test.ts b/src/auto-reply/reply/commands-status.test.ts index fadb3086e56..e47ca00406c 100644 --- a/src/auto-reply/reply/commands-status.test.ts +++ b/src/auto-reply/reply/commands-status.test.ts @@ -2,7 +2,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { withTempHome } from "openclaw/plugin-sdk/test-env"; -import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { normalizeTestText } from "../../../test/helpers/normalize-text.js"; import { clearAgentHarnesses, registerAgentHarness } from "../../agents/harness/registry.js"; import type { AgentHarness } from "../../agents/harness/types.js"; @@ -25,6 +25,17 @@ import { configureInMemoryTaskRegistryStoreForTests, } from "./commands.test-harness.js"; +vi.mock("../../agents/harness/builtin-pi.js", () => ({ + createPiAgentHarness: () => ({ + id: "pi", + label: "OpenClaw Pi", + supports: () => ({ supported: true, priority: 0 }), + runAttempt: async () => { + throw new Error("not used in status tests"); + }, + }), +})); + const baseCfg = baseCommandTestConfig; async function buildStatusReplyForTest(params: { sessionKey?: string; verbose?: boolean }) { diff --git a/src/gateway/server.shared-auth-rotation.test.ts b/src/gateway/server.shared-auth-rotation.test.ts index 8ee2334f398..9a63252a75c 100644 --- a/src/gateway/server.shared-auth-rotation.test.ts +++ b/src/gateway/server.shared-auth-rotation.test.ts @@ -218,6 +218,7 @@ describe("gateway shared auth rotation with unchanged SecretRefs", () => { const ws = await openSecretRefAuthenticatedWs(); try { const closed = waitForGatewayWsClose(ws); + process.env[SECRET_REF_TOKEN_ID] = NEW_TOKEN; const res = await applyCurrentConfig(ws); expect(res.ok).toBe(true); await expect(closed).resolves.toEqual({ diff --git a/src/gateway/shared-auth.test-helpers.ts b/src/gateway/shared-auth.test-helpers.ts index 69f3007e1f1..b589087e28d 100644 --- a/src/gateway/shared-auth.test-helpers.ts +++ b/src/gateway/shared-auth.test-helpers.ts @@ -12,11 +12,18 @@ export async function openAuthenticatedGatewayWs(port: number, token: string): P export async function waitForGatewayWsClose( ws: WebSocket, + timeoutMs = 10_000, ): Promise<{ code: number; reason: string }> { - return await new Promise((resolve) => { - ws.once("close", (code, reason) => { + return await new Promise((resolve, reject) => { + const timer = setTimeout(() => { + ws.off("close", onClose); + reject(new Error(`gateway websocket did not close within ${timeoutMs}ms`)); + }, timeoutMs); + const onClose = (code: number, reason: Buffer) => { + clearTimeout(timer); resolve({ code, reason: reason.toString() }); - }); + }; + ws.once("close", onClose); }); } diff --git a/src/status/status-text.ts b/src/status/status-text.ts index f5f660f6de7..9c73e1d1c7d 100644 --- a/src/status/status-text.ts +++ b/src/status/status-text.ts @@ -7,7 +7,6 @@ import { resolveAgentModelFallbacksOverride, } from "../agents/agent-scope.js"; import { resolveFastModeState } from "../agents/fast-mode.js"; -import { selectAgentHarness } from "../agents/harness/selection.js"; import { resolveModelAuthLabel } from "../agents/model-auth-label.js"; import { resolveInternalSessionKey, @@ -46,6 +45,9 @@ const USAGE_OAUTH_ONLY_PROVIDERS = new Set([ let statusMessageRuntimePromise: Promise | null = null; +let agentHarnessSelectionRuntimePromise: Promise< + typeof import("../agents/harness/selection.js") +> | null = null; let statusQueueRuntimePromise: Promise | null = null; let statusSubagentsRuntimePromise: Promise | null = null; @@ -58,6 +60,14 @@ function loadStatusMessageRuntime(): Promise { + const runtimePromise = (agentHarnessSelectionRuntimePromise ??= + import("../agents/harness/selection.js")); + return runtimePromise; +} + function loadStatusSubagentsRuntime(): Promise { const runtimePromise = (statusSubagentsRuntimePromise ??= import("./status-subagents.runtime.js")); @@ -101,15 +111,16 @@ function formatSessionTaskLine(sessionKey: string): string | undefined { return parts.length ? `๐Ÿ“Œ Tasks: ${parts.join(" ยท ")}` : undefined; } -function resolveStatusHarnessId(params: { +async function resolveStatusHarnessId(params: { cfg: OpenClawConfig; provider: string; model: string; agentId: string; sessionKey: string; sessionEntry?: SessionEntry; -}): string | undefined { +}): Promise { try { + const { selectAgentHarness } = await loadAgentHarnessSelectionRuntime(); const selected = selectAgentHarness({ provider: params.provider, modelId: params.model, @@ -288,14 +299,14 @@ export async function buildStatusText(params: BuildStatusTextParams): Promise