From ff5904f5f4a5303181869b540b49eee34c5e4925 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 19 Apr 2026 02:46:08 +0100 Subject: [PATCH] test: share subagent action fixtures --- .../commands-subagents/action-agents.test.ts | 272 ++++++++---------- 1 file changed, 112 insertions(+), 160 deletions(-) diff --git a/src/auto-reply/reply/commands-subagents/action-agents.test.ts b/src/auto-reply/reply/commands-subagents/action-agents.test.ts index 0f52e4a0098..718ce2630ba 100644 --- a/src/auto-reply/reply/commands-subagents/action-agents.test.ts +++ b/src/auto-reply/reply/commands-subagents/action-agents.test.ts @@ -2,6 +2,7 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const THREAD_CHANNEL = "thread-chat"; const ROOM_CHANNEL = "room-chat"; +const MAIN_SESSION_KEY = "agent:main:main"; const { listBySessionMock, getChannelPluginMock, normalizeChannelIdMock } = vi.hoisted(() => ({ listBySessionMock: vi.fn(), @@ -33,6 +34,66 @@ vi.mock("../../../channels/plugins/index.js", () => ({ let handleSubagentsAgentsAction: typeof import("./action-agents.js").handleSubagentsAgentsAction; +function activeBinding(params: { + bindingId: string; + channel: string; + conversationId: string; + targetSessionKey: string; +}) { + return { + bindingId: params.bindingId, + targetSessionKey: params.targetSessionKey, + targetKind: "subagent", + conversation: { + channel: params.channel, + accountId: "default", + conversationId: params.conversationId, + }, + status: "active", + boundAt: Date.now() - 20_000, + }; +} + +function subagentRun(params: { + childSessionKey: string; + endedAgoMs?: number; + runId: string; + startedAgoMs?: number; + task: string; +}) { + const startedAgoMs = params.startedAgoMs ?? 20_000; + return { + runId: params.runId, + childSessionKey: params.childSessionKey, + requesterSessionKey: MAIN_SESSION_KEY, + requesterDisplayKey: "main", + task: params.task, + cleanup: "keep", + createdAt: Date.now() - startedAgoMs, + startedAt: Date.now() - startedAgoMs, + ...(params.endedAgoMs === undefined + ? {} + : { endedAt: Date.now() - params.endedAgoMs, outcome: { status: "ok" } }), + }; +} + +function agentsActionInput(channel: string, runs: ReturnType[]) { + return { + params: { + ctx: { + Provider: channel, + Surface: channel, + }, + command: { + channel, + }, + }, + requesterKey: MAIN_SESSION_KEY, + runs, + restTokens: [], + } as never; +} + describe("handleSubagentsAgentsAction", () => { beforeAll(async () => { ({ handleSubagentsAgentsAction } = await import("./action-agents.js")); @@ -49,59 +110,32 @@ describe("handleSubagentsAgentsAction", () => { listBySessionMock.mockImplementation((sessionKey: string) => sessionKey === childSessionKey ? [ - { + activeBinding({ bindingId: "binding-1", + channel: THREAD_CHANNEL, + conversationId: "thread-1", targetSessionKey: childSessionKey, - targetKind: "subagent", - conversation: { - channel: THREAD_CHANNEL, - accountId: "default", - conversationId: "thread-1", - }, - status: "active", - boundAt: Date.now() - 20_000, - }, + }), ] : [], ); - const result = handleSubagentsAgentsAction({ - params: { - ctx: { - Provider: THREAD_CHANNEL, - Surface: THREAD_CHANNEL, - }, - command: { - channel: THREAD_CHANNEL, - }, - }, - requesterKey: "agent:main:main", - runs: [ - { + const result = handleSubagentsAgentsAction( + agentsActionInput(THREAD_CHANNEL, [ + subagentRun({ runId: "run-current", childSessionKey, - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "current worker label", - cleanup: "keep", - createdAt: Date.now() - 10_000, - startedAt: Date.now() - 10_000, - }, - { + startedAgoMs: 10_000, + }), + subagentRun({ runId: "run-stale", childSessionKey, - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "stale worker label", - cleanup: "keep", - createdAt: Date.now() - 20_000, - startedAt: Date.now() - 20_000, - endedAt: Date.now() - 15_000, - outcome: { status: "ok" }, - }, - ], - restTokens: [], - } as never); + endedAgoMs: 15_000, + }), + ]), + ); expect(result.reply?.text).toContain("current worker label"); expect(result.reply?.text).not.toContain("stale worker label"); @@ -113,61 +147,33 @@ describe("handleSubagentsAgentsAction", () => { listBySessionMock.mockImplementation((sessionKey: string) => sessionKey === visibleSessionKey ? [ - { + activeBinding({ bindingId: "binding-visible", + channel: THREAD_CHANNEL, + conversationId: "thread-visible", targetSessionKey: visibleSessionKey, - targetKind: "subagent", - conversation: { - channel: THREAD_CHANNEL, - accountId: "default", - conversationId: "thread-visible", - }, - status: "active", - boundAt: Date.now() - 20_000, - }, + }), ] : [], ); - const result = handleSubagentsAgentsAction({ - params: { - ctx: { - Provider: THREAD_CHANNEL, - Surface: THREAD_CHANNEL, - }, - command: { - channel: THREAD_CHANNEL, - }, - }, - requesterKey: "agent:main:main", - runs: [ - { + const result = handleSubagentsAgentsAction( + agentsActionInput(THREAD_CHANNEL, [ + subagentRun({ runId: "run-hidden-recent", childSessionKey: hiddenSessionKey, - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "hidden recent worker", - cleanup: "keep", - createdAt: Date.now() - 10_000, - startedAt: Date.now() - 10_000, - endedAt: Date.now() - 5_000, - outcome: { status: "ok" }, - }, - { + startedAgoMs: 10_000, + endedAgoMs: 5_000, + }), + subagentRun({ runId: "run-visible-bound", childSessionKey: visibleSessionKey, - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "visible bound worker", - cleanup: "keep", - createdAt: Date.now() - 20_000, - startedAt: Date.now() - 20_000, - endedAt: Date.now() - 15_000, - outcome: { status: "ok" }, - }, - ], - restTokens: [], - } as never); + endedAgoMs: 15_000, + }), + ]), + ); expect(result.reply?.text).toContain("2. visible bound worker"); expect(result.reply?.text).not.toContain("1. visible bound worker"); @@ -177,31 +183,15 @@ describe("handleSubagentsAgentsAction", () => { it("shows room-channel runs as unbound when the plugin supports conversation bindings", () => { listBySessionMock.mockReturnValue([]); - const result = handleSubagentsAgentsAction({ - params: { - ctx: { - Provider: ROOM_CHANNEL, - Surface: ROOM_CHANNEL, - }, - command: { - channel: ROOM_CHANNEL, - }, - }, - requesterKey: "agent:main:main", - runs: [ - { + const result = handleSubagentsAgentsAction( + agentsActionInput(ROOM_CHANNEL, [ + subagentRun({ runId: "run-room-worker", childSessionKey: "agent:main:subagent:room-worker", - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "room worker", - cleanup: "keep", - createdAt: Date.now() - 20_000, - startedAt: Date.now() - 20_000, - }, - ], - restTokens: [], - } as never); + }), + ]), + ); expect(result.reply?.text).toContain("room worker (unbound)"); expect(result.reply?.text).not.toContain("bindings unavailable"); @@ -212,47 +202,25 @@ describe("handleSubagentsAgentsAction", () => { listBySessionMock.mockImplementation((sessionKey: string) => sessionKey === childSessionKey ? [ - { + activeBinding({ bindingId: "binding-room", + channel: ROOM_CHANNEL, + conversationId: "room-thread-1", targetSessionKey: childSessionKey, - targetKind: "subagent", - conversation: { - channel: ROOM_CHANNEL, - accountId: "default", - conversationId: "room-thread-1", - }, - status: "active", - boundAt: Date.now() - 20_000, - }, + }), ] : [], ); - const result = handleSubagentsAgentsAction({ - params: { - ctx: { - Provider: ROOM_CHANNEL, - Surface: ROOM_CHANNEL, - }, - command: { - channel: ROOM_CHANNEL, - }, - }, - requesterKey: "agent:main:main", - runs: [ - { + const result = handleSubagentsAgentsAction( + agentsActionInput(ROOM_CHANNEL, [ + subagentRun({ runId: "run-room-bound", childSessionKey, - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "room bound worker", - cleanup: "keep", - createdAt: Date.now() - 20_000, - startedAt: Date.now() - 20_000, - }, - ], - restTokens: [], - } as never); + }), + ]), + ); expect(result.reply?.text).toContain("room bound worker (binding:room-thread-1)"); }); @@ -261,31 +229,15 @@ describe("handleSubagentsAgentsAction", () => { getChannelPluginMock.mockReturnValueOnce(null); listBySessionMock.mockReturnValue([]); - const result = handleSubagentsAgentsAction({ - params: { - ctx: { - Provider: "irc", - Surface: "irc", - }, - command: { - channel: "irc", - }, - }, - requesterKey: "agent:main:main", - runs: [ - { + const result = handleSubagentsAgentsAction( + agentsActionInput("irc", [ + subagentRun({ runId: "run-irc-worker", childSessionKey: "agent:main:subagent:irc-worker", - requesterSessionKey: "agent:main:main", - requesterDisplayKey: "main", task: "irc worker", - cleanup: "keep", - createdAt: Date.now() - 20_000, - startedAt: Date.now() - 20_000, - }, - ], - restTokens: [], - } as never); + }), + ]), + ); expect(result.reply?.text).toContain("irc worker (bindings unavailable)"); });