""" 智能体 Schema """ from typing import Optional, List, Any, Dict from datetime import datetime from pydantic import BaseModel, Field, ConfigDict from app.base_schema import CSTDatetime # ==================== Agent Schema ==================== class PersonaConfig(BaseModel): """人设配置""" role: str = Field(default="", description="角色定位") personality: List[str] = Field(default_factory=list, description="性格特点") skills: List[str] = Field(default_factory=list, description="技能") constraints: List[str] = Field(default_factory=list, description="约束条件") background: str = Field(default="", description="背景介绍") examples: List[Dict[str, str]] = Field(default_factory=list, description="对话示例") class AgentCreate(BaseModel): """创建智能体""" model_config = ConfigDict(protected_namespaces=()) application_id: Optional[str] = Field(None, description="所属应用ID") is_global: bool = Field(default=False, description="是否在子应用中可见") name: str = Field(..., max_length=100, description="智能体名称") code: str = Field(..., max_length=100, pattern=r"^[a-zA-Z][a-zA-Z0-9_]*$", description="智能体编码(字母开头,只能包含字母、数字和下划线)") description: str = Field(default="", description="描述") avatar: str = Field(default="", description="头像") mode: str = Field(default="autonomous", description="运行模式") persona: Dict[str, Any] = Field(default_factory=dict, description="人设配置") system_prompt: str = Field(default="", description="系统提示词") model_id: Optional[str] = Field(None, description="模型 ID") temperature: float = Field(default=0.7, description="温度") top_p: float = Field(default=1.0, description="top_p") max_tokens: int = Field(default=4096, description="最大 Token") max_iterations: int = Field(default=10, description="最大推理轮数") welcome_message: str = Field(default="", description="开场白") suggested_questions: List[str] = Field(default_factory=list, description="推荐问题") workflow_id: Optional[str] = Field(None, description="工作流 ID(对话流模式)") knowledge_base_ids: List[str] = Field(default_factory=list, description="关联的知识库ID列表") knowledge_config: Dict[str, Any] = Field(default_factory=dict, description="知识库检索配置") is_public: bool = Field(default=False, description="是否公开") class AgentUpdate(BaseModel): """更新智能体""" model_config = ConfigDict(protected_namespaces=()) application_id: Optional[str] = None is_global: Optional[bool] = None name: Optional[str] = None description: Optional[str] = None avatar: Optional[str] = None mode: Optional[str] = None persona: Optional[Dict[str, Any]] = None system_prompt: Optional[str] = None model_id: Optional[str] = None temperature: Optional[float] = None top_p: Optional[float] = None max_tokens: Optional[int] = None max_iterations: Optional[int] = None welcome_message: Optional[str] = None suggested_questions: Optional[List[str]] = None workflow_id: Optional[str] = None knowledge_base_ids: Optional[List[str]] = None knowledge_config: Optional[Dict[str, Any]] = None is_public: Optional[bool] = None enable_memory: Optional[bool] = None memory_window: Optional[int] = None enable_streaming: Optional[bool] = None class AgentResponse(BaseModel): """智能体输出""" model_config = ConfigDict(from_attributes=True, protected_namespaces=()) id: str application_id: Optional[str] = None is_global: bool = False name: str code: str description: str = "" avatar: str = "" mode: str = "autonomous" status: str = "draft" persona: Dict[str, Any] = Field(default_factory=dict) system_prompt: str = "" model_id: Optional[str] = None model_name: str = "" temperature: float = 0.7 top_p: float = 1.0 max_tokens: int = 4096 max_iterations: int = 10 welcome_message: str = "" suggested_questions: List[str] = Field(default_factory=list) workflow_id: Optional[str] = None workflow_name: str = "" workflow_type: str = "general" is_public: bool = False enable_memory: bool = False memory_window: int = 10 enable_streaming: bool = True knowledge_base_ids: List[str] = Field(default_factory=list) knowledge_config: Dict[str, Any] = Field(default_factory=dict) conversation_count: int = 0 message_count: int = 0 total_tokens: int = 0 sort: int = 0 sys_create_datetime: Optional[CSTDatetime] = None sys_update_datetime: Optional[CSTDatetime] = None class AgentListResponse(BaseModel): """智能体列表输出""" model_config = ConfigDict(from_attributes=True, protected_namespaces=()) id: str application_id: Optional[str] = None application_name: str = "" is_global: bool = False name: str code: str description: str = "" avatar: str = "" mode: str = "autonomous" status: str = "draft" model_name: str = "" is_public: bool = False conversation_count: int = 0 message_count: int = 0 has_menu: bool = False sys_create_datetime: Optional[CSTDatetime] = None # ==================== 导入/导出 Schema ==================== class AgentImportCheckIn(BaseModel): """智能体导入预检查请求""" code: str = Field(..., description="智能体编码") class AgentImportCheckOut(BaseModel): """智能体导入预检查结果""" code_exists: bool = Field(..., description="智能体编码是否已存在") can_import: bool = Field(..., description="是否可以直接导入(编码不冲突)") class AgentImportIn(BaseModel): """智能体配置导入""" application_id: Optional[str] = Field(None, description="所属应用ID") is_global: bool = Field(default=False, description="是否在子应用中可见") name: str = Field(..., description="智能体名称") code: str = Field(..., description="智能体编码") description: str = Field(default="", description="描述") avatar: str = Field(default="", description="头像") mode: str = Field(default="autonomous", description="运行模式") persona: Dict[str, Any] = Field(default_factory=dict, description="人设配置") system_prompt: str = Field(default="", description="系统提示词") model_name: str = Field(default="", description="模型名称(API model_name)") temperature: float = Field(default=0.7, description="温度") top_p: float = Field(default=1.0, description="top_p") max_tokens: int = Field(default=4096, description="最大 Token") max_iterations: int = Field(default=10, description="最大推理轮数") welcome_message: str = Field(default="", description="开场白") suggested_questions: List[str] = Field(default_factory=list, description="推荐问题") workflow_code: str = Field(default="", description="关联工作流编码") knowledge_base_codes: List[str] = Field(default_factory=list, description="知识库编码列表") knowledge_config: Dict[str, Any] = Field(default_factory=dict, description="知识库检索配置") enable_memory: bool = Field(default=False, description="是否启用对话记忆") memory_window: int = Field(default=10, description="记忆窗口大小") enable_streaming: bool = Field(default=True, description="是否启用流式输出") is_public: bool = Field(default=False, description="是否公开") # ==================== Conversation Schema ==================== class AgentConversationCreate(BaseModel): """创建对话""" title: str = Field(default="", description="对话标题") class AgentConversationResponse(BaseModel): """对话输出""" id: str agent_id: str agent_name: str = "" title: str = "" summary: str = "" message_count: int = 0 total_tokens: int = 0 sys_create_datetime: Optional[CSTDatetime] = None sys_update_datetime: Optional[CSTDatetime] = None model_config = ConfigDict(from_attributes=True) class AgentConversationListResponse(BaseModel): """对话列表输出""" id: str agent_id: str agent_name: str = "" title: str = "" message_count: int = 0 sys_create_datetime: Optional[CSTDatetime] = None model_config = ConfigDict(from_attributes=True) # ==================== Message Schema ==================== class ReasoningStep(BaseModel): """推理步骤""" type: str = Field(..., description="步骤类型: thought/action/observation") content: str = Field(default="", description="内容") tool: str = Field(default="", description="工具名称(action 类型)") params: Dict[str, Any] = Field(default_factory=dict, description="工具参数(action 类型)") timestamp: str = Field(default="", description="时间戳") class ToolCallRecord(BaseModel): """工具调用记录""" tool: str = Field(..., description="工具名称") params: Dict[str, Any] = Field(default_factory=dict, description="参数") result: Any = Field(default=None, description="结果") elapsed_time: int = Field(default=0, description="耗时(毫秒)") status: str = Field(default="success", description="状态") class AttachmentResponse(BaseModel): """附件输出 附件通过 file_id 关联文件管理系统(core_file_manager) 前端通过 file_id 调用文件管理 API 获取访问 URL """ file_id: str = Field(..., description="文件管理系统中的文件 ID") type: str = Field(default="file", description="附件类型: image/file/audio/video") name: str = Field(default="", description="文件名") mime_type: str = Field(default="", description="MIME 类型") size: int = Field(default=0, description="文件大小(字节)") class AgentMessageResponse(BaseModel): """消息输出""" id: str role: str content: str = "" attachments: List[AttachmentResponse] = Field(default_factory=list) status: str = "completed" reasoning_steps: List[ReasoningStep] = Field(default_factory=list) tool_calls: List[ToolCallRecord] = Field(default_factory=list) prompt_tokens: int = 0 completion_tokens: int = 0 total_tokens: int = 0 elapsed_time: int = 0 error_message: str = "" feedback: str = "" sys_create_datetime: Optional[CSTDatetime] = None model_config = ConfigDict(from_attributes=True) class AttachmentInput(BaseModel): """附件输入 附件通过 file_id 关联文件管理系统(core_file_manager) """ file_id: str = Field(..., description="文件管理系统中的文件 ID") type: str = Field(default="file", description="附件类型: image/file/audio/video") class ChatInput(BaseModel): """对话输入""" message: str = Field(..., description="用户消息") conversation_id: Optional[str] = Field(None, description="对话 ID(续聊时提供)") application_id: Optional[str] = Field(None, description="子应用 ID(在子应用下自动注入)") form_code: Optional[str] = Field(None, description="表单编码(从表单列表调用时自动注入)") attachments: Optional[List[AttachmentInput]] = Field(None, description="附件列表") class ChatStreamEvent(BaseModel): """对话流式事件""" type: str = Field(..., description="事件类型") content: str = Field(default="", description="内容") tool: str = Field(default="", description="工具名称") params: Dict[str, Any] = Field(default_factory=dict, description="工具参数") message_id: str = Field(default="", description="消息 ID") conversation_id: str = Field(default="", description="对话 ID") tokens_used: int = Field(default=0, description="Token 使用量") elapsed_time: int = Field(default=0, description="耗时") # ==================== Feedback Schema ==================== class MessageFeedback(BaseModel): """消息反馈""" feedback: str = Field(..., description="反馈类型: like/dislike") content: str = Field(default="", description="反馈内容") # ==================== Publish Schema ==================== class AgentPublishInput(BaseModel): """发布智能体到菜单""" menu_name: str = Field(..., description="菜单名称") menu_parent_id: Optional[str] = Field(None, description="上级菜单 ID") menu_icon: str = Field(default="lucide:bot", description="菜单图标") menu_order: int = Field(default=0, description="菜单排序")