190 lines
6.6 KiB
TypeScript
190 lines
6.6 KiB
TypeScript
import test from "node:test";
|
||
import assert from "node:assert/strict";
|
||
import os from "node:os";
|
||
import path from "node:path";
|
||
import { mkdtemp, rm } from "node:fs/promises";
|
||
|
||
let runtimeRoot = "";
|
||
let appendProjectMessages: (typeof import("../src/lib/boss-data"))["appendProjectMessages"];
|
||
let completeMasterAgentTask: (typeof import("../src/lib/boss-data"))["completeMasterAgentTask"];
|
||
let queueMasterAgentTask: (typeof import("../src/lib/boss-data"))["queueMasterAgentTask"];
|
||
let readState: (typeof import("../src/lib/boss-data"))["readState"];
|
||
|
||
async function setup() {
|
||
if (runtimeRoot) return;
|
||
|
||
runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-control-summary-task-"));
|
||
process.env.BOSS_RUNTIME_ROOT = runtimeRoot;
|
||
process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json");
|
||
|
||
const data = await import("../src/lib/boss-data.ts");
|
||
appendProjectMessages = data.appendProjectMessages;
|
||
completeMasterAgentTask = data.completeMasterAgentTask;
|
||
queueMasterAgentTask = data.queueMasterAgentTask;
|
||
readState = data.readState;
|
||
}
|
||
|
||
test.after(async () => {
|
||
if (runtimeRoot) {
|
||
await rm(runtimeRoot, { recursive: true, force: true });
|
||
}
|
||
});
|
||
|
||
test("completed browser control task mirrors a control summary message into master-agent conversation", async () => {
|
||
await setup();
|
||
|
||
const [requestMessage] = await appendProjectMessages({
|
||
projectId: "master-agent",
|
||
messages: [
|
||
{
|
||
senderLabel: "Boss 超级管理员",
|
||
body: "打开 https://example.com 看一下首页",
|
||
kind: "text",
|
||
},
|
||
],
|
||
});
|
||
|
||
const task = await queueMasterAgentTask({
|
||
projectId: "master-agent",
|
||
taskType: "browser_control",
|
||
requestMessageId: requestMessage.id,
|
||
requestText: "打开 https://example.com 看一下首页",
|
||
requestedBy: "Boss 超级管理员",
|
||
requestedByAccount: "krisolo",
|
||
deviceId: "mac-studio",
|
||
accountId: "openai-master",
|
||
accountLabel: "gpt-5.4-mini",
|
||
intentCategory: "browser_control",
|
||
runtimeKind: "browser-automation-runtime",
|
||
riskLevel: "medium",
|
||
confirmationPolicy: "light_confirm",
|
||
requiresUserConfirmation: true,
|
||
confirmationScopeKey: "mac-studio:master-agent",
|
||
});
|
||
|
||
await completeMasterAgentTask({
|
||
taskId: task.taskId,
|
||
deviceId: "mac-studio",
|
||
status: "completed",
|
||
replyBody: "浏览器控制已完成:打开 https://example.com 看一下首页",
|
||
targetUrl: "https://example.com",
|
||
});
|
||
|
||
const state = await readState();
|
||
const project = state.projects.find((item) => item.id === "master-agent");
|
||
const controlSummary = project?.messages.find((message) =>
|
||
message.kind === "control_summary" &&
|
||
message.body === "浏览器控制已完成:打开 https://example.com 看一下首页"
|
||
);
|
||
|
||
assert.ok(controlSummary);
|
||
assert.equal(controlSummary?.sender, "master");
|
||
assert.equal(controlSummary?.senderLabel, "主 Agent · gpt-5.4-mini");
|
||
assert.equal(controlSummary?.body, "浏览器控制已完成:打开 https://example.com 看一下首页");
|
||
assert.equal((controlSummary as { controlTarget?: string }).controlTarget, "https://example.com");
|
||
});
|
||
|
||
test("completed desktop control task mirrors a control summary message into master-agent conversation", async () => {
|
||
await setup();
|
||
|
||
const [requestMessage] = await appendProjectMessages({
|
||
projectId: "master-agent",
|
||
messages: [
|
||
{
|
||
senderLabel: "Boss 超级管理员",
|
||
body: "打开微信并准备切到聊天窗口",
|
||
kind: "text",
|
||
},
|
||
],
|
||
});
|
||
|
||
const task = await queueMasterAgentTask({
|
||
projectId: "master-agent",
|
||
taskType: "desktop_control",
|
||
requestMessageId: requestMessage.id,
|
||
requestText: "打开微信并准备切到聊天窗口",
|
||
requestedBy: "Boss 超级管理员",
|
||
requestedByAccount: "krisolo",
|
||
deviceId: "mac-studio",
|
||
accountId: "openai-master",
|
||
accountLabel: "gpt-5.4-mini",
|
||
intentCategory: "desktop_control",
|
||
runtimeKind: "computer-use-runtime",
|
||
riskLevel: "medium",
|
||
confirmationPolicy: "light_confirm",
|
||
requiresUserConfirmation: true,
|
||
confirmationScopeKey: "mac-studio:master-agent",
|
||
});
|
||
|
||
await completeMasterAgentTask({
|
||
taskId: task.taskId,
|
||
deviceId: "mac-studio",
|
||
status: "completed",
|
||
replyBody: "桌面控制已完成:打开微信并准备切到聊天窗口",
|
||
targetApp: "微信",
|
||
});
|
||
|
||
const state = await readState();
|
||
const project = state.projects.find((item) => item.id === "master-agent");
|
||
const controlSummary = project?.messages.find((message) =>
|
||
message.kind === "control_summary" &&
|
||
message.body === "桌面控制已完成:打开微信并准备切到聊天窗口"
|
||
);
|
||
|
||
assert.ok(controlSummary);
|
||
assert.equal(controlSummary?.sender, "master");
|
||
assert.equal(controlSummary?.senderLabel, "主 Agent · gpt-5.4-mini");
|
||
assert.equal(controlSummary?.body, "桌面控制已完成:打开微信并准备切到聊天窗口");
|
||
assert.equal((controlSummary as { controlTarget?: string }).controlTarget, "微信");
|
||
});
|
||
|
||
test("failed browser control task uses demo-safe remote control wording", async () => {
|
||
await setup();
|
||
|
||
const [requestMessage] = await appendProjectMessages({
|
||
projectId: "master-agent",
|
||
messages: [
|
||
{
|
||
senderLabel: "Boss 超级管理员",
|
||
body: "打开 Chrome 访问 example.com",
|
||
kind: "text",
|
||
},
|
||
],
|
||
});
|
||
|
||
const task = await queueMasterAgentTask({
|
||
projectId: "master-agent",
|
||
taskType: "browser_control",
|
||
requestMessageId: requestMessage.id,
|
||
requestText: "打开 Chrome 访问 example.com",
|
||
requestedBy: "Boss 超级管理员",
|
||
requestedByAccount: "krisolo",
|
||
deviceId: "mac-studio",
|
||
accountId: "openai-master",
|
||
accountLabel: "gpt-5.4-mini",
|
||
intentCategory: "browser_control",
|
||
runtimeKind: "browser-automation-runtime",
|
||
riskLevel: "medium",
|
||
confirmationPolicy: "light_confirm",
|
||
requiresUserConfirmation: true,
|
||
confirmationScopeKey: "mac-studio:master-agent",
|
||
});
|
||
|
||
await completeMasterAgentTask({
|
||
taskId: task.taskId,
|
||
deviceId: "mac-studio",
|
||
status: "failed",
|
||
errorMessage: "Master Codex Node 执行失败:connect timeout",
|
||
});
|
||
|
||
const state = await readState();
|
||
const project = state.projects.find((item) => item.id === "master-agent");
|
||
const visibleFailure = project?.messages.at(-1);
|
||
|
||
assert.equal(visibleFailure?.sender, "master");
|
||
assert.equal(visibleFailure?.senderLabel, "主 Agent · gpt-5.4-mini");
|
||
assert.match(visibleFailure?.body ?? "", /远程控制未完成/);
|
||
assert.match(visibleFailure?.body ?? "", /目标电脑响应超时/);
|
||
assert.doesNotMatch(visibleFailure?.body ?? "", /Master Codex Node|local_agent|执行失败/);
|
||
});
|