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 = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 清理 currentPlaceholder 引用(当 placeholder 从外部被移除时调用) */
|
||||||
|
export function resetCurrentPlaceholder(): void {
|
||||||
|
if (currentPlaceholder && !currentPlaceholder.isConnected) {
|
||||||
|
currentPlaceholder = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function enableAutoScroll(): void {
|
export function enableAutoScroll(): void {
|
||||||
autoScroll = true;
|
autoScroll = true;
|
||||||
if (scrollBtnEl) scrollBtnEl.style.display = 'none';
|
if (scrollBtnEl) scrollBtnEl.style.display = 'none';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { getSelectedModel, isThinkEnabled, isVisionAvailable, isToolCallingSuppo
|
|||||||
import {
|
import {
|
||||||
renderMessages, clearMessagesDOM, appendAssistantPlaceholder, appendSystemMessage,
|
renderMessages, clearMessagesDOM, appendAssistantPlaceholder, appendSystemMessage,
|
||||||
updateLastAssistantMessage, clearMessages, safeMarkdown, enableAutoScroll, updateTotalTokens,
|
updateLastAssistantMessage, clearMessages, safeMarkdown, enableAutoScroll, updateTotalTokens,
|
||||||
appendToolCallCardToPlaceholder, updateToolCallCardInPlaceholder
|
appendToolCallCardToPlaceholder, updateToolCallCardInPlaceholder, resetCurrentPlaceholder
|
||||||
} from './chat-area.js';
|
} from './chat-area.js';
|
||||||
import { showToast } from './toast.js';
|
import { showToast } from './toast.js';
|
||||||
import { addToolCard, updateToolCard, clearToolCardsExternal, clearTerminalExternal } from './workspace-panel.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.classList.remove('loading');
|
||||||
placeholder.querySelector('.loading-dots')?.remove();
|
placeholder.querySelector('.loading-dots')?.remove();
|
||||||
placeholder.querySelector('.loading-text')?.remove();
|
placeholder.querySelector('.loading-text')?.remove();
|
||||||
if (!assistantContent) placeholder.remove();
|
if (!assistantContent) {
|
||||||
else {
|
placeholder.remove();
|
||||||
|
resetCurrentPlaceholder();
|
||||||
|
} else {
|
||||||
const contentDiv = placeholder.querySelector('.msg-content');
|
const contentDiv = placeholder.querySelector('.msg-content');
|
||||||
if (contentDiv) contentDiv.innerHTML = safeMarkdown(assistantContent) + '<p><code>[已中断]</code></p>';
|
if (contentDiv) contentDiv.innerHTML = safeMarkdown(assistantContent) + '<p><code>[已中断]</code></p>';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -513,8 +513,8 @@ export async function runAgentLoop(
|
|||||||
let totalEvalCount = 0;
|
let totalEvalCount = 0;
|
||||||
/** 跨轮去重:仅跟踪成功的工具调用(失败的允许重试) */
|
/** 跨轮去重:仅跟踪成功的工具调用(失败的允许重试) */
|
||||||
let prevLoopSuccessKeys: string[] = [];
|
let prevLoopSuccessKeys: string[] = [];
|
||||||
/** 每轮工具调用计数(用于去重) */
|
/** 保存上一轮的工具调用,供 onNewIteration 使用 */
|
||||||
let allCallsThisLoop: ToolCall[] = [];
|
let prevToolCalls: ToolCall[] = [];
|
||||||
|
|
||||||
const makeStats = () => {
|
const makeStats = () => {
|
||||||
const totalDuration = (Date.now() - loopStartTime) * 1e6;
|
const totalDuration = (Date.now() - loopStartTime) * 1e6;
|
||||||
@@ -535,7 +535,7 @@ export async function runAgentLoop(
|
|||||||
|
|
||||||
// 非首轮迭代:通知 UI 创建新的消息气泡(防止每轮内容互相覆盖)
|
// 非首轮迭代:通知 UI 创建新的消息气泡(防止每轮内容互相覆盖)
|
||||||
if (loopCount > 1 && callbacks.onNewIteration) {
|
if (loopCount > 1 && callbacks.onNewIteration) {
|
||||||
callbacks.onNewIteration(toolCalls.length > 0 ? toolCalls : undefined);
|
callbacks.onNewIteration(prevToolCalls.length > 0 ? prevToolCalls : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
logAgentLoop(loopCount, maxLoops);
|
logAgentLoop(loopCount, maxLoops);
|
||||||
@@ -543,7 +543,6 @@ export async function runAgentLoop(
|
|||||||
let thinking = '';
|
let thinking = '';
|
||||||
content = '';
|
content = '';
|
||||||
const toolCalls: ToolCall[] = [];
|
const toolCalls: ToolCall[] = [];
|
||||||
allCallsThisLoop = [];
|
|
||||||
|
|
||||||
// v5.1.2 预算警告:接近迭代上限时注入临时提示
|
// v5.1.2 预算警告:接近迭代上限时注入临时提示
|
||||||
let budgetWarningIdx = -1;
|
let budgetWarningIdx = -1;
|
||||||
@@ -873,6 +872,9 @@ export async function runAgentLoop(
|
|||||||
`${r.name}: ${r.result?.success ? 'success' : 'error'}`
|
`${r.name}: ${r.result?.success ? 'success' : 'error'}`
|
||||||
).join('; ');
|
).join('; ');
|
||||||
saveTrace(traceStep);
|
saveTrace(traceStep);
|
||||||
|
|
||||||
|
// 保存本轮工具调用,供下一轮 onNewIteration 使用
|
||||||
|
prevToolCalls = toolCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
logWarn('ReAct Agent Loop 达到最大工具调用次数限制');
|
logWarn('ReAct Agent Loop 达到最大工具调用次数限制');
|
||||||
|
|||||||
Reference in New Issue
Block a user