From 5067d06f5553268cb0c8907e3ecc64db44994373 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 19:03:14 +0000 Subject: [PATCH] refactor: share session status sandbox helpers --- .../openclaw-tools.session-status.test.ts | 135 +++++++----------- 1 file changed, 52 insertions(+), 83 deletions(-) diff --git a/src/agents/openclaw-tools.session-status.test.ts b/src/agents/openclaw-tools.session-status.test.ts index 8b2d9fc467f..0bc079d4ced 100644 --- a/src/agents/openclaw-tools.session-status.test.ts +++ b/src/agents/openclaw-tools.session-status.test.ts @@ -115,6 +115,50 @@ function resetSessionStore(store: Record) { mockConfig = createMockConfig(); } +function installSandboxedSessionStatusConfig() { + mockConfig = { + session: { mainKey: "main", scope: "per-sender" }, + tools: { + sessions: { visibility: "all" }, + agentToAgent: { enabled: true, allow: ["*"] }, + }, + agents: { + defaults: { + model: { primary: "anthropic/claude-opus-4-5" }, + models: {}, + sandbox: { sessionToolsVisibility: "spawned" }, + }, + }, + }; +} + +function mockSpawnedSessionList( + resolveSessions: (spawnedBy: string | undefined) => Array>, +) { + callGatewayMock.mockImplementation(async (opts: unknown) => { + const request = opts as { method?: string; params?: Record }; + if (request.method === "sessions.list") { + return { sessions: resolveSessions(request.params?.spawnedBy as string | undefined) }; + } + return {}; + }); +} + +function expectSpawnedSessionLookupCalls(spawnedBy: string) { + const expectedCall = { + method: "sessions.list", + params: { + includeGlobal: false, + includeUnknown: false, + limit: 500, + spawnedBy, + }, + }; + expect(callGatewayMock).toHaveBeenCalledTimes(2); + expect(callGatewayMock).toHaveBeenNthCalledWith(1, expectedCall); + expect(callGatewayMock).toHaveBeenNthCalledWith(2, expectedCall); +} + function getSessionStatusTool(agentSessionKey = "main", options?: { sandboxed?: boolean }) { const tool = createOpenClawTools({ agentSessionKey, @@ -242,27 +286,8 @@ describe("session_status tool", () => { updatedAt: 10, }, }); - mockConfig = { - session: { mainKey: "main", scope: "per-sender" }, - tools: { - sessions: { visibility: "all" }, - agentToAgent: { enabled: true, allow: ["*"] }, - }, - agents: { - defaults: { - model: { primary: "anthropic/claude-opus-4-5" }, - models: {}, - sandbox: { sessionToolsVisibility: "spawned" }, - }, - }, - }; - callGatewayMock.mockImplementation(async (opts: unknown) => { - const request = opts as { method?: string; params?: Record }; - if (request.method === "sessions.list") { - return { sessions: [] }; - } - return {}; - }); + installSandboxedSessionStatusConfig(); + mockSpawnedSessionList(() => []); const tool = getSessionStatusTool("agent:main:subagent:child", { sandboxed: true, @@ -284,25 +309,7 @@ describe("session_status tool", () => { expect(loadSessionStoreMock).not.toHaveBeenCalled(); expect(updateSessionStoreMock).not.toHaveBeenCalled(); - expect(callGatewayMock).toHaveBeenCalledTimes(2); - expect(callGatewayMock).toHaveBeenNthCalledWith(1, { - method: "sessions.list", - params: { - includeGlobal: false, - includeUnknown: false, - limit: 500, - spawnedBy: "agent:main:subagent:child", - }, - }); - expect(callGatewayMock).toHaveBeenNthCalledWith(2, { - method: "sessions.list", - params: { - includeGlobal: false, - includeUnknown: false, - limit: 500, - spawnedBy: "agent:main:subagent:child", - }, - }); + expectSpawnedSessionLookupCalls("agent:main:subagent:child"); }); it("keeps legacy main requester keys for sandboxed session tree checks", async () => { @@ -316,30 +323,10 @@ describe("session_status tool", () => { updatedAt: 20, }, }); - mockConfig = { - session: { mainKey: "main", scope: "per-sender" }, - tools: { - sessions: { visibility: "all" }, - agentToAgent: { enabled: true, allow: ["*"] }, - }, - agents: { - defaults: { - model: { primary: "anthropic/claude-opus-4-5" }, - models: {}, - sandbox: { sessionToolsVisibility: "spawned" }, - }, - }, - }; - callGatewayMock.mockImplementation(async (opts: unknown) => { - const request = opts as { method?: string; params?: Record }; - if (request.method === "sessions.list") { - return { - sessions: - request.params?.spawnedBy === "main" ? [{ key: "agent:main:subagent:child" }] : [], - }; - } - return {}; - }); + installSandboxedSessionStatusConfig(); + mockSpawnedSessionList((spawnedBy) => + spawnedBy === "main" ? [{ key: "agent:main:subagent:child" }] : [], + ); const tool = getSessionStatusTool("main", { sandboxed: true, @@ -357,25 +344,7 @@ describe("session_status tool", () => { expect(childDetails.ok).toBe(true); expect(childDetails.sessionKey).toBe("agent:main:subagent:child"); - expect(callGatewayMock).toHaveBeenCalledTimes(2); - expect(callGatewayMock).toHaveBeenNthCalledWith(1, { - method: "sessions.list", - params: { - includeGlobal: false, - includeUnknown: false, - limit: 500, - spawnedBy: "main", - }, - }); - expect(callGatewayMock).toHaveBeenNthCalledWith(2, { - method: "sessions.list", - params: { - includeGlobal: false, - includeUnknown: false, - limit: 500, - spawnedBy: "main", - }, - }); + expectSpawnedSessionLookupCalls("main"); }); it("scopes bare session keys to the requester agent", async () => {