Files
hunzi/app/models.py
T

136 lines
5.5 KiB
Python

"""数据模型"""
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import Column, String, Text, Float, Integer, DateTime, ForeignKey, JSON, Boolean
from sqlalchemy.orm import relationship
from .database import Base
class Agent(Base):
"""Agent 定义"""
__tablename__ = "agents"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
name = Column(String(255), nullable=False)
description = Column(Text, nullable=True)
system_prompt = Column(Text, nullable=True)
llm_provider = Column(String(100), nullable=True)
temperature = Column(Float, default=0.7)
max_tokens = Column(Integer, default=2048)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
tools = relationship("AgentTool", back_populates="agent", cascade="all, delete-orphan")
conversations = relationship("Conversation", back_populates="agent", cascade="all, delete-orphan")
def __repr__(self) -> str:
return f"<Agent(id={self.id}, name={self.name!r})>"
class AgentTool(Base):
"""Agent 绑定的工具"""
__tablename__ = "agent_tools"
id = Column(Integer, primary_key=True, autoincrement=True)
agent_id = Column(String(36), ForeignKey("agents.id", ondelete="CASCADE"), nullable=False)
tool_name = Column(String(255), nullable=False)
enabled = Column(Boolean, default=True)
agent = relationship("Agent", back_populates="tools")
def __repr__(self) -> str:
return f"<AgentTool(id={self.id}, agent_id={self.agent_id}, tool_name={self.tool_name!r})>"
class Conversation(Base):
"""对话会话"""
__tablename__ = "conversations"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
agent_id = Column(String(36), ForeignKey("agents.id", ondelete="CASCADE"), nullable=False)
title = Column(String(255), nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
agent = relationship("Agent", back_populates="conversations")
messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
def __repr__(self) -> str:
return f"<Conversation(id={self.id}, agent_id={self.agent_id}, title={self.title!r})>"
class Message(Base):
"""消息记录"""
__tablename__ = "messages"
id = Column(Integer, primary_key=True, autoincrement=True)
conversation_id = Column(String(36), ForeignKey("conversations.id", ondelete="CASCADE"), nullable=False)
role = Column(String(20), nullable=False) # user / assistant / system / tool
content = Column(Text, nullable=True)
tool_calls = Column(JSON, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
conversation = relationship("Conversation", back_populates="messages")
def __repr__(self) -> str:
return f"<Message(id={self.id}, conversation_id={self.conversation_id}, role={self.role!r})>"
class Workflow(Base):
"""工作流定义"""
__tablename__ = "workflows"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
name = Column(String(255), nullable=False)
description = Column(Text, nullable=True)
definition = Column(JSON, nullable=True)
status = Column(String(50), default="draft") # draft / active / archived
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
runs = relationship("WorkflowRun", back_populates="workflow", cascade="all, delete-orphan")
def __repr__(self) -> str:
return f"<Workflow(id={self.id}, name={self.name!r}, status={self.status!r})>"
class WorkflowRun(Base):
"""工作流执行实例"""
__tablename__ = "workflow_runs"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
workflow_id = Column(String(36), ForeignKey("workflows.id", ondelete="CASCADE"), nullable=False)
status = Column(String(50), default="pending") # pending / running / completed / failed
results = Column(JSON, nullable=True)
error = Column(Text, nullable=True)
started_at = Column(DateTime, default=datetime.utcnow)
completed_at = Column(DateTime, nullable=True)
workflow = relationship("Workflow", back_populates="runs")
steps = relationship("WorkflowStep", back_populates="run", cascade="all, delete-orphan")
def __repr__(self) -> str:
return f"<WorkflowRun(id={self.id}, workflow_id={self.workflow_id}, status={self.status!r})>"
class WorkflowStep(Base):
"""工作流步骤"""
__tablename__ = "workflow_steps"
id = Column(Integer, primary_key=True, autoincrement=True)
run_id = Column(String(36), ForeignKey("workflow_runs.id", ondelete="CASCADE"), nullable=False)
step_name = Column(String(255), nullable=False)
agent_id = Column(String(36), ForeignKey("agents.id"), nullable=True)
status = Column(String(50), default="pending") # pending / running / completed / failed
input_data = Column(JSON, nullable=True)
output_data = Column(JSON, nullable=True)
started_at = Column(DateTime, default=datetime.utcnow)
completed_at = Column(DateTime, nullable=True)
run = relationship("WorkflowRun", back_populates="steps")
agent = relationship("Agent")
def __repr__(self) -> str:
return f"<WorkflowStep(id={self.id}, run_id={self.run_id}, step_name={self.step_name!r})>"