import { isAwaitingUserConfirmationWorkflow, type AgentWorkflowState, type AgentWorkflowStatus, type AgentWorkflowType, } from "@/lib/ai/runtime/agent-workflow-state"; import type { AgentThreadState } from "@/lib/ai/runtime/agent-thread-state"; import { interpretStoryboardCommand } from "@/lib/video-agent/storyboard-command-interpreter"; export type HumanConfirmationIntent = | "none" | "confirm" | "revise" | "cancel" | "unclear"; export type HumanConfirmationGateAction = | "pass" | "awaiting_confirmation" | "confirmed" | "revision_requested" | "cancel_requested"; export interface HumanConfirmationGateDecision { action: HumanConfirmationGateAction; confirmationIntent: HumanConfirmationIntent; workflowId?: string; workflowType?: AgentWorkflowType; nextWorkflowStatus?: AgentWorkflowStatus; allowWorkflowExecution: boolean; shouldBypassPlanner: boolean; friendlyMessage?: string; } function buildAwaitingConfirmationMessage(workflowState: AgentWorkflowState): string { const title = workflowState.title || "当前工作流"; const summary = workflowState.summary ? `\n当前待确认内容:${workflowState.summary}` : ""; const pendingItemsPreview = workflowState.pendingItems .slice(0, 3) .map((item) => { const indexText = item.index ? `镜头${item.index}` : item.title || "待确认项"; const summaryText = item.summary ? `:${item.summary}` : ""; return `- ${indexText}${summaryText}`; }) .join("\n"); const previewBlock = pendingItemsPreview ? `\n${pendingItemsPreview}` : ""; const confirmExample = workflowState.confirmPhrases[0] || "确认开始生成视频"; const reviseExample = workflowState.revisionHints[0] || "修改第3镜头"; return [ `当前有一个待确认流程:${title}。`, summary ? summary.trim() : "", previewBlock.trim(), `如果确认无误,请回复“${confirmExample}”。`, `如果需要修改,请直接回复类似“${reviseExample}”。`, ] .filter(Boolean) .join("\n"); } function buildConfirmMessage(workflowState: AgentWorkflowState): string { const title = workflowState.title || "当前流程"; return `已收到确认:${title} 可以进入下一步执行。我会按已确认内容继续处理。`; } function buildRevisionMessage(workflowState: AgentWorkflowState): string { const title = workflowState.title || "当前流程"; return `收到修改意见。我会先更新 ${title} 的草案内容,并在重新确认前暂停执行。`; } function buildCancelMessage(workflowState: AgentWorkflowState): string { const title = workflowState.title || "当前流程"; return `已收到取消指令。${title} 会继续停留在人工确认前状态,不会继续自动执行。`; } export async function runHumanConfirmationGate(params: { text: string; threadState?: AgentThreadState | null; }): Promise { const workflowState = params.threadState?.workflowState; if (!workflowState || !isAwaitingUserConfirmationWorkflow(workflowState)) { return { action: "pass", confirmationIntent: "none", allowWorkflowExecution: true, shouldBypassPlanner: false, }; } const interpreted = await interpretStoryboardCommand({ text: params.text, totalShots: workflowState.pendingItems.length || undefined, items: workflowState.pendingItems.map((item) => ({ index: item.index || 0, title: item.title, summary: item.summary, })), }); const confirmationIntent = interpreted.intent; const baseDecision = { workflowId: workflowState.workflowId, workflowType: workflowState.type, shouldBypassPlanner: true, }; switch (confirmationIntent) { case "confirm": return { ...baseDecision, action: "confirmed", confirmationIntent, nextWorkflowStatus: "confirmed", allowWorkflowExecution: true, friendlyMessage: buildConfirmMessage(workflowState), }; case "revise": return { ...baseDecision, action: "revision_requested", confirmationIntent, nextWorkflowStatus: "draft", allowWorkflowExecution: false, friendlyMessage: buildRevisionMessage(workflowState), }; case "cancel": return { ...baseDecision, action: "cancel_requested", confirmationIntent, nextWorkflowStatus: "cancelled", allowWorkflowExecution: false, friendlyMessage: buildCancelMessage(workflowState), }; case "unclear": default: return { ...baseDecision, action: "awaiting_confirmation", confirmationIntent: "unclear", nextWorkflowStatus: workflowState.status, allowWorkflowExecution: false, friendlyMessage: buildAwaitingConfirmationMessage(workflowState), }; } }