GIGAParviz commited on
Commit
1563358
·
verified ·
1 Parent(s): 44db8b2

Upload 3 files

Browse files
Files changed (3) hide show
  1. requirements.txt +0 -0
  2. static/logo.png +0 -0
  3. web_app.py +390 -0
requirements.txt ADDED
Binary file (24.4 kB). View file
 
static/logo.png ADDED
web_app.py ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # from flask import Flask, render_template_string, request, jsonify
3
+ # import os
4
+ # from groq import Groq
5
+ # import re
6
+ # from pypdf import PdfReader
7
+ # from langchain_huggingface import HuggingFaceEmbeddings
8
+ # from langchain_community.vectorstores import Chroma
9
+ # from langchain_core.documents import Document
10
+ # from langchain_text_splitters import RecursiveCharacterTextSplitter
11
+
12
+ # app = Flask(__name__)
13
+ # app.static_folder = 'static'
14
+
15
+ # client = Groq(
16
+ # api_key="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",
17
+ # )
18
+ # embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
19
+ # vector_store = Chroma(embedding_function=embeddings, collection_name="doc_collection")
20
+ # text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
21
+ # chat_history = []
22
+
23
+ # HTML_TEMPLATE = """
24
+ # <!DOCTYPE html>
25
+ # <html lang="en">
26
+ # <head>
27
+ # <meta charset="UTF-8">
28
+ # <meta name="viewport" content="width=device-width, initial-scale=1.0">
29
+ # <title>Chat</title>
30
+ # <style>
31
+ # :root {
32
+ # --bg-gradient-start: #f0f4ff;
33
+ # --bg-gradient-end: #d9e2ff;
34
+ # --sidebar-bg: #ffffff;
35
+ # --sidebar-border: #e0e0e0;
36
+ # --text-color: #333;
37
+ # --header-color: #483d8b;
38
+ # --sidebar-h3: #6a5acd;
39
+ # --chat-bg: #ffffff;
40
+ # --user-msg-bg: #6a5acd;
41
+ # --user-msg-text: white;
42
+ # --ai-msg-bg: #f0f4ff;
43
+ # --ai-msg-text: #333;
44
+ # --input-bg: #ffffff;
45
+ # --button-bg: #6a5acd;
46
+ # --button-text: white;
47
+ # --button-hover: #483d8b;
48
+ # --thinking-color: #888;
49
+ # --shadow-color: rgba(0,0,0,0.1);
50
+ # }
51
+ # body.dark-mode {
52
+ # --bg-gradient-start: #1e1e2f;
53
+ # --bg-gradient-end: #2a2a3f;
54
+ # --sidebar-bg: #2c2c3e;
55
+ # --sidebar-border: #3a3a4e;
56
+ # --text-color: #ddd;
57
+ # --header-color: #a8a8ff;
58
+ # --sidebar-h3: #a8a8ff;
59
+ # --chat-bg: #2c2c3e;
60
+ # --user-msg-bg: #4a4a7f;
61
+ # --user-msg-text: #fff;
62
+ # --ai-msg-bg: #3a3a4e;
63
+ # --ai-msg-text: #ddd;
64
+ # --input-bg: #2c2c3e;
65
+ # --button-bg: #4a4a7f;
66
+ # --button-text: #fff;
67
+ # --button-hover: #6a6a9f;
68
+ # --thinking-color: #aaa;
69
+ # --shadow-color: rgba(0,0,0,0.3);
70
+ # }
71
+ # body {
72
+ # margin: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
73
+ # background: linear-gradient(135deg, var(--bg-gradient-start), var(--bg-gradient-end));
74
+ # color: var(--text-color); display: flex; height: 100vh;
75
+ # }
76
+ # .sidebar {
77
+ # width: 250px; background: var(--sidebar-bg); border-right: 1px solid var(--sidebar-border);
78
+ # padding: 20px; box-shadow: 0 2px 10px var(--shadow-color);
79
+ # transition: width 0.3s ease;
80
+ # }
81
+ # .sidebar:hover { width: 260px; }
82
+ # .sidebar h3 { color: var(--sidebar-h3); margin-bottom: 10px; }
83
+ # .sidebar ul { list-style: none; padding: 0; }
84
+ # .sidebar li { padding: 10px; border-radius: 8px; cursor: pointer; transition: background 0.2s; }
85
+ # .sidebar li:hover { background: rgba(255,255,255,0.1); }
86
+ # .main { flex: 1; display: flex; flex-direction: column; padding: 20px; }
87
+ # .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
88
+ # .header h1 { color: var(--header-color); font-size: 24px; }
89
+ # .logo { width: 100px; height: auto; display: block; margin: 0 auto 20px auto; } /* اندازه بزرگ‌تر و مرکزی */
90
+ # .chat-area { flex: 1; overflow-y: auto; background: var(--chat-bg); border-radius: 12px; padding: 20px; box-shadow: 0 4px 20px var(--shadow-color); }
91
+ # .message { margin-bottom: 15px; padding: 12px 18px; border-radius: 20px; max-width: 70%; }
92
+ # .user-message { background: var(--user-msg-bg); color: var(--user-msg-text); align-self: flex-end; }
93
+ # .ai-message { background: var(--ai-msg-bg); color: var(--ai-msg-text); align-self: flex-start; }
94
+ # .thinking { color: var(--thinking-color); font-style: italic; opacity: 0.7; }
95
+ # .input-area { display: flex; align-items: center; margin-top: 20px; background: var(--input-bg); border-radius: 50px; padding: 10px; box-shadow: 0 2px 10px var(--shadow-color); }
96
+ # input[type="text"] { flex: 1; border: none; padding: 12px; font-size: 16px; outline: none; background: transparent; color: var(--text-color); }
97
+ # input[type="file"] { margin-left: 10px; color: var(--text-color); }
98
+ # button { background: var(--button-bg); color: var(--button-text); border: none; padding: 10px 20px; border-radius: 50px; cursor: pointer; transition: background 0.2s; }
99
+ # button:hover { background: var(--button-hover); }
100
+ # .dark-mode-toggle { cursor: pointer; font-size: 20px; }
101
+ # </style>
102
+ # </head>
103
+ # <body class="dark-mode">
104
+ # <div class="sidebar">
105
+ # <img src="/static/logo.png" alt="Logo" class="logo">
106
+ # <h3>Chats</h3>
107
+ # <ul>
108
+ # <li>+ New Chat</li>
109
+ # <li>Today</li>
110
+ # <li>Yesterday</li>
111
+ # </ul>
112
+ # </div>
113
+ # <div class="main">
114
+ # <div class="header">
115
+ # <h1>Hi User</h1>
116
+ # <div class="dark-mode-toggle" onclick="toggleDarkMode()">☀️</div>
117
+ # </div>
118
+ # <div class="chat-area" id="chat-area">
119
+ # <div class="message ai-message">How can I help you today?</div>
120
+ # </div>
121
+ # <div class="input-area">
122
+ # <input type="text" id="user-input" placeholder="Type your message...">
123
+ # <input type="file" id="file-upload">
124
+ # <button onclick="sendMessage()">Send</button>
125
+ # </div>
126
+ # </div>
127
+ # <script>
128
+ # function sendMessage() {
129
+ # const input = document.getElementById('user-input').value;
130
+ # const fileInput = document.getElementById('file-upload');
131
+ # const chatArea = document.getElementById('chat-area');
132
+
133
+ # if (input || fileInput.files.length > 0) {
134
+ # // Display user message
135
+ # const userMsg = document.createElement('div');
136
+ # userMsg.className = 'message user-message';
137
+ # userMsg.textContent = input || 'Uploaded file: ' + (fileInput.files[0]?.name || '');
138
+ # chatArea.appendChild(userMsg);
139
+
140
+ # // Prepare form data for upload
141
+ # const formData = new FormData();
142
+ # formData.append('message', input);
143
+ # if (fileInput.files.length > 0) {
144
+ # formData.append('file', fileInput.files[0]);
145
+ # }
146
+
147
+ # // Send to backend API
148
+ # fetch('/chat', {
149
+ # method: 'POST',
150
+ # body: formData
151
+ # })
152
+ # .then(response => response.json())
153
+ # .then(data => {
154
+ # if (data.thinking) {
155
+ # const thinkMsg = document.createElement('div');
156
+ # thinkMsg.className = 'message ai-message thinking';
157
+ # thinkMsg.textContent = data.thinking;
158
+ # chatArea.appendChild(thinkMsg);
159
+ # }
160
+ # const aiMsg = document.createElement('div');
161
+ # aiMsg.className = 'message ai-message';
162
+ # aiMsg.textContent = data.response;
163
+ # chatArea.appendChild(aiMsg);
164
+ # chatArea.scrollTop = chatArea.scrollHeight;
165
+ # });
166
+
167
+ # document.getElementById('user-input').value = '';
168
+ # fileInput.value = '';
169
+ # }
170
+ # }
171
+
172
+ # // Add Enter key listener
173
+ # document.getElementById('user-input').addEventListener('keydown', function(event) {
174
+ # if (event.key === 'Enter') {
175
+ # event.preventDefault();
176
+ # sendMessage();
177
+ # }
178
+ # });
179
+
180
+ # // Dark mode toggle function
181
+ # function toggleDarkMode() {
182
+ # document.body.classList.toggle('dark-mode');
183
+ # const toggle = document.querySelector('.dark-mode-toggle');
184
+ # toggle.textContent = document.body.classList.contains('dark-mode') ? '☀️' : '🌙';
185
+ # }
186
+ # </script>
187
+ # </body>
188
+ # </html>
189
+ # """
190
+
191
+ # @app.route('/')
192
+ # def index():
193
+ # return render_template_string(HTML_TEMPLATE)
194
+
195
+ # def process_file(file_obj):
196
+ # if not file_obj:
197
+ # return None
198
+ # file_path = file_obj.filename
199
+ # file_extension = os.path.splitext(file_path)[1].lower()
200
+ # try:
201
+ # if file_extension == ".pdf":
202
+ # reader = PdfReader(file_obj)
203
+ # file_text = "\n".join(page.extract_text() or "" for page in reader.pages)
204
+ # elif file_extension == ".txt":
205
+ # file_text = file_obj.read().decode('utf-8')
206
+ # else:
207
+ # raise ValueError(f"Unsupported file format: {file_extension}")
208
+
209
+ # file_docs = [Document(page_content=file_text, metadata={"source": "uploaded_file"})]
210
+ # file_splits = text_splitter.split_documents(file_docs)
211
+ # vector_store.add_documents(file_splits)
212
+ # return file_text
213
+ # except Exception as e:
214
+ # raise RuntimeError(f"Error processing file: {str(e)}")
215
+
216
+ # @app.route('/chat', methods=['POST'])
217
+ # def chat():
218
+ # user_message = request.form.get('message', '')
219
+ # uploaded_file = request.files.get('file')
220
+
221
+ # system_prompt = "You are an AI assistant developed by Holding Khalij Fars, tasked with responding to user queries accurately and helpfully."
222
+
223
+ # messages = [{"role": "system", "content": system_prompt}]
224
+ # model = "qwen/qwen3-32b"
225
+ # relevant_content = ""
226
+
227
+ # if uploaded_file:
228
+ # try:
229
+ # file_text = process_file(uploaded_file)
230
+ # if file_text:
231
+ # search_query = user_message
232
+ # retrieved_docs = vector_store.similarity_search(search_query, k=3)
233
+ # relevant_content = "\n".join(doc.page_content for doc in retrieved_docs)
234
+
235
+ # if relevant_content:
236
+ # user_message += f"\nRelevant document content: {relevant_content}"
237
+ # messages.append({"role": "user", "content": user_message})
238
+ # except Exception as e:
239
+ # messages.append({"role": "user", "content": f"Error processing file: {str(e)}. {user_message}"})
240
+ # else:
241
+ # messages.append({"role": "user", "content": user_message})
242
+
243
+ # try:
244
+ # chat_completion = client.chat.completions.create(
245
+ # messages=messages,
246
+ # model=model,
247
+ # )
248
+ # ai_response = chat_completion.choices[0].message.content
249
+
250
+ # think_parts = re.findall(r'<think>(.*?)</think>', ai_response, re.DOTALL)
251
+ # thinking = '\n'.join(think_parts).strip() if think_parts else ''
252
+ # final_response = re.sub(r'<think>.*?</think>', '', ai_response, flags=re.DOTALL).strip()
253
+ # except Exception as e:
254
+ # thinking = ''
255
+ # final_response = ''
256
+
257
+ # return jsonify({'thinking': thinking, 'response': final_response})
258
+
259
+ # if __name__ == '__main__':
260
+ # app.run(debug=True)
261
+
262
+
263
+
264
+
265
+
266
+ import gradio as gr
267
+ import os
268
+ import base64
269
+ from groq import Groq
270
+ import re
271
+ from pypdf import PdfReader
272
+ from langchain_huggingface import HuggingFaceEmbeddings
273
+ from langchain_community.vectorstores import Chroma
274
+ from langchain_core.documents import Document
275
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
276
+
277
+ client = Groq(
278
+ api_key="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",
279
+ )
280
+
281
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
282
+ vector_store = Chroma(embedding_function=embeddings, collection_name="doc_collection")
283
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
284
+ chat_history = []
285
+
286
+ def process_file(file_obj):
287
+ if not file_obj:
288
+ return None
289
+ file_path = file_obj.name
290
+ file_extension = os.path.splitext(file_path)[1].lower()
291
+ if file_extension == ".pdf":
292
+ reader = PdfReader(file_obj)
293
+ file_text = "\n".join(page.extract_text() or "" for page in reader.pages)
294
+ elif file_extension == ".txt":
295
+ file_text = file_obj.read().decode('utf-8')
296
+ else:
297
+ raise ValueError(f"Unsupported file format: {file_extension}")
298
+
299
+ file_docs = [Document(page_content=file_text, metadata={"source": "uploaded_file"})]
300
+ file_splits = text_splitter.split_documents(file_docs)
301
+ vector_store.add_documents(file_splits)
302
+ return file_text
303
+
304
+ def chat(user_message, uploaded_file):
305
+ system_prompt = "You are an AI assistant developed by Holding Khalij Fars, tasked with responding to user queries accurately and helpfully."
306
+
307
+ messages = [{"role": "system", "content": system_prompt}]
308
+ model = "qwen/qwen3-32b"
309
+ relevant_content = ""
310
+
311
+ if uploaded_file:
312
+ try:
313
+ file_text = process_file(uploaded_file)
314
+ if file_text:
315
+ search_query = user_message
316
+ retrieved_docs = vector_store.similarity_search(search_query, k=3)
317
+ relevant_content = "\n".join(doc.page_content for doc in retrieved_docs)
318
+
319
+ if relevant_content:
320
+ user_message += f"\nRelevant document content: {relevant_content}"
321
+ messages.append({"role": "user", "content": user_message})
322
+ except Exception as e:
323
+ messages.append({"role": "user", "content": f"Error processing file: {str(e)}. {user_message}"})
324
+ else:
325
+ messages.append({"role": "user", "content": user_message})
326
+
327
+ chat_completion = client.chat.completions.create(
328
+ messages=messages,
329
+ model=model,
330
+ )
331
+ ai_response = chat_completion.choices[0].message.content
332
+
333
+ think_parts = re.findall(r'<think>(.*?)</think>', ai_response, re.DOTALL)
334
+ thinking = '\n'.join(think_parts).strip() if think_parts else ''
335
+ final_response = re.sub(r'<think>.*?</think>', '', ai_response, flags=re.DOTALL).strip()
336
+
337
+ return thinking, final_response
338
+
339
+ def update_chat_history(user_input, file, thinking_output, response_output):
340
+ global chat_history
341
+ chat_history.append((user_input or f"Uploaded: {file.name if file else 'None'}", response_output))
342
+ return [(msg, resp) for msg, resp in chat_history]
343
+
344
+ def toggle_theme():
345
+ return gr.update(theme=gr.themes.Default() if gr.themes.get_default() == gr.themes.Soft() else gr.themes.Soft())
346
+
347
+ with gr.Blocks(title="Virtual AI Chat", theme=gr.themes.Soft()) as app:
348
+ with gr.Row():
349
+ with gr.Column(scale=1, min_width=250):
350
+ gr.Image("/static/logo.png", label="Logo", elem_classes=["logo"])
351
+ gr.Markdown("### Chats")
352
+ gr.State(value=["+ New Chat", "Today", "Yesterday"])
353
+ with gr.Column(scale=4):
354
+ with gr.Row():
355
+ gr.Markdown("Good afternoon, User", elem_classes=["header"])
356
+ theme_button = gr.Button("🌙", elem_classes=["dark-mode-toggle"])
357
+ chat_output = gr.Chatbot(elem_classes=["chat-area"])
358
+ with gr.Row():
359
+ user_input = gr.Textbox(placeholder="Type your message...", elem_classes=["input-area"])
360
+ file_input = gr.File(file_types=[".pdf", ".txt"], elem_classes=["input-area"])
361
+ send_button = gr.Button("Send", elem_classes=["input-area"])
362
+ thinking_output = gr.Textbox(visible=False)
363
+
364
+ theme_button.click(
365
+ fn=toggle_theme,
366
+ inputs=None,
367
+ outputs=app,
368
+ )
369
+
370
+ send_button.click(
371
+ fn=chat,
372
+ inputs=[user_input, file_input],
373
+ outputs=[thinking_output, chat_output],
374
+ ).then(
375
+ fn=update_chat_history,
376
+ inputs=[user_input, file_input, thinking_output, chat_output],
377
+ outputs=[chat_output]
378
+ )
379
+
380
+ user_input.submit(
381
+ fn=chat,
382
+ inputs=[user_input, file_input],
383
+ outputs=[thinking_output, chat_output],
384
+ ).then(
385
+ fn=update_chat_history,
386
+ inputs=[user_input, file_input, thinking_output, chat_output],
387
+ outputs=[chat_output]
388
+ )
389
+
390
+ app.launch()