Download models.py from embedingHF/AI_Chatbot: direct link, hf CLI and curl.
- Browser
- Download file 6.54 kB
-
https://huggingface.co/embedingHF/AI_Chatbot/resolve/main/models.py
- Command line
-
hf download hf://embedingHF/AI_Chatbot/models.py
-
curl -L -o models.py https://huggingface.co/embedingHF/AI_Chatbot/resolve/main/models.py
6.54 kB
| import uuid | |
| import builtins | |
| from django.db import models | |
| from pgvector.django import VectorField | |
| from django.conf import settings | |
| class GlobalQA(models.Model): | |
| """Global Q&A for greetings - works across ALL properties and agencies""" | |
| id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
| question = models.TextField(unique=True) | |
| answer = models.TextField() | |
| question_embedding = VectorField(dimensions=384) | |
| language = models.CharField(max_length=20, choices=[ | |
| ('en', 'English'), | |
| ('ur', 'Roman Urdu'), | |
| ('both', 'Both') | |
| ], default='both') | |
| is_active = models.BooleanField(default=True) | |
| priority = models.IntegerField(default=0) | |
| created_at = models.DateTimeField(auto_now_add=True) | |
| class Meta: | |
| ordering = ['-priority', 'question'] | |
| indexes = [ | |
| models.Index(fields=['is_active', '-priority']), | |
| models.Index(fields=['language', 'is_active']), | |
| ] | |
| def __str__(self): | |
| return f"{self.question[:50]}" | |
| class MasterQuestion(models.Model): | |
| """Pre-defined questions created by admin that agencies must answer""" | |
| id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
| question = models.TextField(unique=True) | |
| is_active = models.BooleanField(default=True) | |
| order = models.IntegerField(default=0) | |
| created_at = models.DateTimeField(auto_now_add=True) | |
| class Meta: | |
| ordering = ['order'] | |
| indexes = [ | |
| models.Index(fields=['is_active', 'order']), | |
| ] | |
| def __str__(self): | |
| return self.question[:100] | |
| class PropertyQA(models.Model): | |
| """Agency's answers to master questions for a specific property""" | |
| id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
| agency = models.ForeignKey( | |
| settings.AUTH_USER_MODEL, | |
| on_delete=models.CASCADE, | |
| related_name='property_qa_answers' | |
| ) | |
| property = models.ForeignKey( | |
| 'Property.Property', | |
| on_delete=models.CASCADE, | |
| related_name='ai_qa' | |
| ) | |
| master_question = models.ForeignKey( | |
| MasterQuestion, | |
| on_delete=models.CASCADE, | |
| null=True, | |
| blank=True | |
| ) | |
| answer = models.TextField() | |
| # Embedding for similarity search | |
| question_embedding = VectorField(dimensions=384) | |
| is_active = models.BooleanField(default=True) | |
| created_at = models.DateTimeField(auto_now_add=True) | |
| updated_at = models.DateTimeField(auto_now=True) # FIX #5: Track updates | |
| class Meta: | |
| unique_together = ['property', 'master_question'] | |
| # FIX #2: Database indexes for performance | |
| indexes = [ | |
| models.Index(fields=['property', 'is_active']), | |
| models.Index(fields=['agency', 'is_active']), | |
| models.Index(fields=['master_question', 'is_active']), | |
| # Vector index will be added via migration | |
| ] | |
| def question_text(self): | |
| return self.master_question.question if self.master_question else None | |
| def __str__(self): | |
| return f"{self.property.title}: {self.question_text[:50] if self.question_text else 'No question'}" | |
| class AgencyAutoChatSetting(models.Model): | |
| """Auto-chat settings per agency""" | |
| agency = models.OneToOneField( | |
| settings.AUTH_USER_MODEL, | |
| on_delete=models.CASCADE, | |
| related_name='auto_chat_setting' | |
| ) | |
| is_enabled = models.BooleanField(default=False) | |
| delay_seconds = models.IntegerField(default=30, help_text="Seconds to wait before AI replies") | |
| confidence_threshold = models.FloatField(default=0.6, help_text="Minimum similarity score (0-1)") | |
| created_at = models.DateTimeField(auto_now_add=True) | |
| updated_at = models.DateTimeField(auto_now=True) | |
| class Meta: | |
| indexes = [ | |
| models.Index(fields=['is_enabled']), | |
| ] | |
| def __str__(self): | |
| return f"{self.agency.email}: {'ON' if self.is_enabled else 'OFF'}" | |
| class PropertyAutoChatState(models.Model): | |
| """Track auto-chat state per property""" | |
| property = models.OneToOneField( | |
| 'Property.Property', | |
| on_delete=models.CASCADE, | |
| related_name='auto_chat_state' | |
| ) | |
| is_auto_chat_enabled = models.BooleanField(default=False) | |
| last_auto_reply_at = models.DateTimeField(null=True, blank=True) | |
| total_auto_replies = models.IntegerField(default=0) | |
| last_agency_reply_at = models.DateTimeField(null=True, blank=True) | |
| class Meta: | |
| indexes = [ | |
| models.Index(fields=['is_auto_chat_enabled']), | |
| models.Index(fields=['property', 'is_auto_chat_enabled']), | |
| ] | |
| def __str__(self): | |
| return f"{self.property.title}: Auto Chat {'ON' if self.is_auto_chat_enabled else 'OFF'}" | |
| class PropertyCustomQA(models.Model): | |
| """ | |
| Custom Q&A for a specific property (max 5 per property) | |
| Agency writes these when enabling auto-chat | |
| """ | |
| id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
| # Relationships | |
| agency = models.ForeignKey( | |
| settings.AUTH_USER_MODEL, | |
| on_delete=models.CASCADE, | |
| related_name='property_custom_qa' | |
| ) | |
| property = models.ForeignKey( | |
| 'Property.Property', | |
| on_delete=models.CASCADE, | |
| related_name='custom_qa' | |
| ) | |
| # The actual Q&A | |
| question = models.TextField() | |
| answer = models.TextField() | |
| # For AI similarity search | |
| question_embedding = VectorField(dimensions=384) | |
| # Metadata | |
| order = models.IntegerField(default=0) # 1-5 for display order | |
| is_active = models.BooleanField(default=True) | |
| created_at = models.DateTimeField(auto_now_add=True) | |
| updated_at = models.DateTimeField(auto_now=True) | |
| class Meta: | |
| ordering = ['order'] | |
| # Ensure max 5 per property | |
| constraints = [ | |
| models.UniqueConstraint( | |
| fields=['property', 'order'], | |
| name='unique_order_per_property' | |
| ) | |
| ] | |
| indexes = [ | |
| models.Index(fields=['property', 'is_active']), | |
| models.Index(fields=['agency', 'is_active']), | |
| ] | |
| def __str__(self): | |
| return f"{self.property.title}: Q{self.order} - {self.question[:50]}" |