# -*- 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