feat(ai): Phase 24 C — Telegram /ai 動態控制 + Redis 狀態管理
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
新增 ai_control.py: - /ai status: 所有 Provider 狀態 + 路由模式 - /ai router on/off: 動態切換 AIRouter (覆蓋 env var) - /ai primary <provider>: 設定主要 Provider - /ai enable/disable <provider>: 控制 Provider 啟停 - /ai cost: 費用統計 - 白名單: OPENCLAW_TG_USER_WHITELIST 保護 telegram_gateway.py: - _handle_chat_message 加入 /ai 指令攔截路由 - 白名單未授權返回警告 openclaw.py: - Redis 狀態覆蓋 env USE_AI_ROUTER (/ai router on/off 生效) - Redis primary_provider 覆蓋路由決策 (/ai primary 生效) - Redis disabled provider 過濾 (/ai disable 生效) Redis Keys: ai:control:use_router ai:control:primary_provider ai:control:disabled:<provider> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -924,8 +924,19 @@ class OpenClawService:
|
||||
# USE_AI_ROUTER=true → 新 AIRouterExecutor 路由
|
||||
# USE_AI_ROUTER=false → 舊 if/else fallback chain (現狀)
|
||||
# 回滾: kubectl set env deployment/awoooi-api USE_AI_ROUTER=false
|
||||
# Phase 24 C: Redis 狀態覆蓋 env var (/ai router on/off)
|
||||
# =================================================================
|
||||
if settings.USE_AI_ROUTER:
|
||||
# Redis 狀態優先 (Phase 24 C — 2026-04-03 ogt)
|
||||
_use_ai_router = settings.USE_AI_ROUTER
|
||||
try:
|
||||
from src.services.ai_control import get_ai_router_enabled
|
||||
_redis_override = await get_ai_router_enabled()
|
||||
if _redis_override is not None:
|
||||
_use_ai_router = _redis_override
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if _use_ai_router:
|
||||
try:
|
||||
# 2026-04-02 ogt: C2 修復 — 呼叫 AIRouter.route() 智慧路由 (非靜態 order)
|
||||
# D1 意圖分類路由、D7 隱私保護 (DIAGNOSE/CODE_REVIEW 強制 local) 生效
|
||||
@@ -937,10 +948,23 @@ class OpenClawService:
|
||||
decision = await router.route(prompt, alert_context)
|
||||
|
||||
# Step 2: 從 RoutingDecision 建立 provider_order (主 + fallback)
|
||||
# Phase 24 C: Redis primary_provider 覆蓋路由決策
|
||||
provider_order = [decision.selected_provider.value] + [
|
||||
p.value for p, _ in decision.fallback_chain
|
||||
if p.value != decision.selected_provider.value
|
||||
]
|
||||
try:
|
||||
from src.services.ai_control import get_primary_provider, is_provider_disabled
|
||||
_primary = await get_primary_provider()
|
||||
if _primary and _primary != decision.selected_provider.value:
|
||||
# 把 primary 移到首位 (保留原始 fallback)
|
||||
provider_order = [_primary] + [p for p in provider_order if p != _primary]
|
||||
# 過濾被停用的 Provider
|
||||
_filtered = [p for p in provider_order if not await is_provider_disabled(p)]
|
||||
if _filtered:
|
||||
provider_order = _filtered
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Step 3: D7 隱私 — DIAGNOSE/CODE_REVIEW 強制 local
|
||||
require_local = decision.intent in (IntentType.DIAGNOSE, IntentType.CODE_REVIEW)
|
||||
|
||||
Reference in New Issue
Block a user