- 实现Agent管理,支持AI辅助生成系统提示词 - 支持多个AI提供商(OpenRouter、智谱、MiniMax等) - 实现聊天室和讨论引擎 - WebSocket实时消息推送 - 前端使用React + Ant Design - 后端使用FastAPI + MongoDB Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
315 lines
9.2 KiB
Python
315 lines
9.2 KiB
Python
"""
|
|
Agent管理路由
|
|
"""
|
|
from typing import List, Optional, Dict, Any
|
|
from fastapi import APIRouter, HTTPException, status
|
|
from pydantic import BaseModel, Field
|
|
from loguru import logger
|
|
|
|
from services.agent_service import AgentService, AGENT_TEMPLATES
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# ============ 请求/响应模型 ============
|
|
|
|
class CapabilitiesModel(BaseModel):
|
|
"""能力配置模型"""
|
|
memory_enabled: bool = False
|
|
mcp_tools: List[str] = []
|
|
skills: List[str] = []
|
|
multimodal: bool = False
|
|
|
|
|
|
class BehaviorModel(BaseModel):
|
|
"""行为配置模型"""
|
|
speak_threshold: float = 0.5
|
|
max_speak_per_round: int = 2
|
|
speak_style: str = "balanced"
|
|
|
|
|
|
class AgentCreateRequest(BaseModel):
|
|
"""创建Agent请求"""
|
|
name: str = Field(..., description="Agent名称")
|
|
role: str = Field(..., description="角色定义")
|
|
system_prompt: str = Field(..., description="系统提示词")
|
|
provider_id: str = Field(..., description="使用的AI接口ID")
|
|
temperature: float = Field(default=0.7, ge=0, le=2, description="温度参数")
|
|
max_tokens: int = Field(default=2000, gt=0, description="最大token数")
|
|
capabilities: Optional[CapabilitiesModel] = None
|
|
behavior: Optional[BehaviorModel] = None
|
|
avatar: Optional[str] = None
|
|
color: str = "#1890ff"
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"name": "产品经理",
|
|
"role": "产品规划和需求分析专家",
|
|
"system_prompt": "你是一位经验丰富的产品经理...",
|
|
"provider_id": "openrouter-abc123",
|
|
"temperature": 0.7,
|
|
"max_tokens": 2000
|
|
}
|
|
}
|
|
|
|
|
|
class AgentUpdateRequest(BaseModel):
|
|
"""更新Agent请求"""
|
|
name: Optional[str] = None
|
|
role: Optional[str] = None
|
|
system_prompt: Optional[str] = None
|
|
provider_id: Optional[str] = None
|
|
temperature: Optional[float] = Field(default=None, ge=0, le=2)
|
|
max_tokens: Optional[int] = Field(default=None, gt=0)
|
|
capabilities: Optional[CapabilitiesModel] = None
|
|
behavior: Optional[BehaviorModel] = None
|
|
avatar: Optional[str] = None
|
|
color: Optional[str] = None
|
|
enabled: Optional[bool] = None
|
|
|
|
|
|
class AgentResponse(BaseModel):
|
|
"""Agent响应"""
|
|
agent_id: str
|
|
name: str
|
|
role: str
|
|
system_prompt: str
|
|
provider_id: str
|
|
temperature: float
|
|
max_tokens: int
|
|
capabilities: Dict[str, Any]
|
|
behavior: Dict[str, Any]
|
|
avatar: Optional[str]
|
|
color: str
|
|
enabled: bool
|
|
created_at: str
|
|
updated_at: str
|
|
|
|
|
|
class AgentTestRequest(BaseModel):
|
|
"""Agent测试请求"""
|
|
message: str = "你好,请简单介绍一下你自己。"
|
|
|
|
|
|
class AgentTestResponse(BaseModel):
|
|
"""Agent测试响应"""
|
|
success: bool
|
|
message: str
|
|
response: Optional[str] = None
|
|
model: Optional[str] = None
|
|
tokens: Optional[int] = None
|
|
latency_ms: Optional[float] = None
|
|
|
|
|
|
class TemplateResponse(BaseModel):
|
|
"""模板响应"""
|
|
template_id: str
|
|
name: str
|
|
role: str
|
|
system_prompt: str
|
|
color: str
|
|
|
|
|
|
class GeneratePromptRequest(BaseModel):
|
|
"""生成提示词请求"""
|
|
provider_id: str = Field(..., description="使用的AI接口ID")
|
|
name: str = Field(..., description="Agent名称")
|
|
role: str = Field(..., description="角色定位")
|
|
description: Optional[str] = Field(None, description="额外描述(可选)")
|
|
|
|
|
|
class GeneratePromptResponse(BaseModel):
|
|
"""生成提示词响应"""
|
|
success: bool
|
|
message: Optional[str] = None
|
|
prompt: Optional[str] = None
|
|
model: Optional[str] = None
|
|
tokens: Optional[int] = None
|
|
|
|
|
|
# ============ 路由处理 ============
|
|
|
|
@router.post("", response_model=AgentResponse, status_code=status.HTTP_201_CREATED)
|
|
async def create_agent(request: AgentCreateRequest):
|
|
"""
|
|
创建新的Agent
|
|
"""
|
|
try:
|
|
agent = await AgentService.create_agent(
|
|
name=request.name,
|
|
role=request.role,
|
|
system_prompt=request.system_prompt,
|
|
provider_id=request.provider_id,
|
|
temperature=request.temperature,
|
|
max_tokens=request.max_tokens,
|
|
capabilities=request.capabilities.dict() if request.capabilities else None,
|
|
behavior=request.behavior.dict() if request.behavior else None,
|
|
avatar=request.avatar,
|
|
color=request.color
|
|
)
|
|
|
|
return _to_response(agent)
|
|
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
except Exception as e:
|
|
logger.error(f"创建Agent失败: {e}")
|
|
raise HTTPException(status_code=500, detail="创建失败")
|
|
|
|
|
|
@router.get("", response_model=List[AgentResponse])
|
|
async def list_agents(enabled_only: bool = False):
|
|
"""
|
|
获取所有Agent
|
|
"""
|
|
agents = await AgentService.get_all_agents(enabled_only)
|
|
return [_to_response(a) for a in agents]
|
|
|
|
|
|
@router.get("/templates", response_model=List[TemplateResponse])
|
|
async def list_templates():
|
|
"""
|
|
获取Agent预设模板
|
|
"""
|
|
return [
|
|
TemplateResponse(
|
|
template_id=tid,
|
|
name=t["name"],
|
|
role=t["role"],
|
|
system_prompt=t["system_prompt"],
|
|
color=t["color"]
|
|
)
|
|
for tid, t in AGENT_TEMPLATES.items()
|
|
]
|
|
|
|
|
|
@router.post("/generate-prompt", response_model=GeneratePromptResponse)
|
|
async def generate_prompt(request: GeneratePromptRequest):
|
|
"""
|
|
使用AI生成Agent系统提示词
|
|
"""
|
|
result = await AgentService.generate_system_prompt(
|
|
provider_id=request.provider_id,
|
|
name=request.name,
|
|
role=request.role,
|
|
description=request.description
|
|
)
|
|
return GeneratePromptResponse(**result)
|
|
|
|
|
|
@router.get("/{agent_id}", response_model=AgentResponse)
|
|
async def get_agent(agent_id: str):
|
|
"""
|
|
获取指定Agent
|
|
"""
|
|
agent = await AgentService.get_agent(agent_id)
|
|
if not agent:
|
|
raise HTTPException(status_code=404, detail="Agent不存在")
|
|
return _to_response(agent)
|
|
|
|
|
|
@router.put("/{agent_id}", response_model=AgentResponse)
|
|
async def update_agent(agent_id: str, request: AgentUpdateRequest):
|
|
"""
|
|
更新Agent配置
|
|
"""
|
|
update_data = request.dict(exclude_unset=True)
|
|
|
|
# 转换嵌套模型
|
|
if "capabilities" in update_data and update_data["capabilities"]:
|
|
if hasattr(update_data["capabilities"], "dict"):
|
|
update_data["capabilities"] = update_data["capabilities"].dict()
|
|
if "behavior" in update_data and update_data["behavior"]:
|
|
if hasattr(update_data["behavior"], "dict"):
|
|
update_data["behavior"] = update_data["behavior"].dict()
|
|
|
|
try:
|
|
agent = await AgentService.update_agent(agent_id, **update_data)
|
|
if not agent:
|
|
raise HTTPException(status_code=404, detail="Agent不存在")
|
|
return _to_response(agent)
|
|
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
@router.delete("/{agent_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_agent(agent_id: str):
|
|
"""
|
|
删除Agent
|
|
"""
|
|
success = await AgentService.delete_agent(agent_id)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Agent不存在")
|
|
|
|
|
|
@router.post("/{agent_id}/test", response_model=AgentTestResponse)
|
|
async def test_agent(agent_id: str, request: AgentTestRequest = None):
|
|
"""
|
|
测试Agent对话
|
|
"""
|
|
message = request.message if request else "你好,请简单介绍一下你自己。"
|
|
result = await AgentService.test_agent(agent_id, message)
|
|
return AgentTestResponse(**result)
|
|
|
|
|
|
@router.post("/{agent_id}/duplicate", response_model=AgentResponse)
|
|
async def duplicate_agent(agent_id: str, new_name: Optional[str] = None):
|
|
"""
|
|
复制Agent
|
|
"""
|
|
agent = await AgentService.duplicate_agent(agent_id, new_name)
|
|
if not agent:
|
|
raise HTTPException(status_code=404, detail="源Agent不存在")
|
|
return _to_response(agent)
|
|
|
|
|
|
@router.post("/from-template/{template_id}", response_model=AgentResponse)
|
|
async def create_from_template(template_id: str, provider_id: str):
|
|
"""
|
|
从模板创建Agent
|
|
"""
|
|
if template_id not in AGENT_TEMPLATES:
|
|
raise HTTPException(status_code=404, detail="模板不存在")
|
|
|
|
template = AGENT_TEMPLATES[template_id]
|
|
|
|
try:
|
|
agent = await AgentService.create_agent(
|
|
name=template["name"],
|
|
role=template["role"],
|
|
system_prompt=template["system_prompt"],
|
|
provider_id=provider_id,
|
|
color=template["color"]
|
|
)
|
|
return _to_response(agent)
|
|
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
# ============ 辅助函数 ============
|
|
|
|
def _to_response(agent) -> AgentResponse:
|
|
"""
|
|
转换为响应模型
|
|
"""
|
|
return AgentResponse(
|
|
agent_id=agent.agent_id,
|
|
name=agent.name,
|
|
role=agent.role,
|
|
system_prompt=agent.system_prompt,
|
|
provider_id=agent.provider_id,
|
|
temperature=agent.temperature,
|
|
max_tokens=agent.max_tokens,
|
|
capabilities=agent.capabilities,
|
|
behavior=agent.behavior,
|
|
avatar=agent.avatar,
|
|
color=agent.color,
|
|
enabled=agent.enabled,
|
|
created_at=agent.created_at.isoformat(),
|
|
updated_at=agent.updated_at.isoformat()
|
|
)
|