Browse Source

[Mod 0000] 修改AI助手在计划模式下的审批逻辑

wangkeyi 1 week ago
parent
commit
62f453c9df

+ 1 - 1
src/views/ventAI/manageAssistent/api.ts

@@ -343,7 +343,7 @@ export const chatResumeStream = async (
 
             onChunk(data);
 
-            if (data.type === 'done' || data.type === 'error') {
+            if (data.type === 'done' || data.type === 'error' || data.type === 'interrupt') {
               if (data.session_id) {
                 sessionId = data.session_id;
               }

+ 64 - 20
src/views/ventAI/manageAssistent/components/AiAssistantModal.vue

@@ -658,32 +658,43 @@
     }
   };
 
-  const findPendingApprovalTask = async (): Promise<{ taskId: string; approval: { sessionId: string; threadId?: string } } | null> => {
+  const findPendingApprovalTask = (): { taskId: string; approval: { sessionId: string; threadId?: string } } | null => {
+    // 优先用当前任务 ID 查找
     let approval = currentPendingApproval.value;
     if (approval) return { taskId: currentTaskId.value, approval };
+    // 遍历所有审批(可能任务 ID 已变,用 sessionId 做回退匹配)
     for (const [taskId, a] of taskPendingApprovals.value.entries()) {
-      if (currentTaskId.value !== taskId) {
-        await switchTask(taskId);
-      }
       return { taskId, approval: a };
     }
     return null;
   };
 
   const handleAskUserSubmit = async (answers: string[]) => {
-    const found = await findPendingApprovalTask();
+    // 防重复提交:如果当前任务正在流式中,忽略
+    const currentTask = taskList.value.find((t) => t.id === currentTaskId.value);
+    if (currentTask?.isStreaming) return;
+
+    const found = findPendingApprovalTask();
 
     // 优先从 taskPendingApprovals 获取,若被清除则从消息的 pendingApprovalData 回退
     let sessionId = found?.approval.sessionId;
     let threadId = found?.approval.threadId;
-    let taskId = found?.taskId;
+    const foundTaskId = found?.taskId;
 
-    // 查找当前任务中处于审批状态的消息
-    const task = taskId ? taskList.value.find((t) => t.id === taskId) : taskList.value.find((t) => t.id === currentTaskId.value);
+    // 查找任务:优先用 foundTaskId,回退到 currentTaskId
+    let task = foundTaskId ? taskList.value.find((t) => t.id === foundTaskId) : null;
+    if (!task) task = taskList.value.find((t) => t.id === currentTaskId.value);
     if (!task) return;
 
-    const taskMessages = task.messages;
-    const lastMsg = taskMessages[taskMessages.length - 1];
+    // 切换到目标任务(如果不在当前视图)
+    if (task.id !== currentTaskId.value) {
+      await switchTask(task.id);
+    }
+
+    // 使用正确的消息数组:当前视图用 messages.value,否则用 task.messages
+    const isViewingTask = currentTaskId.value === task.id;
+    const sourceArr = isViewingTask ? messages.value : task.messages;
+    const lastMsg = sourceArr[sourceArr.length - 1];
     if (!lastMsg || !lastMsg.isPendingApproval) return;
 
     // 若 taskPendingApprovals 已被清除,从消息的 pendingApprovalData 回退取值
@@ -698,11 +709,12 @@
     lastMsg.isLoading = true;
     lastMsg.generateStartTime = Date.now();
 
-    const aiMsgIndex = taskMessages.length - 1;
-    task.messages = [...taskMessages];
-    if (currentTaskId.value === task.id) {
-      messages.value = task.messages;
+    const aiMsgIndex = sourceArr.length - 1;
+    // 强制触发 Vue 响应式更新
+    if (isViewingTask) {
+      messages.value = [...sourceArr];
     }
+    task.messages = [...sourceArr];
 
     task.isStreaming = true;
     showTodoBar.value = false;
@@ -759,18 +771,31 @@
   };
 
   const handleAskUserCancel = async () => {
-    const found = await findPendingApprovalTask();
+    // 防重复操作:如果当前任务正在流式中,忽略
+    const currentTask = taskList.value.find((t) => t.id === currentTaskId.value);
+    if (currentTask?.isStreaming) return;
+
+    const found = findPendingApprovalTask();
 
     // 优先从 taskPendingApprovals 获取,若被清除则从消息的 pendingApprovalData 回退
     let sessionId = found?.approval.sessionId;
     let threadId = found?.approval.threadId;
+    const foundTaskId = found?.taskId;
 
-    // 查找当前任务中处于审批状态的消息
-    const task = found?.taskId ? taskList.value.find((t) => t.id === found.taskId) : taskList.value.find((t) => t.id === currentTaskId.value);
+    // 查找任务:优先用 foundTaskId,回退到 currentTaskId
+    let task = foundTaskId ? taskList.value.find((t) => t.id === foundTaskId) : null;
+    if (!task) task = taskList.value.find((t) => t.id === currentTaskId.value);
     if (!task) return;
 
-    const taskMessages = task.messages;
-    const lastMsg = taskMessages[taskMessages.length - 1];
+    // 切换到目标任务(如果不在当前视图)
+    if (task.id !== currentTaskId.value) {
+      await switchTask(task.id);
+    }
+
+    // 使用正确的消息数组
+    const isViewingTask = currentTaskId.value === task.id;
+    const sourceArr = isViewingTask ? messages.value : task.messages;
+    const lastMsg = sourceArr[sourceArr.length - 1];
     if (!lastMsg || !lastMsg.isPendingApproval) return;
 
     // 若 taskPendingApprovals 已被清除,从消息的 pendingApprovalData 回退取值
@@ -787,7 +812,10 @@
     lastMsg.isLoading = false;
     lastMsg.content = (lastMsg.content ? lastMsg.content + '\n\n' : '') + '已取消提问。';
 
-    task.messages = [...taskMessages];
+    task.messages = [...sourceArr];
+    if (isViewingTask) {
+      messages.value = task.messages;
+    }
     clearTaskPendingApproval(task.id);
 
     try {
@@ -1498,6 +1526,14 @@
             taskList.value = taskList.value.filter((t) => t.id !== result.session_id);
             originTask.id = result.session_id;
             historyLoadedTasks.add(result.session_id);
+            // 迁移审批状态 key(任务 ID 变了,审批 Map 的 key 也要跟着变)
+            const approvalEntry = taskPendingApprovals.value.get(originTaskId);
+            if (approvalEntry) {
+              const map = new Map(taskPendingApprovals.value);
+              map.delete(originTaskId);
+              map.set(result.session_id, approvalEntry);
+              taskPendingApprovals.value = map;
+            }
           }
           if (currentTaskId.value === originTaskId) {
             currentTaskId.value = result.session_id;
@@ -1612,6 +1648,14 @@
             taskList.value = taskList.value.filter((t) => t.id !== result.session_id);
             originTask.id = result.session_id;
             historyLoadedTasks.add(result.session_id);
+            // 迁移审批状态 key
+            const approvalEntry = taskPendingApprovals.value.get(originTaskId);
+            if (approvalEntry) {
+              const map = new Map(taskPendingApprovals.value);
+              map.delete(originTaskId);
+              map.set(result.session_id, approvalEntry);
+              taskPendingApprovals.value = map;
+            }
           }
           if (currentTaskId.value === originTaskId) {
             currentTaskId.value = result.session_id;

+ 9 - 0
src/views/ventAI/manageAssistent/components/chatModal/ChatMessages.vue

@@ -557,6 +557,15 @@
   };
 
   const handleSubmitAskUser = (index: number) => {
+    // 防御性初始化:如果答案数组未初始化,从 pendingApprovalData 回退
+    if (!askUserAnswers[index]) {
+      const msg = props.messages[index];
+      if (msg?.pendingApprovalData?.ask_user?.questions) {
+        initAskUserAnswers(index, msg.pendingApprovalData.ask_user.questions);
+      } else {
+        return;
+      }
+    }
     const answers = askUserAnswers[index];
     if (!answers) return;
     emit('ask-user-submit', [...answers]);