Files
boss/tests/master-agent-task-reliability.test.ts
2026-06-06 19:05:42 +08:00

201 lines
5.9 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";
import type { Device, MasterAgentTask } from "../src/lib/boss-data";
let runtimeRoot = "";
let data: typeof import("../src/lib/boss-data");
async function setup() {
if (runtimeRoot) return;
runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-master-task-reliability-"));
process.env.BOSS_RUNTIME_ROOT = runtimeRoot;
process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json");
data = await import("../src/lib/boss-data.ts");
}
test.after(async () => {
if (runtimeRoot) await rm(runtimeRoot, { recursive: true, force: true });
});
function makeQueuedTask(taskId: string, overrides: Partial<MasterAgentTask> = {}): MasterAgentTask {
return {
taskId,
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: `${taskId}-request`,
requestText: "回复一句收到",
executionPrompt: "回复一句收到",
requestedBy: "Boss 测试",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
status: "queued",
requestedAt: new Date().toISOString(),
...overrides,
};
}
test("master agent task claim, progress, and complete maintain reliability phase", async () => {
await setup();
const state = await data.readState();
state.masterAgentTasks.unshift(makeQueuedTask("task-phase-normal"));
await data.writeState(state);
const claimed = await data.claimNextMasterAgentTask("mac-studio");
assert.equal(claimed?.taskId, "task-phase-normal");
assert.equal(claimed?.status, "running");
assert.equal(claimed?.phase, "claimed");
assert.ok(claimed?.lastProgressAt);
const progressed = await data.updateMasterAgentTaskProgress({
taskId: "task-phase-normal",
deviceId: "mac-studio",
status: "running",
phase: "awaiting_reply",
});
assert.equal(progressed.status, "running");
assert.equal(progressed.phase, "awaiting_reply");
assert.ok(progressed.leaseExpiresAt);
const completed = await data.completeMasterAgentTask({
taskId: "task-phase-normal",
deviceId: "mac-studio",
status: "completed",
replyBody: "收到。",
});
assert.equal(completed.status, "completed");
assert.equal(completed.phase, "completed");
assert.equal(completed.recoverable, false);
});
test("expired pre-turn task is safely requeued and claimed again", async () => {
await setup();
const state = await data.readState();
state.masterAgentTasks.unshift(
makeQueuedTask("task-phase-retry", {
status: "running",
phase: "executor_starting",
claimedAt: "2020-01-01T08:00:00.000Z",
lastProgressAt: "2020-01-01T08:00:00.000Z",
leaseExpiresAt: "2020-01-01T08:01:00.000Z",
attemptCount: 1,
maxAttempts: 2,
}),
);
await data.writeState(state);
const claimed = await data.claimNextMasterAgentTask("mac-studio");
assert.equal(claimed?.taskId, "task-phase-retry");
assert.equal(claimed?.status, "running");
assert.equal(claimed?.phase, "claimed");
assert.equal(claimed?.attemptCount, 2);
assert.equal(claimed?.recoverable, false);
});
test("expired task after turn start is timed out instead of duplicated", async () => {
await setup();
const state = await data.readState();
state.masterAgentTasks.unshift(
makeQueuedTask("task-phase-no-duplicate", {
status: "running",
phase: "turn_started",
claimedAt: "2020-01-01T08:00:00.000Z",
lastProgressAt: "2020-01-01T08:00:00.000Z",
leaseExpiresAt: "2020-01-01T08:01:00.000Z",
attemptCount: 1,
maxAttempts: 2,
}),
);
await data.writeState(state);
const claimed = await data.claimNextMasterAgentTask("mac-studio");
assert.notEqual(claimed?.taskId, "task-phase-no-duplicate");
const nextState = await data.readState();
const task = nextState.masterAgentTasks.find((item) => item.taskId === "task-phase-no-duplicate");
assert.equal(task?.status, "timed_out");
assert.equal(task?.phase, "timed_out");
assert.equal(task?.recoverable, false);
});
test("codex app server health distinguishes available, degraded, and unavailable", async () => {
await setup();
assert.equal(data.resolveCodexAppServerHealth(undefined), "unavailable");
assert.equal(
data.resolveCodexAppServerHealth({
id: "device-offline",
name: "离线设备",
avatar: "D",
account: "krisolo",
source: "production",
status: "offline",
projects: [],
quota5h: 0,
quota7d: 0,
lastSeenAt: "2026-06-06T08:00:00.000Z",
endpoint: "",
token: "",
note: "",
capabilities: {
codexAppServer: {
connected: false,
lastSeenAt: "2026-06-06T08:00:00.000Z",
},
},
} satisfies Device),
"unavailable",
);
assert.equal(
data.resolveCodexAppServerHealth({
id: "device-degraded",
name: "降级设备",
avatar: "D",
account: "krisolo",
source: "production",
status: "online",
projects: [],
quota5h: 0,
quota7d: 0,
lastSeenAt: new Date().toISOString(),
endpoint: "",
token: "",
note: "",
capabilities: {
codexAppServer: {
connected: true,
lastSeenAt: new Date().toISOString(),
metadata: { errors: ["thread/turns/list:STDIN_CLOSED"] },
},
},
} satisfies Device),
"degraded",
);
assert.equal(
data.resolveCodexAppServerHealth({
id: "device-available",
name: "可用设备",
avatar: "D",
account: "krisolo",
source: "production",
status: "online",
projects: [],
quota5h: 0,
quota7d: 0,
lastSeenAt: new Date().toISOString(),
endpoint: "",
token: "",
note: "",
capabilities: {
codexAppServer: {
connected: true,
lastSeenAt: new Date().toISOString(),
metadata: {},
},
},
} satisfies Device),
"available",
);
});