diff --git a/src/agents/clawdbot-tools.agents.test.ts b/src/agents/clawdbot-tools.agents.test.ts index efb525007..a53b6a152 100644 --- a/src/agents/clawdbot-tools.agents.test.ts +++ b/src/agents/clawdbot-tools.agents.test.ts @@ -120,4 +120,35 @@ describe("agents_list", () => { "research", ]); }); + + it("marks allowlisted-but-unconfigured agents", async () => { + configOverride = { + session: { + mainKey: "main", + scope: "per-sender", + }, + routing: { + agents: { + main: { + subagents: { + allowAgents: ["research"], + }, + }, + }, + }, + }; + + const tool = createClawdbotTools({ + agentSessionKey: "main", + }).find((candidate) => candidate.name === "agents_list"); + if (!tool) throw new Error("missing agents_list tool"); + + const result = await tool.execute("call4", {}); + const agents = (result.details as { + agents?: Array<{ id: string; configured: boolean }>; + }).agents; + expect(agents?.map((agent) => agent.id)).toEqual(["main", "research"]); + const research = agents?.find((agent) => agent.id === "research"); + expect(research?.configured).toBe(false); + }); }); diff --git a/src/agents/clawdbot-tools.subagents.test.ts b/src/agents/clawdbot-tools.subagents.test.ts index 8a26e92d1..fa4020227 100644 --- a/src/agents/clawdbot-tools.subagents.test.ts +++ b/src/agents/clawdbot-tools.subagents.test.ts @@ -408,6 +408,57 @@ describe("subagents", () => { expect(childSessionKey?.startsWith("agent:beta:subagent:")).toBe(true); }); + it("sessions_spawn normalizes allowlisted agent ids", async () => { + resetSubagentRegistryForTests(); + callGatewayMock.mockReset(); + configOverride = { + session: { + mainKey: "main", + scope: "per-sender", + }, + routing: { + agents: { + main: { + subagents: { + allowAgents: ["Research"], + }, + }, + }, + }, + }; + + let childSessionKey: string | undefined; + callGatewayMock.mockImplementation(async (opts: unknown) => { + const request = opts as { method?: string; params?: unknown }; + if (request.method === "agent") { + const params = request.params as { sessionKey?: string } | undefined; + childSessionKey = params?.sessionKey; + return { runId: "run-1", status: "accepted", acceptedAt: 5200 }; + } + if (request.method === "agent.wait") { + return { status: "timeout" }; + } + return {}; + }); + + const tool = createClawdbotTools({ + agentSessionKey: "main", + agentProvider: "whatsapp", + }).find((candidate) => candidate.name === "sessions_spawn"); + if (!tool) throw new Error("missing sessions_spawn tool"); + + const result = await tool.execute("call10", { + task: "do thing", + agentId: "research", + }); + + expect(result.details).toMatchObject({ + status: "accepted", + runId: "run-1", + }); + expect(childSessionKey?.startsWith("agent:research:subagent:")).toBe(true); + }); + it("sessions_spawn forbids cross-agent spawning when not allowed", async () => { resetSubagentRegistryForTests(); callGatewayMock.mockReset();