feat: let master-agent dispatch real threads
This commit is contained in:
@@ -166,6 +166,34 @@ async function createDispatchPlanForTest() {
|
||||
return { groupProject, dispatchPlan: payload.dispatchPlan };
|
||||
}
|
||||
|
||||
async function createMasterAgentDispatchPlanForTest() {
|
||||
await setup();
|
||||
const memberProjects = await ensureTwoSingleThreadProjects();
|
||||
assert.ok(memberProjects.length >= 2, "expected dispatchable single-thread projects");
|
||||
|
||||
const response = await postMessageRoute(
|
||||
await createAuthedRequest(
|
||||
"http://127.0.0.1:3000/api/v1/projects/master-agent/messages",
|
||||
"POST",
|
||||
{ body: "请操作真实线程,先让南区试产线回归只回复:主Agent确认链路正常" },
|
||||
),
|
||||
{ params: Promise.resolve({ projectId: "master-agent" }) },
|
||||
);
|
||||
assert.equal(response.status, 200);
|
||||
const payload = (await response.json()) as {
|
||||
dispatchPlan:
|
||||
| {
|
||||
planId: string;
|
||||
targets: Array<{ projectId: string }>;
|
||||
orchestrationBackendId?: string;
|
||||
orchestrationBackendLabel?: string;
|
||||
}
|
||||
| null;
|
||||
};
|
||||
assert.ok(payload.dispatchPlan, "expected master-agent dispatch plan");
|
||||
return { dispatchPlan: payload.dispatchPlan };
|
||||
}
|
||||
|
||||
test("GET /api/v1/projects/[projectId]/dispatch-plans lists the latest group dispatch plans", async () => {
|
||||
const { groupProject, dispatchPlan } = await createDispatchPlanForTest();
|
||||
|
||||
@@ -271,6 +299,74 @@ test("POST /api/v1/projects/[projectId]/dispatch-plans/[planId]/confirm confirms
|
||||
assert.equal(executionTask?.orchestrationBackendLabel, "Boss Native Orchestrator");
|
||||
});
|
||||
|
||||
test("master-agent dispatch plans can also be confirmed and create queued executions", async () => {
|
||||
const { dispatchPlan } = await createMasterAgentDispatchPlanForTest();
|
||||
const approvedTargetProjectId = dispatchPlan.targets[0]?.projectId;
|
||||
assert.ok(approvedTargetProjectId, "expected a recommended target project");
|
||||
|
||||
const response = await confirmDispatchPlanRoute(
|
||||
await createAuthedRequest(
|
||||
`http://127.0.0.1:3000/api/v1/projects/master-agent/dispatch-plans/${dispatchPlan.planId}/confirm`,
|
||||
"POST",
|
||||
{ approvedTargetProjectIds: [approvedTargetProjectId] },
|
||||
),
|
||||
{ params: Promise.resolve({ projectId: "master-agent", planId: dispatchPlan.planId }) },
|
||||
);
|
||||
assert.equal(response.status, 200);
|
||||
const payload = (await response.json()) as {
|
||||
ok: boolean;
|
||||
plan: { status: string; confirmedTargetProjectIds: string[] };
|
||||
executions: Array<{ targetProjectId: string; status: string }>;
|
||||
notice: { body: string } | null;
|
||||
};
|
||||
assert.equal(payload.ok, true);
|
||||
assert.equal(payload.plan.status, "dispatched");
|
||||
assert.deepEqual(payload.plan.confirmedTargetProjectIds, [approvedTargetProjectId]);
|
||||
assert.equal(payload.executions.length, 1);
|
||||
assert.equal(payload.executions[0]?.targetProjectId, approvedTargetProjectId);
|
||||
assert.equal(payload.executions[0]?.status, "queued");
|
||||
assert.match(payload.notice?.body ?? "", /已确认下发到 1 个线程/);
|
||||
});
|
||||
|
||||
test("confirm rejects targets whose device is offline before creating queued executions", async () => {
|
||||
const { groupProject, dispatchPlan } = await createDispatchPlanForTest();
|
||||
const approvedTargetProjectId = dispatchPlan.targets[0]?.projectId;
|
||||
const targetDeviceId = dispatchPlan.targets[0]?.deviceId;
|
||||
assert.ok(approvedTargetProjectId, "expected a recommended target project");
|
||||
assert.ok(targetDeviceId, "expected a target device");
|
||||
|
||||
const state = await readState();
|
||||
await writeState({
|
||||
...state,
|
||||
devices: state.devices.map((device) =>
|
||||
device.id === targetDeviceId
|
||||
? {
|
||||
...device,
|
||||
status: "offline" as const,
|
||||
}
|
||||
: device,
|
||||
),
|
||||
});
|
||||
|
||||
const response = await confirmDispatchPlanRoute(
|
||||
await createAuthedRequest(
|
||||
`http://127.0.0.1:3000/api/v1/projects/${groupProject.id}/dispatch-plans/${dispatchPlan.planId}/confirm`,
|
||||
"POST",
|
||||
{ approvedTargetProjectIds: [approvedTargetProjectId] },
|
||||
),
|
||||
{ params: Promise.resolve({ projectId: groupProject.id, planId: dispatchPlan.planId }) },
|
||||
);
|
||||
assert.equal(response.status, 400);
|
||||
const payload = (await response.json()) as { ok: boolean; code: string; message: string };
|
||||
assert.equal(payload.ok, false);
|
||||
assert.equal(payload.code, "DISPATCH_TARGET_DEVICE_OFFLINE");
|
||||
assert.equal(payload.message, "目标线程所在设备当前不在线,请先让设备上线后再确认下发。");
|
||||
|
||||
const nextState = await readState();
|
||||
const createdExecution = nextState.dispatchExecutions.find((item) => item.planId === dispatchPlan.planId);
|
||||
assert.equal(createdExecution, undefined);
|
||||
});
|
||||
|
||||
test("confirming a dispatch plan marks approval_required groups as approved", async () => {
|
||||
const { groupProject, dispatchPlan } = await createDispatchPlanForTest();
|
||||
const approvedTargetProjectId = dispatchPlan.targets[0]?.projectId;
|
||||
|
||||
Reference in New Issue
Block a user