diff --git a/src/gateway/server-methods/sessions-abort.test.ts b/src/gateway/server-methods/sessions-abort.test.ts index 5e5f11d30cd4..9193a4ae4c68 100644 --- a/src/gateway/server-methods/sessions-abort.test.ts +++ b/src/gateway/server-methods/sessions-abort.test.ts @@ -13,11 +13,11 @@ import { testState } from "../test-helpers.js"; import { directSessionReq, getGatewayConfigModule, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "../test/server-sessions.test-helpers.js"; import { createActiveRun, createChatAbortContext } from "./chat.abort.test-helpers.js"; -setupGatewaySessionsTestHarness(); +setupGatewaySessionsHandlerTestHarness(); function requireStateDir(): string { const stateDir = process.env.OPENCLAW_STATE_DIR; diff --git a/src/gateway/server-methods/sessions-read.test.ts b/src/gateway/server-methods/sessions-read.test.ts index 45886ba41a1f..2233949d45c4 100644 --- a/src/gateway/server-methods/sessions-read.test.ts +++ b/src/gateway/server-methods/sessions-read.test.ts @@ -15,12 +15,12 @@ import { getGatewayConfigModule, directSessionReq, seedLinearSessionTranscript, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "../test/server-sessions.test-helpers.js"; import { agentsHandlers } from "./agents.js"; import type { GatewayRequestContext } from "./types.js"; -setupGatewaySessionsTestHarness(); +setupGatewaySessionsHandlerTestHarness(); const UNKNOWN_AGENT_ID = "ghost"; const UNKNOWN_SESSION_KEY = `agent:${UNKNOWN_AGENT_ID}:zzz`; diff --git a/src/gateway/server.sessions.agent-model-catalog.test.ts b/src/gateway/server.sessions.agent-model-catalog.test.ts index d41d78c1614f..c492b71a0587 100644 --- a/src/gateway/server.sessions.agent-model-catalog.test.ts +++ b/src/gateway/server.sessions.agent-model-catalog.test.ts @@ -5,10 +5,10 @@ import { writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSelectedGlobalSessionStore } = setupGatewaySessionsTestHarness(); +const { createSelectedGlobalSessionStore } = setupGatewaySessionsHandlerTestHarness(); const mainModel = { id: "main-only", name: "Main Model", provider: "main-provider" }; const workModel = { id: "work-only", name: "Work Model", provider: "work-provider" }; diff --git a/src/gateway/server.sessions.delete-board.test.ts b/src/gateway/server.sessions.delete-board.test.ts index 852c642ce416..03c77f07b263 100644 --- a/src/gateway/server.sessions.delete-board.test.ts +++ b/src/gateway/server.sessions.delete-board.test.ts @@ -7,11 +7,11 @@ import { testState, writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, writeSingleLineSession, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); afterEach(() => { closeOpenClawAgentDatabasesForTest(); diff --git a/src/gateway/server.sessions.list-connection-reuse.test.ts b/src/gateway/server.sessions.list-connection-reuse.test.ts index 0e5c46dbf468..68b63dfa3d3c 100644 --- a/src/gateway/server.sessions.list-connection-reuse.test.ts +++ b/src/gateway/server.sessions.list-connection-reuse.test.ts @@ -9,10 +9,10 @@ import { writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); const LIST_PARAMS = { agentId: "main", diff --git a/src/gateway/server.sessions.list-store-materialization.test.ts b/src/gateway/server.sessions.list-store-materialization.test.ts index 88fb7112d902..f11aa1a85abd 100644 --- a/src/gateway/server.sessions.list-store-materialization.test.ts +++ b/src/gateway/server.sessions.list-store-materialization.test.ts @@ -15,10 +15,10 @@ import { directSessionReq, seedSessionTranscript, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); const LIST_PARAMS = { agentId: "main", diff --git a/src/gateway/server.sessions.patch-expected-identity.test.ts b/src/gateway/server.sessions.patch-expected-identity.test.ts index 295a29390747..539dd41690ac 100644 --- a/src/gateway/server.sessions.patch-expected-identity.test.ts +++ b/src/gateway/server.sessions.patch-expected-identity.test.ts @@ -6,10 +6,10 @@ import { embeddedRunMock, writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); afterEach(() => { closeOpenClawStateDatabaseForTest(); diff --git a/src/gateway/server.sessions.placement-projection.test.ts b/src/gateway/server.sessions.placement-projection.test.ts index 9582d01cd81b..a4572b7acf67 100644 --- a/src/gateway/server.sessions.placement-projection.test.ts +++ b/src/gateway/server.sessions.placement-projection.test.ts @@ -3,12 +3,12 @@ import type { GatewaySessionRow } from "./session-utils.types.js"; import { writeSessionStore } from "./test-helpers.js"; import { directSessionReq, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; import type { WorkerSessionPlacementReader } from "./worker-environments/placement-projector.js"; import type { WorkerSessionPlacementRecord } from "./worker-environments/placement-store.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); function activePlacementRecord(): WorkerSessionPlacementRecord { return { diff --git a/src/gateway/server.sessions.plugin-ownership.test.ts b/src/gateway/server.sessions.plugin-ownership.test.ts index 67c4778e082a..f76dc637a980 100644 --- a/src/gateway/server.sessions.plugin-ownership.test.ts +++ b/src/gateway/server.sessions.plugin-ownership.test.ts @@ -9,10 +9,10 @@ import { writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); test.each([ { diff --git a/src/gateway/server.sessions.process-cleanup.test.ts b/src/gateway/server.sessions.process-cleanup.test.ts index 6e61f4ec8611..b87df36375e8 100644 --- a/src/gateway/server.sessions.process-cleanup.test.ts +++ b/src/gateway/server.sessions.process-cleanup.test.ts @@ -15,10 +15,10 @@ import { writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsHandlerTestHarness(); afterEach(() => { resetProcessRegistryForTests(); diff --git a/src/gateway/server.sessions.reset-cleanup.test.ts b/src/gateway/server.sessions.reset-cleanup.test.ts index 476a4ce42d9c..935ee187a7c7 100644 --- a/src/gateway/server.sessions.reset-cleanup.test.ts +++ b/src/gateway/server.sessions.reset-cleanup.test.ts @@ -19,7 +19,7 @@ import { runExclusiveSessionLifecycle } from "../sessions/session-lifecycle-admi import { closeOpenClawStateDatabaseForTest } from "../state/openclaw-state-db.js"; import { embeddedRunMock, testState, writeSessionStore } from "./test-helpers.js"; import { - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, bootstrapCacheMocks, subagentLifecycleHookMocks, subagentLifecycleHookState, @@ -37,7 +37,7 @@ import { sessionHookMocks, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsHandlerTestHarness(); type ResetAcpState = { backend?: string; diff --git a/src/gateway/server.sessions.reset-concurrency.test.ts b/src/gateway/server.sessions.reset-concurrency.test.ts index ca57416f89f2..ed6b18953eda 100644 --- a/src/gateway/server.sessions.reset-concurrency.test.ts +++ b/src/gateway/server.sessions.reset-concurrency.test.ts @@ -8,12 +8,12 @@ import { writeSessionStore } from "./test-helpers.js"; import { sessionLifecycleHookMocks, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, subagentLifecycleHookMocks, threadBindingMocks, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); afterEach(() => { closeOpenClawStateDatabaseForTest(); diff --git a/src/gateway/server.sessions.reset-hooks.succession.test.ts b/src/gateway/server.sessions.reset-hooks.succession.test.ts index e07e155b17e8..2a98358f75dd 100644 --- a/src/gateway/server.sessions.reset-hooks.succession.test.ts +++ b/src/gateway/server.sessions.reset-hooks.succession.test.ts @@ -8,10 +8,10 @@ import { directSessionReq, seedSessionTranscript, sessionLifecycleHookMocks, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); type HookEvent = { sessionKey?: string; diff --git a/src/gateway/server.sessions.reset-hooks.test.ts b/src/gateway/server.sessions.reset-hooks.test.ts index 2f3506271d44..2f4f8a5156fe 100644 --- a/src/gateway/server.sessions.reset-hooks.test.ts +++ b/src/gateway/server.sessions.reset-hooks.test.ts @@ -9,7 +9,7 @@ import type { InternalSessionEntry } from "../config/sessions/types.js"; import { beginSessionWorkAdmission } from "../sessions/session-lifecycle-admission.js"; import { embeddedRunMock, testState, writeSessionStore } from "./test-helpers.js"; import { - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, bootstrapCacheMocks, sessionHookMocks, beforeResetHookMocks, @@ -23,7 +23,7 @@ import { seedSessionTranscript, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsHandlerTestHarness(); type HookEventRecord = Record & { context?: Record & { diff --git a/src/gateway/server.sessions.reset-models.test.ts b/src/gateway/server.sessions.reset-models.test.ts index 200bab3ecaaa..9de162950f94 100644 --- a/src/gateway/server.sessions.reset-models.test.ts +++ b/src/gateway/server.sessions.reset-models.test.ts @@ -12,12 +12,12 @@ import { listSessionStateEventsSince } from "../sessions/session-state-events.js import { normalizeSessionDeliveryState } from "../utils/delivery-context.shared.js"; import { testState, writeSessionStore } from "./test-helpers.js"; import { - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, sessionStoreEntry, directSessionReq, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); type ResetSessionEntry = { sessionId?: string; diff --git a/src/gateway/server.sessions.thinking-e2e.test.ts b/src/gateway/server.sessions.thinking-e2e.test.ts index 81c3b0770f5a..e5b9d2ff91b0 100644 --- a/src/gateway/server.sessions.thinking-e2e.test.ts +++ b/src/gateway/server.sessions.thinking-e2e.test.ts @@ -12,13 +12,13 @@ import { expect, test, vi } from "vitest"; import { formatThinkingLevels } from "../auto-reply/thinking.js"; import { testState, writeSessionStore } from "./test-helpers.js"; import { - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, getGatewayConfigModule, getSessionsHandlers, sessionStoreEntry, } from "./test/server-sessions.test-helpers.js"; -const { createSessionStoreDir } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir } = setupGatewaySessionsHandlerTestHarness(); /** * Simulates the consumer-side resolution from session-controls.ts and diff --git a/src/gateway/server.sessions.worker-placement-lifecycle.test.ts b/src/gateway/server.sessions.worker-placement-lifecycle.test.ts index 29b75f9a214c..3a06204e6174 100644 --- a/src/gateway/server.sessions.worker-placement-lifecycle.test.ts +++ b/src/gateway/server.sessions.worker-placement-lifecycle.test.ts @@ -6,12 +6,12 @@ import { embeddedRunMock, writeSessionStore } from "./test-helpers.js"; import { directSessionReq, sessionStoreEntry, - setupGatewaySessionsTestHarness, + setupGatewaySessionsHandlerTestHarness, } from "./test/server-sessions.test-helpers.js"; import type { WorkerSessionPlacementReader } from "./worker-environments/placement-projector.js"; import type { WorkerSessionPlacementRecord } from "./worker-environments/placement-store.js"; -const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsTestHarness(); +const { createSessionStoreDir, seedActiveMainSession } = setupGatewaySessionsHandlerTestHarness(); let uninstallResetGuard: (() => void) | undefined; afterEach(() => { diff --git a/src/gateway/test/server-sessions.test-helpers.ts b/src/gateway/test/server-sessions.test-helpers.ts index 82c49880ab99..e21c620873f7 100644 --- a/src/gateway/test/server-sessions.test-helpers.ts +++ b/src/gateway/test/server-sessions.test-helpers.ts @@ -5,27 +5,17 @@ import fsSync from "node:fs"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { expectDefined } from "@openclaw/normalization-core"; import type { AssistantMessage, UserMessage } from "openclaw/plugin-sdk/llm"; import { afterAll, beforeAll, beforeEach, expect, vi } from "vitest"; import type { InternalSessionEntry as SessionEntry } from "../../config/sessions.js"; -import { - loadTranscriptEvents, - persistSessionTranscriptTurn, -} from "../../config/sessions/session-accessor.js"; import type { InternalHookEvent } from "../../hooks/internal-hooks.js"; import { resetSystemEventsForTest } from "../../infra/system-events.js"; import { createLazyRuntimeModule } from "../../shared/lazy-runtime.js"; import type { GatewayRequestContext } from "../server-methods/types.js"; -import { startGatewayServerHarness, type GatewayServerHarness } from "../server.e2e-ws-harness.js"; -import { - connectOk, - embeddedRunMock, - installGatewayTestHooks, - agentDiscoveryMock, - testState, - writeSessionStore, -} from "../test-helpers.js"; +import type { GatewayServerHarness } from "../server.e2e-ws-harness.js"; +import { embeddedRunMock, agentDiscoveryMock, testState } from "../test-helpers.runtime-state.js"; +import type { connectOk } from "../test-helpers.server.js"; +import { installGatewayTestHooks, writeSessionStore } from "../test-helpers.server.js"; import { sessionHandlerTestSurface } from "./server-sessions-handlers.test-support.js"; export const getSessionManagerModule = createLazyRuntimeModule( @@ -36,6 +26,14 @@ export const getGatewayConfigModule = createLazyRuntimeModule( () => import("../../config/config.js"), ); +const getSessionAccessorModule = createLazyRuntimeModule( + () => import("../../config/sessions/session-accessor.js"), +); + +const getGatewayServerHarnessModule = createLazyRuntimeModule( + () => import("../server.e2e-ws-harness.js"), +); + export async function getSessionsHandlers() { return sessionHandlerTestSurface; } @@ -54,6 +52,7 @@ export async function seedSessionTranscript(params: { sessionKey: string; storePath: string; }): Promise { + const { persistSessionTranscriptTurn } = await getSessionAccessorModule(); await persistSessionTranscriptTurn( { agentId: params.agentId, @@ -101,6 +100,7 @@ export async function loadSeededTranscriptEvents(params: { sessionKey: string; storePath: string; }): Promise { + const { loadTranscriptEvents } = await getSessionAccessorModule(); return await loadTranscriptEvents({ agentId: params.agentId, sessionId: params.sessionId, @@ -310,7 +310,18 @@ vi.mock("../../agents/agent-bundle-mcp-tools.js", () => ({ retireSessionMcpRuntime: bundleMcpRuntimeMocks.retireSessionMcpRuntime, })); +export function setupGatewaySessionsHandlerTestHarness() { + const { getHarness, openClient, ...handlerFixture } = createGatewaySessionsTestHarness(false); + void getHarness; + void openClient; + return handlerFixture; +} + export function setupGatewaySessionsTestHarness() { + return createGatewaySessionsTestHarness(true); +} + +function createGatewaySessionsTestHarness(startServer: boolean) { installGatewayTestHooks({ scope: "suite" }); let harness: GatewayServerHarness | undefined; @@ -318,7 +329,10 @@ export function setupGatewaySessionsTestHarness() { let sessionStoreCaseSeq = 0; beforeAll(async () => { - harness = await startGatewayServerHarness(); + if (startServer) { + const { startGatewayServerHarness } = await getGatewayServerHarnessModule(); + harness = await startGatewayServerHarness(); + } sharedSessionStoreDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sessions-")); }); @@ -680,10 +694,11 @@ export async function directSessionReq( let result: | { ok: boolean; payload?: TPayload; error?: { code?: string; message?: string } } | undefined; - await expectDefined( - sessionsHandlers[method], - "sessions handlers entry at method", - )({ + const handler = sessionsHandlers[method]; + if (!handler) { + throw new Error(`missing sessions handler for ${method}`); + } + await handler({ req: {} as never, params, respond: (ok, payload, error) => {