From c5e475121ab597418ddd019568bd6443221e490e Mon Sep 17 00:00:00 2001 From: OG T Date: Thu, 9 Apr 2026 11:14:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(telegram):=20=E4=BF=AE=E5=BE=A9=E5=BB=BA?= =?UTF-8?q?=E8=AD=B0=E6=8C=87=E4=BB=A4=E8=A2=AB=E6=88=AA=E6=96=B7=20+=20de?= =?UTF-8?q?cision=5Fmanager=20enum=20string=20=E8=A3=9C=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因 1: telegram_gateway.py suggested_action[:35] 剛好截到 deployment/ 後 → 改為 [:80],完整顯示 kubectl command 根因 2: 舊 Incident proposal_data 存 enum string (RESTART_DEPLOYMENT) → decision_manager.py 加入偵測,用規則引擎重新查 kubectl command Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/decision_manager.py | 22 ++++++++++++++++++++++ apps/api/src/services/telegram_gateway.py | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index 6466893d..d1b174b8 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -105,6 +105,28 @@ async def _push_decision_to_telegram( target = incident.affected_services[0] if incident.affected_services else "unknown" risk_level = proposal_data.get("risk_level", "medium") action = _strip_placeholders(proposal_data.get("action", proposal_data.get("kubectl_command", ""))) + + # 2026-04-09 Claude Code: 修復舊 Incident proposal_data 存 enum string 導致建議空白 + # 舊 code 存 action="RESTART_DEPLOYMENT" 而非 kubectl command + # 偵測:無 kubectl/ssh/docker 關鍵字 → 用規則引擎重新查 + _KUBECTL_MARKERS = ("kubectl", "ssh", "docker", "systemctl", "/") + if action and not any(m in action for m in _KUBECTL_MARKERS): + # action 是 enum string,嘗試用規則引擎補出 kubectl command + try: + from src.services.alert_rule_engine import match_rule as _match_rule + _labels = incident.signals[0].labels if incident.signals else {} + _rule_resp = _match_rule({ + "labels": _labels, + "alert_type": _labels.get("alertname", target), + "message": incident.title or "", + "target_resource": target, + "namespace": incident.signals[0].labels.get("namespace", "awoooi-prod") if incident.signals else "awoooi-prod", + "severity": risk_level, + }) + if _rule_resp and _rule_resp.get("kubectl_command", "").strip(): + action = _rule_resp["kubectl_command"] + except Exception: + pass # 規則引擎失敗不影響通知,保留原 action description = proposal_data.get("description", "") reasoning = _strip_placeholders(proposal_data.get("reasoning", "")) confidence = proposal_data.get("confidence", 0.0) # 🔴 預設 0.0 表示未經 AI 分析 diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index 2d1699e8..92eb3b98 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -221,7 +221,7 @@ class TelegramMessage: # HTML 轉義用戶輸入內容,防止 "Can't parse entities" 錯誤 safe_resource = html.escape(self.resource_name[:35]) safe_root_cause = html.escape(self.root_cause[:50]) - safe_action = html.escape(self.suggested_action[:35]) + safe_action = html.escape(self.suggested_action[:80]) safe_downtime = html.escape(self.estimated_downtime) # 2026-03-29 ogt: AI Token/Cost 顯示 @@ -372,7 +372,7 @@ class TelegramMessage: # HTML 轉義 safe_resource = html.escape(self.resource_name[:35]) safe_root_cause = html.escape(self.root_cause[:50]) - safe_action = html.escape(self.suggested_action[:35]) + safe_action = html.escape(self.suggested_action[:80]) safe_downtime = html.escape(self.estimated_downtime) # AI Provider 顯示