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 硬限制