diff --git a/src/gateway/server/health-state.test.ts b/src/gateway/server/health-state.test.ts new file mode 100644 index 00000000000..d6ebeaf1a94 --- /dev/null +++ b/src/gateway/server/health-state.test.ts @@ -0,0 +1,102 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +const loadConfigMock = vi.hoisted(() => vi.fn()); +const createConfigIOMock = vi.hoisted(() => vi.fn()); +const resolveDefaultAgentIdMock = vi.hoisted(() => vi.fn()); +const resolveMainSessionKeyMock = vi.hoisted(() => vi.fn()); +const normalizeMainKeyMock = vi.hoisted(() => vi.fn()); +const listSystemPresenceMock = vi.hoisted(() => vi.fn()); +const resolveGatewayAuthMock = vi.hoisted(() => vi.fn()); +const getUpdateAvailableMock = vi.hoisted(() => vi.fn()); +const resolveAgentCortexConfigMock = vi.hoisted(() => vi.fn()); +const getLatestCortexCaptureHistoryEntrySyncMock = vi.hoisted(() => vi.fn()); + +vi.mock("../../config/config.js", () => ({ + STATE_DIR: "/tmp/openclaw-state", + createConfigIO: createConfigIOMock, + loadConfig: loadConfigMock, +})); + +vi.mock("../../agents/agent-scope.js", () => ({ + resolveDefaultAgentId: resolveDefaultAgentIdMock, +})); + +vi.mock("../../config/sessions.js", () => ({ + resolveMainSessionKey: resolveMainSessionKeyMock, +})); + +vi.mock("../../routing/session-key.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + DEFAULT_ACCOUNT_ID: "default", + normalizeMainKey: normalizeMainKeyMock, + }; +}); + +vi.mock("../../infra/system-presence.js", () => ({ + listSystemPresence: listSystemPresenceMock, +})); + +vi.mock("../auth.js", () => ({ + resolveGatewayAuth: resolveGatewayAuthMock, +})); + +vi.mock("../../infra/update-startup.js", () => ({ + getUpdateAvailable: getUpdateAvailableMock, +})); + +vi.mock("../../agents/cortex.js", () => ({ + resolveAgentCortexConfig: resolveAgentCortexConfigMock, +})); + +vi.mock("../../agents/cortex-history.js", () => ({ + getLatestCortexCaptureHistoryEntrySync: getLatestCortexCaptureHistoryEntrySyncMock, +})); + +import { buildGatewaySnapshot } from "./health-state.js"; + +describe("buildGatewaySnapshot", () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it("includes Cortex snapshot details when the prompt bridge is enabled", () => { + loadConfigMock.mockReturnValue({ + session: { mainKey: "main", scope: "per-sender" }, + }); + createConfigIOMock.mockReturnValue({ configPath: "/tmp/openclaw/openclaw.json" }); + resolveDefaultAgentIdMock.mockReturnValue("main"); + resolveMainSessionKeyMock.mockReturnValue("agent:main:main"); + normalizeMainKeyMock.mockReturnValue("main"); + listSystemPresenceMock.mockReturnValue([]); + resolveGatewayAuthMock.mockReturnValue({ mode: "token" }); + getUpdateAvailableMock.mockReturnValue(undefined); + resolveAgentCortexConfigMock.mockReturnValue({ + enabled: true, + mode: "technical", + maxChars: 1500, + graphPath: ".cortex/context.json", + }); + getLatestCortexCaptureHistoryEntrySyncMock.mockReturnValue({ + agentId: "main", + captured: true, + score: 0.7, + reason: "high-signal memory candidate", + syncPlatforms: ["claude-code", "cursor", "copilot"], + timestamp: 1234, + }); + + const snapshot = buildGatewaySnapshot(); + + expect(snapshot.cortex).toEqual({ + enabled: true, + mode: "technical", + graphPath: ".cortex/context.json", + lastCaptureAtMs: 1234, + lastCaptureReason: "high-signal memory candidate", + lastCaptureStored: true, + lastSyncPlatforms: ["claude-code", "cursor", "copilot"], + }); + }); +});