Add files via upload

This commit is contained in:
公明 authored and GitHub committed 2026-05-27 19:56:08 +08:00
1 parent cf09dd36d8
commit 0c9c2ec606
1 file changed
+50 -21
+50 -21
View File
@@ -208,17 +208,31 @@ if (typeof window !== 'undefined') {
window.formatTimelineStreamBody = formatTimelineStreamBody; window.formatTimelineStreamBody = formatTimelineStreamBody;
} }
// 存储工具调用ID到DOM元素的映射,用于更新执行状态 // 存储工具调用ID到DOM元素的映射,用于更新执行状态。
// 键必须带 progressId 作用域,避免不同任务复用相同 toolCallId 时串线。
const toolCallStatusMap = new Map(); const toolCallStatusMap = new Map();
function toolCallMapKey(progressId, toolCallId) {
return String(progressId) + '::' + String(toolCallId);
}
function getToolCallMapping(progressId, toolCallId) {
if (!toolCallId) return null;
const scoped = toolCallStatusMap.get(toolCallMapKey(progressId, toolCallId));
if (scoped) return scoped;
// 兼容历史遗留:若 map 中还有旧格式 key(仅 toolCallId),兜底读取。
return toolCallStatusMap.get(String(toolCallId)) || null;
}
function finalizeOutstandingToolCallsForProgress(progressId, finalStatus) { function finalizeOutstandingToolCallsForProgress(progressId, finalStatus) {
if (!progressId) return; if (!progressId) return;
const pid = String(progressId); const pid = String(progressId);
for (const [toolCallId, mapping] of Array.from(toolCallStatusMap.entries())) { for (const [mapKey, mapping] of Array.from(toolCallStatusMap.entries())) {
if (!mapping) continue; if (!mapping) continue;
if (mapping.progressId != null && String(mapping.progressId) !== pid) continue; if (mapping.progressId != null && String(mapping.progressId) !== pid) continue;
updateToolCallStatus(toolCallId, finalStatus); const tcid = mapping.toolCallId || (String(mapKey).includes('::') ? String(mapKey).split('::').slice(1).join('::') : String(mapKey));
toolCallStatusMap.delete(toolCallId); updateToolCallStatus(mapping.progressId || progressId, tcid, finalStatus);
toolCallStatusMap.delete(mapKey);
} }
} }
@@ -1601,6 +1615,17 @@ function handleStreamEvent(event, progressElement, progressId,
const index = toolInfo.index || 0; const index = toolInfo.index || 0;
const total = toolInfo.total || 0; const total = toolInfo.total || 0;
const toolCallId = toolInfo.toolCallId || null; const toolCallId = toolInfo.toolCallId || null;
if (toolCallId) {
const existing = getToolCallMapping(progressId, toolCallId);
if (existing && existing.itemId) {
const existingItem = document.getElementById(existing.itemId);
if (existingItem) {
// 同一 toolCallId 的重复 tool_call(重试/补发)只更新状态,不重复追加条目。
updateToolCallStatus(progressId, toolCallId, 'running');
break;
}
}
}
const toolCallTitle = formatToolCallTimelineTitle(toolName, index, total); const toolCallTitle = formatToolCallTimelineTitle(toolName, index, total);
const toolCallItemId = addTimelineItem(timeline, 'tool_call', { const toolCallItemId = addTimelineItem(timeline, 'tool_call', {
title: timelineAgentBracketPrefix(toolInfo) + '🔧 ' + toolCallTitle, title: timelineAgentBracketPrefix(toolInfo) + '🔧 ' + toolCallTitle,
@@ -1611,14 +1636,16 @@ function handleStreamEvent(event, progressElement, progressId,
// 如果有toolCallId,存储映射关系以便后续更新状态 // 如果有toolCallId,存储映射关系以便后续更新状态
if (toolCallId && toolCallItemId) { if (toolCallId && toolCallItemId) {
toolCallStatusMap.set(toolCallId, { const mapKey = toolCallMapKey(progressId, toolCallId);
toolCallStatusMap.set(mapKey, {
toolCallId: toolCallId,
itemId: toolCallItemId, itemId: toolCallItemId,
timeline: timeline, timeline: timeline,
progressId: progressId progressId: progressId
}); });
// 添加执行中状态指示器 // 添加执行中状态指示器
updateToolCallStatus(toolCallId, 'running'); updateToolCallStatus(progressId, toolCallId, 'running');
} }
break; break;
@@ -1633,7 +1660,7 @@ function handleStreamEvent(event, progressElement, progressId,
if (!deltaText) break; if (!deltaText) break;
if (!state) { if (!state) {
const mapping = toolCallStatusMap.get(toolCallId); const mapping = getToolCallMapping(progressId, toolCallId);
let callItemId = mapping && mapping.itemId ? mapping.itemId : null; let callItemId = mapping && mapping.itemId ? mapping.itemId : null;
if (callItemId) { if (callItemId) {
const callItem = document.getElementById(callItemId); const callItem = document.getElementById(callItemId);
@@ -1679,24 +1706,26 @@ function handleStreamEvent(event, progressElement, progressId,
mergeToolResultIntoCallItem(streamCallItem, resultInfo); mergeToolResultIntoCallItem(streamCallItem, resultInfo);
} }
toolResultStreamStateByKey.delete(key); toolResultStreamStateByKey.delete(key);
if (toolCallStatusMap.has(resultToolCallId)) { const mapKey = toolCallMapKey(progressId, resultToolCallId);
updateToolCallStatus(resultToolCallId, success ? 'completed' : 'failed'); if (toolCallStatusMap.has(mapKey)) {
toolCallStatusMap.delete(resultToolCallId); updateToolCallStatus(progressId, resultToolCallId, success ? 'completed' : 'failed');
toolCallStatusMap.delete(mapKey);
} }
break; break;
} }
if (attachToolResultToCall(resultToolCallId, resultInfo)) { if (attachToolResultToCall(progressId, resultToolCallId, resultInfo)) {
if (toolCallStatusMap.has(resultToolCallId)) { const mapKey = toolCallMapKey(progressId, resultToolCallId);
updateToolCallStatus(resultToolCallId, success ? 'completed' : 'failed'); if (toolCallStatusMap.has(mapKey)) {
toolCallStatusMap.delete(resultToolCallId); updateToolCallStatus(progressId, resultToolCallId, success ? 'completed' : 'failed');
toolCallStatusMap.delete(mapKey);
} }
break; break;
} }
} }
if (resultToolCallId && toolCallStatusMap.has(resultToolCallId)) { if (resultToolCallId && toolCallStatusMap.has(toolCallMapKey(progressId, resultToolCallId))) {
updateToolCallStatus(resultToolCallId, success ? 'completed' : 'failed'); updateToolCallStatus(progressId, resultToolCallId, success ? 'completed' : 'failed');
toolCallStatusMap.delete(resultToolCallId); toolCallStatusMap.delete(toolCallMapKey(progressId, resultToolCallId));
} }
addTimelineItem(timeline, 'tool_result', { addTimelineItem(timeline, 'tool_result', {
title: timelineAgentBracketPrefix(resultInfo) + statusIcon + ' ' + resultExecText, title: timelineAgentBracketPrefix(resultInfo) + statusIcon + ' ' + resultExecText,
@@ -2676,9 +2705,9 @@ function findToolCallItemById(root, toolCallId) {
} }
} }
function attachToolResultToCall(toolCallId, data, options) { function attachToolResultToCall(progressId, toolCallId, data, options) {
if (!toolCallId || !data) return false; if (!toolCallId || !data) return false;
const mapping = toolCallStatusMap.get(toolCallId); const mapping = getToolCallMapping(progressId, toolCallId);
let item = null; let item = null;
if (mapping && mapping.itemId) { if (mapping && mapping.itemId) {
item = document.getElementById(mapping.itemId); item = document.getElementById(mapping.itemId);
@@ -2755,8 +2784,8 @@ window.parseToolCallArgsFromData = parseToolCallArgsFromData;
window.buildToolResultSectionHtml = buildToolResultSectionHtml; window.buildToolResultSectionHtml = buildToolResultSectionHtml;
// 更新工具调用状态 // 更新工具调用状态
function updateToolCallStatus(toolCallId, status) { function updateToolCallStatus(progressId, toolCallId, status) {
const mapping = toolCallStatusMap.get(toolCallId); const mapping = getToolCallMapping(progressId, toolCallId);
if (!mapping) return; if (!mapping) return;
const item = document.getElementById(mapping.itemId); const item = document.getElementById(mapping.itemId);