feat(compute): 算力引擎对接改造 + 用户生命周期自动同步
- config: 置顶 load_dotenv(.env),修复 .env 未生效;COMPUTE_ADMIN_TOKEN 改读 PINEAGENTS_INTERNAL_TOKEN(回退旧名),新增独立 COMPUTE_RELAY_TOKEN - compute_client: 空令牌不下发 Bearer(避免 httpx 非法头);proxy 空令牌返 503 中文诊断;新增 sync_user_enabled/sync_delete_user - relay: /v1 转发改走 COMPUTE_RELAY_TOKEN(真实消费令牌),空令牌不下发 - rbac_admin: 平台用户创建→自动建引擎账号+签PAT;启用/禁用→同步引擎状态;删除→同步删引擎账号(最佳努力,失败静默)
This commit is contained in:
@@ -29,7 +29,11 @@ def _base() -> str:
|
||||
|
||||
|
||||
def _admin_headers() -> dict[str, str]:
|
||||
return {"Authorization": f"Bearer {config.COMPUTE_ADMIN_TOKEN}"}
|
||||
"""引擎管理员请求头。令牌未配置时不下发 Authorization,避免 `Bearer ` 空令牌被 httpx 判定非法。"""
|
||||
token = config.COMPUTE_ADMIN_TOKEN
|
||||
if not token:
|
||||
return {}
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
|
||||
async def _request(*, method: str, path: str, headers: dict[str, str] | None = None,
|
||||
@@ -106,6 +110,21 @@ async def get_logs(user_pat: str) -> dict:
|
||||
return await _request(method="GET", path="/api/log/self", headers=headers)
|
||||
|
||||
|
||||
async def sync_user_enabled(username: str, enabled: bool) -> dict:
|
||||
"""按 username 同步引擎用户启用/禁用(平台用户生命周期自动同步)。"""
|
||||
return await _request(
|
||||
method="PATCH", path="/api/user/status", headers=_admin_headers(),
|
||||
json={"username": username, "status": 1 if enabled else 0},
|
||||
)
|
||||
|
||||
|
||||
async def sync_delete_user(username: str) -> dict:
|
||||
"""按 username 删除引擎用户(平台用户删除时同步)。"""
|
||||
return await _request(
|
||||
method="DELETE", path=f"/api/user/by_username/{username}", headers=_admin_headers(),
|
||||
)
|
||||
|
||||
|
||||
async def proxy(method: str, path: str, *, json_body: dict | None = None, params: dict | None = None) -> dict:
|
||||
"""管理 API 透传:转发到引擎 ``/api<path>``,返回 ``{status, body}``。
|
||||
|
||||
@@ -113,6 +132,8 @@ async def proxy(method: str, path: str, *, json_body: dict | None = None, params
|
||||
(models/channels/groups/tokens/users/logs/redemption/ratio 等),不改写每个端点契约。
|
||||
保留引擎原始状态码与响应体(网关层不吞错误)。
|
||||
"""
|
||||
if not config.COMPUTE_ADMIN_TOKEN:
|
||||
return {"status": 503, "body": '{"success": false, "message": "算力引擎内部令牌未配置(PINEAGENTS_INTERNAL_TOKEN)"}'}
|
||||
url = f"{_base()}/api{path}"
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=config.COMPUTE_TIMEOUT) as client:
|
||||
|
||||
Reference in New Issue
Block a user