Spaces:
Sleeping
Sleeping
Merge HF Space remote history
Browse files- backend/models/__init__.py +19 -0
- backend/models/agent.py +51 -0
- backend/models/chunk.py +29 -0
- backend/models/conversation.py +35 -0
- backend/models/user.py +18 -0
backend/models/__init__.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
MEXAR Models Package
|
| 3 |
+
Import all models in correct order to resolve relationships.
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
# Import in correct order to resolve relationships
|
| 7 |
+
from models.user import User
|
| 8 |
+
from models.agent import Agent, CompilationJob
|
| 9 |
+
from models.conversation import Conversation, Message
|
| 10 |
+
from models.chunk import DocumentChunk
|
| 11 |
+
|
| 12 |
+
__all__ = [
|
| 13 |
+
"User",
|
| 14 |
+
"Agent",
|
| 15 |
+
"CompilationJob",
|
| 16 |
+
"Conversation",
|
| 17 |
+
"Message",
|
| 18 |
+
"DocumentChunk"
|
| 19 |
+
]
|
backend/models/agent.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey
|
| 2 |
+
from sqlalchemy.sql import func
|
| 3 |
+
from sqlalchemy.orm import relationship
|
| 4 |
+
from sqlalchemy.dialects.postgresql import JSONB
|
| 5 |
+
from core.database import Base
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class Agent(Base):
|
| 9 |
+
"""AI Agent with all metadata stored in Supabase"""
|
| 10 |
+
__tablename__ = "agents"
|
| 11 |
+
|
| 12 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 13 |
+
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
|
| 14 |
+
name = Column(String, nullable=False)
|
| 15 |
+
domain = Column(String, nullable=True)
|
| 16 |
+
system_prompt = Column(Text, nullable=False)
|
| 17 |
+
|
| 18 |
+
# All metadata stored in Supabase (no filesystem)
|
| 19 |
+
domain_keywords = Column(JSONB, nullable=True)
|
| 20 |
+
domain_signature = Column(JSONB, nullable=True)
|
| 21 |
+
prompt_analysis = Column(JSONB, nullable=True)
|
| 22 |
+
knowledge_graph_json = Column(JSONB, nullable=True)
|
| 23 |
+
compilation_stats = Column(JSONB, nullable=True)
|
| 24 |
+
|
| 25 |
+
status = Column(String, default="initializing") # initializing, compiling, ready, failed
|
| 26 |
+
storage_path = Column(String, nullable=True) # Deprecated, kept for compatibility
|
| 27 |
+
chunk_count = Column(Integer, default=0)
|
| 28 |
+
entity_count = Column(Integer, default=0)
|
| 29 |
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
| 30 |
+
|
| 31 |
+
# Relationships
|
| 32 |
+
user = relationship("User", backref="agents")
|
| 33 |
+
compilation_jobs = relationship("CompilationJob", back_populates="agent", cascade="all, delete-orphan")
|
| 34 |
+
conversations = relationship("Conversation", back_populates="agent", cascade="all, delete-orphan")
|
| 35 |
+
chunks = relationship("DocumentChunk", back_populates="agent", cascade="all, delete-orphan")
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class CompilationJob(Base):
|
| 39 |
+
"""Background job for agent compilation"""
|
| 40 |
+
__tablename__ = "compilation_jobs"
|
| 41 |
+
|
| 42 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 43 |
+
agent_id = Column(Integer, ForeignKey("agents.id", ondelete="CASCADE"), nullable=False)
|
| 44 |
+
status = Column(String, default="queued") # queued, processing, completed, failed
|
| 45 |
+
progress = Column(Integer, default=0)
|
| 46 |
+
current_step = Column(String, nullable=True)
|
| 47 |
+
error_message = Column(Text, nullable=True)
|
| 48 |
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
| 49 |
+
completed_at = Column(DateTime(timezone=True), nullable=True)
|
| 50 |
+
|
| 51 |
+
agent = relationship("Agent", back_populates="compilation_jobs")
|
backend/models/chunk.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, Index
|
| 2 |
+
from sqlalchemy.sql import func
|
| 3 |
+
from sqlalchemy.orm import relationship, mapped_column
|
| 4 |
+
from sqlalchemy.dialects.postgresql import TSVECTOR
|
| 5 |
+
from pgvector.sqlalchemy import Vector
|
| 6 |
+
from core.database import Base
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class DocumentChunk(Base):
|
| 10 |
+
"""Document chunk with embedding for RAG retrieval"""
|
| 11 |
+
__tablename__ = "document_chunks"
|
| 12 |
+
|
| 13 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 14 |
+
agent_id = Column(Integer, ForeignKey("agents.id", ondelete="CASCADE"), nullable=False)
|
| 15 |
+
content = Column(Text, nullable=False)
|
| 16 |
+
source = Column(String, nullable=True)
|
| 17 |
+
chunk_index = Column(Integer, nullable=True)
|
| 18 |
+
section_title = Column(String, nullable=True)
|
| 19 |
+
token_count = Column(Integer, nullable=True)
|
| 20 |
+
|
| 21 |
+
# 384 dimensions for bge-small-en-v1.5 (unifying for MEXAR Ultimate)
|
| 22 |
+
embedding = mapped_column(Vector(384))
|
| 23 |
+
|
| 24 |
+
# Full-text search column
|
| 25 |
+
content_tsvector = Column(TSVECTOR)
|
| 26 |
+
|
| 27 |
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
| 28 |
+
|
| 29 |
+
agent = relationship("Agent", back_populates="chunks")
|
backend/models/conversation.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, JSON, Float
|
| 3 |
+
from sqlalchemy.sql import func
|
| 4 |
+
from sqlalchemy.orm import relationship
|
| 5 |
+
from core.database import Base
|
| 6 |
+
|
| 7 |
+
class Conversation(Base):
|
| 8 |
+
__tablename__ = "conversations"
|
| 9 |
+
|
| 10 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 11 |
+
agent_id = Column(Integer, ForeignKey("agents.id", ondelete="CASCADE"), nullable=False)
|
| 12 |
+
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
|
| 13 |
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
| 14 |
+
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
| 15 |
+
|
| 16 |
+
# Relationships
|
| 17 |
+
agent = relationship("Agent", back_populates="conversations")
|
| 18 |
+
messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
|
| 19 |
+
|
| 20 |
+
class Message(Base):
|
| 21 |
+
__tablename__ = "messages"
|
| 22 |
+
|
| 23 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 24 |
+
conversation_id = Column(Integer, ForeignKey("conversations.id", ondelete="CASCADE"), nullable=False)
|
| 25 |
+
role = Column(String, nullable=False) # user, assistant
|
| 26 |
+
content = Column(Text, nullable=False)
|
| 27 |
+
|
| 28 |
+
# Advanced features
|
| 29 |
+
multimodal_data = Column(JSON, nullable=True) # Images, audio paths
|
| 30 |
+
explainability_data = Column(JSON, nullable=True) # Reasoning traces
|
| 31 |
+
confidence = Column(Float, nullable=True)
|
| 32 |
+
|
| 33 |
+
timestamp = Column(DateTime(timezone=True), server_default=func.now())
|
| 34 |
+
|
| 35 |
+
conversation = relationship("Conversation", back_populates="messages")
|
backend/models/user.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from sqlalchemy import Column, Integer, String, DateTime, JSON, Boolean
|
| 3 |
+
from sqlalchemy.sql import func
|
| 4 |
+
from sqlalchemy.orm import relationship
|
| 5 |
+
from core.database import Base
|
| 6 |
+
|
| 7 |
+
class User(Base):
|
| 8 |
+
__tablename__ = "users"
|
| 9 |
+
|
| 10 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 11 |
+
email = Column(String, unique=True, index=True, nullable=False)
|
| 12 |
+
password = Column(String, nullable=False)
|
| 13 |
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
| 14 |
+
last_login = Column(DateTime(timezone=True), nullable=True)
|
| 15 |
+
preferences = Column(JSON, default={})
|
| 16 |
+
|
| 17 |
+
# Relationships
|
| 18 |
+
conversations = relationship("Conversation", backref="user", cascade="all, delete-orphan")
|