更新工具链
This commit is contained in:
+52
-4
@@ -265,6 +265,30 @@
|
||||
white-space: normal;
|
||||
}
|
||||
.trace-panel:empty { display: none; }
|
||||
.reasoning-panel {
|
||||
display: none;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
background: var(--surface2);
|
||||
color: var(--text-dim);
|
||||
font-size: 0.78rem;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
.reasoning-panel.show { display: block; }
|
||||
.reasoning-title {
|
||||
padding: 6px 9px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-weight: 600;
|
||||
}
|
||||
.reasoning-content {
|
||||
padding: 7px 9px;
|
||||
white-space: pre-wrap;
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
font-family: Consolas, 'Fira Code', monospace;
|
||||
}
|
||||
.trace-item {
|
||||
border-left: 2px solid var(--accent-border);
|
||||
padding-left: 8px;
|
||||
@@ -859,18 +883,23 @@ function addAIBubble() {
|
||||
const trace = document.createElement('div');
|
||||
trace.className = 'trace-panel';
|
||||
|
||||
const reasoning = document.createElement('div');
|
||||
reasoning.className = 'reasoning-panel';
|
||||
reasoning.innerHTML = '<div class="reasoning-title">思考过程(模型返回)</div><div class="reasoning-content"></div>';
|
||||
|
||||
const txt = document.createElement('span');
|
||||
txt.className = 'answer-text';
|
||||
const stats = document.createElement('div');
|
||||
stats.className = 'token-stats';
|
||||
bub.appendChild(trace);
|
||||
bub.appendChild(reasoning);
|
||||
bub.appendChild(txt);
|
||||
bub.appendChild(stats);
|
||||
row.appendChild(av);
|
||||
row.appendChild(bub);
|
||||
msgBox.appendChild(row);
|
||||
scrollToBottom();
|
||||
return { bub, txt, trace, stats };
|
||||
return { bub, txt, trace, reasoning, stats };
|
||||
}
|
||||
|
||||
function formatTokenStats(stats) {
|
||||
@@ -903,18 +932,24 @@ function appendTrace(aiBubble, frame) {
|
||||
if (!aiBubble.trace) return;
|
||||
const item = document.createElement('div');
|
||||
item.className = `trace-item ${frame.status || ''}`;
|
||||
const prefix = [frame.tool, frame.stage].filter(Boolean).join('/');
|
||||
const label = frame.message || [frame.tool, frame.stage, frame.status].filter(Boolean).join(' ');
|
||||
item.textContent = label;
|
||||
item.textContent = prefix ? `${prefix}:${label}` : label;
|
||||
|
||||
const data = frame.data || {};
|
||||
const details = [];
|
||||
if (data.sql) details.push(data.sql);
|
||||
if (data.arguments) details.push(`参数:\n${data.arguments}`);
|
||||
if (data.sql) details.push(`SQL:\n${data.sql}`);
|
||||
if (data.result_preview) details.push(`结果预览:\n${data.result_preview}`);
|
||||
const stats = [];
|
||||
if (typeof data.iteration === 'number') stats.push(`轮次: ${data.iteration}${data.max_iterations ? '/' + data.max_iterations : ''}`);
|
||||
if (data.tool_call_id) stats.push(`调用 ID: ${data.tool_call_id}`);
|
||||
if (data.database) stats.push(`数据库: ${data.database}`);
|
||||
if (typeof data.rows === 'number') stats.push(`行数: ${data.rows}`);
|
||||
if (typeof data.columns === 'number') stats.push(`列数: ${data.columns}`);
|
||||
if (typeof data.count === 'number') stats.push(`结果数: ${data.count}`);
|
||||
if (Array.isArray(data.tools) && data.tools.length) stats.push(`工具: ${data.tools.join(', ')}`);
|
||||
if (typeof data.duration_ms === 'number') stats.push(`耗时: ${data.duration_ms}ms`);
|
||||
if (data.truncated) stats.push(`已截断,最多 ${data.max_rows || ''} 行`);
|
||||
if (data.reason) stats.push(`原因: ${data.reason}`);
|
||||
if (data.error) stats.push(`错误: ${data.error}`);
|
||||
@@ -923,7 +958,7 @@ function appendTrace(aiBubble, frame) {
|
||||
if (details.length) {
|
||||
const detail = document.createElement('div');
|
||||
detail.className = 'trace-detail';
|
||||
detail.textContent = details.join('\n');
|
||||
detail.textContent = details.join('\n\n');
|
||||
item.appendChild(detail);
|
||||
}
|
||||
|
||||
@@ -931,6 +966,15 @@ function appendTrace(aiBubble, frame) {
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
function appendReasoning(aiBubble, text) {
|
||||
if (!aiBubble.reasoning || !text) return;
|
||||
aiBubble.reasoning.classList.add('show');
|
||||
const content = aiBubble.reasoning.querySelector('.reasoning-content');
|
||||
content.textContent += text;
|
||||
content.scrollTop = content.scrollHeight;
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
async function streamChat(messages, aiBubble) {
|
||||
const txtEl = aiBubble.txt;
|
||||
let full = '';
|
||||
@@ -996,6 +1040,10 @@ async function streamChat(messages, aiBubble) {
|
||||
scrollToBottom();
|
||||
continue;
|
||||
}
|
||||
if (parsed.type === 'reasoning') {
|
||||
appendReasoning(aiBubble, parsed.text || '');
|
||||
continue;
|
||||
}
|
||||
if (parsed.type === 'trace') {
|
||||
appendTrace(aiBubble, parsed);
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user