fix: platform_silent记忆提取 + 群聊上下文整合 + 多QQ实例支持

- platform_silent模式接入Orchestrator记忆提取:被动观察群聊时提取值得记住的信息到对应命名空间
- post_chat后台思考注入平台观察:对话后思考也能看到群聊摘要
- QQ适配器:OneBot v11 self_id动态捕获、CQ图片URL提取、视觉+OCR并行处理
- Router解耦:ConfigName/PlatformName分离,支持多QQ实例独立连接
- 黑白名单功能:后端API + Ethend代理 + UI面板
- \n\n双换行断句:AI回复按双换行分割为多条消息按间隔发送
- @提及修复:bot自感知UID进行@检测
- 群聊上下文共享:channel-based userID避免记忆碎片化
- 消息日志显示处理后内容而非原始SSE数据
- platform-bridge Dockerfile + docker-compose.yml更新

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 09:37:18 +08:00
parent 71f0a1abdb
commit 47dce276a4
22 changed files with 2375 additions and 313 deletions
+102
View File
@@ -79,6 +79,67 @@ processManager.on('log', (serviceId, stream, text) => {
}
});
// ========== 平台桥接实时日志流 ==========
let logStreamWs = null;
let logStreamReconnectTimer = null;
function connectPlatformBridgeLogStream() {
if (logStreamReconnectTimer) { clearTimeout(logStreamReconnectTimer); logStreamReconnectTimer = null; }
if (logStreamWs && (logStreamWs.readyState === WebSocket.OPEN || logStreamWs.readyState === WebSocket.CONNECTING)) return;
const wsUrl = PLATFORM_BRIDGE_URL.replace(/^http/, 'ws') + '/ws/logs';
console.log(`[LogStream] 连接 ${wsUrl} ...`);
try {
logStreamWs = new WebSocket(wsUrl);
} catch (err) {
console.error(`[LogStream] 创建连接失败: ${err.message}`);
scheduleLogStreamReconnect();
return;
}
logStreamWs.on('open', () => {
console.log('[LogStream] 已连接,实时日志推送中');
});
logStreamWs.on('message', (raw) => {
try {
const entry = JSON.parse(raw.toString());
broadcast('chat-log', entry);
} catch {}
});
logStreamWs.on('close', () => {
console.log('[LogStream] 连接断开');
logStreamWs = null;
scheduleLogStreamReconnect();
});
logStreamWs.on('error', (err) => {
console.error(`[LogStream] 错误: ${err.message}`);
logStreamWs = null;
scheduleLogStreamReconnect();
});
}
function scheduleLogStreamReconnect() {
if (logStreamReconnectTimer) return;
logStreamReconnectTimer = setTimeout(() => {
logStreamReconnectTimer = null;
connectPlatformBridgeLogStream();
}, 5000);
}
// 启动时连接,后续 platform-bridge 重启时通过状态变化自动重连。
connectPlatformBridgeLogStream();
// 监听服务状态:platform-bridge 上线后重连。
setInterval(() => {
if (!logStreamWs || logStreamWs.readyState === WebSocket.CLOSED || logStreamWs.readyState === WebSocket.CLOSING) {
connectPlatformBridgeLogStream();
}
}, 15000);
// ========== Gateway 代理辅助函数 ==========
/** 缓存的 JWT token 和过期时间 */
@@ -740,6 +801,47 @@ app.get('/api/chat-platforms/logs/:name', async (req, res) => {
res.status(result.status).json(result.body);
});
// GET /api/chat-platforms/platforms — 列出所有平台适配器 (含连接状态与能力)
app.get('/api/chat-platforms/platforms', async (_req, res) => {
const result = await proxyToPlatformBridge('/api/v1/platforms');
res.status(result.status).json(result.body);
});
// GET /api/chat-platforms/platforms/:name — 获取单个平台适配器详情
app.get('/api/chat-platforms/platforms/:name', async (req, res) => {
const result = await proxyToPlatformBridge(`/api/v1/platforms/${req.params.name}`);
res.status(result.status).json(result.body);
});
// GET /api/chat-platforms/identities — 列出所有已注册的身份映射
app.get('/api/chat-platforms/identities', async (_req, res) => {
const result = await proxyToPlatformBridge('/api/v1/identities');
res.status(result.status).json(result.body);
});
// GET /api/chat-platforms/health — platform-bridge 整体健康状态
app.get('/api/chat-platforms/health', async (_req, res) => {
const result = await proxyToPlatformBridge('/health');
res.status(result.status).json(result.body);
});
// ---- 黑名单/白名单设置代理 ----
// GET /api/chat-platforms/settings/blocklist
app.get('/api/chat-platforms/settings/blocklist', async (_req, res) => {
const result = await proxyToPlatformBridge('/api/v1/settings/blocklist');
res.status(result.status).json(result.body);
});
// POST /api/chat-platforms/settings/blocklist
app.post('/api/chat-platforms/settings/blocklist', async (req, res) => {
const result = await proxyToPlatformBridge('/api/v1/settings/blocklist', {
method: 'POST',
body: JSON.stringify(req.body),
});
res.status(result.status).json(result.body);
});
// ---- 多端客户端管理代理 (转发到 Gateway) ----
// GET /api/clients — 获取已知客户端列表