forked from xiaohei/taiji-AI-PAD
370 lines
8.1 KiB
Python
370 lines
8.1 KiB
Python
"""
|
|
Pydantic schemas for API requests and responses
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional, Union
|
|
from pydantic import BaseModel, Field, validator
|
|
import uuid
|
|
|
|
|
|
class BaseSchema(BaseModel):
|
|
"""基础schema类"""
|
|
class Config:
|
|
from_attributes = True
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat(),
|
|
uuid.UUID: lambda v: str(v),
|
|
}
|
|
|
|
@staticmethod
|
|
def _convert_uuid(value):
|
|
"""转换asyncpg的UUID为标准UUID"""
|
|
if value is None:
|
|
return None
|
|
try:
|
|
from asyncpg.pgproto.pgproto import UUID as AsyncUUID
|
|
if isinstance(value, AsyncUUID):
|
|
return uuid.UUID(str(value))
|
|
except (ImportError, AttributeError):
|
|
pass
|
|
if isinstance(value, uuid.UUID):
|
|
return value
|
|
try:
|
|
return uuid.UUID(str(value))
|
|
except (ValueError, TypeError):
|
|
return value
|
|
|
|
|
|
# ========== MCP协议相关 ==========
|
|
|
|
class MCPRequest(BaseModel):
|
|
"""MCP请求模型"""
|
|
jsonrpc: str = "2.0"
|
|
id: Union[str, int] = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
method: str
|
|
params: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
class MCPResponse(BaseModel):
|
|
"""MCP响应模型"""
|
|
jsonrpc: str = "2.0"
|
|
id: Union[str, int]
|
|
result: Optional[Any] = None
|
|
error: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
class MCPError(BaseModel):
|
|
"""MCP错误模型"""
|
|
code: int
|
|
message: str
|
|
data: Optional[Any] = None
|
|
|
|
|
|
# ========== 工具相关 ==========
|
|
|
|
class ToolParameter(BaseModel):
|
|
"""工具参数定义"""
|
|
name: str
|
|
type: str
|
|
description: Optional[str] = None
|
|
required: bool = True
|
|
default: Optional[Any] = None
|
|
enum: Optional[List[Any]] = None
|
|
|
|
|
|
class ToolDefinition(BaseSchema):
|
|
"""工具定义"""
|
|
name: str
|
|
description: str
|
|
category: Optional[str] = None
|
|
parameters: List[ToolParameter] = []
|
|
returns: Optional[Dict[str, Any]] = None
|
|
|
|
# API相关
|
|
endpoint: Optional[str] = None
|
|
method: str = "POST"
|
|
headers: Optional[Dict[str, str]] = None
|
|
|
|
# 限制信息
|
|
rate_limit: int = 100
|
|
timeout: int = 30
|
|
cost_per_call: float = 0.0
|
|
|
|
|
|
class ToolExecution(BaseModel):
|
|
"""工具执行请求"""
|
|
tool_name: str
|
|
parameters: Dict[str, Any]
|
|
timeout: Optional[int] = None
|
|
|
|
|
|
class ToolResult(BaseSchema):
|
|
"""工具执行结果"""
|
|
success: bool
|
|
result: Optional[Any] = None
|
|
error: Optional[str] = None
|
|
execution_time: float = 0.0
|
|
cost: float = 0.0
|
|
|
|
|
|
# ========== Agent相关 ==========
|
|
|
|
class AgentCreateRequest(BaseModel):
|
|
"""创建Agent请求"""
|
|
name: str
|
|
description: Optional[str] = None
|
|
role: str = "general-purpose agent"
|
|
goal: str = "Handle generic MCP tasks and routing"
|
|
|
|
tools: List[str] = [] # 工具名称列表
|
|
config: Dict[str, Any] = {}
|
|
capabilities: List[str] = []
|
|
|
|
owner_id: Optional[Union[uuid.UUID, str]] = None
|
|
|
|
|
|
|
|
class AgentUpdateRequest(BaseModel):
|
|
"""更新Agent请求"""
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
role: Optional[str] = None
|
|
goal: Optional[str] = None
|
|
tools: Optional[List[str]] = None
|
|
config: Optional[Dict[str, Any]] = None
|
|
capabilities: Optional[List[str]] = None
|
|
|
|
|
|
class AgentCard(BaseSchema):
|
|
"""Agent卡片信息"""
|
|
id: uuid.UUID
|
|
name: str
|
|
description: Optional[str]
|
|
role: str
|
|
goal: str
|
|
|
|
tools: List[str] = []
|
|
capabilities: List[str] = []
|
|
|
|
# 端点信息
|
|
endpoints: Dict[str, str] = {}
|
|
|
|
# 状态信息
|
|
status: str = "active"
|
|
version: str = "1.0.0"
|
|
|
|
# 统计信息
|
|
total_executions: int = 0
|
|
success_rate: float = 0.0
|
|
avg_execution_time: float = 0.0
|
|
|
|
# 时间信息
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
@validator('id', pre=True)
|
|
def validate_id(cls, v):
|
|
"""转换id为标准UUID"""
|
|
if v is None:
|
|
return None
|
|
# 先转换为字符串,避免asyncpg UUID对象的问题
|
|
v_str = str(v)
|
|
# 然后转换为标准UUID
|
|
return uuid.UUID(v_str)
|
|
|
|
|
|
class AgentExecution(BaseModel):
|
|
"""Agent执行请求"""
|
|
method: str
|
|
params: Optional[Dict[str, Any]] = None
|
|
timeout: Optional[int] = None
|
|
session_id: Optional[str] = None
|
|
|
|
|
|
class ExecutionResult(BaseSchema):
|
|
"""执行结果"""
|
|
execution_id: str
|
|
success: bool
|
|
result: Optional[Any] = None
|
|
error: Optional[str] = None
|
|
|
|
# 性能指标
|
|
execution_time: float = 0.0
|
|
cpu_usage: float = 0.0
|
|
memory_usage: float = 0.0
|
|
network_io: float = 0.0
|
|
|
|
# 成本信息
|
|
eu_consumed: float = 0.0
|
|
cost: float = 0.0
|
|
|
|
# 时间戳
|
|
started_at: datetime
|
|
completed_at: Optional[datetime] = None
|
|
|
|
|
|
# ========== 用户相关 ==========
|
|
|
|
class UserCreate(BaseModel):
|
|
"""创建用户请求"""
|
|
username: str = Field(..., min_length=3, max_length=50)
|
|
email: str = Field(..., pattern=r'^[^@]+@[^@]+\.[^@]+$')
|
|
password: str = Field(..., min_length=8)
|
|
full_name: Optional[str] = None
|
|
|
|
|
|
class UserUpdate(BaseModel):
|
|
"""更新用户请求"""
|
|
email: Optional[str] = None
|
|
full_name: Optional[str] = None
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
class UserResponse(BaseSchema):
|
|
"""用户响应"""
|
|
id: uuid.UUID
|
|
username: str
|
|
email: str
|
|
full_name: Optional[str]
|
|
is_active: bool
|
|
is_admin: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class UserLogin(BaseModel):
|
|
"""用户登录请求"""
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class Token(BaseModel):
|
|
"""访问令牌"""
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
expires_in: int
|
|
|
|
|
|
# ========== 会话相关 ==========
|
|
|
|
class SessionCreate(BaseModel):
|
|
"""创建会话请求"""
|
|
context: Optional[Dict[str, Any]] = None
|
|
metadata: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
class SessionResponse(BaseSchema):
|
|
"""会话响应"""
|
|
id: uuid.UUID
|
|
session_id: str
|
|
status: str
|
|
context: Dict[str, Any]
|
|
metadata: Dict[str, Any]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
# ========== 计费相关 ==========
|
|
|
|
class BillingRecord(BaseSchema):
|
|
"""计费记录"""
|
|
id: uuid.UUID
|
|
execution_id: uuid.UUID
|
|
eu_consumed: float
|
|
cost: float
|
|
currency: str
|
|
|
|
# 资源详情
|
|
cpu_time: float
|
|
memory_max: float
|
|
network_io: float
|
|
storage_io: float
|
|
|
|
created_at: datetime
|
|
|
|
|
|
class BillingSummary(BaseModel):
|
|
"""计费汇总"""
|
|
user_id: uuid.UUID
|
|
period_start: datetime
|
|
period_end: datetime
|
|
|
|
total_executions: int
|
|
total_eu_consumed: float
|
|
total_cost: float
|
|
currency: str
|
|
|
|
# 按服务分类
|
|
breakdown_by_agent: Dict[str, float] = {}
|
|
breakdown_by_tool: Dict[str, float] = {}
|
|
|
|
|
|
# ========== API响应包装 ==========
|
|
|
|
class APIResponse(BaseModel):
|
|
"""API响应包装"""
|
|
success: bool
|
|
message: str = ""
|
|
data: Optional[Any] = None
|
|
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
|
|
class PaginatedResponse(BaseModel):
|
|
"""分页响应"""
|
|
items: List[Any]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
has_next: bool
|
|
has_prev: bool
|
|
|
|
|
|
# ========== 系统状态 ==========
|
|
|
|
class HealthCheck(BaseModel):
|
|
"""健康检查响应"""
|
|
status: str
|
|
timestamp: datetime
|
|
services: Dict[str, str]
|
|
version: str = "1.0.0"
|
|
|
|
|
|
class SystemMetrics(BaseModel):
|
|
"""系统指标"""
|
|
timestamp: datetime
|
|
|
|
# 服务指标
|
|
active_agents: int
|
|
total_executions: int
|
|
success_rate: float
|
|
avg_response_time: float
|
|
|
|
# 资源指标
|
|
cpu_usage: float
|
|
memory_usage: float
|
|
disk_usage: float
|
|
|
|
# 业务指标
|
|
daily_active_users: int
|
|
total_eu_consumed: float
|
|
total_cost: float
|
|
|
|
|
|
# ========== 错误响应 ==========
|
|
|
|
class ErrorResponse(BaseModel):
|
|
"""错误响应"""
|
|
error: str
|
|
message: str
|
|
details: Optional[Dict[str, Any]] = None
|
|
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
|
|
class ValidationError(BaseModel):
|
|
"""验证错误"""
|
|
field: str
|
|
message: str
|
|
invalid_value: Optional[Any] = None
|
|
|