test: share subagent action fixtures

This commit is contained in:
Peter Steinberger
2026-04-19 02:46:08 +01:00
parent faae8e08b3
commit ff5904f5f4

View File

@@ -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<typeof subagentRun>[]) {
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)");
});