Files
boss/tests/master-agent-message-queue.test.ts

1221 lines
43 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import os from "node:os";
import path from "node:path";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { NextRequest } from "next/server";
let runtimeRoot = "";
let POST: (typeof import("../src/app/api/v1/projects/[projectId]/messages/route"))["POST"];
let saveAiAccount: (typeof import("../src/lib/boss-data"))["saveAiAccount"];
let updateProjectAgentControls: (typeof import("../src/lib/boss-data"))["updateProjectAgentControls"];
let updateAiAccountHealth: (typeof import("../src/lib/boss-data"))["updateAiAccountHealth"];
let updateDevice: (typeof import("../src/lib/boss-data"))["updateDevice"];
let readState: (typeof import("../src/lib/boss-data"))["readState"];
let createAuthSession: (typeof import("../src/lib/boss-data"))["createAuthSession"];
let appendProjectMessages: (typeof import("../src/lib/boss-data"))["appendProjectMessages"];
let AUTH_SESSION_COOKIE = "";
async function setup() {
if (runtimeRoot) {
return;
}
runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-master-agent-message-queue-"));
process.env.BOSS_RUNTIME_ROOT = runtimeRoot;
process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json");
const [messageRoute, data, auth] = await Promise.all([
import("../src/app/api/v1/projects/[projectId]/messages/route.ts"),
import("../src/lib/boss-data.ts"),
import("../src/lib/boss-auth.ts"),
]);
POST = messageRoute.POST;
saveAiAccount = data.saveAiAccount;
updateProjectAgentControls = data.updateProjectAgentControls;
updateAiAccountHealth = data.updateAiAccountHealth;
updateDevice = data.updateDevice;
readState = data.readState;
createAuthSession = data.createAuthSession;
appendProjectMessages = data.appendProjectMessages;
AUTH_SESSION_COOKIE = auth.AUTH_SESSION_COOKIE;
}
async function createAuthedRequest(projectId: string, body: unknown) {
const session = await createAuthSession({
account: "krisolo",
role: "highest_admin",
displayName: "Boss 超级管理员",
loginMethod: "password",
});
return new NextRequest(`http://127.0.0.1:3000/api/v1/projects/${projectId}/messages`, {
method: "POST",
headers: {
"content-type": "application/json",
cookie: `${AUTH_SESSION_COOKIE}=${session.sessionToken}`,
},
body: JSON.stringify(body),
});
}
async function waitFor(predicate: () => Promise<boolean>, timeoutMs = 5_000) {
const startedAt = Date.now();
while (Date.now() - startedAt < timeoutMs) {
if (await predicate()) {
return;
}
await new Promise((resolve) => setTimeout(resolve, 50));
}
throw new Error("waitFor timed out");
}
test.after(async () => {
if (runtimeRoot) {
await rm(runtimeRoot, { recursive: true, force: true });
}
});
test.beforeEach(async () => {
await setup();
await rm(runtimeRoot, { recursive: true, force: true });
await mkdir(runtimeRoot, { recursive: true });
});
test("appendProjectMessages 可以一次写入用户消息和主 Agent 本地快反回复", async () => {
const messages = await appendProjectMessages({
projectId: "master-agent",
messages: [
{
senderLabel: "Boss 超级管理员",
body: "你现在是什么模型",
kind: "text",
},
{
sender: "master",
senderLabel: "主 Agent · gpt-5.4-mini",
body: "当前主 Agent 是快速反应模式。",
kind: "text",
},
],
});
assert.equal(messages.length, 2);
assert.equal(messages[0]?.sender, "user");
assert.equal(messages[1]?.sender, "master");
const state = await readState();
const masterProject = state.projects.find((project) => project.id === "master-agent");
assert.equal(
masterProject?.messages.find((message) => message.id === messages[0]?.id)?.body,
"你现在是什么模型",
);
assert.equal(
masterProject?.messages.find((message) => message.id === messages[1]?.id)?.body,
"当前主 Agent 是快速反应模式。",
);
});
test("POST /api/v1/projects/master-agent/messages 快速返回队列态并在异步实际回复时继承当前会话覆盖", async () => {
await saveAiAccount({
accountId: "openai-master-agent-queue",
label: "API 容灾",
role: "api_fallback",
provider: "openai_api",
displayName: "OpenAI API 队列测试",
model: "gpt-5.4",
apiKey: "sk-test-openai-queue",
enabled: true,
setActive: true,
loginStatusNote: "用于 master-agent 队列测试。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-4.1-mini",
reasoningEffortOverride: "high",
});
const fetchCalls: Array<{ url: string; body: unknown }> = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (input, init) => {
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body ?? null;
fetchCalls.push({ url: String(input), body });
return new Response(JSON.stringify({ output_text: "已切到异步队列回复。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-queue",
},
});
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请同步 master-agent 当前阻塞点",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed";
masterReply?: { accountId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReply?.accountId, "openai-master-agent-queue");
assert.equal(payload.masterReplyState, "queued");
assert.ok(payload.task, "expected master-agent message to return a task envelope");
assert.equal(payload.task?.taskType, "conversation_reply");
assert.equal(payload.task?.status, "queued");
assert.ok(payload.task?.taskId, "expected a stable taskId in the response");
await waitFor(async () => {
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
return task?.status === "completed";
});
const nextState = await readState();
const task = nextState.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.ok(task, "expected the queued task to remain in state");
assert.equal(task?.status, "completed");
assert.equal(task?.replyBody, "已切到异步队列回复。");
const masterProject = nextState.projects.find((project) => project.id === "master-agent");
const mirroredReply = masterProject?.messages.at(-1);
assert.ok(mirroredReply, "expected the async reply to be written back to the master-agent ledger");
assert.match(mirroredReply?.body ?? "", /已切到异步队列回复/);
assert.equal(masterProject?.unreadCount, 1);
assert.equal(fetchCalls.length, 1);
assert.equal(fetchCalls[0]?.url, "https://api.openai.com/v1/responses");
const requestBody = fetchCalls[0]?.body as {
model?: string;
reasoning?: { effort?: string };
};
assert.equal(requestBody?.model, "gpt-4.1-mini");
assert.equal(requestBody?.reasoning?.effort, "high");
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages returns browser control task metadata for browser asks", async () => {
await saveAiAccount({
accountId: "openai-master-agent-browser-control",
label: "API 容灾",
role: "api_fallback",
provider: "openai_api",
displayName: "OpenAI API Browser Control",
model: "gpt-5.4-mini",
apiKey: "sk-test-openai-browser-control",
enabled: true,
setActive: true,
loginStatusNote: "用于 browser control 测试。",
});
const response = await POST(
await createAuthedRequest("master-agent", {
body: "打开 Chrome 去后台看一下订单页",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
executionMode?: string;
riskLevel?: string;
requiresConfirmation?: boolean;
};
assert.equal(payload.ok, true);
assert.equal(payload.task?.taskType, "browser_control");
assert.equal(payload.task?.status, "queued");
assert.equal(payload.executionMode, "browser");
assert.equal(payload.riskLevel, "medium");
assert.equal(payload.requiresConfirmation, false);
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.equal(task?.taskType, "browser_control");
assert.equal(task?.intentCategory, "browser_control");
assert.equal(task?.runtimeKind, "browser-automation-runtime");
assert.equal(task?.riskLevel, "medium");
assert.equal(task?.confirmationPolicy, "light_confirm");
assert.equal(task?.requiresUserConfirmation, undefined);
});
test("POST /api/v1/projects/master-agent/messages 在快速反应模式下会对简单问题走同步快路径", async () => {
await saveAiAccount({
accountId: "openai-master-agent-fast-sync",
label: "API 容灾",
role: "api_fallback",
provider: "openai_api",
displayName: "OpenAI API 快反测试",
model: "gpt-5.4",
apiKey: "sk-test-openai-fast-sync",
enabled: true,
setActive: true,
loginStatusNote: "用于 master-agent 快速反应同步路径测试。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-4.1",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-4.1",
deepModelOverride: "gpt-5.4",
});
const fetchCalls: Array<{ url: string; body: unknown }> = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (input, init) => {
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body ?? null;
fetchCalls.push({ url: String(input), body });
return new Response(JSON.stringify({ output_text: "快速反应正常。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-fast-sync",
},
});
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请说:快速反应正常。",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { accountId?: string; requestId?: string; autoEscalated?: boolean } | null;
replyMessage?: { sender?: string; body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.accountId, "openai-master-agent-fast-sync");
assert.equal(payload.masterReply?.requestId, "req-master-agent-fast-sync");
assert.equal(payload.masterReply?.autoEscalated, false);
assert.equal(payload.replyMessage?.sender, "master");
assert.match(payload.replyMessage?.body ?? "", /快速反应正常/);
const nextState = await readState();
const queuedTask = nextState.masterAgentTasks.find((item) => item.requestText === "请说:快速反应正常。");
assert.equal(queuedTask, undefined);
const masterProject = nextState.projects.find((project) => project.id === "master-agent");
const reply = masterProject?.messages.at(-1);
assert.ok(reply, "expected the sync reply to be written back immediately");
assert.match(reply?.body ?? "", /快速反应正常/);
assert.equal(fetchCalls.length, 1);
const requestBody = fetchCalls[0]?.body as {
model?: string;
reasoning?: { effort?: string };
};
assert.equal(requestBody?.model, "gpt-4.1");
assert.equal(requestBody?.reasoning?.effort, "low");
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 对模型状态类问题会本地秒回且不调用模型", async () => {
await saveAiAccount({
accountId: "master-codex-primary-local-status",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "在线主节点。",
});
await saveAiAccount({
accountId: "hyzq-fast-local-status",
label: "环宇快反",
role: "backup",
provider: "hyzq_api",
displayName: "环宇智擎 API",
model: "gpt-5.4-mini",
apiKey: "hyzq-fast-local-status-key",
enabled: true,
setActive: false,
loginStatusNote: "环宇智擎快反账号。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const originalFetch = globalThis.fetch;
let fetchCalled = false;
globalThis.fetch = (async () => {
fetchCalled = true;
throw new Error("model call should not happen for local status replies");
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "你现在是什么模型",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { accountId?: string; requestId?: string; effectiveModel?: string } | null;
replyMessage?: { sender?: string; body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.requestId, "local-fast-path");
assert.equal(payload.masterReply?.effectiveModel, "gpt-5.4-mini");
assert.equal(payload.replyMessage?.sender, "master");
assert.match(payload.replyMessage?.body ?? "", /gpt-5.4-mini/);
assert.equal(fetchCalled, false);
const nextState = await readState();
const reply = nextState.projects.find((project) => project.id === "master-agent")?.messages.at(-1);
assert.match(reply?.body ?? "", /gpt-5.4-mini/);
assert.match(reply?.body ?? "", /快速反应/);
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 本地快反问候会保持职业经理人口吻且不调用模型", async () => {
await saveAiAccount({
accountId: "master-codex-primary-local-greeting",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "在线主节点。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const originalFetch = globalThis.fetch;
let fetchCalled = false;
globalThis.fetch = (async () => {
fetchCalled = true;
throw new Error("model call should not happen for local greeting replies");
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "你好",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { requestId?: string; effectiveModel?: string } | null;
replyMessage?: { body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.requestId, "local-fast-path");
assert.equal(payload.masterReply?.effectiveModel, "gpt-5.4-mini");
assert.match(payload.replyMessage?.body ?? "", /我在/);
assert.match(payload.replyMessage?.body ?? "", /先给你结论/);
assert.match(payload.replyMessage?.body ?? "", /需要我协调线程|需要我直接推进/);
assert.doesNotMatch(payload.replyMessage?.body ?? "", /简单问题我会快速回复/);
assert.equal(fetchCalled, false);
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 英文问候也走本地职业经理人快反", async () => {
await saveAiAccount({
accountId: "master-codex-primary-local-english-greeting",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "在线主节点。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const originalFetch = globalThis.fetch;
let fetchCalled = false;
globalThis.fetch = (async () => {
fetchCalled = true;
throw new Error("model call should not happen for local English greeting replies");
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "hello",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { requestId?: string; effectiveModel?: string } | null;
replyMessage?: { body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.requestId, "local-fast-path");
assert.match(payload.replyMessage?.body ?? "", /我在/);
assert.match(payload.replyMessage?.body ?? "", /先给你结论/);
assert.equal(fetchCalled, false);
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 对可用模型查询会本地秒回并返回模式配置", async () => {
await saveAiAccount({
accountId: "hyzq-fast-local-list",
label: "环宇快反",
role: "primary",
provider: "hyzq_api",
displayName: "环宇智擎 API",
model: "gpt-5.4-mini",
apiKey: "hyzq-fast-local-list-key",
enabled: true,
setActive: true,
loginStatusNote: "环宇智擎快反账号。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const originalFetch = globalThis.fetch;
let fetchCalled = false;
globalThis.fetch = (async () => {
fetchCalled = true;
throw new Error("model call should not happen for local model listing replies");
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "有哪些模型可用",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { requestId?: string } | null;
replyMessage?: { body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.requestId, "local-fast-path");
assert.match(payload.replyMessage?.body ?? "", /gpt-5\.4-mini/);
assert.match(payload.replyMessage?.body ?? "", /gpt-5\.4/);
assert.match(payload.replyMessage?.body ?? "", /gpt-5\.1/);
assert.match(payload.replyMessage?.body ?? "", /gpt-4\.1/);
assert.equal(fetchCalled, false);
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 对深度思考切换请求会本地更新 controls 并秒回", async () => {
await saveAiAccount({
accountId: "hyzq-fast-local-switch",
label: "环宇快反",
role: "primary",
provider: "hyzq_api",
displayName: "环宇智擎 API",
model: "gpt-5.4-mini",
apiKey: "hyzq-fast-local-switch-key",
enabled: true,
setActive: true,
loginStatusNote: "环宇智擎快反账号。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const originalFetch = globalThis.fetch;
let fetchCalled = false;
globalThis.fetch = (async () => {
fetchCalled = true;
throw new Error("model call should not happen for local mode switching replies");
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "切到深度思考",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { requestId?: string; effectiveModel?: string; effectiveReasoningEffort?: string } | null;
replyMessage?: { body?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.requestId, "local-fast-path");
assert.equal(payload.masterReply?.effectiveModel, "gpt-5.4");
assert.equal(payload.masterReply?.effectiveReasoningEffort, "high");
assert.match(payload.replyMessage?.body ?? "", /深度思考/);
assert.match(payload.replyMessage?.body ?? "", /gpt-5\.4/);
assert.equal(fetchCalled, false);
const controls = await readState().then((state) =>
state.userProjectAgentControls.find(
(entry) => entry.projectId === "master-agent" && entry.account === "krisolo",
)?.controls,
);
assert.equal(controls?.modelOverride, "gpt-5.4");
assert.equal(controls?.reasoningEffortOverride, "high");
assert.equal(controls?.fastModelOverride, "gpt-5.4-mini");
assert.equal(controls?.deepModelOverride, "gpt-5.4");
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 在主节点在线时也会优先用环宇智擎执行快速反应", async () => {
await saveAiAccount({
accountId: "master-codex-primary-online-fast",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "在线主节点。",
});
await saveAiAccount({
accountId: "hyzq-fast-backup",
label: "环宇快反",
role: "backup",
provider: "hyzq_api",
displayName: "环宇智擎 API",
model: "gpt-5.4-mini",
apiKey: "hyzq-fast-key",
enabled: true,
setActive: false,
loginStatusNote: "环宇智擎快反账号。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const fetchCalls: Array<{ url: string; body: unknown }> = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (input, init) => {
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body ?? null;
fetchCalls.push({ url: String(input), body });
return new Response(JSON.stringify({ output_text: "环宇快反正常。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-hyzq-fast",
},
});
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请说:环宇快反正常。",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { accountId?: string; requestId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.task ?? null, null);
assert.equal(payload.masterReplyState, "completed");
assert.equal(payload.masterReply?.accountId, "hyzq-fast-backup");
assert.equal(payload.masterReply?.requestId, "req-master-agent-hyzq-fast");
const nextState = await readState();
const queuedTask = nextState.masterAgentTasks.find((item) => item.requestText === "请说:环宇快反正常。");
assert.equal(queuedTask, undefined);
const reply = nextState.projects.find((project) => project.id === "master-agent")?.messages.at(-1);
assert.match(reply?.body ?? "", /环宇快反正常/);
assert.equal(fetchCalls.length, 1);
assert.equal(fetchCalls[0]?.url, "https://api.hyzq2046.com/v1/responses");
const requestBody = fetchCalls[0]?.body as {
model?: string;
reasoning?: { effort?: string };
};
assert.equal(requestBody?.model, "gpt-5.4-mini");
assert.equal(requestBody?.reasoning?.effort, "low");
} finally {
globalThis.fetch = originalFetch;
}
});
test("POST /api/v1/projects/master-agent/messages 在主节点在线时复杂快反请求会自动升档到环宇智擎深度队列", async () => {
await saveAiAccount({
accountId: "master-codex-primary-online-deep",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "在线主节点。",
});
await saveAiAccount({
accountId: "hyzq-deep-backup",
label: "环宇深思",
role: "backup",
provider: "hyzq_api",
displayName: "环宇智擎 API",
model: "gpt-5.4-mini",
apiKey: "hyzq-deep-key",
enabled: true,
setActive: false,
loginStatusNote: "环宇智擎深思账号。",
});
await updateProjectAgentControls("master-agent", {
modelOverride: "gpt-5.4-mini",
reasoningEffortOverride: "low",
fastModelOverride: "gpt-5.4-mini",
deepModelOverride: "gpt-5.4",
});
const fetchCalls: Array<{ url: string; body: unknown }> = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (input, init) => {
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body ?? null;
fetchCalls.push({ url: String(input), body });
return new Response(JSON.stringify({ output_text: "已经升档到环宇深度思考。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-hyzq-deep",
},
});
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请深入分析主 Agent 快速反应链路的性能瓶颈,并给出实现方案、风险和回归测试建议。",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed" | null;
masterReply?: { accountId?: string; autoEscalated?: boolean } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReplyState, "queued");
assert.equal(payload.masterReply?.accountId, "hyzq-deep-backup");
assert.equal(payload.masterReply?.autoEscalated, true);
assert.equal(payload.task?.taskType, "conversation_reply");
await waitFor(async () => {
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
return task?.status === "completed";
});
const nextState = await readState();
const task = nextState.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.equal(task?.accountId, "hyzq-deep-backup");
assert.equal(task?.deviceId, "master-agent-openai");
assert.equal(task?.replyBody, "已经升档到环宇深度思考。");
assert.equal(fetchCalls.length, 1);
assert.equal(fetchCalls[0]?.url, "https://api.hyzq2046.com/v1/responses");
const requestBody = fetchCalls[0]?.body as {
model?: string;
reasoning?: { effort?: string };
};
assert.equal(requestBody?.model, "gpt-5.4");
assert.equal(requestBody?.reasoning?.effort, "high");
} finally {
globalThis.fetch = originalFetch;
}
});
test("master-agent enqueue 在主节点离线时会自动切到 OpenAI 后台队列而不是挂到本机设备队列", async () => {
await updateDevice("mac-studio", {
capabilities: {
gui: { connected: false },
cli: { connected: false },
codexAppServer: { connected: false },
},
});
await saveAiAccount({
accountId: "master-codex-primary-offline",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "离线 Master Codex Node",
nodeId: "offline-node",
nodeLabel: "离线节点",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "离线主节点",
});
await saveAiAccount({
accountId: "openai-backup-queue",
label: "备用 GPT",
role: "backup",
provider: "openai_api",
displayName: "OpenAI 备用账号",
accountIdentifier: "sk-queue-demo",
model: "gpt-5.4",
apiKey: "sk-queue-demo",
enabled: true,
setActive: false,
loginStatusNote: "备用 API 账号",
});
const originalFetch = globalThis.fetch;
globalThis.fetch = (async () =>
new Response(JSON.stringify({ output_text: "离线主节点已切到 API 后台队列。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-offline-fallback-queue",
},
})) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请走备用 API 队列",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed";
masterReply?: { accountId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReply?.accountId, "openai-backup-queue");
assert.equal(payload.masterReplyState, "queued");
assert.equal(payload.task?.taskType, "conversation_reply");
await waitFor(async () => {
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
return task?.status === "completed";
});
const nextState = await readState();
const task = nextState.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.equal(task?.deviceId, "master-agent-openai");
assert.equal(task?.status, "completed");
assert.equal(task?.accountId, "openai-backup-queue");
} finally {
globalThis.fetch = originalFetch;
}
});
test("master-agent enqueue 在显式选择 claw-runtime 时会通过 Claw 异步回写回复", async () => {
const clawDir = await mkdtemp(path.join(os.tmpdir(), "boss-claw-queue-"));
const clawScriptPath = path.join(clawDir, "claw-runtime.mjs");
await writeFile(
clawScriptPath,
`
let stdin = "";
process.stdin.setEncoding("utf8");
for await (const chunk of process.stdin) {
stdin += chunk;
}
const payload = JSON.parse(stdin);
process.stdout.write(JSON.stringify({
status: "completed",
output: "Claw 已接管当前主 Agent 会话:" + payload.body
}));
`,
"utf8",
);
const previousEnv = {
BOSS_CLAW_ENABLED: process.env.BOSS_CLAW_ENABLED,
BOSS_CLAW_COMMAND: process.env.BOSS_CLAW_COMMAND,
BOSS_CLAW_ARGS: process.env.BOSS_CLAW_ARGS,
BOSS_CLAW_TIMEOUT_MS: process.env.BOSS_CLAW_TIMEOUT_MS,
};
process.env.BOSS_CLAW_ENABLED = "true";
process.env.BOSS_CLAW_COMMAND = process.execPath;
process.env.BOSS_CLAW_ARGS = clawScriptPath;
process.env.BOSS_CLAW_TIMEOUT_MS = "1000";
await saveAiAccount({
accountId: "master-codex-primary-claw",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "Mac 上的 Master Codex Node",
nodeId: "local-codex-node",
nodeLabel: "本机 Codex",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "用于 Claw backend 队列测试。",
});
await updateProjectAgentControls("master-agent", {
backendOverride: "claw-runtime",
});
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请走 Claw runtime",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; status: string } | null;
masterReply?: { accountId?: string } | null;
masterReplyState?: string | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReply?.accountId, "claw-runtime");
assert.equal(payload.masterReplyState, "queued");
assert.ok(payload.task?.taskId);
await waitFor(async () => {
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
return task?.status === "completed";
});
const nextState = await readState();
const task = nextState.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.equal(task?.status, "completed");
assert.equal(task?.replyBody, "Claw 已接管当前主 Agent 会话:请走 Claw runtime");
const masterProject = nextState.projects.find((project) => project.id === "master-agent");
const mirroredReply = masterProject?.messages.at(-1);
assert.match(mirroredReply?.body ?? "", /Claw 已接管当前主 Agent 会话/);
} finally {
process.env.BOSS_CLAW_ENABLED = previousEnv.BOSS_CLAW_ENABLED;
process.env.BOSS_CLAW_COMMAND = previousEnv.BOSS_CLAW_COMMAND;
process.env.BOSS_CLAW_ARGS = previousEnv.BOSS_CLAW_ARGS;
process.env.BOSS_CLAW_TIMEOUT_MS = previousEnv.BOSS_CLAW_TIMEOUT_MS;
await rm(clawDir, { recursive: true, force: true });
}
});
test("master-agent enqueue 在首选主节点离线时会回退到可用的备用主节点并返回实际账号", async () => {
await saveAiAccount({
accountId: "master-codex-primary-offline",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "离线 Master Codex Node",
nodeId: "offline-node",
nodeLabel: "离线节点",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "离线主节点",
});
await saveAiAccount({
accountId: "master-codex-backup-online",
label: "备用主节点",
role: "backup",
provider: "master_codex_node",
displayName: "在线备用 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: false,
loginStatusNote: "在线备用主节点",
});
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请走备用主节点队列",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed";
masterReply?: { accountId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReply?.accountId, "master-codex-backup-online");
assert.equal(payload.masterReplyState, "queued");
assert.equal(payload.task?.taskType, "conversation_reply");
assert.equal(payload.task?.status, "queued");
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.ok(task, "expected queued master-agent task");
assert.equal(task?.accountId, "master-codex-backup-online");
assert.equal(task?.deviceId, "mac-studio");
});
test("master-agent enqueue 会继续使用设备在线但账号处于 degraded 的 Master Codex Node", async () => {
await saveAiAccount({
accountId: "master-codex-primary",
label: "主 GPT",
role: "primary",
provider: "master_codex_node",
displayName: "在线但历史失败的 Master Codex Node",
nodeId: "mac-studio",
nodeLabel: "Mac Studio",
model: "gpt-5.4",
enabled: true,
setActive: true,
loginStatusNote: "历史失败后等待自动恢复的主节点",
});
await updateAiAccountHealth({
accountId: "master-codex-primary",
status: "degraded",
lastError: "MASTER_CODEX_NODE_EXEC_FAILED",
lastValidatedAt: new Date().toISOString(),
});
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请把当前托管任务转交给主节点执行,并在完成后回写。",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed";
masterReply?: { accountId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReplyState, "queued");
assert.equal(payload.masterReply?.accountId, "master-codex-primary");
assert.equal(payload.task?.taskType, "conversation_reply");
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.equal(task?.accountId, "master-codex-primary");
assert.equal(task?.deviceId, "mac-studio");
const account = state.aiAccounts.find((item) => item.accountId === "master-codex-primary");
assert.equal(account?.status, "ready");
const masterProject = state.projects.find((project) => project.id === "master-agent");
assert.doesNotMatch(masterProject?.messages.at(-1)?.body ?? "", /当前没有可用的 master 节点账号/);
});
test("master-agent enqueue 会在首个 API 候选失败后切到下一条备用链并重写任务账号", async () => {
await saveAiAccount({
accountId: "openai-primary-queue",
label: "OpenAI 主控",
role: "primary",
provider: "openai_api",
displayName: "OpenAI 主账号",
model: "gpt-5.4",
apiKey: "sk-openai-primary-queue",
enabled: true,
setActive: true,
loginStatusNote: "OpenAI 主控",
});
await saveAiAccount({
accountId: "aliyun-qwen-backup-queue",
label: "阿里备用",
role: "backup",
provider: "aliyun_qwen_api",
displayName: "阿里百炼备用账号",
model: "qwen3.5-plus",
apiKey: "sk-aliyun-backup-queue",
enabled: true,
setActive: false,
loginStatusNote: "阿里备用账号",
});
const fetchCalls: string[] = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (input) => {
fetchCalls.push(String(input));
if (typeof input === "string" && input === "https://api.openai.com/v1/responses") {
return new Response(JSON.stringify({ error: { message: "openai queue failure" } }), {
status: 500,
headers: { "content-type": "application/json" },
});
}
if (typeof input === "string" && input === "https://dashscope.aliyuncs.com/compatible-mode/v1/responses") {
return new Response(JSON.stringify({ output_text: "后台队列已切到阿里备用。" }), {
status: 200,
headers: {
"content-type": "application/json",
"x-request-id": "req-master-agent-queue-fallback-chain",
},
});
}
throw new Error(`unexpected fetch: ${String(input)}`);
}) as typeof fetch;
try {
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请让后台队列自动切备用链",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
task?: { taskId: string; taskType: string; status: string } | null;
masterReplyState?: "queued" | "running" | "completed";
masterReply?: { accountId?: string } | null;
};
assert.equal(payload.ok, true);
assert.equal(payload.masterReply?.accountId, "openai-primary-queue");
assert.equal(payload.masterReplyState, "queued");
await waitFor(async () => {
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
return task?.status === "completed";
});
const state = await readState();
const task = state.masterAgentTasks.find((item) => item.taskId === payload.task?.taskId);
assert.ok(task, "expected queued task to remain in state");
assert.equal(task?.status, "completed");
assert.equal(task?.accountId, "aliyun-qwen-backup-queue");
assert.equal(task?.deviceId, "master-agent-aliyun-qwen");
const aliyunAccount = state.aiAccounts.find((item) => item.accountId === "aliyun-qwen-backup-queue");
assert.equal(aliyunAccount?.isActive, true);
assert.equal(fetchCalls[0], "https://api.openai.com/v1/responses");
assert.equal(fetchCalls[1], "https://dashscope.aliyuncs.com/compatible-mode/v1/responses");
} finally {
globalThis.fetch = originalFetch;
}
});