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