mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-07 04:58:03 +02:00
Add files via upload
This commit is contained in:
@@ -40,6 +40,8 @@ let chatAttachmentSeq = 0;
|
||||
|
||||
// 对话模式:react = 原生 ReAct(/agent-loop);eino_single = Eino ADK 单代理(/api/eino-agent/stream);deep / plan_execute / supervisor = Eino 多代理(/api/multi-agent/stream,请求体 orchestration)
|
||||
const AGENT_MODE_STORAGE_KEY = 'cyberstrike-chat-agent-mode';
|
||||
const REASONING_MODE_LS = 'cyberstrike-chat-reasoning-mode';
|
||||
const REASONING_EFFORT_LS = 'cyberstrike-chat-reasoning-effort';
|
||||
const CHAT_AGENT_MODE_REACT = 'react';
|
||||
const CHAT_AGENT_MODE_EINO_SINGLE = 'eino_single';
|
||||
const CHAT_AGENT_EINO_MODES = ['deep', 'plan_execute', 'supervisor'];
|
||||
@@ -492,6 +494,132 @@ function syncAgentModeFromValue(value) {
|
||||
const v = el.getAttribute('data-value');
|
||||
el.classList.toggle('selected', v === value);
|
||||
});
|
||||
syncReasoningRowVisibility(value);
|
||||
}
|
||||
|
||||
function syncReasoningRowVisibility(modeVal) {
|
||||
const wrap = document.getElementById('chat-reasoning-wrapper');
|
||||
if (!wrap) return;
|
||||
const show = modeVal === CHAT_AGENT_MODE_EINO_SINGLE || (multiAgentAPIEnabled && chatAgentModeIsEino(modeVal));
|
||||
wrap.style.display = show ? '' : 'none';
|
||||
if (!show) {
|
||||
closeChatReasoningPanel();
|
||||
} else {
|
||||
updateChatReasoningSummary();
|
||||
}
|
||||
}
|
||||
|
||||
function reasoningSummaryModeLabel(mode) {
|
||||
const m = (mode || 'default').trim();
|
||||
const t = (typeof window.t === 'function') ? window.t : function (k) { return k; };
|
||||
switch (m) {
|
||||
case 'off': return t('chat.reasoningModeOff');
|
||||
case 'on': return t('chat.reasoningModeOn');
|
||||
case 'auto': return t('chat.reasoningModeAuto');
|
||||
default: return t('chat.reasoningSummaryFollow');
|
||||
}
|
||||
}
|
||||
|
||||
function updateChatReasoningSummary() {
|
||||
const el = document.getElementById('chat-reasoning-summary');
|
||||
const modeEl = document.getElementById('chat-reasoning-mode');
|
||||
const effEl = document.getElementById('chat-reasoning-effort');
|
||||
if (!el || !modeEl) return;
|
||||
const mode = (modeEl.value || 'default').trim();
|
||||
const effort = effEl && effEl.value ? String(effEl.value).trim() : '';
|
||||
const t = (typeof window.t === 'function') ? window.t : function (k) { return k; };
|
||||
const modePart = reasoningSummaryModeLabel(mode);
|
||||
const effPart = effort || t('chat.reasoningSummaryDash');
|
||||
el.textContent = modePart + ' / ' + effPart;
|
||||
}
|
||||
|
||||
function closeChatReasoningPanel() {
|
||||
const panel = document.getElementById('chat-reasoning-panel');
|
||||
const btn = document.getElementById('chat-reasoning-btn');
|
||||
if (panel) panel.style.display = 'none';
|
||||
if (btn) {
|
||||
btn.classList.remove('active');
|
||||
btn.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleChatReasoningPanel() {
|
||||
const panel = document.getElementById('chat-reasoning-panel');
|
||||
const btn = document.getElementById('chat-reasoning-btn');
|
||||
if (!panel || !btn) return;
|
||||
const isOpen = panel.style.display === 'flex';
|
||||
if (isOpen) {
|
||||
closeChatReasoningPanel();
|
||||
return;
|
||||
}
|
||||
if (typeof closeAgentModePanel === 'function') {
|
||||
closeAgentModePanel();
|
||||
}
|
||||
if (typeof closeRoleSelectionPanel === 'function') {
|
||||
closeRoleSelectionPanel();
|
||||
}
|
||||
updateChatReasoningSummary();
|
||||
panel.style.display = 'flex';
|
||||
btn.classList.add('active');
|
||||
btn.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
|
||||
function restoreChatReasoningControlsFromStorage() {
|
||||
try {
|
||||
const m = document.getElementById('chat-reasoning-mode');
|
||||
const e = document.getElementById('chat-reasoning-effort');
|
||||
if (m) {
|
||||
const v = localStorage.getItem(REASONING_MODE_LS);
|
||||
if (v && ['default', 'off', 'on', 'auto'].indexOf(v) !== -1) {
|
||||
m.value = v;
|
||||
}
|
||||
}
|
||||
if (e) {
|
||||
const v = localStorage.getItem(REASONING_EFFORT_LS);
|
||||
if (v !== null && ['', 'low', 'medium', 'high', 'max'].indexOf(v) !== -1) {
|
||||
e.value = v;
|
||||
}
|
||||
}
|
||||
updateChatReasoningSummary();
|
||||
} catch (err) { /* ignore */ }
|
||||
}
|
||||
|
||||
function persistChatReasoningPrefs() {
|
||||
try {
|
||||
const m = document.getElementById('chat-reasoning-mode');
|
||||
const elEff = document.getElementById('chat-reasoning-effort');
|
||||
if (m) localStorage.setItem(REASONING_MODE_LS, m.value || 'default');
|
||||
if (elEff) localStorage.setItem(REASONING_EFFORT_LS, elEff.value || '');
|
||||
updateChatReasoningSummary();
|
||||
} catch (err) { /* ignore */ }
|
||||
}
|
||||
|
||||
/** 供 WebShell 等复用:在 Eino 路径下返回 reasoning 请求片段或 undefined */
|
||||
function buildReasoningRequestPayload() {
|
||||
const wrap = document.getElementById('chat-reasoning-wrapper');
|
||||
if (!wrap || wrap.style.display === 'none') {
|
||||
return undefined;
|
||||
}
|
||||
const modeEl = document.getElementById('chat-reasoning-mode');
|
||||
const effEl = document.getElementById('chat-reasoning-effort');
|
||||
if (!modeEl) return undefined;
|
||||
const mode = (modeEl.value || 'default').trim();
|
||||
const effort = effEl && effEl.value ? String(effEl.value).trim() : '';
|
||||
if (mode === 'default' && !effort) {
|
||||
return undefined;
|
||||
}
|
||||
const o = {};
|
||||
if (mode !== 'default') o.mode = mode;
|
||||
if (effort) o.effort = effort;
|
||||
return Object.keys(o).length ? o : undefined;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.persistChatReasoningPrefs = persistChatReasoningPrefs;
|
||||
window.buildReasoningRequestPayload = buildReasoningRequestPayload;
|
||||
window.closeChatReasoningPanel = closeChatReasoningPanel;
|
||||
window.toggleChatReasoningPanel = toggleChatReasoningPanel;
|
||||
window.updateChatReasoningSummary = updateChatReasoningSummary;
|
||||
}
|
||||
|
||||
function closeAgentModePanel() {
|
||||
@@ -513,6 +641,9 @@ function toggleAgentModePanel() {
|
||||
closeAgentModePanel();
|
||||
return;
|
||||
}
|
||||
if (typeof closeChatReasoningPanel === 'function') {
|
||||
closeChatReasoningPanel();
|
||||
}
|
||||
if (typeof closeRoleSelectionPanel === 'function') {
|
||||
closeRoleSelectionPanel();
|
||||
}
|
||||
@@ -563,6 +694,8 @@ async function initChatAgentModeFromConfig() {
|
||||
} catch (e) { /* ignore */ }
|
||||
sel.value = stored;
|
||||
syncAgentModeFromValue(stored);
|
||||
restoreChatReasoningControlsFromStorage();
|
||||
syncReasoningRowVisibility(stored);
|
||||
} catch (e) {
|
||||
console.warn('initChatAgentModeFromConfig', e);
|
||||
}
|
||||
@@ -575,6 +708,9 @@ document.addEventListener('languagechange', function () {
|
||||
if (v === CHAT_AGENT_MODE_REACT || chatAgentModeIsEinoSingle(v) || chatAgentModeIsEino(v)) {
|
||||
syncAgentModeFromValue(v);
|
||||
}
|
||||
if (typeof updateChatReasoningSummary === 'function') {
|
||||
updateChatReasoningSummary();
|
||||
}
|
||||
});
|
||||
|
||||
// 保存输入框草稿到localStorage(防抖版本)
|
||||
@@ -760,6 +896,10 @@ async function sendMessage() {
|
||||
serverPath: a.serverPath
|
||||
}));
|
||||
}
|
||||
const reasoningPayload = buildReasoningRequestPayload();
|
||||
if (reasoningPayload) {
|
||||
body.reasoning = reasoningPayload;
|
||||
}
|
||||
// 发送后清空附件列表
|
||||
chatAttachments = [];
|
||||
renderChatFileChips();
|
||||
@@ -2228,6 +2368,8 @@ function renderProcessDetails(messageId, processDetails) {
|
||||
}
|
||||
} else if (eventType === 'thinking') {
|
||||
itemTitle = agPx + '🤔 ' + (typeof window.t === 'function' ? window.t('chat.aiThinking') : 'AI思考');
|
||||
} else if (eventType === 'reasoning_chain') {
|
||||
itemTitle = agPx + '🔗 ' + (typeof window.t === 'function' ? window.t('chat.reasoningChain') : '推理过程');
|
||||
} else if (eventType === 'planning') {
|
||||
if (typeof window.einoMainStreamPlanningTitle === 'function') {
|
||||
itemTitle = window.einoMainStreamPlanningTitle(data);
|
||||
@@ -7233,6 +7375,14 @@ document.addEventListener('click', function(event) {
|
||||
closeAgentModePanel();
|
||||
}
|
||||
}
|
||||
|
||||
const reasoningWrap = document.getElementById('chat-reasoning-wrapper');
|
||||
const reasoningPanel = document.getElementById('chat-reasoning-panel');
|
||||
if (reasoningWrap && reasoningPanel && reasoningPanel.style.display === 'flex') {
|
||||
if (!reasoningWrap.contains(event.target)) {
|
||||
closeChatReasoningPanel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 创建分组
|
||||
|
||||
@@ -1223,11 +1223,14 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
break;
|
||||
}
|
||||
|
||||
case 'thinking_stream_start': {
|
||||
case 'thinking_stream_start':
|
||||
case 'reasoning_chain_stream_start': {
|
||||
const d = event.data || {};
|
||||
const streamId = d.streamId || null;
|
||||
if (!streamId) break;
|
||||
|
||||
const timelineType = event.type === 'reasoning_chain_stream_start' ? 'reasoning_chain' : 'thinking';
|
||||
|
||||
let state = thinkingStreamStateByProgressId.get(progressId);
|
||||
if (!state) {
|
||||
state = new Map();
|
||||
@@ -1246,9 +1249,12 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
}
|
||||
break;
|
||||
}
|
||||
const thinkBase = typeof window.t === 'function' ? window.t('chat.aiThinking') : 'AI思考';
|
||||
const title = timelineAgentBracketPrefix(d) + '🤔 ' + thinkBase;
|
||||
const itemId = addTimelineItem(timeline, 'thinking', {
|
||||
const labelBase = typeof window.t === 'function'
|
||||
? window.t(timelineType === 'reasoning_chain' ? 'chat.reasoningChain' : 'chat.aiThinking')
|
||||
: (timelineType === 'reasoning_chain' ? '推理过程' : 'AI思考');
|
||||
const emoji = timelineType === 'reasoning_chain' ? '🔗' : '🤔';
|
||||
const title = timelineAgentBracketPrefix(d) + emoji + ' ' + labelBase;
|
||||
const itemId = addTimelineItem(timeline, timelineType, {
|
||||
title: title,
|
||||
message: ' ',
|
||||
data: d
|
||||
@@ -1257,7 +1263,8 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
break;
|
||||
}
|
||||
|
||||
case 'thinking_stream_delta': {
|
||||
case 'thinking_stream_delta':
|
||||
case 'reasoning_chain_stream_delta': {
|
||||
const d = event.data || {};
|
||||
const streamId = d.streamId || null;
|
||||
if (!streamId) break;
|
||||
@@ -1281,7 +1288,9 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
}
|
||||
|
||||
case 'thinking':
|
||||
// 如果本 thinking 是由 thinking_stream_* 聚合出来的(带 streamId),避免重复创建 timeline item
|
||||
case 'reasoning_chain': {
|
||||
const timelineType = event.type === 'reasoning_chain' ? 'reasoning_chain' : 'thinking';
|
||||
// 若已由 *_stream_* 聚合(带 streamId),避免重复创建 timeline item
|
||||
if (event.data && event.data.streamId) {
|
||||
const streamId = event.data.streamId;
|
||||
const state = thinkingStreamStateByProgressId.get(progressId);
|
||||
@@ -1303,12 +1312,17 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
}
|
||||
}
|
||||
|
||||
addTimelineItem(timeline, 'thinking', {
|
||||
title: timelineAgentBracketPrefix(event.data) + '🤔 ' + (typeof window.t === 'function' ? window.t('chat.aiThinking') : 'AI思考'),
|
||||
const labelBase = typeof window.t === 'function'
|
||||
? window.t(timelineType === 'reasoning_chain' ? 'chat.reasoningChain' : 'chat.aiThinking')
|
||||
: (timelineType === 'reasoning_chain' ? '推理过程' : 'AI思考');
|
||||
const emoji = timelineType === 'reasoning_chain' ? '🔗' : '🤔';
|
||||
addTimelineItem(timeline, timelineType, {
|
||||
title: timelineAgentBracketPrefix(event.data) + emoji + ' ' + labelBase,
|
||||
message: event.message,
|
||||
data: event.data
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tool_calls_detected':
|
||||
addTimelineItem(timeline, 'tool_calls_detected', {
|
||||
@@ -2475,7 +2489,7 @@ function addTimelineItem(timeline, type, options) {
|
||||
`;
|
||||
|
||||
// 根据类型添加详细内容
|
||||
if ((type === 'thinking' || type === 'planning') && options.message) {
|
||||
if ((type === 'thinking' || type === 'reasoning_chain' || type === 'planning') && options.message) {
|
||||
const streamBody = typeof formatTimelineStreamBody === 'function'
|
||||
? formatTimelineStreamBody(options.message, options.data)
|
||||
: options.message;
|
||||
@@ -3410,6 +3424,8 @@ function refreshProgressAndTimelineI18n() {
|
||||
} else {
|
||||
titleSpan.textContent = ap + '\uD83E\uDD14 ' + _t('chat.aiThinking');
|
||||
}
|
||||
} else if (type === 'reasoning_chain') {
|
||||
titleSpan.textContent = ap + '\uD83D\uDD17 ' + _t('chat.reasoningChain');
|
||||
} else if (type === 'planning') {
|
||||
if (item.dataset.orchestration && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
titleSpan.textContent = einoMainStreamPlanningTitle({
|
||||
|
||||
@@ -256,6 +256,9 @@ function toggleRoleSelectionPanel() {
|
||||
if (typeof closeAgentModePanel === 'function') {
|
||||
closeAgentModePanel();
|
||||
}
|
||||
if (typeof closeChatReasoningPanel === 'function') {
|
||||
closeChatReasoningPanel();
|
||||
}
|
||||
panel.style.display = 'flex'; // 使用flex布局
|
||||
// 添加打开状态的视觉反馈
|
||||
if (roleSelectorBtn) {
|
||||
|
||||
@@ -159,6 +159,27 @@ async function loadConfig(loadTools = true) {
|
||||
if (maxTokensEl) {
|
||||
maxTokensEl.value = currentConfig.openai.max_total_tokens || 120000;
|
||||
}
|
||||
const orm = currentConfig.openai && currentConfig.openai.reasoning ? currentConfig.openai.reasoning : {};
|
||||
const orModeEl = document.getElementById('openai-reasoning-mode');
|
||||
if (orModeEl) {
|
||||
const mv = (orm.mode || 'auto').toString().trim().toLowerCase();
|
||||
orModeEl.value = ['auto', 'on', 'off'].includes(mv) ? mv : 'auto';
|
||||
}
|
||||
const orEffEl = document.getElementById('openai-reasoning-effort');
|
||||
if (orEffEl) {
|
||||
const ev = (orm.effort || '').toString().trim().toLowerCase();
|
||||
orEffEl.value = ['', 'low', 'medium', 'high', 'max'].includes(ev) ? ev : '';
|
||||
}
|
||||
const orProfEl = document.getElementById('openai-reasoning-profile');
|
||||
if (orProfEl) {
|
||||
const pv = (orm.profile || 'auto').toString().trim().toLowerCase();
|
||||
const ok = ['auto', 'deepseek_compat', 'openai_compat', 'output_config_effort'];
|
||||
orProfEl.value = ok.includes(pv) ? pv : 'auto';
|
||||
}
|
||||
const orAllowEl = document.getElementById('openai-reasoning-allow-client');
|
||||
if (orAllowEl) {
|
||||
orAllowEl.checked = orm.allow_client_reasoning !== false;
|
||||
}
|
||||
|
||||
// 填充FOFA配置
|
||||
const fofa = currentConfig.fofa || {};
|
||||
@@ -1065,13 +1086,22 @@ async function applySettings() {
|
||||
};
|
||||
|
||||
const wecomAgentIdVal = document.getElementById('robot-wecom-agent-id')?.value.trim();
|
||||
const prevOpenai = (currentConfig && currentConfig.openai) ? currentConfig.openai : {};
|
||||
const config = {
|
||||
openai: {
|
||||
...prevOpenai,
|
||||
provider: provider,
|
||||
api_key: apiKey,
|
||||
base_url: baseUrl,
|
||||
model: model,
|
||||
max_total_tokens: parseInt(document.getElementById('openai-max-total-tokens')?.value) || 120000
|
||||
max_total_tokens: parseInt(document.getElementById('openai-max-total-tokens')?.value) || 120000,
|
||||
reasoning: {
|
||||
...(prevOpenai.reasoning || {}),
|
||||
mode: document.getElementById('openai-reasoning-mode')?.value || 'auto',
|
||||
effort: (document.getElementById('openai-reasoning-effort')?.value || '').trim(),
|
||||
profile: document.getElementById('openai-reasoning-profile')?.value || 'auto',
|
||||
allow_client_reasoning: document.getElementById('openai-reasoning-allow-client')?.checked !== false
|
||||
}
|
||||
},
|
||||
fofa: {
|
||||
email: document.getElementById('fofa-email')?.value.trim() || '',
|
||||
|
||||
+23
-11
@@ -1658,6 +1658,8 @@ function buildWebshellTimelineItemFromDetail(detail) {
|
||||
title = ap + ((typeof window.t === 'function') ? window.t('chat.iterationRound', { n: data.iteration || 1 }) : ('第 ' + (data.iteration || 1) + ' 轮迭代'));
|
||||
} else if (eventType === 'thinking') {
|
||||
title = ap + '🤔 ' + ((typeof window.t === 'function') ? window.t('chat.aiThinking') : 'AI 思考');
|
||||
} else if (eventType === 'reasoning_chain') {
|
||||
title = ap + '🔗 ' + ((typeof window.t === 'function') ? window.t('chat.reasoningChain') : '推理过程');
|
||||
} else if (eventType === 'tool_calls_detected') {
|
||||
title = ap + '🔧 ' + ((typeof window.t === 'function') ? window.t('chat.toolCallsDetected', { count: data.count || 0 }) : ('检测到 ' + (data.count || 0) + ' 个工具调用'));
|
||||
} else if (eventType === 'tool_call') {
|
||||
@@ -2847,6 +2849,12 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
|
||||
if (info && info.orchestration) {
|
||||
body.orchestration = info.orchestration;
|
||||
}
|
||||
if (typeof window.buildReasoningRequestPayload === 'function') {
|
||||
var rp = window.buildReasoningRequestPayload();
|
||||
if (rp) {
|
||||
body.reasoning = rp;
|
||||
}
|
||||
}
|
||||
return apiFetch(info.path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -2953,17 +2961,19 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
|
||||
appendTimelineItem('iteration', '🔍 ' + iterTitle, iterMessage, _ed);
|
||||
if (!streamingTarget) assistantDiv.textContent = '…';
|
||||
|
||||
// ─── Thinking (non-stream + stream) ───
|
||||
} else if (_et === 'thinking_stream_start' && _ed.streamId) {
|
||||
// ─── Thinking / reasoning_chain(推理过程,reasoning_content) ───
|
||||
} else if ((_et === 'thinking_stream_start' || _et === 'reasoning_chain_stream_start') && _ed.streamId) {
|
||||
var isRcStart = _et === 'reasoning_chain_stream_start';
|
||||
if (wsThinkingStreams.has(_ed.streamId)) {
|
||||
var tsExist = wsThinkingStreams.get(_ed.streamId);
|
||||
tsExist.buf = '';
|
||||
if (tsExist.body) tsExist.body.textContent = '';
|
||||
} else {
|
||||
var thinkSLabel = wsTOr('chat.aiThinking', 'AI 思考');
|
||||
var thinkSLabel = wsTOr(isRcStart ? 'chat.reasoningChain' : 'chat.aiThinking', isRcStart ? '推理过程' : 'AI 思考');
|
||||
var thinkEmoji = isRcStart ? '🔗' : '🤔';
|
||||
var thinkSItem = document.createElement('div');
|
||||
thinkSItem.className = 'webshell-ai-timeline-item webshell-ai-timeline-thinking';
|
||||
thinkSItem.innerHTML = '<span class="webshell-ai-timeline-title">' + escapeHtml(webshellAgentPx(_ed) + '🤔 ' + thinkSLabel) + '</span>';
|
||||
thinkSItem.className = 'webshell-ai-timeline-item webshell-ai-timeline-' + (isRcStart ? 'reasoning_chain' : 'thinking');
|
||||
thinkSItem.innerHTML = '<span class="webshell-ai-timeline-title">' + escapeHtml(webshellAgentPx(_ed) + thinkEmoji + ' ' + thinkSLabel) + '</span>';
|
||||
var thinkSPre = document.createElement('div');
|
||||
thinkSPre.className = 'webshell-ai-timeline-msg webshell-thinking-stream-body';
|
||||
thinkSItem.appendChild(thinkSPre);
|
||||
@@ -2972,7 +2982,7 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
|
||||
wsThinkingStreams.set(_ed.streamId, { el: thinkSItem, body: thinkSPre, buf: '' });
|
||||
}
|
||||
if (!streamingTarget) assistantDiv.textContent = '…';
|
||||
} else if (_et === 'thinking_stream_delta' && _ed.streamId) {
|
||||
} else if ((_et === 'thinking_stream_delta' || _et === 'reasoning_chain_stream_delta') && _ed.streamId) {
|
||||
var tsD = wsThinkingStreams.get(_ed.streamId);
|
||||
if (tsD) {
|
||||
var normT = (typeof window.normalizeStreamingDeltaJs === 'function')
|
||||
@@ -2985,7 +2995,7 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
|
||||
}
|
||||
}
|
||||
if (!streamingTarget) assistantDiv.textContent = '…';
|
||||
} else if (_et === 'thinking_stream_end' && _ed.streamId) {
|
||||
} else if ((_et === 'thinking_stream_end' || _et === 'reasoning_chain_stream_end') && _ed.streamId) {
|
||||
var tsE = wsThinkingStreams.get(_ed.streamId);
|
||||
if (tsE) {
|
||||
var fullThink = (_em != null && _em !== '') ? String(_em) : tsE.buf;
|
||||
@@ -2996,13 +3006,15 @@ function runWebshellAiSend(conn, inputEl, sendBtn, messagesContainer) {
|
||||
}
|
||||
wsThinkingStreams.delete(_ed.streamId);
|
||||
}
|
||||
} else if (_et === 'thinking' && _em) {
|
||||
} else if ((_et === 'thinking' || _et === 'reasoning_chain') && _em) {
|
||||
// 如果有 streamId 且已存在流式条目,跳过避免重复
|
||||
if (_ed.streamId && wsThinkingStreams.has(_ed.streamId)) {
|
||||
// 已由 thinking_stream_* 处理
|
||||
// 已由 *_stream_* 处理
|
||||
} else {
|
||||
var thinkLabel = wsTOr('chat.aiThinking', 'AI 思考');
|
||||
appendTimelineItem('thinking', webshellAgentPx(_ed) + '🤔 ' + thinkLabel, _em, _ed);
|
||||
var isRc = _et === 'reasoning_chain';
|
||||
var thinkLabel = wsTOr(isRc ? 'chat.reasoningChain' : 'chat.aiThinking', isRc ? '推理过程' : 'AI 思考');
|
||||
var thinkEm = isRc ? '🔗' : '🤔';
|
||||
appendTimelineItem(isRc ? 'reasoning_chain' : 'thinking', webshellAgentPx(_ed) + thinkEm + ' ' + thinkLabel, _em, _ed);
|
||||
}
|
||||
if (!streamingTarget) assistantDiv.textContent = '…';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user