diff --git a/web/static/js/chat.js b/web/static/js/chat.js index 28781313..b2384aac 100644 --- a/web/static/js/chat.js +++ b/web/static/js/chat.js @@ -105,10 +105,12 @@ async function sendMessage() { // 显示用户消息 addMessage('user', message); - // 立即清空输入框并清除草稿(在发送请求之前) - input.value = ''; - // 强制重置输入框高度为初始高度(44px) - input.style.height = '44px'; + // 清除防抖定时器,防止在清空输入框后重新保存草稿 + if (draftSaveTimer) { + clearTimeout(draftSaveTimer); + draftSaveTimer = null; + } + // 立即清除草稿,防止页面刷新时恢复 clearChatDraft(); // 使用同步方式确保草稿被清除 @@ -118,6 +120,11 @@ async function sendMessage() { // 忽略错误 } + // 立即清空输入框并清除草稿(在发送请求之前) + input.value = ''; + // 强制重置输入框高度为初始高度(44px) + input.style.height = '44px'; + // 创建进度消息容器(使用详细的进度展示) const progressId = addProgressMessage(); const progressElement = document.getElementById(progressId); @@ -1162,8 +1169,19 @@ function startNewConversation() { updateActiveConversation(); // 刷新对话列表,确保显示最新的历史对话 loadConversations(); - // 恢复草稿(新对话时也保留用户输入) - restoreChatDraft(); + // 清除防抖定时器,防止恢复草稿时触发保存 + if (draftSaveTimer) { + clearTimeout(draftSaveTimer); + draftSaveTimer = null; + } + // 清除草稿,新对话不应该恢复之前的草稿 + clearChatDraft(); + // 清空输入框 + const chatInput = document.getElementById('chat-input'); + if (chatInput) { + chatInput.value = ''; + chatInput.style.height = '44px'; + } } // 加载对话列表(按时间分组) diff --git a/web/static/js/monitor.js b/web/static/js/monitor.js index f2e7954a..db207402 100644 --- a/web/static/js/monitor.js +++ b/web/static/js/monitor.js @@ -428,7 +428,22 @@ function handleStreamEvent(event, progressElement, progressId, switch (event.type) { case 'conversation': if (event.data && event.data.conversationId) { + // 在更新之前,先获取任务对应的原始对话ID + const taskState = progressTaskState.get(progressId); + const originalConversationId = taskState?.conversationId; + + // 更新任务状态 updateProgressConversation(progressId, event.data.conversationId); + + // 如果用户已经开始了新对话(currentConversationId 为 null), + // 且这个 conversation 事件来自旧对话,就不更新 currentConversationId + if (currentConversationId === null && originalConversationId !== null) { + // 用户已经开始了新对话,忽略旧对话的 conversation 事件 + // 但仍然更新任务状态,以便正确显示任务信息 + break; + } + + // 更新当前对话ID currentConversationId = event.data.conversationId; updateActiveConversation(); addAttackChainButton(currentConversationId); @@ -573,6 +588,10 @@ function handleStreamEvent(event, progressElement, progressId, break; case 'response': + // 在更新之前,先获取任务对应的原始对话ID + const responseTaskState = progressTaskState.get(progressId); + const responseOriginalConversationId = responseTaskState?.conversationId; + // 先添加助手回复 const responseData = event.data || {}; const mcpIds = responseData.mcpExecutionIds || []; @@ -580,6 +599,15 @@ function handleStreamEvent(event, progressElement, progressId, // 更新对话ID if (responseData.conversationId) { + // 如果用户已经开始了新对话(currentConversationId 为 null), + // 且这个 response 事件来自旧对话,就不更新 currentConversationId 也不添加消息 + if (currentConversationId === null && responseOriginalConversationId !== null) { + // 用户已经开始了新对话,忽略旧对话的 response 事件 + // 但仍然更新任务状态,以便正确显示任务信息 + updateProgressConversation(progressId, responseData.conversationId); + break; + } + currentConversationId = responseData.conversationId; updateActiveConversation(); addAttackChainButton(currentConversationId);