feat(监控): 管理员排行榜实时并发监控 + 真正停止对话 + 409 中文化
- 排行榜页顶部新增「实时并发监控」面板(admin-only):当前并发大模型调用数 +
调用列表(用户/智能体/类型/已运行时长),每行「停止」+「全部停止」经
RunManager.cancel 真正中断 LLM 流式调用,减轻大模型压力
- 并发量折线图(峰值/均值,按分钟/小时):新增轻量后台采样器写入新表
concurrency_samples(create_all 自动建表),可按分/时聚合
- 大模型出字速度折线图(tokens/秒,按分钟/小时):复用 llm_call_metrics 聚合,
便于定位是模型/供应商慢
- 后台采样可开关、默认关闭(opt-in)、运行时切换免重启、对线上零影响
(单条极小 INSERT、保留期清理、查询有上限、全程 best-effort)
- 409 中文化:上一轮未结束又发新问题时返回中文提示,前端 onError 友好映射
后端:runtime/runs/manager.py(list_active)、persistence/concurrency(新模块)、
config/system_settings(ConcurrencyMonitorSettings)、gateway/routers/admin_active_runs、
app.py(采样后台任务)、services.py(409)。前端:core/admin/{active-runs,hooks}、
components/workspace/admin/concurrency-monitor、AdminUserLeaderboardPage、threads/hooks。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
158d157af4
commit
26f8010a57
17 files changed
+1488
-1
No files matched your search
@@ -219,6 +219,19 @@ function isRunNotFoundError(message: string): boolean {
|
||||
return /run\s+[\w-]{8,}\s+not\s+found/i.test(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一会话上一轮还没生成完,又提交了新问题 → 后端返回 409
|
||||
* 「already has an active run」。匹配 HTTP 409、英文兜底文案,或后端已中文化
|
||||
* 的提示,统一映射成一句友好的中文。
|
||||
*/
|
||||
function isActiveRunConflictError(message: string): boolean {
|
||||
return (
|
||||
/\b409\b/.test(message) ||
|
||||
/already has an active run/i.test(message) ||
|
||||
/还在生成回答/.test(message)
|
||||
);
|
||||
}
|
||||
|
||||
function buildCurrentUserLabel(): string {
|
||||
const auth = getStoredAuth();
|
||||
if (!auth) {
|
||||
@@ -555,6 +568,12 @@ export function useThreadStream({
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 上一轮还没结束又发了新问题(后端 409):给一句明确的中文提示,而不是
|
||||
// 把原始的英文/HTTP 错误抛给用户。
|
||||
if (isActiveRunConflictError(message)) {
|
||||
toast.info("当前对话还在生成回答,请等待本轮回复结束,或先点「停止」再发送新的问题。");
|
||||
return;
|
||||
}
|
||||
toast.error(message);
|
||||
},
|
||||
onFinish(state) {
|
||||
|
||||
Reference in new issue
Block a user