"""App、Flow和Service等外置配置数据结构"""
import uuid
from typing import Any
from pydantic import BaseModel, Field
from apps.models import AppType, PermissionType
from .appcenter import AppLink
from .enum_var import EdgeType, MetadataType
from .flow_topology import FlowBasicConfig, FlowCheckStatus, FlowItem, PositionItem
from .response_data import ResponseData
class Edge(BaseModel):
"""Flow中Edge的数据"""
id: uuid.UUID = Field(description="边的ID")
edge_from: str = Field(description="边的来源节点ID")
edge_to: str = Field(description="边的目标节点ID")
edge_type: EdgeType | None = Field(description="边的类型", default=EdgeType.NORMAL)
class Step(BaseModel):
"""Flow中Step的数据"""
node: str = Field(description="Step的Node ID")
type: str = Field(description="Step的类型")
name: str = Field(description="Step的名称")
description: str = Field(description="Step的描述")
pos: PositionItem = Field(description="Step在画布上的位置", default=PositionItem(x=0, y=0))
params: dict[str, Any] = Field(description="用户手动指定的Node参数", default={})
class FlowError(BaseModel):
"""Flow的错误处理节点"""
use_llm: bool = Field(description="是否使用LLM处理错误")
output_format: str | None = Field(description="错误处理节点的输出格式", default=None)
class Flow(BaseModel):
"""Flow(工作流)的数据格式"""
name: str = Field(description="Flow的名称", min_length=1)
description: str = Field(description="Flow的描述")
checkStatus: FlowCheckStatus = Field(description="Flow的配置检查状态")
basicConfig: FlowBasicConfig = Field(description="Flow的基本配置")
onError: FlowError = FlowError(use_llm=True)
steps: dict[uuid.UUID, Step] = Field(description="节点列表", default={})
edges: list[Edge] = Field(description="边列表", default=[])
class Permission(BaseModel):
"""权限配置"""
type: PermissionType = Field(description="权限类型", default=PermissionType.PRIVATE)
users: list[str] = Field(description="可访问的用户列表", default=[])
class MetadataBase(BaseModel):
"""
Service或App的元数据
注意:hash字段在save和load的时候exclude
"""
type: MetadataType = Field(description="元数据类型")
id: uuid.UUID = Field(description="元数据ID")
name: str = Field(description="元数据名称")
description: str = Field(description="元数据描述")
author: str = Field(description="创建者的用户名")
hashes: dict[str, str] | None = Field(description="资源(App、Service等)下所有文件的hash值", default=None)
class ServiceApiAuthKeyVal(BaseModel):
"""Service的API鉴权方式的键值对"""
name: str = Field(description="鉴权参数名称")
value: str = Field(description="鉴权参数值")
class ServiceApiAuth(BaseModel):
"""Service的API鉴权方式"""
header: list[ServiceApiAuthKeyVal] = Field(description="HTTP头鉴权配置", default=[])
cookie: list[ServiceApiAuthKeyVal] = Field(description="HTTP Cookie鉴权配置", default=[])
query: list[ServiceApiAuthKeyVal] = Field(description="HTTP URL参数鉴权配置", default=[])
class ServiceApiConfig(BaseModel):
"""Service的API配置"""
server: str = Field(description="服务器地址", pattern=r"^(https|http)://.*$")
auth: ServiceApiAuth | None = Field(description="API鉴权方式", default=None)
class ServiceMetadata(MetadataBase):
"""Service的元数据"""
id: uuid.UUID = Field(description="Service的ID")
type: MetadataType = MetadataType.SERVICE
api: ServiceApiConfig = Field(description="API配置")
permission: Permission | None = Field(description="服务权限配置", default=None)
class AppFlow(BaseModel):
"""Flow的元数据;会被存储在App下面"""
id: uuid.UUID
name: str
description: str
enabled: bool = Field(description="是否启用", default=True)
path: str = Field(description="Flow的路径")
debug: bool = Field(description="调试是否成功", default=False)
class AppMetadataBase(MetadataBase):
"""App的基础元数据(智能体和Flow应用的公共部分)"""
type: MetadataType = MetadataType.APP
app_type: AppType = Field(description="应用类型", frozen=True)
published: bool = Field(description="是否发布", default=False)
links: list[AppLink] = Field(description="相关链接", default=[])
first_questions: list[str] = Field(description="首次提问", default=[])
history_len: int = Field(description="对话轮次", default=3, le=10)
permission: Permission | None = Field(description="应用权限配置", default=None)
class AgentAppMetadata(AppMetadataBase):
"""智能体App的元数据"""
app_type: AppType = Field(default=AppType.AGENT, description="应用类型", frozen=True)
mcp_service: list[str] = Field(default=[], description="MCP服务id列表")
class FlowAppMetadata(AppMetadataBase):
"""Flow App的元数据"""
app_type: AppType = Field(default=AppType.FLOW, description="应用类型", frozen=True)
flows: list[AppFlow] = Field(description="Flow列表", default=[])
class FlowStructureGetMsg(BaseModel):
"""GET /api/flow result"""
flow: FlowItem = Field(default=FlowItem())
class FlowStructureGetRsp(ResponseData):
"""GET /api/flow 返回数据结构"""
result: FlowStructureGetMsg
class FlowStructurePutMsg(BaseModel):
"""PUT /api/flow result"""
flow: FlowItem = Field(default=FlowItem())
class FlowStructurePutRsp(ResponseData):
"""PUT /api/flow 返回数据结构"""
result: FlowStructurePutMsg
class FlowStructureDeleteMsg(BaseModel):
"""DELETE /api/flow/ result"""
flow_id: str = Field(alias="flowId", default="")
class FlowStructureDeleteRsp(ResponseData):
"""DELETE /api/flow/ 返回数据结构"""
result: FlowStructureDeleteMsg
flows: list[AppFlow] = Field(description="Flow列表", default=[])