Spaces:
Runtime error
Runtime error
| # Experimental | |
| from sqlalchemy import Column, String, Enum, ForeignKey, DateTime | |
| from sqlalchemy.dialects.postgresql import UUID, ENUM, JSONB | |
| from sqlalchemy.orm import relationship | |
| from sqlalchemy.sql import func | |
| from enum import Enum | |
| from sqlalchemy.ext.declarative import as_declarative, declared_attr | |
| from llama_index.core.callbacks.schema import CBEventType | |
| # Model | |
| class Base: | |
| id = Column(UUID, primary_key=True, index=True, default=func.uuid_generate_v4()) | |
| created_at = Column(DateTime, server_default=func.now(), nullable=False) | |
| updated_at = Column( | |
| DateTime, server_default=func.now(), onupdate=func.now(), nullable=False | |
| ) | |
| __name__: str | |
| # Generate __tablename__ automatically | |
| def __tablename__(cls) -> str: | |
| return cls.__name__.lower() | |
| # DB | |
| class MessageRoleEnum(str, Enum): | |
| user = "user" | |
| assistant = "assistant" | |
| class MessageStatusEnum(str, Enum): | |
| PENDING = "PENDING" | |
| SUCCESS = "SUCCESS" | |
| ERROR = "ERROR" | |
| class MessageSubProcessStatusEnum(str, Enum): | |
| PENDING = "PENDING" | |
| FINISHED = "FINISHED" | |
| # python doesn't allow enums to be extended, so we have to do this | |
| additional_message_subprocess_fields = { | |
| "CONSTRUCTED_QUERY_ENGINE": "constructed_query_engine", | |
| "SUB_QUESTIONS": "sub_questions", | |
| } | |
| MessageSubProcessSourceEnum = Enum( | |
| "MessageSubProcessSourceEnum", | |
| [(event_type.name, event_type.value) for event_type in CBEventType] | |
| + list(additional_message_subprocess_fields.items()), | |
| ) | |
| def to_pg_enum(enum_class) -> ENUM: | |
| return ENUM(enum_class, name=enum_class.__name__) | |
| class Document(Base): | |
| """ | |
| A document along with its metadata | |
| """ | |
| # URL to the actual document (e.g. a PDF) | |
| url = Column(String, nullable=False, unique=True) | |
| metadata_map = Column(JSONB, nullable=True) | |
| conversations = relationship("ConversationDocument", back_populates="document") | |
| class Conversation(Base): | |
| """ | |
| A conversation with messages and linked documents | |
| """ | |
| messages = relationship("Message", back_populates="conversation") | |
| conversation_documents = relationship( | |
| "ConversationDocument", back_populates="conversation" | |
| ) | |
| class ConversationDocument(Base): | |
| """ | |
| A many-to-many relationship between a conversation and a document | |
| """ | |
| conversation_id = Column( | |
| UUID(as_uuid=True), ForeignKey("conversation.id"), index=True | |
| ) | |
| document_id = Column(UUID(as_uuid=True), ForeignKey("document.id"), index=True) | |
| conversation = relationship("Conversation", back_populates="conversation_documents") | |
| document = relationship("Document", back_populates="conversations") | |
| class Message(Base): | |
| """ | |
| A message in a conversation | |
| """ | |
| conversation_id = Column( | |
| UUID(as_uuid=True), ForeignKey("conversation.id"), index=True | |
| ) | |
| content = Column(String) | |
| role = Column(to_pg_enum(MessageRoleEnum)) | |
| status = Column(to_pg_enum(MessageStatusEnum), default=MessageStatusEnum.PENDING) | |
| conversation = relationship("Conversation", back_populates="messages") | |
| sub_processes = relationship("MessageSubProcess", back_populates="message") | |
| class MessageSubProcess(Base): | |
| """ | |
| A record of a sub-process that occurred as part of the generation of a message from an AI assistant | |
| """ | |
| message_id = Column(UUID(as_uuid=True), ForeignKey("message.id"), index=True) | |
| source = Column(to_pg_enum(MessageSubProcessSourceEnum)) | |
| message = relationship("Message", back_populates="sub_processes") | |
| status = Column( | |
| to_pg_enum(MessageSubProcessStatusEnum), | |
| default=MessageSubProcessStatusEnum.FINISHED, | |
| nullable=False, | |
| ) | |
| metadata_map = Column(JSONB, nullable=True) |