"""设置 API(模型网关状态 + 生成偏好)。 对应前端 settingsApi。模型网关为只读总览,生成偏好可读可写; 真实密钥不进入响应。业务逻辑在 services/preferences(与系统配置 core/config/settings 区分)。 """ from fastapi import APIRouter, Depends from app.api.v1.deps import get_current_user from app.core.errors import AppError from app.schemas.auth import CurrentUser from app.schemas.preferences import ( GenerationPreferencesResponse, ModelEndpointStatus, ModelGatewayStatus, UpdateEndpointOverrideRequest, UpdateGenerationPreferencesRequest, ) from app.services.ai_provider_admin import update_endpoint_override from app.services.preferences import ( get_generation_preferences, get_provider_gateway, update_generation_preferences, ) router = APIRouter(prefix="/settings", tags=["settings"]) @router.get("/models", response_model=ModelGatewayStatus) async def read_provider_gateway() -> ModelGatewayStatus: return get_provider_gateway() @router.patch( "/models/{model}/endpoints/{endpoint}", response_model=ModelEndpointStatus, ) async def update_model_endpoint( model: str, endpoint: str, payload: UpdateEndpointOverrideRequest, ) -> ModelEndpointStatus: """更新 endpoint 覆盖(base_url / api_key / status / weight / priority,DB 优先 env)。 写后热重载 registry(reset_model_router)。响应脱敏,不回 base_url / api_key 原值。 """ await update_endpoint_override(model, endpoint, payload) gateway = get_provider_gateway() for m in gateway.models: if m.name != model: continue for ep in m.endpoints or []: if ep.name == endpoint: return ep raise AppError("not_found", "endpoint 不存在。") @router.get("/preferences", response_model=GenerationPreferencesResponse) async def read_generation_preferences( current_user: CurrentUser = Depends(get_current_user), ) -> GenerationPreferencesResponse: return await get_generation_preferences(owner_scope=current_user.owner_scope) @router.patch("/preferences", response_model=GenerationPreferencesResponse) async def update_generation_preferences_api( payload: UpdateGenerationPreferencesRequest, current_user: CurrentUser = Depends(get_current_user), ) -> GenerationPreferencesResponse: return await update_generation_preferences(payload, owner_scope=current_user.owner_scope)