Ashutosh1975270's picture
feat: redesign multi-hop reasoning, add sticky layout, query logs history tracking, and hybrid fallback search
0527a95
Raw
History Blame Contribute Delete
3.67 kB
import uuid
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
class User(AbstractUser):
"""
Custom User Model to allow for seamless future attribute additions
without database schema breakage. Uses UUID as the primary key.
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
def __str__(self):
return self.username
class Document(models.Model):
"""
Tracks uploaded documents, ingestion status, metadata, and error details.
"""
class Status(models.TextChoices):
PENDING = 'PENDING', 'Pending'
PROCESSING = 'PROCESSING', 'Processing'
COMPLETED = 'COMPLETED', 'Completed'
FAILED = 'FAILED', 'Failed'
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='documents'
)
name = models.CharField(max_length=255)
file = models.FileField(upload_to='uploaded_documents/')
status = models.CharField(
max_length=20,
choices=Status.choices,
default=Status.PENDING
)
entity_count = models.IntegerField(default=0)
relationship_count = models.IntegerField(default=0)
error_message = models.TextField(blank=True, null=True)
source = models.CharField(max_length=255, blank=True, default='', help_text="Optional source label (e.g. research-paper, internal-wiki)")
processing_progress = models.IntegerField(default=0, help_text="Progress percentage (0-100)")
processing_step = models.CharField(max_length=200, blank=True, default='', help_text="Current processing step description")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"{self.name} ({self.status})"
class QueryLog(models.Model):
"""
Logs queries, selected retrieval strategies, generated answers, and response times.
"""
class RetrievalMode(models.TextChoices):
GRAPH = 'GRAPH', 'Graph Only'
VECTOR = 'VECTOR', 'Vector Only'
HYBRID = 'HYBRID', 'Hybrid'
MULTIHOP = 'MULTIHOP', 'Multi-Hop'
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='query_logs'
)
query_text = models.TextField()
retrieval_mode = models.CharField(
max_length=20,
choices=RetrievalMode.choices,
default=RetrievalMode.HYBRID
)
answer_text = models.TextField()
response_time = models.FloatField(help_text="Response time in seconds")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Query: {self.query_text[:30]}... ({self.retrieval_mode})"
class EvaluationPair(models.Model):
"""
Stores target question-answer evaluation pairs to compute metrics against.
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='evaluation_pairs'
)
question = models.TextField()
expected_answer = models.TextField()
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Question: {self.question[:40]}..."