feat(adr-075): Phase 2 — TYPE-8M 飛輪/告警鏈路健康通知格式與路由
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 4m0s

新增 send_meta_alert() — ⚙️ META SYSTEM 卡片(觸發診斷/查看面板/靜默)
decision_manager 新增 TYPE-8M elif 分支(在 TYPE-4D 後)
_alert_category 提取提前至 if 鏈前,三個分支共用

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-12 18:39:04 +08:00
parent 2cef2098d3
commit 561c1d806b
2 changed files with 78 additions and 3 deletions

View File

@@ -227,6 +227,11 @@ async def _push_decision_to_telegram(
decision_state=_decision_state, decision_state=_decision_state,
) )
# 2026-04-12 ogt: ADR-075 — 從 Incident 提取 alert_category/notification_type各分支共用
_alert_category = getattr(incident, "alert_category", "") or ""
_notification_type = getattr(incident, "notification_type", "") or (_notif_type.value if _notif_type else "")
_alertname = incident.signals[0].labels.get("alertname", "MetaSystemAlert") if incident.signals else "MetaSystemAlert"
if _notif_type == NotificationType.TYPE_1: if _notif_type == NotificationType.TYPE_1:
# 純資訊通知 — 無按鈕 # 純資訊通知 — 無按鈕
tg_result = await gateway.send_info_notification( tg_result = await gateway.send_info_notification(
@@ -244,11 +249,20 @@ async def _push_decision_to_telegram(
resource_name=target[:50], resource_name=target[:50],
diff_summary=description[:500], diff_summary=description[:500],
) )
elif _notif_type.value == "TYPE-8M" or _alert_category in ("alertchain_health", "flywheel_health"):
# TYPE-8M飛輪/告警鏈路健康異常,發到個人 DM不發群組
tg_result = await gateway.send_meta_alert(
incident_id=incident.incident_id,
approval_id=approval_id,
alertname=_alertname,
alert_category=_alert_category,
diagnosis=reasoning[:100] if reasoning else description[:100],
severity_level=risk_level,
system_impact=description[:150] if description else "",
probable_cause=reasoning[:100] if reasoning else "",
)
else: else:
# TYPE-2 / TYPE-3 / TYPE-4 都走 send_approval_card按鈕組合由 alert_category 決定) # TYPE-2 / TYPE-3 / TYPE-4 都走 send_approval_card按鈕組合由 alert_category 決定)
# 2026-04-12 ogt: ADR-075 斷點 A 修復 — 從 Incident 提取 alert_category/notification_type
_alert_category = getattr(incident, "alert_category", "") or ""
_notification_type = getattr(incident, "notification_type", "") or _notif_type.value if _notif_type else ""
tg_result = await gateway.send_approval_card( tg_result = await gateway.send_approval_card(
approval_id=approval_id, approval_id=approval_id,
risk_level=risk_level, risk_level=risk_level,

View File

@@ -1867,6 +1867,67 @@ class TelegramGateway:
}, },
) )
# =========================================================================
# ADR-075: TYPE-8M Meta-System 告警(飛輪/告警鏈路健康)
# 2026-04-12 ogt
# =========================================================================
async def send_meta_alert(
self,
incident_id: str,
approval_id: str,
alertname: str,
alert_category: str, # "flywheel_health" or "alertchain_health"
diagnosis: str,
severity_level: str = "critical",
system_impact: str = "",
probable_cause: str = "",
) -> dict:
"""
TYPE-8M Meta-System 告警 — 飛輪或告警鏈路自身健康異常。
適用: FlywheelPlaybookZero / AlertChainBroken_* 等
按鈕: 固定 3 個([觸發診斷] [查看面板] [靜默]
只發個人 DM不發群組雙頻道路由規則
"""
severity_emoji = "🔴" if severity_level == "critical" else "🟠"
category_label = "飛輪核心異常" if alert_category == "flywheel_health" else "告警鏈路異常"
text = (
f"⚙️ META SYSTEM | {severity_emoji} {category_label}\n"
f"━━━━━━━━━━━━━━━━━━━\n"
f"📋 <code>{html.escape(incident_id)}</code>\n"
f"🚨 異常元件:<b>{html.escape(alertname)}</b>\n"
f"🎯 診斷結果:{html.escape(diagnosis[:100])}\n"
)
if system_impact:
text += f"\n🧠 <b>系統影響</b>\n{html.escape(system_impact[:150])}\n"
if probable_cause:
text += f"└─ 可能根因:{html.escape(probable_cause[:100])}\n"
silence_nonce = self._security.generate_callback_nonce(approval_id, "silence")
keyboard = {
"inline_keyboard": [
[
{"text": "🔄 觸發診斷", "callback_data": f"action:flywheel_diag:{incident_id}"},
{"text": "📊 查看面板", "callback_data": f"action:flywheel_dashboard:{incident_id}"},
],
[
{"text": "🔕 靜默 1h", "callback_data": silence_nonce},
],
]
}
return await self._make_request(
"sendMessage",
{
"chat_id": settings.OPENCLAW_TG_CHAT_ID,
"text": text,
"parse_mode": "HTML",
"reply_markup": keyboard,
},
)
# ========================================================================= # =========================================================================
# 新訊息發送方法 (2026-03-29 ogt: ADR-038) # 新訊息發送方法 (2026-03-29 ogt: ADR-038)
# ========================================================================= # =========================================================================