fix(phase24): 首席架構師 Review C1/C2/C3/I4 修復
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 7m12s
E2E Health Check / e2e-health (push) Successful in 18s

C1 (P0): AIRouterExecutor.execute() 補 Langfuse Trace (D5)
  - 建立 langfuse_trace("ai_router_execute") 包住整個執行鏈
  - 成功時記錄 generation (model/input/output/tokens/cost)
  - prod 所有 AI 呼叫現在有 LLMOps 追蹤

C2 (P0): 絞殺者改為呼叫 AIRouter.route() 智慧路由
  - 先取得 RoutingDecision (意圖分類 + 複雜度評分)
  - provider_order 從 selected_provider + fallback_chain 動態生成
  - D1 意圖路由矩陣、D7 隱私保護 (DIAGNOSE 強制 local) 生效

C3 (P1): 型別標注 typo 修復
  - AIProviderEnumEnum → AIProviderEnum
  - AIProviderEnumProtocol → AIProviderProtocol

I4 (P1): interfaces.py AIProvider Protocol 補 close() 定義

S1: ai_router.py 模組版本標頭更新至 v4.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-02 21:47:06 +08:00
parent 9d00b0389e
commit 5a8aae89c4
3 changed files with 72 additions and 10 deletions

View File

@@ -917,19 +917,38 @@ class OpenClawService:
# =================================================================
if settings.USE_AI_ROUTER:
try:
from src.services.ai_router import get_ai_executor
# 2026-04-02 ogt: C2 修復 — 呼叫 AIRouter.route() 智慧路由 (非靜態 order)
# D1 意圖分類路由、D7 隱私保護 (DIAGNOSE/CODE_REVIEW 強制 local) 生效
from src.services.ai_router import get_ai_router, get_ai_executor, IntentType
router = get_ai_router()
executor = get_ai_executor()
# Step 1: 取得路由決策 (含意圖分類 + 複雜度評分)
decision = await router.route(prompt, alert_context)
# Step 2: 從 RoutingDecision 建立 provider_order (主 + fallback)
provider_order = [decision.selected_provider.value] + [
p.value for p, _ in decision.fallback_chain
if p.value != decision.selected_provider.value
]
# Step 3: D7 隱私 — DIAGNOSE/CODE_REVIEW 強制 local
require_local = decision.intent in (IntentType.DIAGNOSE, IntentType.CODE_REVIEW)
result = await executor.execute(
prompt=prompt,
provider_order=settings.AI_FALLBACK_ORDER,
provider_order=provider_order,
context=alert_context,
cache_ttl=3600,
require_local=require_local,
)
logger.info(
"phase24_ai_router_used",
provider=result.provider,
success=result.success,
latency_ms=round(result.latency_ms, 1),
intent=decision.intent.value,
routing_reason=decision.routing_reason,
)
return result.raw_response, result.provider, result.success, result.tokens, result.cost_usd
except Exception as e: