feat: ASR语音转写管线 + 群聊身份混淆修复

- 新增ASR语音识别管线: QQ语音→下载音频→qwen3-asr-flash转录→注入用户消息
- 模型名称全部从models.json路由获取,无硬编码
- 修复群聊中AI将非管理员用户误称为管理员昵称(叶酱)的问题
  - 助手回复缓存时标注[回复 昵称 (UID)],防止对话历史中身份混淆
  - 群聊上下文指令改为肯定性表述,移除具体名称提及
- trace面板时间戳改为YYYY-MM-DD HH:MM:SS格式,耗时统一显示为秒
- 修复Go time.Duration纳秒值在前端显示问题(Duration/1e6转毫秒)
- 新增video_tool插件模板
- 优化OpenAI adapter reasoning_content处理

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 16:46:47 +08:00
parent d112fdd540
commit a9c79d7887
16 changed files with 780 additions and 67 deletions
+4 -4
View File
@@ -6364,7 +6364,7 @@ function pruneTimeline() {
}
function traceHopHtml(t, prevT) {
var time = new Date(t.timestamp).toISOString().replace('T', ' ').slice(11, 19);
var time = new Date(t.timestamp).toISOString().replace('T', ' ').slice(0, 19);
var isError = t.status === 'error';
var gapHtml = '';
@@ -6381,7 +6381,7 @@ function traceHopHtml(t, prevT) {
'<span class="hop-time">' + escHtml(time) + '</span>' +
'<span class="hop-service ' + escHtml(t.service) + '">' + escHtml(t.service) + '</span>' +
'<span class="hop-label">' + escHtml(t.label) + '</span>' +
(t.durationMs > 0 ? '<span class="hop-duration">' + (t.durationMs >= 1000 ? (t.durationMs / 1000).toFixed(2) + 's' : t.durationMs + 'ms') + '</span>' : '') +
(t.durationMs > 0 ? '<span class="hop-duration">' + (t.durationMs / 1000).toFixed(3) + 's</span>' : '') +
'<span class="hop-status">' + (isError ? '❌' : '✅') + '</span>' +
'</div>' +
'<div class="trace-hop-detail">' +
@@ -6389,7 +6389,7 @@ function traceHopHtml(t, prevT) {
'<div><strong>服务:</strong> ' + escHtml(t.service) + '</div>' +
'<div><strong>节点:</strong> ' + escHtml(t.hop) + '</div>' +
'<div><strong>标签:</strong> ' + escHtml(t.label) + '</div>' +
(t.durationMs > 0 ? '<div><strong>耗时:</strong> ' + (t.durationMs >= 1000 ? (t.durationMs / 1000).toFixed(2) + 's' : t.durationMs + 'ms') + '</div>' : '') +
(t.durationMs > 0 ? '<div><strong>耗时:</strong> ' + (t.durationMs / 1000).toFixed(3) + 's</div>' : '') +
'<div><strong>状态:</strong> ' + (isError ? '❌ 失败' : '✅ 成功') + '</div>' +
(t.detail ? '<div style="margin-top:6px"><strong>详情:</strong><br>' + escHtml(String(t.detail)) + '</div>' : '') +
'</div>';
@@ -6423,7 +6423,7 @@ function llmCallToTrace(call) {
hop: 'llm_call',
label: 'LLM 调用: ' + (call.model || 'unknown'),
status: call.success ? 'success' : 'error',
durationMs: call.duration_ms || call.Duration || 0,
durationMs: call.duration_ms || (call.Duration ? Math.round(call.Duration / 1e6) : 0),
detail: call.error || (call.prompt_tokens || 0) + '+' + (call.completion_tokens || 0) + ' tokens',
data: call
};