From 87d3364886b9619414f9cf1d16994cf1e861f142 Mon Sep 17 00:00:00 2001 From: thzxx Date: Sat, 13 Jun 2026 07:42:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=9A=E6=97=B6=E5=99=A815=E7=A7=92?= =?UTF-8?q?=E9=97=B4=E9=9A=94=20+=20=E6=BB=9A=E5=8A=A8rAF=20+=20=E9=97=B2?= =?UTF-8?q?=E7=BD=AE=E8=BF=BD=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 流式进度定时器改为15秒间隔 - lastContentTime 追踪真正的无新内容时长 - appendToolCardDOM/renderToolCalls 用 rAF 确保布局后滚动 --- src/renderer/components/workspace-panel.ts | 12 +++++++---- src/renderer/services/agent-engine.ts | 25 +++++++++++----------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/renderer/components/workspace-panel.ts b/src/renderer/components/workspace-panel.ts index 10a3149..9fdb68b 100644 --- a/src/renderer/components/workspace-panel.ts +++ b/src/renderer/components/workspace-panel.ts @@ -831,8 +831,10 @@ function appendToolCardDOM(tc: ToolCallRecord): void { if (card) { card.dataset.toolName = tc.name; container.appendChild(card); - // 新卡片出现时始终滚到底部(用户需要看到最新的工具状态) - container.scrollTop = container.scrollHeight; + // 等浏览器完成布局后再滚到底部 + requestAnimationFrame(() => { + container.scrollTop = container.scrollHeight; + }); } } @@ -936,8 +938,10 @@ function renderToolCalls(): void { html += renderToolCard(tc); } container.innerHTML = html; - // 全量渲染后滚到底部 - container.scrollTop = container.scrollHeight; + // 等浏览器完成布局后再滚到底部 + requestAnimationFrame(() => { + container.scrollTop = container.scrollHeight; + }); } function getToolDisplayName(name: string): string { diff --git a/src/renderer/services/agent-engine.ts b/src/renderer/services/agent-engine.ts index e3b6fb7..8d55bbe 100644 --- a/src/renderer/services/agent-engine.ts +++ b/src/renderer/services/agent-engine.ts @@ -717,23 +717,24 @@ Shell: ${osInfo.shell} // 流式调用 const streamStartTime = Date.now(); let lastLoggedLen = 0; - let lastProgressAt = 0; - const PROGRESS_INTERVAL = 5000; // 每5秒输出一次流式进度 + let lastContentTime = streamStartTime; // 追踪最后一次收到新内容的时间 + const PROGRESS_INTERVAL = 15000; // 每15秒输出一次流式进度 // ── 独立定时器:即使没有新 chunk 也会持续输出进度 ── progressTimer = setInterval(() => { const elapsed = Date.now() - streamStartTime; const grew = content.length - lastLoggedLen; - const sinceLast = elapsed - lastProgressAt; - if (sinceLast >= PROGRESS_INTERVAL) { - lastProgressAt = elapsed; - const sec = Math.round(elapsed / 1000); - if (grew > 0) { - lastLoggedLen = content.length; - logStream(`流式输出中… ${content.length} 字 / ${sec}s${toolCalls.length > 0 ? ` [${toolCalls.length} 个工具调用]` : ''}`); - } else if (elapsed > 15000 && content.length > 0) { - // 超过 15 秒无新内容 → 可能模型卡住了 - logStream(`⚠️ 无新内容 ${Math.round(sinceLast / 1000)}s,当前 ${content.length} 字`); + const sec = Math.round(elapsed / 1000); + if (grew > 0) { + // 有新增内容 → 正常进度 + lastLoggedLen = content.length; + lastContentTime = Date.now(); + logStream(`流式输出中… ${content.length} 字 / ${sec}s${toolCalls.length > 0 ? ` [${toolCalls.length} 个工具调用]` : ''}`); + } else if (content.length > 0) { + // 内容不变 → 计算真正的无新内容时长 + const idleSec = Math.round((Date.now() - lastContentTime) / 1000); + if (idleSec >= 10) { + logStream(`⚠️ ${idleSec}s 无新内容,当前 ${content.length} 字`); } } }, PROGRESS_INTERVAL);