fix: 彻底修复 TDZ 错误和用户消息不显示问题
1. agent-engine.ts: onNewIteration 改用 prevToolCalls 传递上一轮工具调用, 避免引用未声明的 toolCalls 导致 TDZ (Cannot access 'B' before initialization) 2. chat-area.ts: 新增 resetCurrentPlaceholder() 清理悬空 DOM 引用 3. input-area.ts: 错误处理器删除 placeholder 后清理 currentPlaceholder 引用, 防止后续 updateLastAssistantMessage 操作已脱离 DOM 的旧节点
This commit is contained in:
@@ -495,6 +495,13 @@ export function clearMessages(): void {
|
||||
currentPlaceholder = null;
|
||||
}
|
||||
|
||||
/** 清理 currentPlaceholder 引用(当 placeholder 从外部被移除时调用) */
|
||||
export function resetCurrentPlaceholder(): void {
|
||||
if (currentPlaceholder && !currentPlaceholder.isConnected) {
|
||||
currentPlaceholder = null;
|
||||
}
|
||||
}
|
||||
|
||||
export function enableAutoScroll(): void {
|
||||
autoScroll = true;
|
||||
if (scrollBtnEl) scrollBtnEl.style.display = 'none';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getSelectedModel, isThinkEnabled, isVisionAvailable, isToolCallingSuppo
|
||||
import {
|
||||
renderMessages, clearMessagesDOM, appendAssistantPlaceholder, appendSystemMessage,
|
||||
updateLastAssistantMessage, clearMessages, safeMarkdown, enableAutoScroll, updateTotalTokens,
|
||||
appendToolCallCardToPlaceholder, updateToolCallCardInPlaceholder
|
||||
appendToolCallCardToPlaceholder, updateToolCallCardInPlaceholder, resetCurrentPlaceholder
|
||||
} from './chat-area.js';
|
||||
import { showToast } from './toast.js';
|
||||
import { addToolCard, updateToolCard, clearToolCardsExternal, clearTerminalExternal } from './workspace-panel.js';
|
||||
@@ -1109,8 +1109,10 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
|
||||
placeholder.classList.remove('loading');
|
||||
placeholder.querySelector('.loading-dots')?.remove();
|
||||
placeholder.querySelector('.loading-text')?.remove();
|
||||
if (!assistantContent) placeholder.remove();
|
||||
else {
|
||||
if (!assistantContent) {
|
||||
placeholder.remove();
|
||||
resetCurrentPlaceholder();
|
||||
} else {
|
||||
const contentDiv = placeholder.querySelector('.msg-content');
|
||||
if (contentDiv) contentDiv.innerHTML = safeMarkdown(assistantContent) + '<p><code>[已中断]</code></p>';
|
||||
}
|
||||
|
||||
@@ -513,8 +513,8 @@ export async function runAgentLoop(
|
||||
let totalEvalCount = 0;
|
||||
/** 跨轮去重:仅跟踪成功的工具调用(失败的允许重试) */
|
||||
let prevLoopSuccessKeys: string[] = [];
|
||||
/** 每轮工具调用计数(用于去重) */
|
||||
let allCallsThisLoop: ToolCall[] = [];
|
||||
/** 保存上一轮的工具调用,供 onNewIteration 使用 */
|
||||
let prevToolCalls: ToolCall[] = [];
|
||||
|
||||
const makeStats = () => {
|
||||
const totalDuration = (Date.now() - loopStartTime) * 1e6;
|
||||
@@ -535,7 +535,7 @@ export async function runAgentLoop(
|
||||
|
||||
// 非首轮迭代:通知 UI 创建新的消息气泡(防止每轮内容互相覆盖)
|
||||
if (loopCount > 1 && callbacks.onNewIteration) {
|
||||
callbacks.onNewIteration(toolCalls.length > 0 ? toolCalls : undefined);
|
||||
callbacks.onNewIteration(prevToolCalls.length > 0 ? prevToolCalls : undefined);
|
||||
}
|
||||
|
||||
logAgentLoop(loopCount, maxLoops);
|
||||
@@ -543,7 +543,6 @@ export async function runAgentLoop(
|
||||
let thinking = '';
|
||||
content = '';
|
||||
const toolCalls: ToolCall[] = [];
|
||||
allCallsThisLoop = [];
|
||||
|
||||
// v5.1.2 预算警告:接近迭代上限时注入临时提示
|
||||
let budgetWarningIdx = -1;
|
||||
@@ -873,6 +872,9 @@ export async function runAgentLoop(
|
||||
`${r.name}: ${r.result?.success ? 'success' : 'error'}`
|
||||
).join('; ');
|
||||
saveTrace(traceStep);
|
||||
|
||||
// 保存本轮工具调用,供下一轮 onNewIteration 使用
|
||||
prevToolCalls = toolCalls;
|
||||
}
|
||||
|
||||
logWarn('ReAct Agent Loop 达到最大工具调用次数限制');
|
||||
|
||||
Reference in New Issue
Block a user