mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:20:42 +00:00
test: share subagent action fixtures
This commit is contained in:
@@ -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)");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user