44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
from dataclasses import dataclass
|
|
from collections.abc import Mapping
|
|
from typing import Any
|
|
|
|
from app.config import Settings
|
|
|
|
|
|
def _configured(value: str) -> bool:
|
|
return bool(value) and not value.startswith("replace_with_")
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ProviderCapability:
|
|
provider: str
|
|
configured: bool
|
|
strengths: tuple[str, ...]
|
|
|
|
|
|
class ModelRouter:
|
|
def __init__(self, settings: Settings | Mapping[str, Any]) -> None:
|
|
self.settings = settings
|
|
|
|
def _value(self, key: str, default: str = "") -> str:
|
|
if isinstance(self.settings, Mapping):
|
|
return str(self.settings.get(key, default) or "")
|
|
return str(getattr(self.settings, key, default) or "")
|
|
|
|
def capabilities(self) -> list[ProviderCapability]:
|
|
return [
|
|
ProviderCapability(
|
|
provider=self._value("ai_provider", "custom"),
|
|
configured=_configured(self._value("ai_api_key"))
|
|
and bool(self._value("ai_base_url"))
|
|
and bool(self._value("image_model")),
|
|
strengths=("统一模型网关", "空间理解", "图像生成与编辑"),
|
|
),
|
|
]
|
|
|
|
def choose_image_provider(self, task: str) -> str:
|
|
configured = [item.provider for item in self.capabilities() if item.configured]
|
|
if configured:
|
|
return configured[0]
|
|
raise RuntimeError("No image provider is configured.")
|