diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py
index 444e82d5..6466893d 100644
--- a/apps/api/src/services/decision_manager.py
+++ b/apps/api/src/services/decision_manager.py
@@ -139,6 +139,8 @@ async def _push_decision_to_telegram(
nemotron_tools=nemotron_tools,
nemotron_validation=nemotron_validation,
nemotron_latency_ms=nemotron_latency_ms,
+ # 2026-04-05 Claude Code: 傳入 incident_id 以啟用 detail/reanalyze/history 按鈕
+ incident_id=incident.incident_id,
)
# 🔴 發送成功後設置去重 key (TTL 10 分鐘)
diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py
index a5e7a2c9..5916f751 100644
--- a/apps/api/src/services/telegram_gateway.py
+++ b/apps/api/src/services/telegram_gateway.py
@@ -271,25 +271,26 @@ class TelegramMessage:
else:
source_label = "⚙️ 規則匹配"
+ # 2026-04-05 Claude Code: 重設計訊息格式,提升易讀性
# 組裝訊息
message = (
- f"═══════════════════════════\n"
- f"{self.status_emoji} {html.escape(self.risk_level)} | {html.escape(self.resource_name[:25])}\n"
- f"═══════════════════════════\n"
- f"📋 {html.escape(incident_id)}\n"
- f"🎯 資源: {safe_resource}\n"
- f"━━━━━━━━━━━━━━━━━━━\n"
- f"{source_label}\n"
- f"👥 責任: {resp_display}\n"
- f"📊 信心: {conf_emoji} {confidence_pct}%\n"
- f"{ai_cost_display}"
- f"💡 原因: {safe_root_cause}\n"
- f"{frequency_block}"
- f"{signoz_block}"
- f"━━━━━━━━━━━━━━━━━━━\n"
- f"🔧 建議: {safe_action}\n"
+ f"{self.status_emoji} {html.escape(self.risk_level)} {html.escape(incident_id)}\n"
+ f"{safe_resource}\n"
+ f"\n"
+ f"{source_label} {conf_emoji} {confidence_pct}%\n"
+ f"👥 {resp_display}\n"
+ f"💡 {safe_root_cause}\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🔧 建議: {safe_action}\n"
f"⏱️ 停機: {safe_downtime}\n"
- f"🔍 查看 SignOz Trace (±5min)"
+ f"🔍 SignOz Trace"
)
return message[:900]
@@ -397,21 +398,20 @@ class TelegramMessage:
if self.nemotron_latency_ms > 0:
nemotron_block += f"└ 延遲: {self.nemotron_latency_ms:.0f}ms\n"
+ # 2026-04-05 Claude Code: 重設計訊息格式,提升易讀性
# 組裝訊息
message = (
- f"═══════════════════════════\n"
- f"{self.status_emoji} {html.escape(self.risk_level)} | {html.escape(self.resource_name[:25])}\n"
- f"═══════════════════════════\n"
- f"📋 {html.escape(incident_id)}\n"
- f"🎯 資源: {safe_resource}\n"
- f"━━━━━━━━━━━━━━━━━━━\n"
- f"{source_label}\n"
- f"├ 📊 信心: {conf_emoji} {confidence_pct}%\n"
- f"├ 👥 責任: {resp_display}\n"
- f"└ 💡 原因: {safe_root_cause}\n"
- f"{nemotron_block}"
- f"━━━━━━━━━━━━━━━━━━━\n"
- f"🔧 建議: {safe_action}\n"
+ f"{self.status_emoji} {html.escape(self.risk_level)} {html.escape(incident_id)}\n"
+ f"{safe_resource}\n"
+ f"\n"
+ f"{source_label} {conf_emoji} {confidence_pct}%\n"
+ f"👥 {resp_display}\n"
+ f"💡 {safe_root_cause}\n"
+ )
+ if nemotron_block:
+ message += f"\n{nemotron_block}"
+ message += (
+ f"\n🔧 建議: {safe_action}\n"
f"⏱️ 停機: {safe_downtime}"
)
@@ -1281,6 +1281,8 @@ class TelegramGateway:
nemotron_tools: list[dict] | None = None,
nemotron_validation: str = "",
nemotron_latency_ms: float = 0.0,
+ # 2026-04-05 Claude Code: incident_id 用於 detail/reanalyze/history 按鈕
+ incident_id: str = "",
) -> dict:
"""
推送待簽核卡片到 Telegram (v7.0 含 SignOz 整合)
@@ -1330,6 +1332,7 @@ class TelegramGateway:
suggested_action=suggested_action,
estimated_downtime=estimated_downtime,
approval_id=approval_id,
+ incident_id=incident_id,
primary_responsibility=primary_responsibility,
confidence=confidence,
namespace=namespace,
@@ -1356,10 +1359,12 @@ class TelegramGateway:
text = message.format_with_nemotron() if nemotron_enabled else message.format()
# 建立按鈕 (含自動調優)
+ # 2026-04-05 Claude Code: 傳入 incident_id 以啟用 detail/reanalyze/history 按鈕
keyboard = self._build_inline_keyboard(
approval_id=approval_id,
include_auto_tuning=bool(auto_tuning_command),
auto_tuning_command=auto_tuning_command,
+ incident_id=incident_id or message.incident_id,
)
# 發送訊息