mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/ - 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层 - 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构 - 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations) - 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image - 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
194 lines
6.5 KiB
Python
194 lines
6.5 KiB
Python
"""
|
||
能力配置公共 API
|
||
|
||
提供系统支持的能力列表,供前端展示和配置使用。
|
||
"""
|
||
|
||
from dataclasses import dataclass
|
||
from typing import Any
|
||
|
||
from fastapi import APIRouter, Depends, Request
|
||
from sqlalchemy.orm import Session
|
||
|
||
from src.api.base.adapter import ApiAdapter, ApiMode
|
||
from src.api.base.context import ApiRequestContext
|
||
from src.api.base.pipeline import get_pipeline
|
||
from src.core.key_capabilities import (
|
||
get_all_capabilities,
|
||
get_user_configurable_capabilities,
|
||
)
|
||
from src.database import get_db
|
||
|
||
router = APIRouter(prefix="/api/capabilities", tags=["System Catalog"])
|
||
pipeline = get_pipeline()
|
||
|
||
|
||
def _serialize_capability(cap: Any) -> dict[str, Any]:
|
||
return {
|
||
"name": cap.name,
|
||
"display_name": cap.display_name,
|
||
"short_name": cap.short_name,
|
||
"description": cap.description,
|
||
"match_mode": cap.match_mode.value,
|
||
"config_mode": cap.config_mode.value,
|
||
}
|
||
|
||
|
||
class PublicCapabilitiesApiAdapter(ApiAdapter):
|
||
mode = ApiMode.PUBLIC
|
||
|
||
def authorize(self, context: ApiRequestContext) -> None: # type: ignore[override]
|
||
return None
|
||
|
||
|
||
class PublicCapabilitiesListAdapter(PublicCapabilitiesApiAdapter):
|
||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||
del context
|
||
return {"capabilities": [_serialize_capability(cap) for cap in get_all_capabilities()]}
|
||
|
||
|
||
class PublicUserConfigurableCapabilitiesAdapter(PublicCapabilitiesApiAdapter):
|
||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||
del context
|
||
return {
|
||
"capabilities": [
|
||
_serialize_capability(cap) for cap in get_user_configurable_capabilities()
|
||
]
|
||
}
|
||
|
||
|
||
@dataclass
|
||
class PublicModelCapabilitiesAdapter(PublicCapabilitiesApiAdapter):
|
||
model_name: str
|
||
|
||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||
from src.models.database import GlobalModel
|
||
|
||
global_model = (
|
||
context.db.query(GlobalModel)
|
||
.filter(GlobalModel.name == self.model_name, GlobalModel.is_active == True)
|
||
.first()
|
||
)
|
||
|
||
if not global_model:
|
||
return {
|
||
"model": self.model_name,
|
||
"supported_capabilities": [],
|
||
"capability_details": [],
|
||
"error": "模型不存在",
|
||
}
|
||
|
||
supported_caps = global_model.supported_capabilities or []
|
||
all_caps = {cap.name: cap for cap in get_all_capabilities()}
|
||
capability_details = [
|
||
{
|
||
"name": cap.name,
|
||
"display_name": cap.display_name,
|
||
"description": cap.description,
|
||
"match_mode": cap.match_mode.value,
|
||
"config_mode": cap.config_mode.value,
|
||
}
|
||
for cap_name in supported_caps
|
||
if (cap := all_caps.get(cap_name)) is not None
|
||
]
|
||
|
||
return {
|
||
"model": self.model_name,
|
||
"global_model_id": str(global_model.id),
|
||
"global_model_name": global_model.name,
|
||
"supported_capabilities": supported_caps,
|
||
"capability_details": capability_details,
|
||
}
|
||
|
||
|
||
@router.get("")
|
||
async def list_capabilities(request: Request, db: Session = Depends(get_db)) -> Any:
|
||
"""
|
||
获取所有能力定义
|
||
|
||
返回系统中定义的所有能力(capabilities),包括用户可配置和系统内部使用的能力。
|
||
能力用于描述模型支持的功能特性,如视觉输入、函数调用、流式输出等。
|
||
|
||
**返回字段**
|
||
- capabilities: 能力列表,每个能力包含:
|
||
- name: 能力的唯一标识符(如 vision、function_calling)
|
||
- display_name: 能力的显示名称(如"视觉输入"、"函数调用")
|
||
- short_name: 能力的简短名称(如"视觉"、"函数")
|
||
- description: 能力的详细描述
|
||
- match_mode: 匹配模式(exact 精确匹配,fuzzy 模糊匹配,prefix 前缀匹配等)
|
||
- config_mode: 配置模式(user_configurable 用户可配置,system_only 仅系统使用)
|
||
"""
|
||
adapter = PublicCapabilitiesListAdapter()
|
||
return await pipeline.run(
|
||
adapter=adapter,
|
||
http_request=request,
|
||
db=db,
|
||
mode=ApiMode.PUBLIC,
|
||
)
|
||
|
||
|
||
@router.get("/user-configurable")
|
||
async def list_user_configurable_capabilities(
|
||
request: Request,
|
||
db: Session = Depends(get_db),
|
||
) -> Any:
|
||
"""
|
||
获取用户可配置的能力列表
|
||
|
||
返回允许用户在 API Key 中配置的能力列表,用于前端展示配置选项。
|
||
用户可以通过配置这些能力来限制或指定 API Key 可以访问的模型功能。
|
||
|
||
**返回字段**
|
||
- capabilities: 用户可配置的能力列表,每个能力包含:
|
||
- name: 能力的唯一标识符
|
||
- display_name: 能力的显示名称
|
||
- short_name: 能力的简短名称
|
||
- description: 能力的详细描述
|
||
- match_mode: 匹配模式(exact、fuzzy、prefix 等)
|
||
- config_mode: 配置模式(此接口返回的都是 user_configurable)
|
||
"""
|
||
adapter = PublicUserConfigurableCapabilitiesAdapter()
|
||
return await pipeline.run(
|
||
adapter=adapter,
|
||
http_request=request,
|
||
db=db,
|
||
mode=ApiMode.PUBLIC,
|
||
)
|
||
|
||
|
||
@router.get("/model/{model_name}")
|
||
async def get_model_supported_capabilities(
|
||
model_name: str,
|
||
request: Request,
|
||
db: Session = Depends(get_db),
|
||
) -> Any:
|
||
"""
|
||
获取指定模型支持的能力列表
|
||
|
||
根据全局模型名称(GlobalModel.name)查询该模型支持的能力,
|
||
并返回每个能力的详细定义。只查询活跃的全局模型。
|
||
|
||
**路径参数**
|
||
- model_name: 全局模型名称(如 claude-sonnet-4-20250514,必须是 GlobalModel.name)
|
||
|
||
**返回字段**
|
||
- model: 查询的模型名称
|
||
- global_model_id: 全局模型的 UUID
|
||
- global_model_name: 全局模型的标准名称
|
||
- supported_capabilities: 该模型支持的能力名称列表
|
||
- capability_details: 支持的能力详细信息列表,每个能力包含:
|
||
- name: 能力标识符
|
||
- display_name: 能力显示名称
|
||
- description: 能力描述
|
||
- match_mode: 匹配模式
|
||
- config_mode: 配置模式
|
||
- error: 错误信息(仅在模型不存在时返回)
|
||
"""
|
||
adapter = PublicModelCapabilitiesAdapter(model_name=model_name)
|
||
return await pipeline.run(
|
||
adapter=adapter,
|
||
http_request=request,
|
||
db=db,
|
||
mode=ApiMode.PUBLIC,
|
||
)
|