diff --git a/apps/api/src/main.py b/apps/api/src/main.py index 1886eed6..47aed008 100644 --- a/apps/api/src/main.py +++ b/apps/api/src/main.py @@ -229,15 +229,14 @@ async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]: register_all_providers() logger.info("mcp_providers_registered") - # Phase 6.5: Telegram 心跳監控 (防止沉默盲點) - # - 每 30 分鐘發送心跳,證明告警鏈路正常 - # - 超過 2 小時沒訊息則告警 - if settings.OPENCLAW_TG_BOT_TOKEN: - await telegram_gw.start_heartbeat_monitor( - heartbeat_interval_minutes=30, - silence_threshold_hours=2, - ) - logger.info("telegram_heartbeat_monitor_started") + # Phase 6.5: Telegram 心跳監控 + # 2026-04-15 ogt: 停用 — 心跳已轉發到另一個 Telegram 群組,不需在此頻道重複發送 + # if settings.OPENCLAW_TG_BOT_TOKEN: + # await telegram_gw.start_heartbeat_monitor( + # heartbeat_interval_minutes=30, + # silence_threshold_hours=2, + # ) + logger.info("telegram_heartbeat_monitor_disabled", reason="forwarded_to_separate_group") # Reboot Recovery: Warm-up Redis Working Memory from PostgreSQL # 2026-04-05 ogt: 重開機後 Redis 清空,從 DB restore 未解決的 incidents diff --git a/apps/api/src/services/ai_router.py b/apps/api/src/services/ai_router.py index 6958985b..97663f70 100644 --- a/apps/api/src/services/ai_router.py +++ b/apps/api/src/services/ai_router.py @@ -1001,19 +1001,23 @@ class AIRouterExecutor: pass # 2026-04-04 ogt: Phase 25 P0 — require_local 全部失敗時 Telegram 通知(隱私邊界) + # 2026-04-15 ogt: 改用 ADR-075 TYPE-1 格式,禁止純文字 raw notification if require_local: try: from src.services.telegram_gateway import get_telegram_gateway tg = get_telegram_gateway() import asyncio as _asyncio - # 2026-04-14 Claude Sonnet 4.6: send_text 方法不存在,改 send_notification + tried_str = ", ".join(provider_order) + formatted = ( + "⚠️ TYPE-1 | AI Provider 不可用\n" + "──────────────────────\n" + f"├─ 已嘗試: {tried_str}\n" + "└─ 原因: require_local=True,無可用本地 Provider\n" + "\n" + "需要人工介入" + ) _asyncio.create_task( - tg.send_notification( - "⚠️ DIAGNOSE 本地 Provider 不可用\n" - f"已嘗試: {', '.join(provider_order)}\n" - "需要人工介入,雲端 Provider 不會被呼叫(隱私邊界)。", - parse_mode="HTML", - ) + tg.send_notification(formatted, parse_mode="HTML") ) except Exception as _tg_e: logger.warning("diagnose_reject_telegram_failed", error=str(_tg_e)) diff --git a/apps/api/src/services/openclaw.py b/apps/api/src/services/openclaw.py index ee887690..b29a68f0 100644 --- a/apps/api/src/services/openclaw.py +++ b/apps/api/src/services/openclaw.py @@ -893,8 +893,11 @@ class OpenClawService: except Exception as _e: logger.warning("ai_control_override_failed", error=str(_e)) - # Step 3: D7 隱私 — DIAGNOSE/CODE_REVIEW 強制 local - require_local = decision.intent in (IntentType.DIAGNOSE, IntentType.CODE_REVIEW) + # Step 3: D7 隱私 — CODE_REVIEW 強制 local + # 2026-04-15 ogt: DIAGNOSE 移除 require_local(v4.3 決策:NIM 為主力,無隱私問題) + # ai_router.py v4.3 已明確:「NIM 從 Phase 22 起就是主力,無隱私問題」 + # require_local=True 對 DIAGNOSE 只會讓所有 provider 被 privacy_skip → 永遠失敗 + require_local = decision.intent in (IntentType.CODE_REVIEW,) result = await executor.execute( prompt=prompt,