From e24e0cf364f5297159dfd20227fb2f95e13c2bc9 Mon Sep 17 00:00:00 2001 From: Azade Date: Thu, 8 Jan 2026 23:32:42 +0000 Subject: [PATCH] test(sessions): add tests for sessions_send label lookup - Test finding session by label - Test error when label not found - Test error when neither sessionKey nor label provided --- src/gateway/server.sessions-send.test.ts | 144 +++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/src/gateway/server.sessions-send.test.ts b/src/gateway/server.sessions-send.test.ts index 73ea13d8b..3972ef6ac 100644 --- a/src/gateway/server.sessions-send.test.ts +++ b/src/gateway/server.sessions-send.test.ts @@ -101,3 +101,147 @@ describe("sessions_send gateway loopback", () => { } }); }); + +describe("sessions_send label lookup", () => { + it("finds session by label and sends message", async () => { + const port = await getFreePort(); + const prevPort = process.env.CLAWDBOT_GATEWAY_PORT; + process.env.CLAWDBOT_GATEWAY_PORT = String(port); + + const server = await startGatewayServer(port); + const spy = vi.mocked(agentCommand); + spy.mockImplementation(async (opts) => { + const params = opts as { + sessionId?: string; + runId?: string; + extraSystemPrompt?: string; + }; + const sessionId = params.sessionId ?? "test-labeled"; + const runId = params.runId ?? sessionId; + const sessionFile = resolveSessionTranscriptPath(sessionId); + await fs.mkdir(path.dirname(sessionFile), { recursive: true }); + + const startedAt = Date.now(); + emitAgentEvent({ + runId, + stream: "lifecycle", + data: { phase: "start", startedAt }, + }); + + const text = "labeled response"; + const message = { + role: "assistant", + content: [{ type: "text", text }], + }; + await fs.appendFile( + sessionFile, + `${JSON.stringify({ message })}\n`, + "utf8", + ); + + emitAgentEvent({ + runId, + stream: "lifecycle", + data: { phase: "end", startedAt, endedAt: Date.now() }, + }); + }); + + try { + // First, create a session with a label via sessions.patch + const { callGateway } = await import("./call.js"); + await callGateway({ + method: "sessions.patch", + params: { key: "test-labeled-session", label: "my-test-worker" }, + timeoutMs: 5000, + }); + + const tool = createClawdbotTools().find( + (candidate) => candidate.name === "sessions_send", + ); + if (!tool) throw new Error("missing sessions_send tool"); + + // Send using label instead of sessionKey + const result = await tool.execute("call-by-label", { + label: "my-test-worker", + message: "hello labeled session", + timeoutSeconds: 5, + }); + const details = result.details as { + status?: string; + reply?: string; + sessionKey?: string; + }; + expect(details.status).toBe("ok"); + expect(details.reply).toBe("labeled response"); + expect(details.sessionKey).toBe("test-labeled-session"); + } finally { + if (prevPort === undefined) { + delete process.env.CLAWDBOT_GATEWAY_PORT; + } else { + process.env.CLAWDBOT_GATEWAY_PORT = prevPort; + } + await server.close(); + } + }); + + it("returns error when label not found", async () => { + const port = await getFreePort(); + const prevPort = process.env.CLAWDBOT_GATEWAY_PORT; + process.env.CLAWDBOT_GATEWAY_PORT = String(port); + + const server = await startGatewayServer(port); + + try { + const tool = createClawdbotTools().find( + (candidate) => candidate.name === "sessions_send", + ); + if (!tool) throw new Error("missing sessions_send tool"); + + const result = await tool.execute("call-missing-label", { + label: "nonexistent-label", + message: "hello", + timeoutSeconds: 5, + }); + const details = result.details as { status?: string; error?: string }; + expect(details.status).toBe("error"); + expect(details.error).toContain("No session found with label"); + } finally { + if (prevPort === undefined) { + delete process.env.CLAWDBOT_GATEWAY_PORT; + } else { + process.env.CLAWDBOT_GATEWAY_PORT = prevPort; + } + await server.close(); + } + }); + + it("returns error when neither sessionKey nor label provided", async () => { + const port = await getFreePort(); + const prevPort = process.env.CLAWDBOT_GATEWAY_PORT; + process.env.CLAWDBOT_GATEWAY_PORT = String(port); + + const server = await startGatewayServer(port); + + try { + const tool = createClawdbotTools().find( + (candidate) => candidate.name === "sessions_send", + ); + if (!tool) throw new Error("missing sessions_send tool"); + + const result = await tool.execute("call-no-key", { + message: "hello", + timeoutSeconds: 5, + }); + const details = result.details as { status?: string; error?: string }; + expect(details.status).toBe("error"); + expect(details.error).toContain("Either sessionKey or label is required"); + } finally { + if (prevPort === undefined) { + delete process.env.CLAWDBOT_GATEWAY_PORT; + } else { + process.env.CLAWDBOT_GATEWAY_PORT = prevPort; + } + await server.close(); + } + }); +});