diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py
index 021944e0..08a07567 100644
--- a/apps/api/src/services/telegram_gateway.py
+++ b/apps/api/src/services/telegram_gateway.py
@@ -215,10 +215,14 @@ class TelegramMessage:
raw_url = self.signoz_trace_url or f"http://192.168.0.188:3301/traces?service={service_name}"
signoz_url = html.escape(raw_url, quote=True)
- # SignOz 指標區塊
+ # SignOz 指標區塊(含 Trace 連結)
signoz_block = ""
if self.signoz_metrics:
- signoz_block = f"━━━━━━━━━━━━━━━━━━━\n{self.signoz_metrics.format()}\n"
+ signoz_block = (
+ f"━━━━━━━━━━━━━━━━━━━\n"
+ f"{self.signoz_metrics.format()}\n"
+ f"🔍 SignOz Trace\n"
+ )
# HTML 轉義用戶輸入內容,防止 "Can't parse entities" 錯誤
safe_resource = html.escape(self.resource_name)
@@ -272,51 +276,56 @@ class TelegramMessage:
if freq.get("escalation_level"):
frequency_block += f"🔺 升級: {freq['escalation_level']}\n"
- # 2026-03-29 ogt: 根據 confidence + ai_provider 動態顯示來源
- # confidence > 0 = 真實 AI 分析, confidence == 0 = 規則匹配/降級
- # 2026-04-04 ogt: 加入 ai_model 顯示底層模型名稱
- # 2026-04-12 ogt: 規則匹配不顯示 🔴 0%,改用 ✅ 避免誤判為錯誤
+ # ADR-075 TYPE-3 格式 (2026-04-12 ogt)
+ # AI 來源標籤:confidence=0 不顯示 0%,顯示 📋 規則分析
if self.confidence > 0 and self.ai_provider:
provider_names = {
"ollama": "Ollama",
"gemini": "Gemini",
"claude": "Claude",
"nvidia": "Nemotron",
- "openclaw_nemo": "OpenClaw Nemo",
- "openclaw_nvidia_nim": "OpenClaw Nemo",
- "openclaw_qwen": "OpenClaw Nemo",
+ "openclaw_nemo": "Nemotron",
+ "openclaw_nvidia_nim": "Nemotron",
+ "openclaw_qwen": "Nemotron",
}
provider_display = provider_names.get(self.ai_provider.lower(), self.ai_provider.upper())
model_suffix = f" ({html.escape(self.ai_model)})" if self.ai_model else ""
- source_label = f"🤖 {provider_display} 仲裁{model_suffix}"
- conf_line = f"{source_label} {conf_emoji} {confidence_pct}%"
+ ai_source = f"🤖 {provider_display}{model_suffix} {conf_emoji} {confidence_pct}%"
elif self.confidence > 0:
- source_label = "🤖 AI 仲裁判定"
- conf_line = f"{source_label} {conf_emoji} {confidence_pct}%"
+ ai_source = f"🤖 AI 仲裁 {conf_emoji} {confidence_pct}%"
else:
- conf_line = "⚙️ 規則匹配 ✅"
+ ai_source = "📋 規則分析"
- # 2026-04-05 Claude Code: 重設計訊息格式,提升易讀性
- # 組裝訊息
+ # 風險等級中文
+ risk_zh = {
+ "CRITICAL": "嚴重",
+ "HIGH": "高風險",
+ "MEDIUM": "中風險",
+ "LOW": "低風險",
+ }.get(self.risk_level.upper(), self.risk_level)
+
+ # ADR-075 TYPE-3 格式組裝
message = (
- f"{self.status_emoji} {html.escape(self.risk_level)} {html.escape(incident_id)}\n"
- f"{safe_resource}\n"
+ f"{self.status_emoji} ACTION REQUIRED | {html.escape(risk_zh)}\n"
+ f"──────────────────────\n"
+ f"📋 {html.escape(incident_id)}\n"
+ f"🎯 資源:{safe_resource}\n"
f"\n"
- f"{conf_line}\n"
- f"👥 {resp_display}\n"
- f"💡 {safe_root_cause}\n"
+ f"🧠 AI 深度診斷\n"
+ f"├─ 分析:{safe_root_cause}\n"
+ f"├─ 責任:{resp_display}\n"
+ f"└─ {ai_source}\n"
+ f"\n"
+ f"⚡ 建議修復動作\n"
+ f"{safe_action}\n"
)
if ai_cost_display:
message += f"{ai_cost_display}"
- if frequency_block:
- message += f"\n{frequency_block}"
if signoz_block:
message += f"\n{signoz_block}"
- message += (
- f"\n🔧 建議: {safe_action}\n"
- f"⏱️ 停機: {safe_downtime}\n"
- f"🔍 SignOz Trace"
- )
+ if frequency_block:
+ message += f"\n{frequency_block}"
+ message += f"\n⏱️ 停機: {safe_downtime}"
return message[:4096] # Telegram 硬限制