980a2db6d9
- 基础设施层 async:SQLAlchemy 异步引擎/会话、33 Repository async 化、models/security/seed 迁入 infrastructure、新增 cache.py(redis.asyncio) 与 oss.py(aioboto3) - 接口层:routers 迁 api/routers 并全 async,dependencies 迁 api/dependencies(get_db/get_current_user async) - 依赖:sqlalchemy[asyncio]/aiosqlite/asyncmy/redis/aioboto3;config 异步 URL + Redis/OSS 配置 - 删除废弃:旧同步 db/dependencies/repositories/storage - 验证:平台 19 路由 + 培训 48 路由全注册;/health /auth/login /auth/me /admin/tasks /notifications 等接口 async 可用
103 lines
3.4 KiB
Python
103 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""智能体路由:每用户隔离的身份 CRUD。
|
||
|
||
智能体"基础信息 + 身份 CRUD"托管在服务端(后续入数据库);运行时配置、workspace、
|
||
技能、对话仍由 PineAgents 主后端在本地管理。本地后端把 /agents 的身份部分转发到这里。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from fastapi import APIRouter, Depends, HTTPException
|
||
|
||
from ..dependencies import get_db, require_port
|
||
from ...infrastructure.models import AgentCreate, AgentInfo, AgentUpdate
|
||
from ...infrastructure.repositories import Database
|
||
|
||
router = APIRouter(prefix="/agents", tags=["agents"])
|
||
|
||
|
||
def _agent_info(record: dict) -> AgentInfo:
|
||
"""构建 AgentInfo,`deletable` 以记录中的 flag 为准(服务端决定)。"""
|
||
rec = dict(record)
|
||
rec.setdefault("deletable", True)
|
||
rec.setdefault("port", "opc")
|
||
return AgentInfo(**rec)
|
||
|
||
|
||
@router.get("", response_model=list[AgentInfo], summary="当前用户智能体列表")
|
||
async def list_agents(
|
||
user: dict = Depends(require_port),
|
||
db: Database = Depends(get_db),
|
||
):
|
||
return [_agent_info(r) for r in await db.agents.get_by_user(user["id"], port=user["port"])]
|
||
|
||
|
||
@router.get("/{agent_id}", response_model=AgentInfo, summary="智能体详情")
|
||
async def get_agent(
|
||
agent_id: str,
|
||
user: dict = Depends(require_port),
|
||
db: Database = Depends(get_db),
|
||
):
|
||
record = await db.agents.get(agent_id, user["id"], port=user["port"])
|
||
if record is None:
|
||
raise HTTPException(status_code=404, detail="Agent not found")
|
||
return _agent_info(record)
|
||
|
||
|
||
@router.post(
|
||
"",
|
||
response_model=AgentInfo,
|
||
status_code=201,
|
||
summary="创建智能体身份",
|
||
)
|
||
async def create_agent(
|
||
req: AgentCreate,
|
||
user: dict = Depends(require_port),
|
||
db: Database = Depends(get_db),
|
||
):
|
||
if not req.name.strip():
|
||
raise HTTPException(status_code=400, detail="Agent name is required")
|
||
record = await db.agents.create(
|
||
user["id"],
|
||
req.name,
|
||
description=req.description,
|
||
language=req.language or "zh",
|
||
model_name=req.model_name,
|
||
port=user["port"],
|
||
)
|
||
return _agent_info(record)
|
||
|
||
|
||
@router.put("/{agent_id}", response_model=AgentInfo, summary="更新智能体身份")
|
||
async def update_agent(
|
||
agent_id: str,
|
||
req: AgentUpdate,
|
||
user: dict = Depends(require_port),
|
||
db: Database = Depends(get_db),
|
||
):
|
||
payload = req.model_dump(exclude_none=True)
|
||
if not payload:
|
||
raise HTTPException(status_code=400, detail="Nothing to update")
|
||
record = await db.agents.update(agent_id, user["id"], payload, port=user["port"])
|
||
if record is None:
|
||
raise HTTPException(status_code=404, detail="Agent not found")
|
||
return _agent_info(record)
|
||
|
||
|
||
@router.delete("/{agent_id}", status_code=204, summary="删除智能体")
|
||
async def delete_agent(
|
||
agent_id: str,
|
||
user: dict = Depends(require_port),
|
||
db: Database = Depends(get_db),
|
||
):
|
||
record = await db.agents.get(agent_id, user["id"], port=user["port"])
|
||
if record is None:
|
||
raise HTTPException(status_code=404, detail="Agent not found")
|
||
if not record.get("deletable", True):
|
||
raise HTTPException(
|
||
status_code=400,
|
||
detail="Cannot delete this agent",
|
||
)
|
||
if not await db.agents.delete(agent_id, user["id"], port=user["port"]):
|
||
raise HTTPException(status_code=404, detail="Agent not found")
|
||
return None
|