import { beforeEach, describe, expect, it } from "vitest"; import "./test-helpers/fast-core-tools.js"; import { getCallGatewayMock, getSessionsSpawnTool, setSessionsSpawnConfigOverride, } from "./openclaw-tools.subagents.sessions-spawn.test-harness.js"; import { listSubagentRunsForRequester, resetSubagentRegistryForTests, } from "./subagent-registry.js"; describe("sessions_spawn requesterOrigin threading", () => { const spawnAndReadRequesterRun = async (opts?: { agentThreadId?: number }) => { const tool = await getSessionsSpawnTool({ agentSessionKey: "main", agentChannel: "telegram", agentTo: "telegram:123", ...(opts?.agentThreadId === undefined ? {} : { agentThreadId: opts.agentThreadId }), }); const result = await tool.execute("call", { task: "do thing", runTimeoutSeconds: 1, }); expect(result.details).toMatchObject({ status: "accepted", runId: "run-1" }); const runs = listSubagentRunsForRequester("main"); expect(runs).toHaveLength(1); return runs[0]; }; beforeEach(() => { const callGatewayMock = getCallGatewayMock(); resetSubagentRegistryForTests(); callGatewayMock.mockClear(); setSessionsSpawnConfigOverride({ session: { mainKey: "main", scope: "per-sender", }, }); callGatewayMock.mockImplementation(async (opts: unknown) => { const req = opts as { method?: string }; if (req.method === "agent") { return { runId: "run-1", status: "accepted", acceptedAt: 1 }; } // Prevent background announce flow by returning a non-terminal status. if (req.method === "agent.wait") { return { runId: "run-1", status: "running" }; } return {}; }); }); it("captures threadId in requesterOrigin", async () => { const run = await spawnAndReadRequesterRun({ agentThreadId: 42 }); expect(run?.requesterOrigin).toMatchObject({ channel: "telegram", to: "telegram:123", threadId: 42, }); }); it("stores requesterOrigin without threadId when none is provided", async () => { const run = await spawnAndReadRequesterRun(); expect(run?.requesterOrigin?.threadId).toBeUndefined(); }); });