feat(FN-3935): align engineer role routing with explicit assignment and del
Centralized routing policy helpers in core and aligned both direct assignment and delegation to route engineer-role agents consistently, ensuring assigned tasks respect explicit engineer routing the same way delegated tasks do. Added comprehensive test coverage across core, CLI, dashboard, and engin Fusion-Task-Id: FN-3935 Fusion-Task-Lineage: 069f4d54-f7a8-4bd3-a2c3-4de830de042f
This commit is contained in:
@@ -2371,6 +2371,7 @@ describe("PATCH /tasks/:id/assign and GET /agents/:id/tasks", () => {
|
||||
let fusionDir: string;
|
||||
let agentId: string;
|
||||
let reviewerAgentId: string;
|
||||
let engineerAgentId: string;
|
||||
let store: TaskStore;
|
||||
|
||||
// Agent store init + createAgent is ~50ms per call; hoisted to beforeAll
|
||||
@@ -2391,8 +2392,13 @@ describe("PATCH /tasks/:id/assign and GET /agents/:id/tasks", () => {
|
||||
name: "Assignment reviewer agent",
|
||||
role: "reviewer",
|
||||
});
|
||||
const engineer = await agentStore.createAgent({
|
||||
name: "Assignment engineer agent",
|
||||
role: "engineer",
|
||||
});
|
||||
agentId = agent.id;
|
||||
reviewerAgentId = reviewer.id;
|
||||
engineerAgentId = engineer.id;
|
||||
}, 30_000);
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -2432,7 +2438,26 @@ describe("PATCH /tasks/:id/assign and GET /agents/:id/tasks", () => {
|
||||
expect(res.body.assignedAgentId).toBe(agentId);
|
||||
}, 20000);
|
||||
|
||||
it("returns 409 when assigning implementation task to non-executor without override", async () => {
|
||||
it("allows assigning implementation task to durable engineer without override", async () => {
|
||||
(store.updateTask as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
...FAKE_TASK_DETAIL,
|
||||
id: "FN-200",
|
||||
assignedAgentId: engineerAgentId,
|
||||
});
|
||||
|
||||
const res = await REQUEST(
|
||||
buildApp(),
|
||||
"PATCH",
|
||||
"/api/tasks/FN-200/assign",
|
||||
JSON.stringify({ agentId: engineerAgentId }),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-200", { assignedAgentId: engineerAgentId });
|
||||
}, 20000);
|
||||
|
||||
it("returns 409 when assigning implementation task to reviewer without override", async () => {
|
||||
const res = await REQUEST(
|
||||
buildApp(),
|
||||
"PATCH",
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
resolveTitleSummarizerSettingsModel,
|
||||
toReplicatedCreateInput,
|
||||
validateNodeOverrideChange,
|
||||
canAgentTakeImplementationTask,
|
||||
canAgentTakeImplementationTaskForExplicitRouting,
|
||||
formatRoleMismatchReason,
|
||||
getCurrentRepo,
|
||||
} from "@fusion/core";
|
||||
@@ -1880,7 +1880,7 @@ export function registerTaskWorkflowRoutes(ctx: ApiRoutesContext, deps: TaskWork
|
||||
throw notFound("Task not found");
|
||||
}
|
||||
|
||||
if (override !== true && !canAgentTakeImplementationTask(agent, targetTask)) {
|
||||
if (override !== true && !canAgentTakeImplementationTaskForExplicitRouting(agent, targetTask)) {
|
||||
throw new ApiError(409, formatRoleMismatchReason(agent, targetTask));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user