From cd68812743af370e9e09eb5f4e99029f2572041f Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Mon, 9 Mar 2026 16:31:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E6=97=B6=E6=80=9D=E8=80=83=E5=9D=97=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=B1=95=E5=BC=80=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在历史加载时给思考块设置 collapsed: true 默认折叠 - 在任务恢复时跳过思考块的展开/折叠动画 - 延迟清除 _rebuildingFromScratch 标记,确保所有历史事件处理完毕 - 删除过早清除重建标记的逻辑,避免后续思考块被展开 Co-Authored-By: Claude Sonnet 4.5 --- static/src/app/methods/history.ts | 1 + static/src/app/methods/taskPolling.ts | 220 +++++++++++++------------- 2 files changed, 114 insertions(+), 107 deletions(-) diff --git a/static/src/app/methods/history.ts b/static/src/app/methods/history.ts index eb57c54..54eccdf 100644 --- a/static/src/app/methods/history.ts +++ b/static/src/app/methods/history.ts @@ -194,6 +194,7 @@ export const historyMethods = { type: 'thinking', content: reasoningText, streaming: false, + collapsed: true, timestamp: Date.now(), blockId }); diff --git a/static/src/app/methods/taskPolling.ts b/static/src/app/methods/taskPolling.ts index 5bcd6bb..82cccd0 100644 --- a/static/src/app/methods/taskPolling.ts +++ b/static/src/app/methods/taskPolling.ts @@ -104,12 +104,8 @@ export const taskPollingMethods = { debugLog(`[TaskPolling] 未知事件类型: ${eventType}`); } - // 如果正在从头重建,检查是否已经处理到当前事件 - // 当处理到工具相关事件时,说明思考已经结束,可以清除重建标记 - if (this._rebuildingFromScratch && (eventType === 'tool_preparing' || eventType === 'tool_start')) { - debugLog('[TaskPolling] 检测到工具事件,清除重建标记'); - this._rebuildingFromScratch = false; - } + // 注意:不要在这里清除 _rebuildingFromScratch 标记 + // 该标记应该在恢复完所有历史事件后才清除 }, handleAiMessageStart(data: any, eventIdx: number) { @@ -160,42 +156,48 @@ export const taskPollingMethods = { this.monitorShowThinking(); - // 获取当前 actions 数量,用于调试 - const lastMessage = this.messages[this.messages.length - 1]; - const beforeCount = lastMessage?.actions?.length || 0; - console.log('[TaskPolling] 添加思考块前,actions 数量:', beforeCount); - console.log('[TaskPolling] 当前 currentMessageIndex:', this.currentMessageIndex); - console.log('[TaskPolling] messages 总数:', this.messages.length); - console.log('[TaskPolling] 最后一条消息 role:', lastMessage?.role); + // 获取当前 actions 数量,用于调试(已禁用) + // const lastMessage = this.messages[this.messages.length - 1]; + // const beforeCount = lastMessage?.actions?.length || 0; + // console.log('[TaskPolling] 添加思考块前,actions 数量:', beforeCount); + // console.log('[TaskPolling] 当前 currentMessageIndex:', this.currentMessageIndex); + // console.log('[TaskPolling] messages 总数:', this.messages.length); + // console.log('[TaskPolling] 最后一条消息 role:', lastMessage?.role); const result = this.chatStartThinkingAction(); - console.log('[TaskPolling] chatStartThinkingAction 返回:', result); + // console.log('[TaskPolling] chatStartThinkingAction 返回:', result); if (result && result.blockId) { const blockId = result.blockId; - // 检查新添加的 action - const afterCount = lastMessage?.actions?.length || 0; - console.log('[TaskPolling] 添加思考块后,actions 数量:', afterCount); + // 检查新添加的 action(已禁用) + // const afterCount = lastMessage?.actions?.length || 0; + // console.log('[TaskPolling] 添加思考块后,actions 数量:', afterCount); - // 检查 currentMessageIndex 指向的消息 - const currentMsg = this.messages[this.currentMessageIndex]; - if (currentMsg) { - console.log('[TaskPolling] currentMessageIndex 指向的消息 actions 数量:', currentMsg.actions?.length || 0); + // 检查 currentMessageIndex 指向的消息(已禁用) + // const currentMsg = this.messages[this.currentMessageIndex]; + // if (currentMsg) { + // console.log('[TaskPolling] currentMessageIndex 指向的消息 actions 数量:', currentMsg.actions?.length || 0); + // } + + // if (afterCount > beforeCount) { + // const newAction = lastMessage.actions[afterCount - 1]; + // console.log('[TaskPolling] 新添加的思考块:', { + // type: newAction.type, + // blockId: newAction.blockId, + // hasId: !!newAction.id, + // timestamp: newAction.timestamp + // }); + // } + + const lastMessage = this.messages[this.messages.length - 1]; + + // 只在非历史恢复时展开思考块 + if (!this._rebuildingFromScratch) { + this.chatExpandBlock(blockId); } - if (afterCount > beforeCount) { - const newAction = lastMessage.actions[afterCount - 1]; - console.log('[TaskPolling] 新添加的思考块:', { - type: newAction.type, - blockId: newAction.blockId, - hasId: !!newAction.id, - timestamp: newAction.timestamp - }); - } - - this.chatExpandBlock(blockId); this.scrollToBottom(); this.chatSetThinkingLock(blockId, true); @@ -235,11 +237,17 @@ export const taskPollingMethods = { // 解锁思考块 this.chatSetThinkingLock(blockId, false); - // 延迟折叠思考块(给用户一点时间看到思考完成) - setTimeout(() => { + // 只在非历史恢复时延迟折叠思考块 + if (!this._rebuildingFromScratch) { + // 延迟折叠思考块(给用户一点时间看到思考完成) + setTimeout(() => { + this.chatCollapseBlock(blockId); + this.$forceUpdate(); + }, 1000); + } else { + // 历史恢复时立即折叠,不需要动画 this.chatCollapseBlock(blockId); - this.$forceUpdate(); - }, 1000); + } this.$nextTick(() => this.scrollThinkingToBottom(blockId)); } @@ -641,12 +649,12 @@ export const taskPollingMethods = { const lastMessage = this.messages[this.messages.length - 1]; const isAssistantMessage = lastMessage && lastMessage.role === 'assistant'; - console.log('[TaskPolling] 最后一条消息:', { - exists: !!lastMessage, - role: lastMessage?.role, - actionsCount: lastMessage?.actions?.length || 0, - isAssistant: isAssistantMessage - }); + // console.log('[TaskPolling] 最后一条消息:', { + // exists: !!lastMessage, + // role: lastMessage?.role, + // actionsCount: lastMessage?.actions?.length || 0, + // isAssistant: isAssistantMessage + // }); // 检查是否需要从头重建 // 1. 最后一条不是 assistant 消息 @@ -661,13 +669,13 @@ export const taskPollingMethods = { historyIncomplete; if (needsRebuild) { - if (historyIncomplete) { - console.log('[TaskPolling] 历史不完整,从头重建:', { - historyActionsCount, - eventCount, - diff: eventCount - historyActionsCount - }); - } + // if (historyIncomplete) { + // console.log('[TaskPolling] 历史不完整,从头重建:', { + // historyActionsCount, + // eventCount, + // diff: eventCount - historyActionsCount + // }); + // } debugLog('[TaskPolling] 需要从头重建 assistant 响应'); // 清空所有消息,准备从头重建 @@ -687,6 +695,7 @@ export const taskPollingMethods = { // 标记正在从头重建,用于后续处理 this._rebuildingFromScratch = true; + this._rebuildingEventCount = allEvents.length; // 记录当前事件总数 (window as any).__taskEventHandler = (event: any) => { this.handleTaskEvent(event); @@ -695,6 +704,14 @@ export const taskPollingMethods = { taskStore.startPolling((event: any) => { this.handleTaskEvent(event); }); + + // 延迟清除重建标记,确保所有历史事件都处理完毕 + setTimeout(() => { + debugLog('[TaskPolling] 历史事件处理完毕,清除重建标记'); + this._rebuildingFromScratch = false; + this._rebuildingEventCount = 0; + }, 2000); + return; } @@ -718,95 +735,84 @@ export const taskPollingMethods = { } } - console.log('[TaskPolling] 分析结果:', { - inThinking, - inText, - totalEvents: allEvents.length, - lastEventType: allEvents[allEvents.length - 1]?.type, - lastEventIdx: allEvents[allEvents.length - 1]?.idx - }); + // console.log('[TaskPolling] 分析结果:', { + // inThinking, + // inText, + // totalEvents: allEvents.length, + // lastEventType: allEvents[allEvents.length - 1]?.type, + // lastEventIdx: allEvents[allEvents.length - 1]?.idx + // }); // 恢复思考块状态 if (lastMessage.actions) { - console.log('[TaskPolling] 历史中的 actions 详情:', lastMessage.actions.map((a, idx) => ({ - index: idx, - type: a.type, - id: a.id, - hasContent: !!a.content, - contentLength: a.content?.length || 0, - toolName: a.tool?.name, - hasBlockId: !!a.blockId, - blockId: a.blockId, - collapsed: a.collapsed, - streaming: a.streaming - }))); + // console.log('[TaskPolling] 历史中的 actions 详情:', lastMessage.actions.map((a, idx) => ({ + // index: idx, + // type: a.type, + // id: a.id, + // hasContent: !!a.content, + // contentLength: a.content?.length || 0, + // toolName: a.tool?.name, + // hasBlockId: !!a.blockId, + // blockId: a.blockId, + // collapsed: a.collapsed, + // streaming: a.streaming + // }))); const thinkingActions = lastMessage.actions.filter(a => a.type === 'thinking'); - console.log('[TaskPolling] 思考块数量:', thinkingActions.length); + // console.log('[TaskPolling] 思考块数量:', thinkingActions.length); if (inThinking && thinkingActions.length > 0) { // 正在思考中,检查最后一个思考块是否正在流式输出 const lastThinking = thinkingActions[thinkingActions.length - 1]; - // 只有当思考块正在流式输出时才展开 + // 只有当思考块正在流式输出时才设置锁定状态(但不展开) if (lastThinking.streaming && lastThinking.blockId) { - console.log('[TaskPolling] 找到正在流式输出的思考块,展开:', lastThinking.blockId); - lastThinking.collapsed = false; + // console.log('[TaskPolling] 找到正在流式输出的思考块,设置锁定状态:', lastThinking.blockId); this.$nextTick(() => { - this.chatExpandBlock(lastThinking.blockId); this.chatSetThinkingLock(lastThinking.blockId, true); }); - } else { - console.log('[TaskPolling] 没有找到正在流式输出的思考块,不展开'); - // 折叠所有思考块 - for (const thinking of thinkingActions) { - if (thinking.blockId) { - thinking.collapsed = true; - } - } - } - } else { - // 不在思考中,折叠所有思考块 - console.log('[TaskPolling] 不在思考中,折叠所有思考块'); - for (const thinking of thinkingActions) { - if (thinking.blockId) { - thinking.collapsed = true; - } } } - // 检查思考块状态(在设置之后) - thinkingActions.forEach((thinking, idx) => { - console.log(`[TaskPolling] 思考块 ${idx} (设置后):`, { - hasBlockId: !!thinking.blockId, - blockId: thinking.blockId, - collapsed: thinking.collapsed, - contentLength: thinking.content?.length || 0 - }); - }); + // 确保所有思考块都是折叠状态 + for (const thinking of thinkingActions) { + if (thinking.blockId) { + thinking.collapsed = true; + } + } + + // 检查思考块状态(在设置之后)(已禁用) + // thinkingActions.forEach((thinking, idx) => { + // console.log(`[TaskPolling] 思考块 ${idx} (设置后):`, { + // hasBlockId: !!thinking.blockId, + // blockId: thinking.blockId, + // collapsed: thinking.collapsed, + // contentLength: thinking.content?.length || 0 + // }); + // }); // 恢复文本块状态 const textActions = lastMessage.actions.filter(a => a.type === 'text'); - console.log('[TaskPolling] 文本块数量:', textActions.length); + // console.log('[TaskPolling] 文本块数量:', textActions.length); if (inText && textActions.length > 0) { const lastText = textActions[textActions.length - 1]; - console.log('[TaskPolling] 标记文本块为流式状态'); + // console.log('[TaskPolling] 标记文本块为流式状态'); lastText.streaming = true; } // 注册历史中的工具块到 toolActionIndex // 这样后续的 update_action 事件可以找到对应的块进行状态更新 const toolActions = lastMessage.actions.filter(a => a.type === 'tool'); - console.log('[TaskPolling] 工具块数量:', toolActions.length); + // console.log('[TaskPolling] 工具块数量:', toolActions.length); for (const toolAction of toolActions) { if (toolAction.tool && toolAction.tool.id) { - console.log('[TaskPolling] 注册工具块:', { - id: toolAction.tool.id, - name: toolAction.tool.name, - status: toolAction.tool.status - }); + // console.log('[TaskPolling] 注册工具块:', { + // id: toolAction.tool.id, + // name: toolAction.tool.name, + // status: toolAction.tool.status + // }); // 注册到 toolActionIndex this.toolRegisterAction(toolAction, toolAction.tool.id); // 如果有 executionId,也注册 @@ -830,7 +836,7 @@ export const taskPollingMethods = { const lastMessageIndex = this.messages.length - 1; if (lastMessage && lastMessage.role === 'assistant') { this.currentMessageIndex = lastMessageIndex; - console.log('[TaskPolling] 设置 currentMessageIndex 为:', lastMessageIndex); + // console.log('[TaskPolling] 设置 currentMessageIndex 为:', lastMessageIndex); } // 强制更新界面