BOB0920 commited on
Commit
ecf7075
·
verified ·
1 Parent(s): a21a92d

Upload 7 files

Browse files
__pycache__/rag.cpython-311.pyc ADDED
Binary file (3.27 kB). View file
 
__pycache__/templates/index.html ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>RGB Bot</title>
7
+ <style>
8
+ :root {
9
+ --bg-color: #0d0d0d;
10
+ --text-color: #e0e0e0;
11
+ --accent-color: #00ff00; /* Green typical of terminal/RGB */
12
+ --input-bg: #1a1a1a;
13
+ --bot-msg-bg: #2a2a2a;
14
+ --user-msg-bg: #004400;
15
+ }
16
+
17
+ body {
18
+ font-family: 'Courier New', Courier, monospace;
19
+ background-color: var(--bg-color);
20
+ color: var(--text-color);
21
+ margin: 0;
22
+ display: flex;
23
+ flex-direction: column;
24
+ height: 100vh;
25
+ overflow: hidden;
26
+ }
27
+
28
+ /* RGB Border Effect */
29
+ body::before {
30
+ content: "";
31
+ position: absolute;
32
+ top: 0; left: 0; right: 0; height: 3px;
33
+ background: linear-gradient(90deg, red, green, blue);
34
+ z-index: 1000;
35
+ }
36
+
37
+ header {
38
+ padding: 20px;
39
+ text-align: center;
40
+ border-bottom: 1px solid #333;
41
+ background: rgba(0,0,0,0.8);
42
+ }
43
+
44
+ h1 {
45
+ margin: 0;
46
+ font-size: 1.5rem;
47
+ text-transform: uppercase;
48
+ letter-spacing: 2px;
49
+ background: linear-gradient(90deg, #ff0000, #00ff00, #0000ff);
50
+ -webkit-background-clip: text;
51
+ -webkit-text-fill-color: transparent;
52
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.1);
53
+ }
54
+
55
+ #chat-container {
56
+ flex: 1;
57
+ padding: 20px;
58
+ overflow-y: auto;
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 15px;
62
+ scroll-behavior: smooth;
63
+ }
64
+
65
+ .message {
66
+ max-width: 80%;
67
+ padding: 12px 16px;
68
+ border-radius: 8px;
69
+ line-height: 1.5;
70
+ position: relative;
71
+ word-wrap: break-word;
72
+ }
73
+
74
+ .bot-message {
75
+ align-self: flex-start;
76
+ background-color: var(--bot-msg-bg);
77
+ border-left: 3px solid #00f;
78
+ box-shadow: 0 0 10px rgba(0, 0, 255, 0.2);
79
+ }
80
+
81
+ .user-message {
82
+ align-self: flex-end;
83
+ background-color: var(--user-msg-bg);
84
+ border-right: 3px solid #0f0;
85
+ box-shadow: 0 0 10px rgba(0, 255, 0, 0.2);
86
+ }
87
+
88
+ .input-area {
89
+ padding: 20px;
90
+ background-color: #111;
91
+ border-top: 1px solid #333;
92
+ display: flex;
93
+ gap: 10px;
94
+ }
95
+
96
+ input[type="text"] {
97
+ flex: 1;
98
+ padding: 15px;
99
+ background-color: var(--input-bg);
100
+ border: 1px solid #333;
101
+ color: white;
102
+ border-radius: 4px;
103
+ font-family: inherit;
104
+ outline: none;
105
+ transition: border-color 0.3s;
106
+ }
107
+
108
+ input[type="text"]:focus {
109
+ border-color: var(--accent-color);
110
+ box-shadow: 0 0 8px rgba(0, 255, 0, 0.1);
111
+ }
112
+
113
+ button {
114
+ padding: 10px 25px;
115
+ background: linear-gradient(45deg, #0000aa, #00aa00);
116
+ border: none;
117
+ color: white;
118
+ font-weight: bold;
119
+ font-family: inherit;
120
+ cursor: pointer;
121
+ border-radius: 4px;
122
+ text-transform: uppercase;
123
+ letter-spacing: 1px;
124
+ transition: transform 0.1s;
125
+ }
126
+
127
+ button:active {
128
+ transform: scale(0.98);
129
+ }
130
+
131
+ /* Scrollbar */
132
+ ::-webkit-scrollbar {
133
+ width: 8px;
134
+ }
135
+ ::-webkit-scrollbar-track {
136
+ background: #111;
137
+ }
138
+ ::-webkit-scrollbar-thumb {
139
+ background: #333;
140
+ border-radius: 4px;
141
+ }
142
+ ::-webkit-scrollbar-thumb:hover {
143
+ background: #555;
144
+ }
145
+
146
+ .typing-indicator::after {
147
+ content: '...';
148
+ animation: blink 1s infinite;
149
+ }
150
+
151
+ @keyframes blink {
152
+ 0% { opacity: 0; }
153
+ 50% { opacity: 1; }
154
+ 100% { opacity: 0; }
155
+ }
156
+ </style>
157
+ </head>
158
+ <body>
159
+ <header>
160
+ <h1>Peronal Assistant</h1>
161
+ </header>
162
+
163
+ <div id="chat-container">
164
+ <div class="message bot-message">
165
+ Hello! I'm Sagar's personal assistant. Feel free to ask me anything about Sagar.
166
+ </div>
167
+ </div>
168
+
169
+ <div class="input-area">
170
+ <input type="text" id="user-input" placeholder="Type your question..." autocomplete="off">
171
+ <button onclick="sendMessage()">Send</button>
172
+ </div>
173
+
174
+ <script>
175
+ const inputField = document.getElementById("user-input");
176
+ const chatContainer = document.getElementById("chat-container");
177
+
178
+ inputField.addEventListener("keypress", function(event) {
179
+ if (event.key === "Enter") {
180
+ sendMessage();
181
+ }
182
+ });
183
+
184
+ async function sendMessage() {
185
+ const text = inputField.value.trim();
186
+ if (!text) return;
187
+
188
+ // Add User Message
189
+ addMessage(text, "user-message");
190
+ inputField.value = "";
191
+
192
+ // Add Loading Indicator
193
+ const loadingId = "loading-" + Date.now();
194
+ addMessage("Thinking", "bot-message typing-indicator", loadingId);
195
+
196
+ try {
197
+ const response = await fetch("/chat", {
198
+ method: "POST",
199
+ headers: { "Content-Type": "application/json" },
200
+ body: JSON.stringify({ message: text })
201
+ });
202
+
203
+ const data = await response.json();
204
+
205
+ // Remove loading
206
+ const loadingElement = document.getElementById(loadingId);
207
+ if (loadingElement) loadingElement.remove();
208
+
209
+ // Add Bot Response
210
+ addMessage(data.answer, "bot-message");
211
+
212
+ } catch (error) {
213
+ console.error("Error:", error);
214
+ const loadingElement = document.getElementById(loadingId);
215
+ if (loadingElement) loadingElement.remove();
216
+ addMessage("Error connecting to server.", "bot-message");
217
+ }
218
+ }
219
+
220
+ function addMessage(text, className, id = null) {
221
+ const div = document.createElement("div");
222
+ div.className = "message " + className;
223
+ div.innerText = text;
224
+ if (id) div.id = id;
225
+ chatContainer.appendChild(div);
226
+ // Scroll to bottom
227
+ chatContainer.scrollTop = chatContainer.scrollHeight;
228
+ }
229
+ </script>
230
+ </body>
231
+ </html>
ingest.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_community.document_loaders import PyPDFLoader, TextLoader
3
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
4
+ from langchain_community.vectorstores import FAISS
5
+ from langchain_huggingface import HuggingFaceEmbeddings
6
+ from dotenv import load_dotenv
7
+
8
+ # Load environment variables
9
+ load_dotenv()
10
+
11
+ DATA_PATH = "data"
12
+ DB_FAISS_PATH = "vectorstore/db_faiss"
13
+
14
+ def create_vector_db():
15
+ documents = []
16
+
17
+ # Check if data directory exists
18
+ if not os.path.exists(DATA_PATH):
19
+ print(f"Directory {DATA_PATH} not found.")
20
+ return
21
+
22
+ # Load documents
23
+ for filename in os.listdir(DATA_PATH):
24
+ file_path = os.path.join(DATA_PATH, filename)
25
+ if filename.endswith(".pdf"):
26
+ loader = PyPDFLoader(file_path)
27
+ documents.extend(loader.load())
28
+ print(f"Loaded {filename}")
29
+ elif filename.endswith(".txt"):
30
+ loader = TextLoader(file_path, encoding='utf-8')
31
+ documents.extend(loader.load())
32
+ print(f"Loaded {filename}")
33
+
34
+ if not documents:
35
+ print("No documents found to ingest.")
36
+ return
37
+
38
+ # Split text
39
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
40
+ texts = text_splitter.split_documents(documents)
41
+ print(f"Split documents into {len(texts)} chunks.")
42
+
43
+ # Create embeddings
44
+ print("Generating embeddings... This might take a moment.")
45
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2',
46
+ model_kwargs={'device': 'cpu'})
47
+
48
+ # Create vector store
49
+ db = FAISS.from_documents(texts, embeddings)
50
+ db.save_local(DB_FAISS_PATH)
51
+ print(f"Vector store saved to {DB_FAISS_PATH}")
52
+
53
+ if __name__ == "__main__":
54
+ create_vector_db()
main.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from rag import get_answer
2
+ import sys
3
+
4
+ def main():
5
+ print("🔵 RGB Bot: Hello! I'm here to answer questions about Sagar. (Type 'exit' to quit)")
6
+
7
+ while True:
8
+ try:
9
+ query = input("\nYou: ")
10
+ if query.lower() in ["exit", "quit", "q"]:
11
+ print("🔵 RGB Bot: Goodbye!")
12
+ break
13
+
14
+ if not query.strip():
15
+ continue
16
+
17
+ print("🔵 RGB Bot: Thinking...")
18
+ response = get_answer(query)
19
+ print(f"🔵 RGB Bot: {response}")
20
+
21
+ except KeyboardInterrupt:
22
+ print("\n🔵 RGB Bot: Goodbye!")
23
+ sys.exit()
24
+ except Exception as e:
25
+ print(f"Error: {e}")
26
+
27
+ if __name__ == "__main__":
28
+ main()
rag.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_openai import ChatOpenAI
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+ from langchain_core.output_parsers import StrOutputParser
5
+ from langchain_core.runnables import RunnablePassthrough
6
+ from langchain_community.vectorstores import FAISS
7
+ from langchain_huggingface import HuggingFaceEmbeddings
8
+ from dotenv import load_dotenv
9
+
10
+ load_dotenv()
11
+
12
+ DB_FAISS_PATH = "vectorstore/db_faiss"
13
+
14
+ def format_docs(docs):
15
+ return "\n\n".join(doc.page_content for doc in docs)
16
+
17
+ def get_answer(query):
18
+ # Load Embeddings
19
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2',
20
+ model_kwargs={'device': 'cpu'})
21
+
22
+ # Load Vector DB
23
+ try:
24
+ db = FAISS.load_local(DB_FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
25
+ except Exception as e:
26
+ return f"Error loading FAISS index: {e} \n (Did you run ingest.py?)"
27
+
28
+ # Setup LLM (OpenRouter)
29
+ llm = ChatOpenAI(
30
+ base_url="https://openrouter.ai/api/v1",
31
+ api_key=os.getenv("OPENROUTER_API_KEY"),
32
+ model="openai/gpt-3.5-turbo",
33
+ )
34
+
35
+ # Define Prompt
36
+ template = """You are the RGB Bot, a personal assistant for Sagar.
37
+ Answer questions based strictly on the following context:
38
+ {context}
39
+
40
+ Guidelines:
41
+ 1. Answer only from the provided context.
42
+ 2. Be professional, friendly, and slightly playful (RGB style).
43
+ 3. If the answer is not in the context, say 'As an AI chatbot. I don't have information about that yet, you may contact with orignal Sagar Rathi at sagar_rathi@zohomail.in.'
44
+ 4. Do not make up facts.
45
+
46
+ Question: {question}
47
+ """
48
+ prompt = ChatPromptTemplate.from_template(template)
49
+
50
+ # Create LCEL Chain
51
+ retriever = db.as_retriever()
52
+ rag_chain = (
53
+ {"context": retriever | format_docs, "question": RunnablePassthrough()}
54
+ | prompt
55
+ | llm
56
+ | StrOutputParser()
57
+ )
58
+
59
+ try:
60
+ response = rag_chain.invoke(query)
61
+ return response
62
+ except Exception as e:
63
+ return f"Error gathering response: {e}"
64
+
65
+ # Kept for backward compatibility if main.py expects get_rag_chain (it doesn't, it calls get_answer)
66
+
vectorstore/db_faiss/index.faiss ADDED
Binary file (47.7 kB). View file
 
vectorstore/db_faiss/index.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ac097e42d4290b6266f343f0f098c639b10aec869762c68ee080529bee217072
3
+ size 14840