feat(provider): 添加厂商预设与模型发现接口

This commit is contained in:
2026-08-30 10:43:55 +08:00
parent 11cb384115
commit f7d864bc4d
5 changed files with 112 additions and 3 deletions
+12
View File
@@ -438,6 +438,18 @@ class ProviderListResponse(Contract):
items: list[ProviderConfig] = Field(default_factory=list)
class ProviderPreset(Contract):
preset_id: str
name: str
provider_type: ProviderType
base_url: str
requires_credential: bool = True
class ProviderPresetListResponse(Contract):
items: list[ProviderPreset] = Field(default_factory=list)
class ModelInfo(Contract):
model: str
display_name: str
+25 -1
View File
@@ -1,4 +1,4 @@
from app.contracts import ModelCapability, ProviderConfig, ProviderType
from app.contracts import ModelCapability, ProviderConfig, ProviderPreset, ProviderType
from app.providers.base import ModelProvider
from app.providers.credentials import CredentialResolver
from app.providers.ollama import OllamaProvider
@@ -27,6 +27,30 @@ class ProviderFactory:
return OllamaProvider(config.base_url or "http://127.0.0.1:11434")
raise UnsupportedProviderError(config.provider_type.value)
@staticmethod
def presets() -> list[ProviderPreset]:
return [
ProviderPreset(
preset_id="openai",
name="OpenAI",
provider_type=ProviderType.openai_chat,
base_url="https://api.openai.com/v1",
),
ProviderPreset(
preset_id="deepseek",
name="DeepSeek",
provider_type=ProviderType.openai_compatible,
base_url="https://api.deepseek.com",
),
ProviderPreset(
preset_id="ollama",
name="Ollama",
provider_type=ProviderType.ollama,
base_url="http://127.0.0.1:11434",
requires_credential=False,
),
]
@staticmethod
def capabilities(provider_type: ProviderType) -> list[ModelCapability]:
if provider_type in {
+27 -1
View File
@@ -31,6 +31,7 @@ from app.contracts import (
ProviderCreateRequest,
ProviderListResponse,
ProviderModelsResponse,
ProviderPresetListResponse,
ProviderTestRequest,
ProviderTestResponse,
ProviderUpdateRequest,
@@ -52,6 +53,7 @@ from app.errors import ApiError
from app.extensions import ExtensionError
from app.providers.registry import ProviderNotFoundError
from app.providers.factory import UnsupportedProviderError
from app.providers.base import ProviderError
from app.retrieval.engine import engine
from app.services import index_service, note_service, task_service, transcription_service
@@ -416,6 +418,15 @@ async def list_providers() -> ProviderListResponse:
return ProviderListResponse(items=container.providers.list_configs())
@router.get(
"/providers/presets",
response_model=ProviderPresetListResponse,
tags=["Providers"],
)
async def list_provider_presets() -> ProviderPresetListResponse:
return ProviderPresetListResponse(items=container.provider_factory.presets())
@router.get(
"/providers/{provider_id}",
response_model=ProviderConfig,
@@ -502,9 +513,24 @@ async def delete_provider(provider_id: str) -> OperationResponse:
)
async def list_provider_models(provider_id: str) -> ProviderModelsResponse:
provider_or_404(provider_id)
try:
models = await container.providers.list_models(provider_id)
except ProviderError as exc:
status_code = {
"PROVIDER_AUTH_FAILED": 401,
"MODEL_NOT_FOUND": 404,
"PROVIDER_RATE_LIMITED": 429,
"PROVIDER_TIMEOUT": 504,
}.get(exc.code, 502)
raise ApiError(
status_code,
exc.code,
exc.message,
{"provider_id": provider_id},
) from exc
return ProviderModelsResponse(
provider_id=provider_id,
items=await container.providers.list_models(provider_id),
items=models,
)