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 顯示