refactor: extract execution permission policy

This commit is contained in:
kris
2026-04-02 22:46:41 +08:00
parent 384dd570de
commit a3a4f3e980
8 changed files with 204 additions and 39 deletions

View File

@@ -1,31 +1,12 @@
import { NextRequest, NextResponse } from "next/server";
import { requireRequestSession } from "@/lib/boss-auth";
import { appendProjectMessage, readState } from "@/lib/boss-data";
import { appendProjectMessage, buildCollaborationGate, readState } from "@/lib/boss-data";
import {
queueGroupDispatchPlan,
queueThreadConversationReplyTask,
replyToMasterAgentUserMessage,
} from "@/lib/boss-master-agent";
function buildCollaborationGate(project?: {
isGroup: boolean;
collaborationMode: "development" | "approval_required";
approvalState: "not_required" | "pending_agent" | "pending_user" | "approved" | "rejected";
}) {
return project
? {
isGroup: project.isGroup,
collaborationMode: project.collaborationMode,
requiresMasterAgentApproval: project.isGroup && project.collaborationMode === "approval_required",
approvalState: project.approvalState,
}
: {
isGroup: false,
collaborationMode: "development" as const,
requiresMasterAgentApproval: false,
approvalState: "not_required" as const,
};
}
import { evaluatePermissionPolicy } from "@/lib/execution/permission-policy";
function dispatchFailureNotice(error?: string) {
switch (error) {
@@ -61,23 +42,28 @@ export async function POST(
(body.kind ?? "text") === "text" &&
(body.body ?? "").trim().length > 0;
if (shouldCreateDispatchPlan && project.collaborationMode === "approval_required") {
const pendingPlan = [...state.dispatchPlans]
.filter(
(plan) => plan.groupProjectId === projectId && plan.status === "pending_user_confirmation",
)
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))[0];
if (pendingPlan) {
return NextResponse.json(
{
ok: false,
message: "当前还有一条主 Agent 推荐等待你确认,请先确认或拒绝后再继续发送新指令。",
pendingPlan,
collaborationGate: buildCollaborationGate(project),
},
{ status: 409 },
);
}
const pendingPlan = shouldCreateDispatchPlan
? [...state.dispatchPlans]
.filter(
(plan) => plan.groupProjectId === projectId && plan.status === "pending_user_confirmation",
)
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))[0]
: null;
const permission = evaluatePermissionPolicy({
project,
hasPendingDispatchPlan: Boolean(pendingPlan),
});
if (!permission.allowed) {
return NextResponse.json(
{
ok: false,
message: permission.reason,
pendingPlan,
collaborationGate: buildCollaborationGate(project),
},
{ status: 409 },
);
}
const message = await appendProjectMessage({