File size: 2,503 Bytes
b6db694 10b8d56 c0fe20c 10b8d56 c0fe20c 10b8d56 e5e756a 8ffb677 10b8d56 8ffb677 10b8d56 b6db694 10b8d56 b6db694 c0fe20c b6db694 10b8d56 b6db694 c0fe20c e5e756a 10b8d56 b6db694 10b8d56 b6db694 10b8d56 b6db694 c0fe20c 10b8d56 b6db694 10b8d56 b6db694 c0fe20c 10b8d56 b6db694 10b8d56 b6db694 c0fe20c 10b8d56 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | """
插件 API 端点。
"""
from fastapi import APIRouter, HTTPException
from app.plugins.manager import get_plugin_manager
from app.plugins.models import PluginStatus
from app.plugins.model_probe import probe_all_providers, probe_cpu_only_environment
router = APIRouter()
@router.get("/")
async def get_plugins():
"""获取所有插件列表。"""
manager = get_plugin_manager()
return manager.get_plugin_list()
@router.get("/stats")
async def get_plugins_stats():
"""获取插件统计信息。"""
manager = get_plugin_manager()
return manager.get_system_plugin_summary()
@router.get("/providers/status")
async def get_providers_status():
"""获取所有模型 Provider 的 CPU-only 可用性状态。
不强制加载完整模型,仅检查依赖和缓存。
用于前端展示模型可用性和部署环境信息。
"""
result = probe_all_providers()
return result.model_dump(mode="json")
@router.get("/providers/environment")
async def get_provider_environment():
"""获取 CPU-only 环境探测信息。
检查 HuggingFace 缓存目录、Hub 可用性、GPU 状态等。
"""
return probe_cpu_only_environment()
@router.get("/{plugin_name}")
async def get_plugin(plugin_name: str):
"""获取指定插件详情。"""
manager = get_plugin_manager()
detail = manager.get_plugin_detail(plugin_name)
if detail is None:
raise HTTPException(status_code=404, detail=f"插件 {plugin_name} 不存在")
return detail
@router.post("/{plugin_name}/enable")
async def enable_plugin(plugin_name: str):
"""启用插件。"""
manager = get_plugin_manager()
result = manager.enable_plugin(plugin_name)
if not result.success:
raise HTTPException(
status_code=_operation_error_status(manager, plugin_name),
detail=result.error or result.message,
)
return result
@router.post("/{plugin_name}/disable")
async def disable_plugin(plugin_name: str):
"""禁用插件。"""
manager = get_plugin_manager()
result = manager.disable_plugin(plugin_name)
if not result.success:
raise HTTPException(status_code=400, detail=result.error or result.message)
return result
def _operation_error_status(manager, plugin_name: str) -> int:
"""依赖错误按契约返回 409,其它非法状态迁移保持 400。"""
if manager.get_plugin_status(plugin_name) == PluginStatus.DEPENDENCY_ERROR:
return 409
return 400
|