From 0ac756b24125dde745349ac0b74c38ce4e674203 Mon Sep 17 00:00:00 2001 From: hmo Date: Sat, 18 Jul 2026 13:23:43 +0800 Subject: [PATCH] fix: F Tab unique keys per instance + spec buttons + dedup + naming rules --- docs/dev-spec.md | 3 +++ gateway/scripts/dashboard.py | 9 ++++---- gateway/scripts/templates/dashboard.html | 29 ++++++++++++++++-------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/docs/dev-spec.md b/docs/dev-spec.md index 67b4dae..5e5fb62 100644 --- a/docs/dev-spec.md +++ b/docs/dev-spec.md @@ -141,6 +141,9 @@ H: 需求文档 — 双轨体系覆盖不到的架构级/跨模块需求(性 - **监控数据**:Tier1(5min)/ Tier2(日报)作为实时状态输入 - **服务拓扑**:所有服务的健康、端口、看门狗状态 - **跨平台检测**:远程服务(非本机)标记为 `remote(见平台Tab)`,避免误报 +- **命名唯一性**:F Tab 中的每条服务必须有唯一的 `key`(实例级,如 `agent-001:xmpp_bot`),禁止按类型折叠导致多条同名。M 映射表必须逐条定义友好标签,不可复用同一条目 +- **跨 Tab 一致性**:同一模块在 F Tab、I Tab、K Tab 中的展示名称必须一致。例如 `article_processor` 在 F Tab 叫"文章抓取服务",在 I Tab 也应叫"文章抓取服务",不能一处叫"微信全文抓取" +- **?§ 覆盖**:F Tab 中的每条服务必须有对应的 ?(human_help)和 §(ai_spec)按钮,链接到 `specs/{spec_module}.json`。没有 spec 的服务不应出现在 F Tab 中 ### H — 需求文档(Dashboard H Tab) diff --git a/gateway/scripts/dashboard.py b/gateway/scripts/dashboard.py index 93eb87d..c830caa 100644 --- a/gateway/scripts/dashboard.py +++ b/gateway/scripts/dashboard.py @@ -975,9 +975,10 @@ def api_expected(): if bot_type == "hermes" and svc_type == "xmpp_bot": continue port = svc.get("port") - # key 供前端 M 映射表查找友好标签 - key = svc_type - entry = {"name": f"{display}({host}):{svc_type}", "key": key, "host": host, "expected": "running", "critical": True} + # key 供前端 M 映射表查找唯一标签(实例级,不按类型折叠) + key = f"{agent['id']}:{svc_type}" + spec = svc_type # spec 模块名,供 ?§ 按钮链接 specs/{module}.json + entry = {"name": f"{display}({host}):{svc_type}", "key": key, "spec": spec, "host": host, "expected": "running", "critical": True} if port: entry["port"] = port entry["check"] = "tcp" @@ -990,7 +991,7 @@ def api_expected(): # 2. 从 PLATFORM_SERVICES 生成平台服务的期望 for ps in PLATFORM_SERVICES: - entry = {"name": f"{ps['name']} ({ps['id']})", "key": ps["id"], "host": ps.get("host", "127.0.0.1"), "expected": "running", "critical": True} + entry = {"name": f"{ps['name']} ({ps['id']})", "key": ps["id"], "spec": ps["id"], "host": ps.get("host", "127.0.0.1"), "expected": "running", "critical": True} if ps.get("health_url"): entry["health_url"] = ps["health_url"] entry["check"] = "health_url" diff --git a/gateway/scripts/templates/dashboard.html b/gateway/scripts/templates/dashboard.html index cec6b21..34c4de3 100644 --- a/gateway/scripts/templates/dashboard.html +++ b/gateway/scripts/templates/dashboard.html @@ -158,14 +158,21 @@ async function fL(id){var el=qs('lc-'+id);if(!el||!L.has(id))return;try{var r=aw async function fHealth(){try{ // Helpers function isHealthy(st){return st==='running'||st==='online'||(st&&st.indexOf('remote')===0);} - // Service metadata: label / layer / impact + // Service metadata: label / layer / impact (per-instance key → metadata) var M={}; + M['agent-001:xmpp_bot']={n:'研发助理-XMPP Bot',l:'通信层',i:'小小莫(Windows)XMPP 消息收发中断',spec:'xmpp_bot'}; + M['agent-002:hermes_gateway']={n:'Hermes网关-莫荷',l:'AI网关',i:'莫荷智能体(246 Linux)不可用',spec:'hermes_gateway'}; + M['agent-003:xmpp_bot']={n:'本地推理-XMPP Bot',l:'通信层',i:'小果(Mac)XMPP 消息收发中断',spec:'xmpp_bot'}; + M['agent-003:omlx_server']={n:'OMLX推理服务(小果)',l:'AI网关',i:'小果(Mac)本地推理服务不可用',spec:'omlx_server'}; + M['agent-004:hermes_gateway']={n:'Hermes网关-知微',l:'AI网关',i:'知微智能体(246 Linux)不可用',spec:'hermes_gateway'}; + M.wechat_bridge={n:'莫荷微信桥接',l:'通信层',i:'微信消息收发中断',spec:'wechat_bridge'}; + M.article_processor={n:'文章抓取服务',l:'辅助服务',i:'微信长文章无法读取',spec:'article_processor'}; + // 兼容层:/api/services 返回的旧名称仍然映射到友好标签 + M.xmpp_bot={n:'XMPP消息收发',l:'通信层',i:'消息收发中断'}; + M.hermes_gateway={n:'Hermes网关',l:'AI网关',i:'Hermes Agent不可用'}; M.ejabberd={n:'XMPP服务器',l:'通信层',i:'所有XMPP连接不可用'}; - M.xmpp_bot={n:'XMPP消息收发',l:'通信层',i:'所有Agent消息收发中断'}; - M.hermes_gateway={n:'Hermes AI网关',l:'AI网关',i:'Hermes Agent不可用'}; - M.article_processor={n:'微信全文抓取',l:'辅助服务',i:'微信长文章无法读取'}; - M.wechat_bridge={n:'莫荷微信桥接',l:'通信层',i:'微信消息收发中断'}; - M.omlx_server={n:'OMLX推理服务',l:'AI网关',i:'本地推理服务不可用'}; + M.gateway_mohe={n:'Gateway-莫荷',l:'AI网关',i:'莫荷智能体不可用'}; + M.gateway_zhiwei={n:'Gateway-知微',l:'AI网关',i:'知微智能体不可用'}; M.dashboard={n:'管理门户',l:'辅助服务',i:'Dashboard无法访问'}; M.watchdog={n:'进程看门狗',l:'辅助服务',i:'异常进程无自动恢复'}; M['agents-health-check']={n:'健康检查(5min)',l:'定时任务',i:'5分钟级健康检测未运行'}; @@ -217,10 +224,12 @@ async function fHealth(){try{ var layers={}; var added={}; for(var i=0;i'; h+=''+esc(it.label)+''; if(it.port)h+=':'+it.port+''; + if(it.spec){h+='?'; + h+='§';} h+=''+(run?'运行中':esc(it.status))+''; h+='';} }