feat: 多功能升级 — 流式逐字渲染、对话缓存、会话组织优化、记忆管理修复、性能仪表盘
- 前端消息流式逐字渲染 (AI-Core ChatStream → SSE → Gateway → WebSocket stream_chunk → fadeInUp + cursorBlink) - 后端对话缓存 (conversationCache sync.Map, GET /sessions/:id/messages) - 前端侧边栏历史多轮对话显示 - DevTools 性能监控图标移至首页仪表盘 - DevTools 用户记忆查询/删减功能修复 (补全 DELETE 数据链路) - 后端和 DevTools 按用户分类组织实时活动会话 (map[userID]map[sessionID]*Client) - 新增 docs/api-reference/ 路由参考文档 - 新增 docs/message-flow-architecture.md 消息链路架构文档
This commit is contained in:
@@ -198,6 +198,12 @@ app.get('/api/sessions', async (_req, res) => {
|
||||
res.status(result.status).json(result.body);
|
||||
});
|
||||
|
||||
// GET /api/sessions/active — 获取按用户分组的活跃会话
|
||||
app.get('/api/sessions/active', async (_req, res) => {
|
||||
const result = await proxyToGateway('/api/v1/sessions/active');
|
||||
res.status(result.status).json(result.body);
|
||||
});
|
||||
|
||||
app.get('/api/sessions/:id', async (req, res) => {
|
||||
const result = await proxyToGateway(`/api/v1/admin/sessions/${req.params.id}`);
|
||||
res.status(result.status).json(result.body);
|
||||
@@ -230,6 +236,14 @@ app.post('/api/memory/add', async (req, res) => {
|
||||
res.status(result.status).json(result.body);
|
||||
});
|
||||
|
||||
app.delete('/api/memory/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
if (!id) return res.status(400).json({ error: '缺少 memory id' });
|
||||
const qs = new URLSearchParams({ id }).toString();
|
||||
const result = await proxyToGateway(`/api/v1/memory?${qs}`, { method: 'DELETE' });
|
||||
res.status(result.status).json(result.body);
|
||||
});
|
||||
|
||||
// ---- 服务状态 ----
|
||||
app.get('/api/services', (_req, res) => {
|
||||
res.json(processManager.getStatus());
|
||||
@@ -311,6 +325,16 @@ app.get('/api/performance', async (_req, res) => {
|
||||
res.json(snapshot);
|
||||
});
|
||||
|
||||
// 性能仪表盘聚合数据 (供首页仪表盘使用)
|
||||
app.get('/api/performance/dashboard', async (_req, res) => {
|
||||
try {
|
||||
const dashboardData = await performanceMonitor.updateDashboard();
|
||||
res.json(dashboardData);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: `获取性能仪表盘数据失败: ${err.message}` });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/performance/history', (_req, res) => {
|
||||
res.json(performanceMonitor.getAllHistory());
|
||||
});
|
||||
|
||||
@@ -103,6 +103,63 @@ class PerformanceMonitor {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新仪表盘数据 — 返回聚合的性能摘要供首页仪表盘使用
|
||||
* 调用方负责将数据渲染到 #performance-dashboard 元素
|
||||
* @returns {object} 仪表盘性能摘要
|
||||
*/
|
||||
async updateDashboard() {
|
||||
const snapshot = await this.getSnapshot();
|
||||
const entries = Object.entries(snapshot);
|
||||
|
||||
let totalCpu = 0, totalMem = 0, activeCount = 0;
|
||||
for (const [, p] of entries) {
|
||||
totalCpu += p.cpu || 0;
|
||||
totalMem += p.mem || 0;
|
||||
if (p.pid) activeCount++;
|
||||
}
|
||||
|
||||
const avgCpu = entries.length > 0 ? Math.round(totalCpu / entries.length * 10) / 10 : 0;
|
||||
const totalMemRounded = Math.round(totalMem * 100) / 100;
|
||||
|
||||
// 计算平均延迟 (基于各服务进程的 elapsed 时间)
|
||||
let avgLatencyMs = null;
|
||||
let totalElapsed = 0, elapsedCount = 0;
|
||||
for (const [, p] of entries) {
|
||||
if (p.elapsed && p.elapsed > 0) { totalElapsed += p.elapsed; elapsedCount++; }
|
||||
}
|
||||
if (elapsedCount > 0) {
|
||||
avgLatencyMs = Math.round(totalElapsed / elapsedCount);
|
||||
}
|
||||
|
||||
// 获取最近历史用于趋势判断
|
||||
const recentHistory = this.getAllHistory();
|
||||
let trendCpu = 'stable', trendMem = 'stable';
|
||||
for (const [, hist] of Object.entries(recentHistory)) {
|
||||
if (hist.length < 5) continue;
|
||||
const recent = hist.slice(-5);
|
||||
const firstCpu = recent[0].cpu, lastCpu = recent[recent.length - 1].cpu;
|
||||
const firstMem = recent[0].mem, lastMem = recent[recent.length - 1].mem;
|
||||
if (lastCpu > firstCpu * 1.15) trendCpu = 'up';
|
||||
else if (lastCpu < firstCpu * 0.85) trendCpu = 'down';
|
||||
if (lastMem > firstMem * 1.15) trendMem = 'up';
|
||||
else if (lastMem < firstMem * 0.85) trendMem = 'down';
|
||||
}
|
||||
|
||||
return {
|
||||
timestamp: Date.now(),
|
||||
summary: {
|
||||
avgCpu,
|
||||
totalMemMB: totalMemRounded,
|
||||
activeProcesses: activeCount,
|
||||
monitoredServices: entries.length,
|
||||
avgLatencyMs,
|
||||
trend: { cpu: trendCpu, mem: trendMem },
|
||||
},
|
||||
perService: snapshot,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const performanceMonitor = new PerformanceMonitor();
|
||||
|
||||
Reference in New Issue
Block a user