fix(adr075): TYPE-3 格式改用 spec 模板 — ACTION REQUIRED + AI深度診斷 + 建議修復動作
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 2m15s

- 標頭改為 "{emoji} ACTION REQUIRED | {severity_zh}"
- 新增 "🧠 AI 深度診斷" 區塊 (分析/責任/AI來源)
- 新增 " 建議修復動作" 區塊 (<code> 格式)
- confidence=0 顯示 "📋 規則分析" 取代誤導性 "🔴 0%"
- SignOz 指標區塊補回 Trace 連結

2026-04-12 ogt: ADR-075 TYPE-3 格式標準化

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-12 21:00:28 +08:00
parent a7f2b9c0f5
commit 3d8b0e4f90

View File

@@ -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"🔍 <a href='{signoz_url}'>SignOz Trace</a>\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"🔺 升級: <b>{freq['escalation_level']}</b>\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"🤖 <b>{provider_display} 仲裁</b>{model_suffix}"
conf_line = f"{source_label} {conf_emoji} {confidence_pct}%"
ai_source = f"🤖 <b>{provider_display}{model_suffix}</b> {conf_emoji} {confidence_pct}%"
elif self.confidence > 0:
source_label = "🤖 <b>AI 仲裁判定</b>"
conf_line = f"{source_label} {conf_emoji} {confidence_pct}%"
ai_source = f"🤖 <b>AI 仲裁</b> {conf_emoji} {confidence_pct}%"
else:
conf_line = "⚙️ <b>規則匹配</b> ✅"
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} <b>{html.escape(self.risk_level)}</b> <code>{html.escape(incident_id)}</code>\n"
f"<b>{safe_resource}</b>\n"
f"{self.status_emoji} ACTION REQUIRED | <b>{html.escape(risk_zh)}</b>\n"
f"──────────────────────\n"
f"📋 <code>{html.escape(incident_id)}</code>\n"
f"🎯 資源:<code>{safe_resource}</code>\n"
f"\n"
f"{conf_line}\n"
f"👥 {resp_display}\n"
f"💡 {safe_root_cause}\n"
f"🧠 <b>AI 深度診斷</b>\n"
f"├─ 分析:{safe_root_cause}\n"
f"├─ 責任:{resp_display}\n"
f"└─ {ai_source}\n"
f"\n"
f"⚡ <b>建議修復動作</b>\n"
f"<code>{safe_action}</code>\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🔧 <b>建議:</b> {safe_action}\n"
f"⏱️ 停機: {safe_downtime}\n"
f"🔍 <a href='{signoz_url}'>SignOz Trace</a>"
)
if frequency_block:
message += f"\n{frequency_block}"
message += f"\n⏱️ 停機: {safe_downtime}"
return message[:4096] # Telegram 硬限制