Files
aiagent/backend/app/api/orchestration_templates.py
renjianbo 5b5eb84dfb fix: #33 内置多模态工具现在在工具市场 /api/v1/tools 中可见
list_tools 端点合并内置工具(image_ocr/image_vision/speech_to_text/text_to_speech 等),
按 scope=public/all 时自动包含,无需额外种子到 DB。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-06 22:13:41 +08:00

163 lines
5.4 KiB
Python

"""
编排模板 CRUD API
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.api.auth import get_current_user
from app.models.user import User
from app.models.orchestration_template import OrchestrationTemplate
router = APIRouter(prefix="/api/v1/orchestration-templates", tags=["orchestration-templates"])
class TemplateCreate(BaseModel):
name: str
description: str = ""
nodes: List[dict] = Field(..., description="编排节点列表")
edges: List[dict] = Field(..., description="编排连线列表")
class TemplateUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
nodes: Optional[List[dict]] = None
edges: Optional[List[dict]] = None
class TemplateResponse(BaseModel):
id: str
name: str
description: str
nodes: List[dict]
edges: List[dict]
user_id: Optional[str] = None
created_at: Optional[str] = None
updated_at: Optional[str] = None
@router.get("", response_model=List[TemplateResponse])
async def list_templates(
search: Optional[str] = Query(None, description="按名称搜索"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""获取当前用户的编排模板列表"""
q = db.query(OrchestrationTemplate).filter(OrchestrationTemplate.user_id == current_user.id)
if search:
q = q.filter(OrchestrationTemplate.name.contains(search))
q = q.order_by(OrchestrationTemplate.updated_at.desc())
templates = q.all()
return [
TemplateResponse(
id=t.id, name=t.name, description=t.description or "",
nodes=t.nodes or [], edges=t.edges or [],
user_id=t.user_id,
created_at=t.created_at.isoformat() if t.created_at else None,
updated_at=t.updated_at.isoformat() if t.updated_at else None,
)
for t in templates
]
@router.post("", response_model=TemplateResponse)
async def create_template(
body: TemplateCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""创建编排模板"""
template = OrchestrationTemplate(
name=body.name,
description=body.description,
nodes=body.nodes,
edges=body.edges,
user_id=current_user.id,
)
db.add(template)
db.commit()
db.refresh(template)
return TemplateResponse(
id=template.id, name=template.name, description=template.description or "",
nodes=template.nodes or [], edges=template.edges or [],
user_id=template.user_id,
created_at=template.created_at.isoformat() if template.created_at else None,
updated_at=template.updated_at.isoformat() if template.updated_at else None,
)
@router.get("/{template_id}", response_model=TemplateResponse)
async def get_template(
template_id: str,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""获取模板详情"""
template = db.query(OrchestrationTemplate).filter(
OrchestrationTemplate.id == template_id,
OrchestrationTemplate.user_id == current_user.id,
).first()
if not template:
raise HTTPException(status_code=404, detail="模板不存在")
return TemplateResponse(
id=template.id, name=template.name, description=template.description or "",
nodes=template.nodes or [], edges=template.edges or [],
user_id=template.user_id,
created_at=template.created_at.isoformat() if template.created_at else None,
updated_at=template.updated_at.isoformat() if template.updated_at else None,
)
@router.put("/{template_id}", response_model=TemplateResponse)
async def update_template(
template_id: str,
body: TemplateUpdate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""更新模板"""
template = db.query(OrchestrationTemplate).filter(
OrchestrationTemplate.id == template_id,
OrchestrationTemplate.user_id == current_user.id,
).first()
if not template:
raise HTTPException(status_code=404, detail="模板不存在")
if body.name is not None:
template.name = body.name
if body.description is not None:
template.description = body.description
if body.nodes is not None:
template.nodes = body.nodes
if body.edges is not None:
template.edges = body.edges
db.commit()
db.refresh(template)
return TemplateResponse(
id=template.id, name=template.name, description=template.description or "",
nodes=template.nodes or [], edges=template.edges or [],
user_id=template.user_id,
created_at=template.created_at.isoformat() if template.created_at else None,
updated_at=template.updated_at.isoformat() if template.updated_at else None,
)
@router.delete("/{template_id}")
async def delete_template(
template_id: str,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""删除模板"""
template = db.query(OrchestrationTemplate).filter(
OrchestrationTemplate.id == template_id,
OrchestrationTemplate.user_id == current_user.id,
).first()
if not template:
raise HTTPException(status_code=404, detail="模板不存在")
db.delete(template)
db.commit()
return {"detail": "ok"}