From e60225ea298d22b75cfc5a781eb23fad577d6818 Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 3 Apr 2026 13:22:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(ai):=20I1+I3=20=E2=80=94=20Redis=20TTL=20+?= =?UTF-8?q?=20openclaw=5Fnemo=20=E5=91=BD=E5=90=8D=E5=B0=8D=E9=BD=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I1: ai_control.py 所有寫入 Redis 的 key 加入 30 天 TTL 防止 ai:control:* keys 永久累積造成記憶體洩漏 I3: ai_rate_limiter.py "nvidia" key → "openclaw_nemo" 對齊 Phase 24 AIProviderEnum,使 rate limit 正確作用 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/ai_control.py | 15 +++++++++------ apps/api/src/services/ai_rate_limiter.py | 6 ++++-- 2 files changed, 13 insertions(+), 8 deletions(-) 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, # 不發送成本告警 },