diff --git a/apps/api/src/services/ai_control.py b/apps/api/src/services/ai_control.py index 5ff7d678..139c377b 100644 --- a/apps/api/src/services/ai_control.py +++ b/apps/api/src/services/ai_control.py @@ -6,9 +6,9 @@ Telegram /ai 指令動態控制 AI Router 狀態 - OPENCLAW_TG_USER_WHITELIST 白名單保護 Redis Keys: - ai:control:use_router "true"/"false" (覆蓋 USE_AI_ROUTER env) - ai:control:primary_provider "openclaw_nemo"/"gemini"/"ollama"/"claude" - ai:control:disabled: "1" (TTL: 永久或手動清除) + ai:control:use_router "true"/"false" (TTL: 30天) + ai:control:primary_provider "openclaw_nemo"/"gemini"/"ollama"/"claude" (TTL: 30天) + ai:control:disabled: "1" (TTL: 30天) Usage: /ai status — 顯示所有 Provider 狀態 + 當前路由模式 @@ -29,6 +29,9 @@ _AI_ROUTER_KEY = "ai:control:use_router" _PRIMARY_PROVIDER_KEY = "ai:control:primary_provider" _DISABLED_KEY_PREFIX = "ai:control:disabled:" +# 2026-04-03 ogt: I1 防止記憶體洩漏 — 所有控制 key 統一 30 天 TTL +_CONTROL_KEY_TTL = 30 * 24 * 3600 # 30 days + VALID_PROVIDERS = {"openclaw_nemo", "gemini", "ollama", "claude", "nemotron"} @@ -57,7 +60,7 @@ async def set_ai_router_enabled(enabled: bool) -> bool: """設定 AIRouter 啟用狀態到 Redis""" try: r = await _get_redis() - await r.set(_AI_ROUTER_KEY, "true" if enabled else "false") + await r.set(_AI_ROUTER_KEY, "true" if enabled else "false", ex=_CONTROL_KEY_TTL) logger.info("ai_control_router_set", enabled=enabled) return True except Exception as e: @@ -83,7 +86,7 @@ async def set_primary_provider(provider: str) -> bool: return False try: r = await _get_redis() - await r.set(_PRIMARY_PROVIDER_KEY, provider) + await r.set(_PRIMARY_PROVIDER_KEY, provider, ex=_CONTROL_KEY_TTL) logger.info("ai_control_primary_set", provider=provider) return True except Exception as e: @@ -119,7 +122,7 @@ async def set_provider_disabled(provider: str, disabled: bool) -> bool: r = await _get_redis() key = f"{_DISABLED_KEY_PREFIX}{provider}" if disabled: - await r.set(key, "1") + await r.set(key, "1", ex=_CONTROL_KEY_TTL) else: await r.delete(key) logger.info("ai_control_provider_set", provider=provider, disabled=disabled) diff --git a/apps/api/src/services/ai_rate_limiter.py b/apps/api/src/services/ai_rate_limiter.py index f7c275e6..3771ca37 100644 --- a/apps/api/src/services/ai_rate_limiter.py +++ b/apps/api/src/services/ai_rate_limiter.py @@ -39,7 +39,8 @@ RATE_LIMITS = { }, # 2026-03-31 ogt: NVIDIA NIM 免費版無每日限制! # 只保留 RPM 限制 (併發控制) + 極大的 daily 上限 (監控用) - "nvidia": { + # 2026-04-03 ogt: I3 — "nvidia" → "openclaw_nemo" 對齊 AIProviderEnum (Phase 24) + "openclaw_nemo": { "rpm": 10, # 每分鐘請求數 (放寬到 10) "daily_requests": 99999, # 🔴 免費版無限制!設大數避免誤觸 "daily_tokens": 9999999, # 免費版無限制 @@ -61,7 +62,8 @@ COST_LIMITS = { }, # 2026-03-29 ogt: ADR-036 Nemotron (免費 Tier,設定低限制作為監控) # 2026-03-31 ogt: 修復 $0.00 >= $0.00 永遠 True 的 Bug,改用大數值表示無限制 - "nvidia": { + # 2026-04-03 ogt: I3 — "nvidia" → "openclaw_nemo" 對齊 AIProviderEnum (Phase 24) + "openclaw_nemo": { "total_cost_usd": 999999.0, # 免費 Tier 無成本限制 "alert_threshold_usd": 0.0, # 不發送成本告警 },