from src.services.telegram_gateway import TelegramMessage def test_action_required_card_exposes_ai_automation_on_fallback() -> None: message = TelegramMessage( status_emoji="🚨", risk_level="CRITICAL", resource_name="node-exporter-110", root_cause="AI 分析超時(90s),降級至人工審核", suggested_action="待分析", estimated_downtime="5-15 min", approval_id="test-approval-id", incident_id="INC-20260429-TEST01", primary_responsibility="INFRA", confidence=0.0, ) body = message.format() assert "AI 自動化鏈路" in body assert "rule_fallback" in body assert "llm_timeout_manual_gate" in body assert "OpenClaw" in body assert "NemoTron" in body assert "Hermes" in body assert "ElephantAlpha" in body assert "流程進度" in body assert "執行:no_action_or_observe" in body def test_repair_candidate_missing_card_exposes_manual_handoff_package() -> None: message = TelegramMessage( status_emoji="ℹ️", risk_level="LOW", resource_name="node-exporter-188", root_cause="AI 選擇不執行修復,需人工判斷是否接手", suggested_action="NO_ACTION - REPAIR_CANDIDATE_MISSING: LLM 分析失敗,尚未產生安全可執行修復指令", estimated_downtime="unknown", approval_id="test-approval-id", incident_id="INC-20260611-34BBF5", primary_responsibility="INFRA", confidence=0.0, alert_category="host_resource", repair_candidate_blocker_summary="只命中通用兜底 PlayBook,禁止當成修復命令", repair_candidate_next_step=( "建立專屬 PlayBook 草案:綁定 alertname / target selector,補 MCP evidence refs、" "修復命令、rollback、verifier plan 與 owner review。" ), repair_candidate_required_fields=[ "alertname", "target_selector", "mcp_evidence_refs", "repair_command", "rollback_command", "verifier_plan", "owner_review", ], repair_candidate_work_item_href=( "https://awoooi.wooo.work/zh-TW/awooop/work-items?" "project_id=awoooi&incident_id=INC-20260611-34BBF5" "&work_item_id=repair-candidate-draft%3Aawoooi%3AINC-20260611-34BBF5" ), repair_candidate_work_item_id="repair-candidate-draft:awoooi:INC-20260611-34BBF5", ) body = message.format() assert "缺少可執行修復候選,已產生人工處置包" in body assert "Mode:repair_candidate_missing_manual_handoff" in body assert "人工處置包" in body assert "只命中通用兜底 PlayBook" in body assert "建立專屬 PlayBook 草案" in body assert "PlayBook 草案欄位" in body assert "repair_command" in body assert "工作項目" in body assert "AwoooP 修復候選草案" in body assert "https://awoooi.wooo.work/zh-TW/awooop/work-items?" in body assert "補證據:node_exporter target up" in body assert "AwoooP 建立修復候選" in body assert "按鈕:處置包" in body assert "修復候選狀態" in body assert "等待人工批准" not in body def test_nemotron_card_exposes_same_ai_automation_chain() -> None: message = TelegramMessage( status_emoji="🚨", risk_level="CRITICAL", resource_name="awoooi-api", root_cause="Pod restart loop", suggested_action="restart deployment/awoooi-api", estimated_downtime="30s", approval_id="test-approval-id", incident_id="INC-20260429-TEST02", primary_responsibility="INFRA", confidence=0.86, ai_provider="openclaw_nemo", ai_model="llama-3.1-nemotron", nemotron_enabled=True, playbook_name="restart_deployment", ) body = message.format_with_nemotron() assert "AI 自動化鏈路" in body assert "OpenClaw Nemo" in body assert "tool_ready" in body assert "restart_deployment" in body assert "流程進度" in body def test_action_required_card_exposes_truth_chain_progress() -> None: message = TelegramMessage( status_emoji="⚠️", risk_level="LOW", resource_name="awoooi-api", root_cause="restart spike", suggested_action="kubectl rollout restart deployment/awoooi-api", estimated_downtime="30s", approval_id="approval-id", incident_id="INC-20260513-TEST03", primary_responsibility="INFRA", confidence=0.91, playbook_name="restart_deployment", automation_quality={ "verdict": "auto_repaired_verified", "facts": { "auto_repair_execution_records": 1, "automation_operation_records": 1, "verification_result": "success", "mcp_gateway_total": 5, "knowledge_entries": 2, }, }, ) body = message.format() assert "流程進度" in body assert "執行:auto_repair_recorded:1" in body assert "驗證:success" in body assert "KM:2" in body assert "MCP:5" in body assert "已驗證自動修復" in body assert "已驗證自動修復完成" in body assert "等待人工批准" not in body def test_action_required_card_does_not_call_diagnostic_ops_auto_repair() -> None: message = TelegramMessage( status_emoji="🚨", risk_level="CRITICAL", resource_name="dirty-reboot-evidence", root_cause="Expert System: 偵測到高錯誤率", suggested_action="ssh 192.168.0.110 'df -h /data/minio'", estimated_downtime="0 min", approval_id="approval-id", incident_id="INC-20260530-88D960", primary_responsibility="INFRA", confidence=0.0, playbook_name="rule_catalog", automation_quality={ "verdict": "auto_repaired_verification_degraded", "facts": { "auto_repair_execution_records": 0, "automation_operation_records": 1, "effective_execution_records": 0, "verification_result": "degraded", "mcp_gateway_total": 22, "knowledge_entries": 2, }, }, ) body = message.format() assert "已記錄診斷/觀察,驗證結果:degraded" in body assert "執行:diagnostic_recorded:1" in body assert "已記錄診斷/觀察,尚未證明修復" in body assert "已自動執行" not in body