Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added chat for brains #1851

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from modules.chat.controller import chat_router
from modules.contact_support.controller import contact_router
from modules.knowledge.controller import knowledge_router
from modules.message.controller import messages_router
from modules.misc.controller import misc_router
from modules.notification.controller import notification_router
from modules.onboarding.controller import onboarding_router
Expand Down Expand Up @@ -49,6 +50,7 @@
],
)


app = FastAPI()

add_cors_middleware(app)
Expand All @@ -58,9 +60,9 @@
app.include_router(crawl_router)
app.include_router(onboarding_router)
app.include_router(misc_router)

app.include_router(upload_router)
app.include_router(user_router)
app.include_router(messages_router)
app.include_router(api_key_router)
app.include_router(subscription_router)
app.include_router(prompt_router)
Expand Down
Empty file.
1 change: 1 addition & 0 deletions backend/modules/message/controller/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .message_routes import messages_router
79 changes: 79 additions & 0 deletions backend/modules/message/controller/message_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from typing import List

from fastapi import APIRouter, Depends
from middlewares.auth import ( # Assuming you have a get_current_user function
AuthBearer,
get_current_user,
)
from modules.message.dto.inputs import CreateMessageProperties, UpdateMessageProperties
from modules.message.entity.message import Message
from modules.message.service.messages_service import MessagesService
from modules.user.entity.user_identity import UserIdentity

messages_router = APIRouter()

messages_services = MessagesService()


@messages_router.get(
"/messages",
dependencies=[Depends(AuthBearer())],
tags=["Messages"],
)
async def get_messages_user_brain(
brain_id: str,
current_user: UserIdentity = Depends(get_current_user),
) -> List[Message] | List[None]:
"""
Get users messages information for the current user and brain
"""

return messages_services.get_messages_brain(current_user.id, brain_id)


@messages_router.put(
"/messages",
dependencies=[Depends(AuthBearer())],
tags=["Messages"],
)
async def update_messages_brain(
message: UpdateMessageProperties,
current_user: UserIdentity = Depends(get_current_user),
) -> Message | None:
"""
Update user message information for the current user
"""

return messages_services.update_message(current_user.id, message)


@messages_router.delete(
"/messages",
dependencies=[Depends(AuthBearer())],
tags=["Messages"],
)
async def delete_messages_brain(
message_id: str,
current_user: UserIdentity = Depends(get_current_user),
) -> Message | None:
"""
Delete user message for the current user with message_id
"""

return messages_services.remove_message(current_user.id, message_id)


@messages_router.post(
"/messages",
dependencies=[Depends(AuthBearer())],
tags=["Messages"],
)
async def create_messages_brain(
message: CreateMessageProperties,
current_user: UserIdentity = Depends(get_current_user),
) -> Message | None:
"""
Create user message for the current user
"""

return messages_services.create_message(current_user.id, message)
1 change: 1 addition & 0 deletions backend/modules/message/dto/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .inputs import CreateMessageProperties, UpdateMessageProperties
25 changes: 25 additions & 0 deletions backend/modules/message/dto/inputs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from uuid import UUID

from pydantic import BaseModel


class CreateMessageProperties(BaseModel):

"""Properties that can be received on message creation"""

brain_id: UUID
content: str

class Config:
extra = "forbid"


class UpdateMessageProperties(BaseModel):

"""Properties that can be received on message update"""

message_id: UUID
content: str

class Config:
extra = "forbid"
1 change: 1 addition & 0 deletions backend/modules/message/entity/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .message import Message
13 changes: 13 additions & 0 deletions backend/modules/message/entity/message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from uuid import UUID

from pydantic import BaseModel


class Message(BaseModel):
"""Response when getting messages"""

message_id: UUID
brain_id: UUID
user_id: UUID
content: str
created_at: str
Empty file.
79 changes: 79 additions & 0 deletions backend/modules/message/repository/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from models.settings import get_supabase_client
from modules.message.entity.message import Message

from .messages_interface import MessagesInterface


class Messages(MessagesInterface):
def __init__(self):
supabase_client = get_supabase_client()
self.db = supabase_client

def get_messages_brain(self, user_id, brain_id):
"""
Get user messages information by user_id and brain_id
"""
messages_data = (
self.db.from_("messages")
.select("*")
.match({"user_id": str(user_id), "brain_id": str(brain_id)})
.execute()
).data

if messages_data == []:
return []

messages = []
for message in messages_data:
messages.append(Message(**message))

return messages

def update_message(self, user_id, update):
"""
Update user messages information by user_id and message_id
"""
response = (
self.db.table("messages")
.update({"content": update.content})
.match({"user_id": str(user_id), "message_id": str(update.message_id)})
.execute()
)

if len(response.data) == 0:
return None
return Message(**response.data[0])

def remove_message(self, user_id, message_id):
"""
Remove message by user_id and message_id
"""
response = (
self.db.table("messages")
.delete()
.match({"user_id": str(user_id), "message_id": str(message_id)})
.execute()
)

if len(response.data) == 0:
return None
return Message(**response.data[0])

def create_message(self, user_id, message_create):
"""
Create user messages information by user_id
"""
response = (
self.db.table("messages")
.insert(
[
{
"brain_id": str(message_create.brain_id),
"user_id": str(user_id),
"content": message_create.content,
}
]
)
.execute()
)
return Message(**response.data[0])
40 changes: 40 additions & 0 deletions backend/modules/message/repository/messages_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from abc import ABC, abstractmethod
from typing import List
from uuid import UUID

from modules.message.dto.inputs import CreateMessageProperties, UpdateMessageProperties
from modules.message.entity.message import Message


class MessagesInterface(ABC):
@abstractmethod
def get_messages_brain(
self, user_id: UUID, brain: UUID
) -> List[Message] | List[None]:
"""
Get messages by user_id and brain_id
"""
pass

@abstractmethod
def update_message(
self, user_id: UUID, update: UpdateMessageProperties
) -> Message | None:
"""Update user onboarding information by user_id"""
pass

@abstractmethod
def remove_message(self, user_id: UUID, message_id: UUID) -> Message | None:
"""
Remove message by user_id and message_id
"""
pass

@abstractmethod
def create_message(
self, user_id: UUID, message_create: CreateMessageProperties
) -> Message:
"""
Create user onboarding information by user_id
"""
pass
1 change: 1 addition & 0 deletions backend/modules/message/service/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .messages_service import MessagesService
40 changes: 40 additions & 0 deletions backend/modules/message/service/messages_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import List
from uuid import UUID

from modules.message.dto.inputs import CreateMessageProperties, UpdateMessageProperties
from modules.message.entity.message import Message
from modules.message.repository.messages import Messages
from modules.message.repository.messages_interface import MessagesInterface


class MessagesService:
repository: MessagesInterface

def __init__(self):
self.repository = Messages()

def get_messages_brain(
self, user_id: UUID, brain_id: UUID
) -> List[Message] | List[None]:
"""Update user onboarding information by user_id"""

return self.repository.get_messages_brain(user_id, brain_id)

def update_message(
self, user_id: UUID, message: UpdateMessageProperties
) -> Message | None:
"""Update user onboarding information by user_id"""

return self.repository.update_message(user_id, message)

def remove_message(self, user_id: UUID, message_id: UUID) -> Message | None:
"""Update user onboarding information by user_id"""

return self.repository.remove_message(user_id, message_id)

def create_message(
self, user_id: UUID, message_create: CreateMessageProperties
) -> Message:
"""Update user onboarding information by user_id"""

return self.repository.create_message(user_id, message_create)
33 changes: 33 additions & 0 deletions scripts/20231209003200_new_message_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
DO $$
BEGIN
-- Check if the messages table does not exist
IF NOT EXISTS (SELECT FROM pg_catalog.pg_tables
WHERE schemaname = 'public' AND tablename = 'messages') THEN

-- Create the table if it does not exist
CREATE TABLE public.messages (
message_id uuid NOT NULL DEFAULT gen_random_uuid(),
brain_id uuid NOT NULL,
user_id uuid NOT NULL,
content text NOT NULL,
created_at timestamp without time zone NOT NULL DEFAULT current_timestamp,
CONSTRAINT messages_pkey PRIMARY KEY (message_id),
CONSTRAINT messages_brain_id_fkey FOREIGN KEY (brain_id) REFERENCES public.brains (brain_id),
CONSTRAINT messages_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users (id)
) TABLESPACE pg_default;

RAISE NOTICE 'Created table public.messages';
ELSE
RAISE NOTICE 'Table public.messages already exists';
END IF;
END $$;


-- Update migrations table
INSERT INTO migrations (name)
SELECT '20231209003200_new_message_table'
WHERE NOT EXISTS (
SELECT 1 FROM migrations WHERE name = '20231209003200_new_message_table'
);

COMMIT;