diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index 79a12c4b..5d725667 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -21,6 +21,7 @@ Decision Manager - Phase 6.5 非同步決策狀態機 """ import asyncio +import json from datetime import UTC, datetime from enum import Enum from typing import Any, Protocol, runtime_checkable @@ -312,24 +313,44 @@ async def _push_decision_to_telegram( if _notif_type == NotificationType.TYPE_1: # 純資訊通知 — 無按鈕 # 2026-04-12 ogt: Incident 沒有 title 欄位,用 alertname + # 2026-04-17 ogt + Claude Sonnet 4.6: BUG-A 修復 — 只取 diagnosis 欄位 + # 舊:message=reasoning[:200] → 整條 debate_summary 生文字傾倒 + # 新:解析 debate_summary,只取「診斷:...」部分給 SRE 看 _info_title = ( incident.signals[0].labels.get("alertname", "") or incident.signals[0].alert_name ) if incident.signals else "告警通知" + _parsed_info = _parse_debate_summary(reasoning) + _info_msg = _smt(_parsed_info.get("diagnosis") or description, 200) tg_result = await gateway.send_info_notification( incident_id=incident.incident_id, title=_info_title or "告警通知", - message=reasoning[:200] if reasoning else description[:200], + message=_info_msg, alertname=incident.signals[0].labels.get("alertname", "") if incident.signals else "", severity="info", ) elif _notif_type == NotificationType.TYPE_4_DRIFT: # Config Drift 專屬卡片 + # 2026-04-17 ogt + Claude Sonnet 4.6: BUG-B JSON Catcher + # LLM 可能輸出 JSON 結構({"action_title":"...","description":"...","rollback":"..."}) + # 解析成功 → 格式化可讀文字;失敗 → 平滑降級為原始截斷字串(不可拋出 Exception) + try: + _drift_data = json.loads(description) + _parts: list[str] = [] + if _drift_data.get("action_title"): + _parts.append(f"📝 建議操作:{_drift_data['action_title']}") + if _drift_data.get("description"): + _parts.append(f"📖 說明:{_smt(_drift_data['description'], 200)}") + if _drift_data.get("rollback"): + _parts.append(f"⏪ 回滾方案:{_smt(_drift_data['rollback'], 100)}") + _diff_text = "\n".join(_parts) if _parts else description[:500] + except (json.JSONDecodeError, TypeError, AttributeError): + _diff_text = description[:500] tg_result = await gateway.send_drift_card( incident_id=incident.incident_id, approval_id=approval_id, resource_name=target[:50], - diff_summary=description[:500], + diff_summary=_diff_text, ) elif _notif_type == NotificationType.TYPE_8M or _alert_category in ("alertchain_health", "flywheel_health"): # TYPE-8M:飛輪/告警鏈路健康異常,發到個人 DM(不發群組)