Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions backend/.env.example

This file was deleted.

28 changes: 26 additions & 2 deletions backend/backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
ALLOWED_HOSTS = ["*"]

# Application definition

Expand All @@ -47,17 +47,20 @@
"authentication",
"chat",
"gpt",
#Added crontab to run the cleanup_conversation
"django_crontab",
]

MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"corsheaders.middleware.CorsMiddleware",

]

ROOT_URLCONF = "backend.urls"
Expand Down Expand Up @@ -91,6 +94,19 @@
}
}

# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.postgresql',
# 'NAME': 'my_user',
# 'USER': 'admin',
# 'PASSWORD': '1234',
# 'HOST': 'localhost',
# 'PORT': '5432',
# }
# }



# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

Expand Down Expand Up @@ -139,13 +155,21 @@

CORS_ALLOWED_ORIGINS = [
FRONTEND_URL,
"http://localhost:3000",
]
CORS_ALLOW_CREDENTIALS = True

CSRF_TRUSTED_ORIGINS = [
FRONTEND_URL,
"http://localhost:3000",
]

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = "None"

#Responsibe for deleting the conversations automatically that are older than 30-days
CRONJOBS = [
('0 0 1 * *', 'django.core.management.call_command', ['cleanup_conversations']),
]

12 changes: 8 additions & 4 deletions backend/chat/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.contrib import admin
from django.utils import timezone
from nested_admin.nested import NestedModelAdmin, NestedStackedInline, NestedTabularInline

#Imported conversation from model
from .models import Conversation
from chat.models import Conversation, Message, Role, Version


Expand Down Expand Up @@ -47,11 +48,14 @@ def queryset(self, request, queryset):
return queryset.filter(deleted_at__isnull=True)
return queryset


#Added this
@admin.register(Conversation)
class ConversationAdmin(NestedModelAdmin):
actions = ["undelete_selected", "soft_delete_selected"]
inlines = [VersionInline]
list_display = ("title", "id", "created_at", "modified_at", "deleted_at", "version_count", "is_deleted", "user")
#Added Summary to display
list_display = ("title", "id","summary","created_at", "modified_at", "deleted_at", "version_count", "is_deleted", "user")
search_fields = ('summary',)
list_filter = (DeletedListFilter,)
ordering = ("-modified_at",)

Expand Down Expand Up @@ -88,5 +92,5 @@ class VersionAdmin(NestedModelAdmin):

admin.site.register(Role, RoleAdmin)
admin.site.register(Message, MessageAdmin)
admin.site.register(Conversation, ConversationAdmin)
#admin.site.register(Conversation, ConversationAdmin)
admin.site.register(Version, VersionAdmin)
16 changes: 16 additions & 0 deletions backend/chat/management/commands/cleanup_conversations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#Automatically delete the conversations older than 30 days
from django.core.management.base import BaseCommand
from chat.models import Conversation
from django.utils import timezone
from datetime import timedelta

class Command(BaseCommand):
help = 'Delete conversations older than 30 days'

def handle(self, *args, **kwargs):
cutoff_date = timezone.now() - timedelta(days=30)
old_conversations = Conversation.objects.filter(created_at__lt=cutoff_date)
count = old_conversations.count()
old_conversations.delete()
self.stdout.write(f"Deleted {count} old conversations.")

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "../../../.."
}
],
"settings": {}
}
17 changes: 17 additions & 0 deletions backend/chat/migrations/0002_conversation_summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.0.2 on 2025-04-20 04:30

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("chat", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="conversation",
name="summary",
field=models.TextField(blank=True, default="", null=True),
),
]
20 changes: 20 additions & 0 deletions backend/chat/migrations/0003_message_conversation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 5.0.2 on 2025-04-20 10:31

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("chat", "0002_conversation_summary"),
]

operations = [
migrations.AddField(
model_name="message",
name="conversation",
field=models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="chat.conversation"
),
),
]
17 changes: 17 additions & 0 deletions backend/chat/migrations/0004_conversation_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.0.2 on 2025-04-20 14:03

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("chat", "0003_message_conversation"),
]

operations = [
migrations.AddField(
model_name="conversation",
name="content",
field=models.TextField(default="Placeholder content"),
),
]
28 changes: 27 additions & 1 deletion backend/chat/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from django.db import models

from authentication.models import CustomUser
#Imported generate summary function
from src.utils.gpt import generate_summary


class Role(models.Model):
Expand All @@ -13,6 +15,7 @@ def __str__(self):


class Conversation(models.Model):
content = models.TextField(default="Placeholder content") #Addede default value
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=100, blank=False, null=False, default="Mock title")
created_at = models.DateTimeField(auto_now_add=True)
Expand All @@ -23,6 +26,26 @@ class Conversation(models.Model):
deleted_at = models.DateTimeField(null=True, blank=True)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)

# New field for conversation summary
summary = models.TextField(null=True, blank=True, default="") # New summary field

# def save(self, *args, **kwargs):
# if self.content and not self.summary:
# self.summary = generate_summary(self.content)
# super().save(*args, **kwargs)
def save(self, *args, **kwargs):
#if not self.summary and self.messages:
if not self.summary and Message.objects.filter(version__conversation=self).exists():
try:
messages = Message.objects.filter(version__conversation=self).order_by("created_at")
message_list = [{"role": message.role.name, "content": message.content} for message in messages]
self.summary = generate_summary(message_list, model="gpt4")
except Exception as e:
print(f"Summary generation failed: {e}")
self.summary = "Summary generation failed."
super().save(*args, **kwargs)


def __str__(self):
return self.title

Expand All @@ -49,9 +72,12 @@ def __str__(self):

class Message(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
content = models.TextField(blank=False, null=False)
#Changed this as per chatgpt
content = models.TextField() #blank=False, null=False
role = models.ForeignKey(Role, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
#conversation = models.ForeignKey(Conversation,related_name = "messages",on_delete=models.CASCADE)
conversation = models.ForeignKey("Conversation",on_delete=models.CASCADE,null=True,blank=True)
version = models.ForeignKey("Version", related_name="messages", on_delete=models.CASCADE)

class Meta:
Expand Down
Loading