feat(api): Phase 16 R1.2 絞殺者模式 (Strangler Fig Pattern)

- 新增 USE_NEW_ENGINE 設定開關 (預設 False)
- incident_memory.py 雙軌切換: 內嵌版本 ↔ lewooogo-brain
- 自動降級: lewooogo-brain 不可用時回退內嵌版本
- 回滾指令: kubectl set env deployment/awoooi-api USE_NEW_ENGINE=false

統帥批准 2026-03-26 立即執行

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-25 15:23:03 +08:00
parent cdbd6f0fa6
commit a202a2693a
2 changed files with 101 additions and 3 deletions

View File

@@ -51,6 +51,21 @@ class Settings(BaseSettings):
description="Enable mock mode for external services (Redis, Ollama, OpenClaw, PostgreSQL, SigNoz)",
)
# ==========================================================================
# Phase 16: leWOOOgo 積木化絞殺者模式 (Strangler Fig Pattern)
# 2026-03-26 統帥批准立即執行
#
# 功能開關:
# - False: 使用 apps/api 內嵌版本 (當前)
# - True: 使用 lewooogo-brain/lewooogo-data 套件版本
#
# 回滾指令: kubectl set env deployment/awoooi-api USE_NEW_ENGINE=false
# ==========================================================================
USE_NEW_ENGINE: bool = Field(
default=False,
description="Phase 16: True=lewooogo packages, False=內嵌版本",
)
# ==========================================================================
# CORS - 嚴格白名單 (無 UAT, 無 wildcard)
# ==========================================================================

View File

@@ -2,6 +2,7 @@
Incident Memory Provider - 事件記憶體提供者
============================================
Phase 6.4e: DualIncidentMemory 整合
Phase 16 R1.2: 絞殺者模式 (Strangler Fig Pattern) 2026-03-26
設計:
- 實作 IIncidentMemory 協定 (Protocol)
@@ -13,8 +14,14 @@ Phase 6.4e: DualIncidentMemory 整合
- Episodic Memory (PostgreSQL): 永久
- 反向索引: 30 分鐘 TTL (聚合窗口)
Phase 16 絞殺者模式:
- USE_NEW_ENGINE=False: 使用此內嵌版本 (當前預設)
- USE_NEW_ENGINE=True: 使用 lewooogo-brain 套件版本
- 回滾指令: kubectl set env deployment/awoooi-api USE_NEW_ENGINE=false
- 監控週期: 48 小時驗證期
NOTE: 此模組為 lewooogo-brain/adapters/incident_memory.py 的 apps/api 內嵌版本
Phase 6.4i 完成 monorepo Docker 解法後,將直接引用 lewooogo-brain 套件
Phase 16 R2 階段會在 48 小時驗證通過後移除此檔案
"""
from datetime import UTC, datetime, timedelta
@@ -469,15 +476,91 @@ class DualIncidentMemory:
# =============================================================================
# Singleton
# Singleton + 絞殺者模式 (Phase 16 R1.2)
# =============================================================================
_dual_memory: DualIncidentMemory | None = None
_new_engine_memory: Any | None = None # lewooogo-brain 版本
def get_incident_memory() -> DualIncidentMemory:
"""取得 DualIncidentMemory 實例 (Singleton)"""
"""
取得 DualIncidentMemory 實例 (Singleton)
Phase 16 絞殺者模式:
- USE_NEW_ENGINE=False (預設): 返回內嵌版本
- USE_NEW_ENGINE=True: 返回 lewooogo-brain 套件版本
回滾指令: kubectl set env deployment/awoooi-api USE_NEW_ENGINE=false
"""
from src.core.config import settings
if settings.USE_NEW_ENGINE:
return _get_new_engine_memory()
else:
return _get_legacy_memory()
def _get_legacy_memory() -> DualIncidentMemory:
"""取得內嵌版本 (Phase 16 舊引擎)"""
global _dual_memory
if _dual_memory is None:
_dual_memory = DualIncidentMemory()
logger.info("incident_memory_initialized", engine="legacy_embedded")
return _dual_memory
def _get_new_engine_memory() -> Any:
"""
取得 lewooogo-brain 套件版本 (Phase 16 新引擎)
注意事項:
- 需要 lewooogo-brain 已安裝 (Dockerfile 已配置)
- PostgreSQL 整合尚未完成 (TODO in lewooogo-brain)
- 初次啟用建議 48 小時監控
回滾: 設定 USE_NEW_ENGINE=false 即可瞬間切回
"""
global _new_engine_memory
if _new_engine_memory is None:
try:
# 延遲導入: 避免 lewooogo-brain 未安裝時啟動失敗
from lewooogo_brain.adapters.incident_memory import (
DualIncidentMemory as NewDualIncidentMemory,
)
from src.core.redis_client import get_redis
from src.db.base import get_db_context
redis_client = get_redis()
# 初始化 lewooogo-brain 版本
_new_engine_memory = NewDualIncidentMemory(
redis_client=redis_client,
pg_session_factory=get_db_context,
key_prefix="awoooi:incidents",
)
logger.info(
"incident_memory_initialized",
engine="lewooogo_brain_package",
redis_connected=True,
)
except ImportError as e:
# lewooogo-brain 未安裝,降級到內嵌版本
logger.warning(
"lewooogo_brain_not_available_fallback_to_legacy",
error=str(e),
)
return _get_legacy_memory()
except Exception as e:
# 其他錯誤,降級到內嵌版本
logger.error(
"new_engine_init_failed_fallback_to_legacy",
error=str(e),
)
return _get_legacy_memory()
return _new_engine_memory