Add files via upload

This commit is contained in:
公明
2026-05-19 16:23:21 +08:00
committed by GitHub
parent 59312d428e
commit a022baef03
4 changed files with 390 additions and 111 deletions
+62 -44
View File
@@ -1666,7 +1666,13 @@ function buildWebshellTimelineItemFromDetail(detail) {
var tn = data.toolName || ((typeof window.t === 'function') ? window.t('chat.unknownTool') : '未知工具');
var idx = data.index || 0;
var total = data.total || 0;
title = ap + '🔧 ' + ((typeof window.t === 'function') ? window.t('chat.callTool', { name: tn, index: idx, total: total }) : ('调用: ' + tn + (total ? ' (' + idx + '/' + total + ')' : '')));
var wsHint = typeof window.toolCallArgHint === 'function'
? window.toolCallArgHint(typeof window.parseToolCallArgsFromData === 'function' ? window.parseToolCallArgsFromData(data) : {})
: '';
var wsCallTitle = typeof window.formatToolCallTimelineTitle === 'function'
? window.formatToolCallTimelineTitle(tn, idx, total, wsHint)
: ((typeof window.t === 'function') ? window.t('chat.callTool', { name: tn, index: idx, total: total }) : ('调用: ' + tn + (total ? ' (' + idx + '/' + total + ')' : '')));
title = ap + '🔧 ' + wsCallTitle;
} else if (eventType === 'tool_result') {
var success = data.success !== false;
var tname = data.toolName || '工具';
@@ -1695,6 +1701,9 @@ function buildWebshellTimelineItemFromDetail(detail) {
html += '<div class="webshell-ai-timeline-msg"><div class="tool-arg-section"><strong>' + escapeHtml(paramsLabel) + '</strong><pre class="tool-args">' + escapeHtml(JSON.stringify(args, null, 2)) + '</pre></div></div>';
}
} catch (e) {}
}
if (eventType === 'tool_call' && data && data._mergedResult && typeof window.buildToolResultSectionHtml === 'function') {
html += '<div class="webshell-ai-timeline-msg tool-result-slot">' + window.buildToolResultSectionHtml(data._mergedResult) + '</div>';
} else if (eventType === 'tool_result' && data) {
var isError = data.isError || data.success === false;
var noResultText = (typeof window.t === 'function') ? window.t('timeline.noResult') : '无结果';
@@ -1712,6 +1721,9 @@ function buildWebshellTimelineItemFromDetail(detail) {
// 渲染「执行过程及调用工具」折叠块(默认折叠,刷新后加载历史时保留并可展开)
function renderWebshellProcessDetailsBlock(processDetails, defaultCollapsed) {
if (!processDetails || processDetails.length === 0) return null;
if (typeof window.coalesceProcessDetailsToolPairs === 'function') {
processDetails = window.coalesceProcessDetailsToolPairs(processDetails);
}
var expandLabel = (typeof window.t === 'function') ? window.t('chat.expandDetail') : '展开详情';
var collapseLabel = (typeof window.t === 'function') ? window.t('tasks.collapseDetail') : '收起详情';
var headerLabel = (typeof window.t === 'function') ? (window.t('chat.penetrationTestDetail') || '执行过程及调用工具') : '执行过程及调用工具';
@@ -2772,7 +2784,7 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
var html = '<span class="webshell-ai-timeline-title">' + escapeHtml(title || message || '') + '</span>';
// 工具调用入参
// 工具调用入参 + 结果同卡
if (type === 'tool_call' && data) {
try {
var args = data.argumentsObj;
@@ -2783,14 +2795,20 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
args = { _raw: String(data.arguments) };
}
}
if (args && typeof args === 'object') {
var paramsLabel = (typeof window.t === 'function') ? window.t('timeline.params') : '参数:';
html += '<div class="webshell-ai-timeline-msg"><div class="tool-arg-section"><strong>' +
escapeHtml(paramsLabel) +
'</strong><pre class="tool-args">' +
escapeHtml(JSON.stringify(args, null, 2)) +
'</pre></div></div>';
if (args == null || typeof args !== 'object') {
args = {};
}
var paramsLabel = (typeof window.t === 'function') ? window.t('timeline.params') : '参数:';
var pendingResult = (typeof window.buildToolResultSectionHtml === 'function')
? window.buildToolResultSectionHtml({}, { pending: true })
: '';
html += '<div class="webshell-ai-timeline-msg"><div class="tool-arg-section"><strong>' +
escapeHtml(paramsLabel) +
'</strong><pre class="tool-args">' +
escapeHtml(JSON.stringify(args, null, 2)) +
'</pre></div>' +
(pendingResult ? '<div class="tool-result-slot">' + pendingResult + '</div>' : '') +
'</div>';
} catch (e) {
// JSON 解析失败时忽略参数详情,避免打断主流程
}
@@ -2829,6 +2847,7 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
var einoSubReplyStreams = new Map();
var wsThinkingStreams = new Map(); // streamId → { el, buf }
var wsToolResultStreams = new Map(); // toolCallId → { el, buf }
var wsToolCallItems = new Map(); // toolCallId → DOM item(参数+结果同卡)
if (inputEl) inputEl.value = '';
@@ -3035,11 +3054,16 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
var tn = _ed.toolName || '未知工具';
var idx = _ed.index || 0;
var total = _ed.total || 0;
var callTitle = wsTOr('chat.callTool', '') || ('调用工具: ' + tn + (total ? ' (' + idx + '/' + total + ')' : ''));
if (typeof window.t === 'function') {
try { callTitle = window.t('chat.callTool', { name: tn, index: idx, total: total }); } catch (e) { /* */ }
var wsHintLive = typeof window.toolCallArgHint === 'function'
? window.toolCallArgHint(typeof window.parseToolCallArgsFromData === 'function' ? window.parseToolCallArgsFromData(_ed) : {})
: '';
var callTitle = typeof window.formatToolCallTimelineTitle === 'function'
? window.formatToolCallTimelineTitle(tn, idx, total, wsHintLive)
: (wsTOr('chat.callTool', '') || ('调用工具: ' + tn + (total ? ' (' + idx + '/' + total + ')' : '')));
var callItem = appendTimelineItem('tool_call', webshellAgentPx(_ed) + '🔧 ' + callTitle, _em || '', _ed);
if (_ed.toolCallId && callItem) {
wsToolCallItems.set(_ed.toolCallId, callItem);
}
appendTimelineItem('tool_call', webshellAgentPx(_ed) + '🔧 ' + callTitle, _em || '', _ed);
if (!streamingTarget) assistantDiv.textContent = '…';
// ─── Tool result delta (streaming output) ───
@@ -3049,22 +3073,18 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
if (trdDelta) {
var trdState = wsToolResultStreams.get(trdKey);
if (!trdState) {
var trdName = _ed.toolName || '工具';
var runLabel = wsTOr('timeline.running', '执行中...');
var trdItem = document.createElement('div');
trdItem.className = 'webshell-ai-timeline-item webshell-ai-timeline-tool_result';
trdItem.innerHTML = '<span class="webshell-ai-timeline-title">' +
escapeHtml(webshellAgentPx(_ed) + '⏳ ' + runLabel + ' ' + trdName) +
'</span><div class="webshell-ai-timeline-msg"><div class="tool-result-section success">' +
'<pre class="tool-result"></pre></div></div>';
timelineContainer.appendChild(trdItem);
timelineContainer.classList.add('has-items');
trdState = { el: trdItem, buf: '' };
var callEl = wsToolCallItems.get(trdKey);
trdState = { el: callEl || null, buf: '', onCall: !!callEl };
wsToolResultStreams.set(trdKey, trdState);
}
trdState.buf += trdDelta;
var trdPre = trdState.el.querySelector('pre.tool-result');
if (trdPre) trdPre.textContent = trdState.buf;
if (trdState.el) {
var trdPre = trdState.el.querySelector('pre.tool-result');
if (trdPre) {
trdPre.classList.remove('tool-result-pending');
trdPre.textContent = trdState.buf;
}
}
}
if (!streamingTarget) assistantDiv.textContent = '…';
@@ -3072,25 +3092,23 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
} else if (_et === 'tool_result' && _ed) {
var success = _ed.success !== false;
var tname = _ed.toolName || '工具';
var titleText = wsTOr(success ? 'chat.toolExecComplete' : 'chat.toolExecFailed', '') ||
(tname + (success ? ' 执行完成' : ' 执行失败'));
if (typeof window.t === 'function') {
try { titleText = window.t(success ? 'chat.toolExecComplete' : 'chat.toolExecFailed', { name: tname }); } catch (e) { /* */ }
var merged = false;
if (_ed.toolCallId) {
var streamSt = wsToolResultStreams.get(_ed.toolCallId);
var callElRes = wsToolCallItems.get(_ed.toolCallId) || (streamSt && streamSt.el);
if (callElRes && typeof window.mergeToolResultIntoCallItem === 'function') {
window.mergeToolResultIntoCallItem(callElRes, _ed);
merged = true;
wsToolResultStreams.delete(_ed.toolCallId);
wsToolCallItems.delete(_ed.toolCallId);
}
}
// 如果有流式占位条目,更新标题
var trdExist = _ed.toolCallId ? wsToolResultStreams.get(_ed.toolCallId) : null;
if (trdExist) {
var trdTitleEl = trdExist.el.querySelector('.webshell-ai-timeline-title');
if (trdTitleEl) trdTitleEl.textContent = webshellAgentPx(_ed) + (success ? '✅ ' : '❌ ') + titleText;
// 更新结果内容
var resultText = _ed.result ? String(_ed.result) : (_em || '');
var trdPreEl = trdExist.el.querySelector('pre.tool-result');
if (trdPreEl && resultText) trdPreEl.textContent = resultText;
// 更新 section class
var trdSection = trdExist.el.querySelector('.tool-result-section');
if (trdSection) { trdSection.className = 'tool-result-section ' + (success ? 'success' : 'error'); }
wsToolResultStreams.delete(_ed.toolCallId);
} else {
if (!merged) {
var titleText = wsTOr(success ? 'chat.toolExecComplete' : 'chat.toolExecFailed', '') ||
(tname + (success ? ' 执行完成' : ' 执行失败'));
if (typeof window.t === 'function') {
try { titleText = window.t(success ? 'chat.toolExecComplete' : 'chat.toolExecFailed', { name: tname }); } catch (e) { /* */ }
}
var title = webshellAgentPx(_ed) + (success ? '✅ ' : '❌ ') + titleText;
var sub = _em || (_ed.result ? String(_ed.result).slice(0, 300) : '');
appendTimelineItem('tool_result', title, sub, _ed);