diff --git a/src/agents/tools/sessions-announce-target.e2e.test.ts b/src/agents/tools/sessions-announce-target.e2e.test.ts
deleted file mode 100644
index fe28be7dff9..00000000000
--- a/src/agents/tools/sessions-announce-target.e2e.test.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import { beforeEach, describe, expect, it, vi } from "vitest";
-import { createTestRegistry } from "../../test-utils/channel-plugins.js";
-
-const callGatewayMock = vi.fn();
-vi.mock("../../gateway/call.js", () => ({
- callGateway: (opts: unknown) => callGatewayMock(opts),
-}));
-
-const loadResolveAnnounceTarget = async () => await import("./sessions-announce-target.js");
-
-const installRegistry = async () => {
- const { setActivePluginRegistry } = await import("../../plugins/runtime.js");
- setActivePluginRegistry(
- createTestRegistry([
- {
- pluginId: "discord",
- source: "test",
- plugin: {
- id: "discord",
- meta: {
- id: "discord",
- label: "Discord",
- selectionLabel: "Discord",
- docsPath: "/channels/discord",
- blurb: "Discord test stub.",
- },
- capabilities: { chatTypes: ["direct", "channel", "thread"] },
- config: {
- listAccountIds: () => ["default"],
- resolveAccount: () => ({}),
- },
- },
- },
- {
- pluginId: "whatsapp",
- source: "test",
- plugin: {
- id: "whatsapp",
- meta: {
- id: "whatsapp",
- label: "WhatsApp",
- selectionLabel: "WhatsApp",
- docsPath: "/channels/whatsapp",
- blurb: "WhatsApp test stub.",
- preferSessionLookupForAnnounceTarget: true,
- },
- capabilities: { chatTypes: ["direct", "group"] },
- config: {
- listAccountIds: () => ["default"],
- resolveAccount: () => ({}),
- },
- },
- },
- ]),
- );
-};
-
-describe("resolveAnnounceTarget", () => {
- beforeEach(async () => {
- callGatewayMock.mockReset();
- await installRegistry();
- });
-
- it("derives non-WhatsApp announce targets from the session key", async () => {
- const { resolveAnnounceTarget } = await loadResolveAnnounceTarget();
- const target = await resolveAnnounceTarget({
- sessionKey: "agent:main:discord:group:dev",
- displayKey: "agent:main:discord:group:dev",
- });
- expect(target).toEqual({ channel: "discord", to: "channel:dev" });
- expect(callGatewayMock).not.toHaveBeenCalled();
- });
-
- it("hydrates WhatsApp accountId from sessions.list when available", async () => {
- const { resolveAnnounceTarget } = await loadResolveAnnounceTarget();
- callGatewayMock.mockResolvedValueOnce({
- sessions: [
- {
- key: "agent:main:whatsapp:group:123@g.us",
- deliveryContext: {
- channel: "whatsapp",
- to: "123@g.us",
- accountId: "work",
- },
- },
- ],
- });
-
- const target = await resolveAnnounceTarget({
- sessionKey: "agent:main:whatsapp:group:123@g.us",
- displayKey: "agent:main:whatsapp:group:123@g.us",
- });
- expect(target).toEqual({
- channel: "whatsapp",
- to: "123@g.us",
- accountId: "work",
- });
- expect(callGatewayMock).toHaveBeenCalledTimes(1);
- const first = callGatewayMock.mock.calls[0]?.[0] as { method?: string } | undefined;
- expect(first).toBeDefined();
- expect(first?.method).toBe("sessions.list");
- });
-});
diff --git a/src/agents/tools/sessions-helpers.e2e.test.ts b/src/agents/tools/sessions-helpers.e2e.test.ts
deleted file mode 100644
index 887cc1f4670..00000000000
--- a/src/agents/tools/sessions-helpers.e2e.test.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { describe, expect, it } from "vitest";
-import { extractAssistantText, sanitizeTextContent } from "./sessions-helpers.js";
-
-describe("sanitizeTextContent", () => {
- it("strips minimax tool call XML and downgraded markers", () => {
- const input =
- 'Hello payload ' +
- "[Tool Call: foo (ID: 1)] world";
- const result = sanitizeTextContent(input).trim();
- expect(result).toBe("Hello world");
- expect(result).not.toContain("invoke");
- expect(result).not.toContain("Tool Call");
- });
-
- it("strips thinking tags", () => {
- const input = "Before secret after";
- const result = sanitizeTextContent(input).trim();
- expect(result).toBe("Before after");
- });
-});
-
-describe("extractAssistantText", () => {
- it("sanitizes blocks without injecting newlines", () => {
- const message = {
- role: "assistant",
- content: [
- { type: "text", text: "Hi " },
- { type: "text", text: "secretthere" },
- ],
- };
- expect(extractAssistantText(message)).toBe("Hi there");
- });
-
- it("rewrites error-ish assistant text only when the transcript marks it as an error", () => {
- const message = {
- role: "assistant",
- stopReason: "error",
- errorMessage: "500 Internal Server Error",
- content: [{ type: "text", text: "500 Internal Server Error" }],
- };
- expect(extractAssistantText(message)).toBe("HTTP 500: Internal Server Error");
- });
-
- it("keeps normal status text that mentions billing", () => {
- const message = {
- role: "assistant",
- content: [
- {
- type: "text",
- text: "Firebase downgraded us to the free Spark plan. Check whether billing should be re-enabled.",
- },
- ],
- };
- expect(extractAssistantText(message)).toBe(
- "Firebase downgraded us to the free Spark plan. Check whether billing should be re-enabled.",
- );
- });
-});
diff --git a/src/agents/tools/sessions-list-tool.gating.e2e.test.ts b/src/agents/tools/sessions-list-tool.gating.e2e.test.ts
deleted file mode 100644
index 636c2c5a1c3..00000000000
--- a/src/agents/tools/sessions-list-tool.gating.e2e.test.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { beforeEach, describe, expect, it, vi } from "vitest";
-
-const callGatewayMock = vi.fn();
-vi.mock("../../gateway/call.js", () => ({
- callGateway: (opts: unknown) => callGatewayMock(opts),
-}));
-
-vi.mock("../../config/config.js", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- loadConfig: () =>
- ({
- session: { scope: "per-sender", mainKey: "main" },
- tools: { agentToAgent: { enabled: false } },
- }) as never,
- };
-});
-
-import { createSessionsListTool } from "./sessions-list-tool.js";
-
-describe("sessions_list gating", () => {
- beforeEach(() => {
- callGatewayMock.mockReset();
- callGatewayMock.mockResolvedValue({
- path: "/tmp/sessions.json",
- sessions: [
- { key: "agent:main:main", kind: "direct" },
- { key: "agent:other:main", kind: "direct" },
- ],
- });
- });
-
- it("filters out other agents when tools.agentToAgent.enabled is false", async () => {
- const tool = createSessionsListTool({ agentSessionKey: "agent:main:main" });
- const result = await tool.execute("call1", {});
- expect(result.details).toMatchObject({
- count: 1,
- sessions: [{ key: "agent:main:main" }],
- });
- });
-});
diff --git a/src/agents/tools/sessions-send-tool.gating.e2e.test.ts b/src/agents/tools/sessions-send-tool.gating.e2e.test.ts
deleted file mode 100644
index 76a242c9898..00000000000
--- a/src/agents/tools/sessions-send-tool.gating.e2e.test.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { beforeEach, describe, expect, it, vi } from "vitest";
-
-const callGatewayMock = vi.fn();
-vi.mock("../../gateway/call.js", () => ({
- callGateway: (opts: unknown) => callGatewayMock(opts),
-}));
-
-vi.mock("../../config/config.js", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- loadConfig: () =>
- ({
- session: { scope: "per-sender", mainKey: "main" },
- tools: { agentToAgent: { enabled: false } },
- }) as never,
- };
-});
-
-import { createSessionsSendTool } from "./sessions-send-tool.js";
-
-describe("sessions_send gating", () => {
- beforeEach(() => {
- callGatewayMock.mockReset();
- });
-
- it("blocks cross-agent sends when tools.agentToAgent.enabled is false", async () => {
- const tool = createSessionsSendTool({
- agentSessionKey: "agent:main:main",
- agentChannel: "whatsapp",
- });
-
- const result = await tool.execute("call1", {
- sessionKey: "agent:other:main",
- message: "hi",
- timeoutSeconds: 0,
- });
-
- expect(callGatewayMock).not.toHaveBeenCalled();
- expect(result.details).toMatchObject({ status: "forbidden" });
- });
-});
diff --git a/src/agents/tools/sessions.e2e.test.ts b/src/agents/tools/sessions.e2e.test.ts
new file mode 100644
index 00000000000..f94be78d57f
--- /dev/null
+++ b/src/agents/tools/sessions.e2e.test.ts
@@ -0,0 +1,219 @@
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import { createTestRegistry } from "../../test-utils/channel-plugins.js";
+import { extractAssistantText, sanitizeTextContent } from "./sessions-helpers.js";
+
+const callGatewayMock = vi.fn();
+vi.mock("../../gateway/call.js", () => ({
+ callGateway: (opts: unknown) => callGatewayMock(opts),
+}));
+
+vi.mock("../../config/config.js", async (importOriginal) => {
+ const actual = await importOriginal();
+ return {
+ ...actual,
+ loadConfig: () =>
+ ({
+ session: { scope: "per-sender", mainKey: "main" },
+ tools: { agentToAgent: { enabled: false } },
+ }) as never,
+ };
+});
+
+import { createSessionsListTool } from "./sessions-list-tool.js";
+import { createSessionsSendTool } from "./sessions-send-tool.js";
+
+const loadResolveAnnounceTarget = async () => await import("./sessions-announce-target.js");
+
+const installRegistry = async () => {
+ const { setActivePluginRegistry } = await import("../../plugins/runtime.js");
+ setActivePluginRegistry(
+ createTestRegistry([
+ {
+ pluginId: "discord",
+ source: "test",
+ plugin: {
+ id: "discord",
+ meta: {
+ id: "discord",
+ label: "Discord",
+ selectionLabel: "Discord",
+ docsPath: "/channels/discord",
+ blurb: "Discord test stub.",
+ },
+ capabilities: { chatTypes: ["direct", "channel", "thread"] },
+ config: {
+ listAccountIds: () => ["default"],
+ resolveAccount: () => ({}),
+ },
+ },
+ },
+ {
+ pluginId: "whatsapp",
+ source: "test",
+ plugin: {
+ id: "whatsapp",
+ meta: {
+ id: "whatsapp",
+ label: "WhatsApp",
+ selectionLabel: "WhatsApp",
+ docsPath: "/channels/whatsapp",
+ blurb: "WhatsApp test stub.",
+ preferSessionLookupForAnnounceTarget: true,
+ },
+ capabilities: { chatTypes: ["direct", "group"] },
+ config: {
+ listAccountIds: () => ["default"],
+ resolveAccount: () => ({}),
+ },
+ },
+ },
+ ]),
+ );
+};
+
+describe("sanitizeTextContent", () => {
+ it("strips minimax tool call XML and downgraded markers", () => {
+ const input =
+ 'Hello payload ' +
+ "[Tool Call: foo (ID: 1)] world";
+ const result = sanitizeTextContent(input).trim();
+ expect(result).toBe("Hello world");
+ expect(result).not.toContain("invoke");
+ expect(result).not.toContain("Tool Call");
+ });
+
+ it("strips thinking tags", () => {
+ const input = "Before secret after";
+ const result = sanitizeTextContent(input).trim();
+ expect(result).toBe("Before after");
+ });
+});
+
+describe("extractAssistantText", () => {
+ it("sanitizes blocks without injecting newlines", () => {
+ const message = {
+ role: "assistant",
+ content: [
+ { type: "text", text: "Hi " },
+ { type: "text", text: "secretthere" },
+ ],
+ };
+ expect(extractAssistantText(message)).toBe("Hi there");
+ });
+
+ it("rewrites error-ish assistant text only when the transcript marks it as an error", () => {
+ const message = {
+ role: "assistant",
+ stopReason: "error",
+ errorMessage: "500 Internal Server Error",
+ content: [{ type: "text", text: "500 Internal Server Error" }],
+ };
+ expect(extractAssistantText(message)).toBe("HTTP 500: Internal Server Error");
+ });
+
+ it("keeps normal status text that mentions billing", () => {
+ const message = {
+ role: "assistant",
+ content: [
+ {
+ type: "text",
+ text: "Firebase downgraded us to the free Spark plan. Check whether billing should be re-enabled.",
+ },
+ ],
+ };
+ expect(extractAssistantText(message)).toBe(
+ "Firebase downgraded us to the free Spark plan. Check whether billing should be re-enabled.",
+ );
+ });
+});
+
+describe("resolveAnnounceTarget", () => {
+ beforeEach(async () => {
+ callGatewayMock.mockReset();
+ await installRegistry();
+ });
+
+ it("derives non-WhatsApp announce targets from the session key", async () => {
+ const { resolveAnnounceTarget } = await loadResolveAnnounceTarget();
+ const target = await resolveAnnounceTarget({
+ sessionKey: "agent:main:discord:group:dev",
+ displayKey: "agent:main:discord:group:dev",
+ });
+ expect(target).toEqual({ channel: "discord", to: "channel:dev" });
+ expect(callGatewayMock).not.toHaveBeenCalled();
+ });
+
+ it("hydrates WhatsApp accountId from sessions.list when available", async () => {
+ const { resolveAnnounceTarget } = await loadResolveAnnounceTarget();
+ callGatewayMock.mockResolvedValueOnce({
+ sessions: [
+ {
+ key: "agent:main:whatsapp:group:123@g.us",
+ deliveryContext: {
+ channel: "whatsapp",
+ to: "123@g.us",
+ accountId: "work",
+ },
+ },
+ ],
+ });
+
+ const target = await resolveAnnounceTarget({
+ sessionKey: "agent:main:whatsapp:group:123@g.us",
+ displayKey: "agent:main:whatsapp:group:123@g.us",
+ });
+ expect(target).toEqual({
+ channel: "whatsapp",
+ to: "123@g.us",
+ accountId: "work",
+ });
+ expect(callGatewayMock).toHaveBeenCalledTimes(1);
+ const first = callGatewayMock.mock.calls[0]?.[0] as { method?: string } | undefined;
+ expect(first).toBeDefined();
+ expect(first?.method).toBe("sessions.list");
+ });
+});
+
+describe("sessions_list gating", () => {
+ beforeEach(() => {
+ callGatewayMock.mockReset();
+ callGatewayMock.mockResolvedValue({
+ path: "/tmp/sessions.json",
+ sessions: [
+ { key: "agent:main:main", kind: "direct" },
+ { key: "agent:other:main", kind: "direct" },
+ ],
+ });
+ });
+
+ it("filters out other agents when tools.agentToAgent.enabled is false", async () => {
+ const tool = createSessionsListTool({ agentSessionKey: "agent:main:main" });
+ const result = await tool.execute("call1", {});
+ expect(result.details).toMatchObject({
+ count: 1,
+ sessions: [{ key: "agent:main:main" }],
+ });
+ });
+});
+
+describe("sessions_send gating", () => {
+ beforeEach(() => {
+ callGatewayMock.mockReset();
+ });
+
+ it("blocks cross-agent sends when tools.agentToAgent.enabled is false", async () => {
+ const tool = createSessionsSendTool({
+ agentSessionKey: "agent:main:main",
+ agentChannel: "whatsapp",
+ });
+
+ const result = await tool.execute("call1", {
+ sessionKey: "agent:other:main",
+ message: "hi",
+ timeoutSeconds: 0,
+ });
+
+ expect(callGatewayMock).not.toHaveBeenCalled();
+ expect(result.details).toMatchObject({ status: "forbidden" });
+ });
+});