feat(static/aibox.js): 同步BotOps修复到Web前端
同步以下修复: 1. endReasoning()/abortReasoning() 结束后清除引用(DOM保留显示), 多轮工具调用时每轮创建独立思考区域,按时间顺序分布 2. 新增 breakAi() 分段函数,处理 ai_break 信号:工具调用前分段 AI文本,后续chunk创建新气泡,避免思考区域被夹在AI文本中间 3. line消息过滤前缀扩展:增加分析工具结果/需要调用工具等 4. 未知消息类型fallback从appendAi改为addTaskLine,防止非AI内容污染聊天区
This commit is contained in:
1 parent
392a734707
commit
2bb1d69d8a
1 file changed
+21
-5
@@ -3,8 +3,8 @@
|
|||||||
* aibox Web 客户端 · 移动端版(经 gateway WS 反向代理,仅管理员可用)
|
* aibox Web 客户端 · 移动端版(经 gateway WS 反向代理,仅管理员可用)
|
||||||
* 协议与 BotOps/aibox client.py 完全兼容:
|
* 协议与 BotOps/aibox client.py 完全兼容:
|
||||||
* 发送:{"type":"message","content":...} / {"type":"command","command":"/..."} / {"type":"interrupt",...}
|
* 发送:{"type":"message","content":...} / {"type":"command","command":"/..."} / {"type":"interrupt",...}
|
||||||
* 接收:chunk(增量片段) / reasoning_start / reasoning / reasoning_end / complete /
|
* 接收:chunk(增量片段) / reasoning_start / reasoning / reasoning_end / ai_break /
|
||||||
* line(过程行) / task_process / task_status / task_error / task_added /
|
* complete / line(过程行) / task_process / task_status / task_error / task_added /
|
||||||
* dialogue_ended / dialogue_reset / interrupt_ack / error / info /
|
* dialogue_ended / dialogue_reset / interrupt_ack / error / info /
|
||||||
* command_result / connection_ack / notification / pong
|
* command_result / connection_ack / notification / pong
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
@@ -152,6 +152,8 @@ function endReasoning() {
|
|||||||
reasoningHead.textContent = '💭 思考过程(' + reasoningText.length + ' 字符,点击折叠/展开)';
|
reasoningHead.textContent = '💭 思考过程(' + reasoningText.length + ' 字符,点击折叠/展开)';
|
||||||
reasoningBody.classList.add('folded'); /* 结束后默认折叠,避免占屏 */
|
reasoningBody.classList.add('folded'); /* 结束后默认折叠,避免占屏 */
|
||||||
}
|
}
|
||||||
|
/* 清除引用(DOM元素保留显示),下一轮 reasoning_start 创建新的思考区域 */
|
||||||
|
reasoningBox = null; reasoningHead = null; reasoningBody = null; reasoningText = '';
|
||||||
}
|
}
|
||||||
function abortReasoning() {
|
function abortReasoning() {
|
||||||
/* 用户中断:更新思考区域标签为已中断,保留已展示内容 */
|
/* 用户中断:更新思考区域标签为已中断,保留已展示内容 */
|
||||||
@@ -162,6 +164,16 @@ function abortReasoning() {
|
|||||||
reasoningHead.textContent = '🛑 思考已中断';
|
reasoningHead.textContent = '🛑 思考已中断';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* 清除引用,DOM元素保留显示 */
|
||||||
|
reasoningBox = null; reasoningHead = null; reasoningBody = null; reasoningText = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- AI 文本分段(工具调用时 breakAi,后续 chunk 创建新气泡) ---------- */
|
||||||
|
function breakAi() {
|
||||||
|
if (aiBubble) {
|
||||||
|
aiBubble.classList.remove('streaming');
|
||||||
|
aiBubble = null; aiText = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 连接状态 ---------- */
|
/* ---------- 连接状态 ---------- */
|
||||||
@@ -242,11 +254,14 @@ function routeMessage(data) {
|
|||||||
appendReasoning(content);
|
appendReasoning(content);
|
||||||
} else if (t === 'reasoning_end') {
|
} else if (t === 'reasoning_end') {
|
||||||
endReasoning();
|
endReasoning();
|
||||||
|
} else if (t === 'ai_break') {
|
||||||
|
/* 工具调用前分段:结束当前AI文本段(保留已显示内容),后续chunk创建新气泡 */
|
||||||
|
breakAi();
|
||||||
} else if (t === 'line') {
|
} else if (t === 'line') {
|
||||||
/* 过程行:工具调用提示 / 工具输出 → 任务面板;助手前缀 / 思考提示聊天区已有承载,跳过 */
|
/* 过程行:工具调用提示 / 工具输出 → 任务面板;助手前缀 / 思考提示等聊天区已有承载,跳过 */
|
||||||
const stripped = content.trim();
|
const stripped = content.trim();
|
||||||
if (!stripped) return;
|
if (!stripped) return;
|
||||||
if (/^(💬 助手|💬 Assistant|🤔 思考中|🤔 Thinking|🤔 深度思考中)/.test(stripped)) return;
|
if (/^(💬 助手|💬 Assistant|🤔 思考中|🤔 Thinking|🤔 深度思考中|🤔 分析工具结果|🤔 Analyzing|🔧 需要调用工具|🔧 Need to call)/.test(stripped)) return;
|
||||||
addTaskLine(stripped);
|
addTaskLine(stripped);
|
||||||
} else if (t === 'complete') {
|
} else if (t === 'complete') {
|
||||||
finishAi(content);
|
finishAi(content);
|
||||||
@@ -290,7 +305,8 @@ function routeMessage(data) {
|
|||||||
} else if (t === 'notification') {
|
} else if (t === 'notification') {
|
||||||
addSystem('🔔 ' + content);
|
addSystem('🔔 ' + content);
|
||||||
} else if (content) {
|
} else if (content) {
|
||||||
appendAi(content); /* 未知类型兜底:按 AI 增量处理(与 BotOps 一致) */
|
/* 未知消息类型不追加到AI聊天区(避免非AI内容污染回复),记入任务面板 */
|
||||||
|
addTaskLine('[未知消息 type=' + t + '] ' + content.slice(0, 200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user