diff --git a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py index 00d1b7b6..93946264 100644 --- a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py +++ b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py @@ -23,7 +23,10 @@ def __init__(self, chain: Chain, chatHistoryManager: ChatHistoryManager): def askChatbot(self, message: Message, chatId: ChatId) -> MessageResponse: if chatId is not None: self.chain.memory = self.chatHistoryManager.getChatHistory(chatId) - answer = self.chain.invoke({"question": message.content, "chat_history": ""}) + print(self.chatHistoryManager.getChatHistory(chatId.id).messages, flush=True) + answer = self.chain.invoke({"question": message.content}) + else: + answer = self.chain.invoke({"question": message.content, "chat_history": ""}) return MessageResponse( True, diff --git a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py index 2e22d06a..f289b823 100644 --- a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py +++ b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py @@ -13,9 +13,8 @@ def __init__(self, postgresChatORM: PostgresChatORM): self.postgresChatORM = postgresChatORM def persistChat(self, messages: List[Message], chatId: ChatId) -> ChatOperationResponse: - for message in messages: - print(self.toPostgresMessageFrom(message).sender.name, flush=True) postgresChatOperationResponse = self.postgresChatORM.persistChat([self.toPostgresMessageFrom(message) for message in messages], chatId) + print(postgresChatOperationResponse, flush=True) return postgresChatOperationResponse.toChatOperationResponse() def toPostgresMessageFrom(self, message: Message) -> PostgresMessage: @@ -23,5 +22,5 @@ def toPostgresMessageFrom(self, message: Message) -> PostgresMessage: content=message.content, timestamp=message.timestamp, relevantDocuments=[relevantDocumentId.id for relevantDocumentId in message.relevantDocuments] if message.relevantDocuments else None, - sender=PostgresMessageSenderType.USER if message.sender.value == MessageSender.USER.value else PostgresMessageSenderType.CHATBOT + sender=PostgresMessageSenderType.human if message.sender.value == MessageSender.USER.value else PostgresMessageSenderType.ai ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py index 4494f063..ca164860 100644 --- a/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py +++ b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py @@ -20,11 +20,12 @@ def getDocumentsContent(self, documentIds: List[DocumentId]) -> List[PlainDocume for documentId in documentIds: retrievedDocument = self.awsS3Manager.getDocumentContent(documentId.id) documents.append(retrievedDocument) + plainDocuments = [ PlainDocument( DocumentMetadata( - id= DocumentId(document.id), - type=DocumentType.PDF if document.type.split('/')[1].upper() == "PDF" else DocumentType.DOCX, + id=DocumentId(document.id), + type=DocumentType.PDF if document.type.split('.')[1].upper() == "PDF" else DocumentType.DOCX, size=document.size, uploadTime=document.uploadTime ), diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py index 48546a20..02dd3f48 100644 --- a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py @@ -106,7 +106,6 @@ def getDocumentsMetadata(self, documentFilter: str) -> List[AWSDocumentMetadata] def getDocumentContent(self, documentId: str) -> AWSDocument: try: documentContentResponse = self.s3.get_object(Bucket=self.awsBucketName, Key=documentId) - print(f"DOCUMENT TYPE: {documentContentResponse.get('ContentType')}", flush=True) return AWSDocument( documentId, documentContentResponse.get('Body').read(), diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py index c6f8c891..cb20aa29 100644 --- a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py @@ -1,6 +1,6 @@ from typing import List -from langchain_community.chat_message_histories import PostgresChatMessageHistory +from langchain_community.chat_message_histories import (PostgresChatMessageHistory) from langchain_core.messages import BaseMessage import os @@ -8,7 +8,9 @@ from langchain.memory import ConversationBufferMemory class ChatHistoryManager: - def getChatHistory(self, chatId:ChatId)-> PostgresChatMessageHistory: - history = PostgresChatMessageHistory(session_id=str(chatId.id), - connection_string=os.environ.get('DATABASE_URL')) + def getChatHistory(self, chatId: int)-> PostgresChatMessageHistory: + history = PostgresChatMessageHistory( + connection_string=os.environ.get('DATABASE_URL'), + session_id=str(chatId), + ) return history diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py index 192fe94e..f5af3969 100644 --- a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py @@ -1,7 +1,5 @@ -from sqlalchemy import Column, Integer, String, Enum as SQLEnum, ForeignKey, Text, JSON -from enum import Enum +from sqlalchemy import Column, Integer, String, Text, JSON, ForeignKey from sqlalchemy.orm import relationship - from adapter.out.persistence.postgres.database import Base, db_session class Chat(Base): @@ -9,9 +7,16 @@ class Chat(Base): id = Column('id', Integer, primary_key=True, autoincrement=True) title = Column('title', Text, unique=True, nullable=False) + messages_cascade = relationship( + 'MessageStore', + back_populates="messages_cascade_rel", + cascade="all, delete", + passive_deletes=True + ) + def __init__(self, title: str) -> None: self.title = title - + def __repr__(self): return f'({self.id}, {self.title})' @@ -20,20 +25,35 @@ class MessageStore(Base): id = Column('id', Integer, primary_key=True, autoincrement=True) sessionId = Column('session_id', Integer, ForeignKey('chat.id')) message = Column('message', JSON) - - chatIdConstraint = relationship(Chat, foreign_keys=[sessionId]) - + + messages_cascade_rel = relationship("Chat", back_populates="messages_cascade") + relevant_documents_cascade = relationship( + 'MessageRelevantDocuments', + back_populates="relevant_documents_cascade_rel", + cascade="all, delete", + passive_deletes=True + ) + def __init__(self, sessionId: str, message: str) -> None: self.sessionId = sessionId self.message = message - + def __repr__(self): - return f'({self.id}, {self.sessionId}, {self.message})' + return f'({self.id}, {self.session_id}, {self.message})' class MessageRelevantDocuments(Base): __tablename__ = 'message_relevant_documents' id = Column('id', Integer, ForeignKey('message_store.id'), primary_key=True) documentId = Column('document_id', Text, primary_key=True) + + relevant_documents_cascade_rel = relationship("MessageStore", back_populates="relevant_documents_cascade") + + def __init__(self, id: str, documentId: str) -> None: + self.id = id + self.documentId = documentId + + def __repr__(self): + return f'({self.id}, {self.documentId})' def initChat(): - Base.metadata.create_all(bind=db_session.bind) \ No newline at end of file + Base.metadata.create_all(bind=db_session.bind) diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py index 5c8f7763..7621293e 100644 --- a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py @@ -39,7 +39,7 @@ def createChat(self) -> PostgresChatOperationResponse: def saveMessages(self, messages: List[PostgresMessage], chatId: int) -> PostgresChatOperationResponse: try: - newMessages = [MessageStore(chatId, {"data": {"type": message.sender.name, "content": message.content, "timestamp": message.timestamp.isoformat()}}) for message in messages] + newMessages = [MessageStore(chatId, {"type": message.sender.name, "data": {"content": message.content, "timestamp": message.timestamp.isoformat()}}) for message in messages] db_session.add_all(newMessages) db_session.commit() newMessageIds = [newMessage.id for newMessage in newMessages] @@ -83,7 +83,7 @@ def getChats(self, chatFilter:str) -> List[PostgresChatPreview]: lastMessage.message["data"]["content"], datetime.fromisoformat(lastMessage.message["data"]["timestamp"]), [document.documentId for document in db_session.query(MessageRelevantDocuments).filter(MessageRelevantDocuments.id == lastMessage.id).all()], - PostgresMessageSenderType[lastMessage.message["data"]["type"]])) + PostgresMessageSenderType[lastMessage.message["type"]])) ) else: chatPreviews.append(PostgresChatPreview(chat.id, chat.title, None)) @@ -99,7 +99,7 @@ def getChatMessages(self, chatId: int) -> PostgresChat: message.message["data"]["content"], datetime.fromisoformat(message.message["data"]["timestamp"]), [document.documentId for document in db_session.query(MessageRelevantDocuments).filter(MessageRelevantDocuments.id == message.id).all()], - PostgresMessageSenderType[message.message["data"]["type"]]) for message in messages] + PostgresMessageSenderType[message.message["type"]]) for message in messages] return PostgresChat(chat.id, chat.title, postgresMessages) except Exception as e: diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py index f8b6f45b..b6743de9 100644 --- a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py @@ -9,8 +9,8 @@ @dataclass class PostgresMessageSenderType(Enum): - USER = 1 - CHATBOT = 2 + human = 1 + ai = 2 @dataclass class PostgresMessage: @@ -20,8 +20,9 @@ class PostgresMessage: sender: PostgresMessageSenderType def toMessage(self) -> Message: - return Message(self.content, - self.timestamp, - [DocumentId(relevantDocument) for relevantDocument in self.relevantDocuments], - MessageSender.USER if self.sender.value == PostgresMessageSenderType.USER.value else MessageSender.CHATBOT - ) \ No newline at end of file + return Message( + self.content, + self.timestamp, + [DocumentId(relevantDocument) for relevantDocument in self.relevantDocuments], + MessageSender.USER if self.sender.value == PostgresMessageSenderType.human.value else MessageSender.CHATBOT + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/delete_chats_service.py b/3 - PB/MVP/src/backend/application/service/delete_chats_service.py index 0e2aa5b2..a70cfa5e 100644 --- a/3 - PB/MVP/src/backend/application/service/delete_chats_service.py +++ b/3 - PB/MVP/src/backend/application/service/delete_chats_service.py @@ -9,4 +9,4 @@ def __init__(self, deleteChatsPort: DeleteChatsPort): self.outPort = deleteChatsPort def deleteChats(self, chatsIdsList: List[ChatId]) -> List[ChatOperationResponse]: - self.outPort.deleteChats(chatsIdsList) \ No newline at end of file + return self.outPort.deleteChats(chatsIdsList) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/rename_chat_service.py b/3 - PB/MVP/src/backend/application/service/rename_chat_service.py index 7d9a8bd2..5dd1691a 100644 --- a/3 - PB/MVP/src/backend/application/service/rename_chat_service.py +++ b/3 - PB/MVP/src/backend/application/service/rename_chat_service.py @@ -8,4 +8,4 @@ def __init__(self, renameChatPort: RenameChatPort): self.outPort = renameChatPort def renameChat(self, chatId: ChatId, title: str) -> ChatOperationResponse: - self.outPort.renameChat(chatId, title) \ No newline at end of file + return self.outPort.renameChat(chatId, title) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py b/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py index 1ac4f9f5..7198e824 100644 --- a/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py +++ b/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py @@ -37,6 +37,7 @@ def AskChatbot(): "chatbotResponse": { "message": chatbotResponse.messageResponse.content, "timestamp": chatbotResponse.messageResponse.timestamp, - "relevantDocuments": [relevantDocument.id for relevantDocument in chatbotResponse.messageResponse.relevantDocuments] - }, + "relevantDocuments": [relevantDocument.id for relevantDocument in chatbotResponse.messageResponse.relevantDocuments], + "sender": chatbotResponse.messageResponse.sender.name + }, "chatId": chatbotResponse.chatId.id}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/delete_chats.py b/3 - PB/MVP/src/backend/blueprints/delete_chats.py index 42f0123e..ad93b7dd 100644 --- a/3 - PB/MVP/src/backend/blueprints/delete_chats.py +++ b/3 - PB/MVP/src/backend/blueprints/delete_chats.py @@ -5,6 +5,8 @@ from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM from adapter.out.configuration_manager import ConfigurationManager from api_exceptions import InsufficientParameters +from adapter.out.delete_chats.delete_chats_postgres import DeleteChatsPostgres +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM deleteChatsBlueprint = Blueprint("deleteChats", __name__) @@ -14,10 +16,11 @@ def deleteChats(): if requestedIds is None: raise InsufficientParameters() - configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) - controller = DeleteChatsController( - DeleteChatsService(configurationManager.getDeleteChatsPort())) + DeleteChatsService( + DeleteChatsPostgres(PostgresChatORM()) + ) + ) chatOperationResponses = controller.deleteChats(requestedIds) diff --git a/3 - PB/MVP/src/backend/requirements.txt b/3 - PB/MVP/src/backend/requirements.txt index 77796645..30c0050e 100644 --- a/3 - PB/MVP/src/backend/requirements.txt +++ b/3 - PB/MVP/src/backend/requirements.txt @@ -17,7 +17,7 @@ pytest pytest-mock python-dotenv pinecone-client -psycopg +psycopg[binary,pool] psycopg2-binary # sentence-transformers tiktoken