File size: 10,063 Bytes
a2b6bfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import os
from groq import Groq
from langchain.memory import ConversationSummaryBufferMemory
from langdetect import detect
from deep_translator import GoogleTranslator
from langchain_community.document_loaders.csv_loader import CSVLoader
from langchain_community.vectorstores import FAISS
class Comsatsbot:
    def __init__(self, hf, llm, api_key, chats_collection, paths, index_path='faiss_kb'):
        self.llm = llm
        self.client = Groq(api_key=api_key)

        # Initialize memory buffer and MongoDB connection
        self.memory = ConversationSummaryBufferMemory(llm=self.llm, max_token_limit=3000)
        self.chats_collection = chats_collection
        self.index_path = index_path
        self.hf = hf
        self.faiss_index = None
        self.faiss_retriever = None
        self.paths = paths
        self.initialize_faiss_index()

    def load_data(self, paths):
        documents = []
        for path in paths:
            loader = CSVLoader(file_path=path)
            data = loader.load()
            documents.extend(data)
        return documents

    def initialize_faiss_index(self):
        if os.path.exists(self.index_path):
            self.faiss_index = FAISS.load_local(self.index_path, self.hf, allow_dangerous_deserialization=True)
            self.faiss_retriever = self.faiss_index.as_retriever(search_kwargs={"k": 5})
        else:
            documents = self.load_data(self.paths)
            self.faiss_index = FAISS.from_documents(documents, self.hf)
            self.faiss_index.save_local(self.index_path)
            self.faiss_retriever = self.faiss_index.as_retriever(search_kwargs={"k": 5})

    def retrieve_answer(self, query):
        if self.faiss_retriever:
            return self.faiss_retriever.invoke(query)
        else:
            print("FAISS retriever is not initialized. Please create or load an index.")
            return None

    def create_chat_record(self, chat_id):
        self.chats_collection.insert_one({
            "_id": chat_id,
            "history": []
        })

    def update_chat(self, chat_id, question, answer):
        self.chats_collection.update_one(
            {"_id": chat_id},
            {"$push": {"history": {"question": question, "answer": answer}}}
        )

    def load_chat(self, chat_id):
        chat_record = self.chats_collection.find_one({"_id": chat_id})
        if not chat_record:
            raise KeyError(f"Chat ID {chat_id} does not exist.")
        return chat_record.get('history', [])

    def new_chat(self, chat_id):
        # Check if chat ID already exists
        if self.chats_collection.find_one({"_id": chat_id}):
            raise KeyError(f"Chat ID {chat_id} exist already.")

        # Create a new chat record if it doesn't exist
        self.create_chat_record(chat_id)
        return "success"

    def delete_chat(self, chat_id):
        # Check if the chat ID exists
        if not self.chats_collection.find_one({"_id": chat_id}):
            raise KeyError(f"Chat ID {chat_id} does not exist.")

        # Delete the chat if it exists
        self.chats_collection.delete_one({"_id": chat_id})
        return "success"

    def generate_response(self, question, history, context, detected_language):
        if detected_language == 'ur':
            language = 'Urdu'

            chat_completion = self.client.chat.completions.create(
                messages=[
                    {
                        "role": "user",
                        "content": f'''
        
        You are a conversational and helpfull agent to help the comsats university attock campus students, and your task is to provide concise and direct answers to the questions asked in {language} Language. kindly answer in correct way and to the point in {language} language. 
        Dont need to explain irrelevant thinga nd use the correct {language} in response.
        Please follow these guidelines when answering:
        Dont need to explain and repeat the prompt in response. Answer in {language} language.
    
        1. If the question is in {language}, answer in {language}.
        2. Dont need to explain irrelevant explanation and use the proper emojis in answer.
        3. Always respond in a **human-like tone** and keep your answers concise, to the point, and friendly.
        4. If the question is **conversational** (like greetings, need any converstaion etc), respond in a warm, conversational tone and use appropriate **emojis**.
        5. Always consider the provided **context** and **chat history** to formulate your response.
        6. If you don’t know the answer to the question or you did not find the answer from the context, kindly respond with "I don't know the answer to this." without adding irrelevant explanations.
        7. KIndly generate a perfect and to the point answer with the proper use of emojis. Dont use any irrelevant text explanation and i want full concise and to the oint answer.
        8. Kindly answer in {language} and dont need to generate a response in other language and i want answer in this language {language}.
    
        **Question:** {question}
    
        **Use the following context to answer:** 
        Comsats Attock Campus Provide BSomputerScience, BSSoftwareEngineer BSArtificialIntelligence BSEnglish BSmath BSElectricalEngineering BSComputerEngineering BSBBA 
        Has three departments CS(CS, AI, SE), Math(math, BBA, english) and EE(EE, CE).
        It has cricket ground and football ground and two canteens. First near math and ee department and second near cs department. There is also mosque near cs department. CS department has threater liker rooms lt and total 9 theaters called lt and math has classroom cr and ee has labs.
        They accept the nts test for admission and provide the cgpa for 4 on 85 percent and 3.66 between 79 to 84 and many more. 
        {context}
    
        **Consider the following chat history for additional context to answer the question:** 
        {history}
        '''
                    }
                ],
                model="llama3-70b-8192",
            )
        else:
            language = 'English'
            chat_completion = self.client.chat.completions.create(
                messages=[
                    {
                        "role": "user",
                        "content": f'''
        
        You are a conversational and helpfull agent to help the comsats university attock campus students, and your task is to provide concise and direct answers to the questions asked in {language} Language. kindly answer in correct way and to the point in {language} language. 
        Dont need to explain irrelevant thinga nd use the correct {language} in response.
        Please follow these guidelines when answering:
        Dont need to explain and repeat the prompt in response. Answer in {language} language.
    
        1. If the question is in {language}, answer in {language}.
        2. Dont need to explain irrelevant explanation and use the proper emojis in answer.
        3. Always respond in a **human-like tone** and keep your answers concise, to the point, and friendly.
        4. If the question is **conversational** (like greetings, need any converstaion etc), respond in a warm, conversational tone and use appropriate **emojis**.
        5. Always consider the provided **context** and **chat history** to formulate your response.
        6. If you don’t know the answer to the question or you did not find the answer from the context, kindly respond with "I don't know the answer to this." without adding irrelevant explanations.
        7. KIndly generate a perfect and to the point answer with the proper use of emojis. Dont use any irrelevant text explanation and i want full concise and to the oint answer.
        8. Kindly answer in {language} and dont need to generate a response in other language and i want answer in this language {language}.
    
        **Question:** {question}
    
        **Use the following context to answer:** 
        Comsats Attock Campus Provide BSomputerScience, BSSoftwareEngineer BSArtificialIntelligence BSEnglish BSmath BSElectricalEngineering BSComputerEngineering BSBBA 
        Has three departments CS(CS, AI, SE), Math(math, BBA, english) and EE(EE, CE).
        It has cricket ground and football ground and two canteens. First near math and ee department and second near cs department. There is also mosque near cs department. CS department has threater liker rooms lt and total 9 theaters called lt and math has classroom cr and ee has labs.
        They accept the nts test for admission and provide the cgpa for 4 on 85 percent and 3.66 between 79 to 84 and many more. 
        {context}
    
        **Consider the following chat history for additional context to answer the question:** 
        {history}
        '''
                    }
                ],
                model="llama3-70b-8192",
            )

        response_content = chat_completion.choices[0].message.content
        return response_content

    def response(self, question, chat_id):
        chat_history = self.load_chat(chat_id)

        # Load the previous conversation into memory
        for entry in chat_history:
            self.memory.save_context({"input": entry["question"]}, {"output": entry["answer"]})

        language = detect(question)
        if language == 'ur':
            question_translation = GoogleTranslator(source='ur', target='en').translate(question)
            context = self.faiss_retriever.invoke(question_translation)
        else:
            context = self.faiss_retriever.invoke(question)

        all_content = ''
        for document in context:
            page_content = document.page_content
            all_content += page_content + '\n'  # Add a line break between contents for readability

        answer = self.generate_response(question, self.memory.load_memory_variables({})['history'], all_content, language)

        self.update_chat(chat_id, question, answer)
        return answer