Files
jxxghp 6d4ce83837 fix(types): clear host mypy debt and prevent typing regressions
严格检查全部宿主源码,清零类型错误预算并移除按模块类型豁免。
按原因、所属方法、错误码及语法指纹锁定必要兼容例外和站点类型桩,
CI 阻断新增忽略、检查范围退化、本地桩替代真实接口及新的类型错误。

修复空值、异步和供应方类型边界,保持插件与 API 兼容合同,
并补充存储、订阅、通知、Agent 和工作流边界的回归覆盖。
2026-10-21 22:03:18 +08:00

86 lines
2.9 KiB
Python

"""
提供语言模型配置、能力和服务连通性查询接口。
"""
from typing import Any, Dict, List, Optional, Union
from fastapi import Depends, Request, Response
from fastapi.responses import HTMLResponse
from app.agent.llm.auth import render_auth_result_html
from app.agent.llm.gateway import resolve_llm_provider_runtime
from app.api.dependencies.auth import get_current_active_superuser_async
from app.api.response import ResponseAPIRouter
from app.schemas.common import ManageRequest as _SchemaManageRequest
from app.schemas.response import Response as _SchemaResponse
router = ResponseAPIRouter()
@router.post(
"/manage",
summary="LLM提供商统一管理",
# 各动作 data 形态不一:目录查询返回列表,其余动作返回映射,
# 须用具体联合类型声明,而非单一开放映射
response_model=_SchemaResponse[Union[List[Dict[str, Any]], Dict[str, Any]]],
)
async def manage_provider(
request: Request,
payload: _SchemaManageRequest,
_: object = Depends(get_current_active_superuser_async),
) -> _SchemaResponse[object]:
"""
LLM 提供商统一管理入口:前端上送 target/action/params 原样透传,
端点不定义任何提供商特定的名称、参数或响应字段;
OAuth 回跳地址由具名回调路由统一构造后注入动作参数
"""
params = dict(payload.params)
# 目录类查询动作的 target 可为空,此时无需回跳地址;
# 且 url_for 的路径参数不允许空值,必须先行防护
if payload.target:
params.setdefault(
"callback_url",
str(request.url_for("llm_provider_auth_callback", provider_id=payload.target)),
)
result = await resolve_llm_provider_runtime().provider_manage(
payload.target, payload.action, **params
)
return _SchemaResponse(
success=bool(result.get("success")),
message=result.get("message") or "",
data=result.get("data"),
)
@router.get(
"/provider-auth/callback/{provider_id}",
summary="LLM提供商OAuth回调",
response_class=Response,
name="llm_provider_auth_callback",
response_model=None,
responses={
200: {
"description": "OAuth 授权结果页面",
"content": {"text/html": {"schema": {"type": "string"}}},
}
},
)
async def llm_provider_auth_callback(
provider_id: str,
code: Optional[str] = None,
state: Optional[str] = None,
error: Optional[str] = None,
error_description: Optional[str] = None,
) -> HTMLResponse:
"""
处理需要浏览器回跳的 OAuth provider。
"""
success, message = await resolve_llm_provider_runtime().handle_chatgpt_callback(
provider_id,
code,
state,
error,
error_description,
)
return HTMLResponse(content=render_auth_result_html(success, message))