diff --git a/apps/api/src/services/ai_router.py b/apps/api/src/services/ai_router.py index 0e4dea2d..9d1dcbda 100644 --- a/apps/api/src/services/ai_router.py +++ b/apps/api/src/services/ai_router.py @@ -36,9 +36,13 @@ from __future__ import annotations import time from dataclasses import dataclass, field from enum import Enum +from typing import TYPE_CHECKING, Protocol import structlog +if TYPE_CHECKING: + from src.services.intent_classifier import IntentResult + from src.services.complexity_scorer import ( ComplexityScore, get_complexity_scorer, @@ -80,6 +84,43 @@ PROVIDER_LATENCY_BUDGET: dict[AIProvider, int] = { } +# ============================================================================= +# Interface 定義 (P1 修復 - 2026-04-01 首席架構師審查) +# ============================================================================= + + +class IAIRouter(Protocol): + """ + AI Router Protocol - 支援 DI 測試替換 + + 2026-04-01 ogt: 首席架構師審查 P1 修復 + - 新增 Protocol 定義支援依賴注入 + - 參考: IModelRegistry, IComplexityScorer + """ + + async def route( + self, + text: str, + context: dict | None = None, + ) -> "RoutingDecision": + """路由請求到最適 AI Provider""" + ... + + def route_sync( + self, + text: str, + context: dict | None = None, + ) -> "RoutingDecision": + """同步版本路由""" + ... + + def route_tool_calling( + self, + ) -> tuple[AIProvider, str, list[tuple[AIProvider, str]]]: + """Tool Calling 專用路由""" + ... + + @dataclass class RoutingDecision: """