fix(aiops): 修復 sensors=0/0 根因 — MCPToolRegistry 從未在 startup 初始化
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m44s

三個問題同時修復:

1. main.py: 補上 init_mcp_tool_registry() 呼叫
   - ADR-081 Phase 1 建立了 MCPToolRegistry 但從未在 lifespan startup 被呼叫
   - 導致 PreDecisionInvestigator sensors=0/0,evidence_summary 永遠空白
   - 空白 evidence → Diagnostician 永遠 ABSTAIN

2. signal_producer.py: str(dict) → json.dumps()
   - labels/annotations 用 Python str() 序列化,寫入 Redis 後無法反序列化

3. brain/incident_engine.py: 新增 _parse_dict_field() helper
   - 從 Redis 讀回的 labels/annotations 可能是 JSON 字串
   - isinstance(..., dict) 防禦不足,需先 json.loads()

2026-04-16 ogt + Claude Sonnet 4.6(亞太): 飛輪感官修復

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-16 15:35:19 +08:00
parent d294caf830
commit 588b0d745b
3 changed files with 30 additions and 4 deletions

View File

@@ -230,6 +230,15 @@ async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]:
register_all_providers()
logger.info("mcp_providers_registered")
# ADR-081 Phase 1: MCPToolRegistry 初始化PreDecisionInvestigator 感官工具)
# 2026-04-16 ogt + Claude Sonnet 4.6: 修復 sensors=0/0 根因 — init 從未在 startup 被呼叫
try:
from src.services.mcp_tool_registry import init_mcp_tool_registry
await init_mcp_tool_registry()
logger.info("mcp_tool_registry_initialized")
except Exception as e:
logger.warning("mcp_tool_registry_init_failed", error=str(e))
# Phase 6.5: Telegram 心跳監控(每 30 分鐘發送到 SRE 戰情室群組)
# 2026-04-16 ogt + Claude Sonnet 4.6: 恢復 — 使用者確認必須繼續在 SRE 戰情室發送
# 上次停用原因forwarded_to_separate_group有誤群組就是 SRE_GROUP_CHAT_ID

View File

@@ -12,6 +12,7 @@ Signal Producer Service - Phase 17 P0 Router 層違規修復
- Router -> Service -> Redis
"""
import json
from dataclasses import dataclass
from typing import Any
@@ -74,8 +75,8 @@ class SignalProducerService:
"namespace": signal.namespace,
"target": signal.target,
"message": signal.message,
"labels": str(signal.labels or {}),
"annotations": str(signal.annotations or {}),
"labels": json.dumps(signal.labels or {}),
"annotations": json.dumps(signal.annotations or {}),
"received_at": now_taipei().isoformat(),
}