michsethowusu commited on
Commit
c3d3c70
·
verified ·
1 Parent(s): ce41796

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -330
app.py CHANGED
@@ -10,50 +10,20 @@ from sentence_transformers import SentenceTransformer
10
  import faiss
11
  import json
12
  import numpy as np
13
- import os
14
- import time
15
 
16
  # Load model and index at startup
17
  print("Loading model and index...")
18
  MODEL_NAME = 'intfloat/multilingual-e5-large'
 
19
 
20
- try:
21
- model = SentenceTransformer(MODEL_NAME)
22
- print(f"Model loaded: {MODEL_NAME}")
23
-
24
- # Load FAISS index
25
- index_path = 'faiss_index.bin'
26
- if not os.path.exists(index_path):
27
- # Try to find the file with different naming
28
- for file in os.listdir('.'):
29
- if file.endswith('.bin') and 'faiss' in file.lower():
30
- index_path = file
31
- break
32
-
33
- index = faiss.read_index(index_path)
34
- print(f"FAISS index loaded with {index.ntotal} vectors")
35
-
36
- # Load metadata
37
- metadata_path = 'metadata.json'
38
- if not os.path.exists(metadata_path):
39
- # Try to find the file with different naming
40
- for file in os.listdir('.'):
41
- if file.endswith('.json') and 'metadata' in file.lower():
42
- metadata_path = file
43
- break
44
-
45
- with open(metadata_path, 'r', encoding='utf-8') as f:
46
- metadata = json.load(f)
47
-
48
- print(f"Loaded {len(metadata):,} question-answer pairs")
49
-
50
- except Exception as e:
51
- print(f"Error loading resources: {e}")
52
- # Create dummy data for demo purposes
53
- model = None
54
- index = None
55
- metadata = []
56
- print("Running in demo mode with limited functionality")
57
 
58
  def search_answers(query, top_k=1):
59
  """
@@ -66,350 +36,213 @@ def search_answers(query, top_k=1):
66
  Returns:
67
  List of top matching answers
68
  """
69
- if model is None or index is None or not metadata:
70
- # Return demo response
71
- return [{
72
- 'rank': 1,
73
- 'question': "Demo mode: System is initializing",
74
- 'answer': "Sɛ moadwendwen sɛ, twerɛ wo nsɛm bio anaasɛ san bra bio.\n\nPlease try again or rephrase your question.",
75
- 'similarity': 0.8
76
- }]
77
 
78
- try:
79
- # Encode query with E5 prefix for query encoding
80
- query_text = "query: " + query.strip()
81
- query_embedding = model.encode(
82
- [query_text],
83
- normalize_embeddings=True,
84
- show_progress_bar=False
85
- )
86
-
87
- # Search in FAISS
88
- distances, indices = index.search(query_embedding.astype('float32'), top_k)
89
-
90
- # Prepare results
91
- results = []
92
- for idx, (similarity, index_pos) in enumerate(zip(distances[0], indices[0]), 1):
93
- if 0 <= index_pos < len(metadata):
94
- item = metadata[index_pos]
95
- results.append({
96
- 'rank': idx,
97
- 'question': item.get('question', 'No question found'),
98
- 'answer': item.get('answer', 'No answer found'),
99
- 'similarity': float(similarity)
100
- })
101
-
102
- # If no results found, return a default response
103
- if not results:
104
  results.append({
105
- 'rank': 1,
106
- 'question': "No exact match found",
107
- 'answer': "Menya mmuae a ɛne wo nsɛmmisa no hyia. Yɛsrɛ wo sɛ bɔ mmɔden bio wɔ nsɛmmisa foforɔ so anaasɛ kyerɛw wo nsɛmmisa no bio wɔ Twi anaa English mu.\n\nI couldn't find an exact match. Please try a different question or rephrase your question in Twi or English.",
108
- 'similarity': 0.0
109
  })
110
-
111
- return results
112
 
113
- except Exception as e:
114
- print(f"Search error: {e}")
115
- return [{
116
- 'rank': 1,
117
- 'question': "Error in search",
118
- 'answer': "Sɛ moadwendwen sɛ, adwenemhye a ɛwɔ sistɛm mu no ama adwuma no atɔe. Yɛsrɛ wo sɛ san bɛsɛ bio.\n\nThere was an error processing your request. Please try again.",
119
- 'similarity': 0.0
120
- }]
121
 
122
- # Welcome message in Twi - FIXED: Removed extra quotes
123
  WELCOME_MESSAGE = """Akwaaba! 👋
124
 
125
  Meyɛ Twi Akwahosan Boafoɔ. Metumi aboa wo wɔ nsɛmmisa ahorow a ɛfa akwahosan ho.
126
 
127
  Bisa me nsɛmmisa biara wɔ Twi anaa English mu, na mɛma wo mmuae wɔ Twi mu.
128
 
129
- **Nhwɛsoɔ Nsɛmmisa:**
130
- - "Dɛn na menyɛ fa alcohol ho wɔ nufunom bere mu?"
131
- - "Ɛyɛ dɛn sɛ meyi nyinsɛn adi ntɛm?"
132
- - "What should I do if I have malaria?"
133
-
134
  ---
135
 
136
- _Welcome! I'm your Twi Health Assistant. I can help you with various health-related questions. Ask me anything in Twi or English, and I'll provide answers in Twi._
137
-
138
- **Example Questions:**
139
- - "What should I do about alcohol while breastfeeding?"
140
- - "How do I know if I'm pregnant early?"
141
- - "What are the symptoms of malaria?" """
142
-
143
- def user_message(user_msg, history):
144
- """Handle user message submission"""
145
- if not user_msg or user_msg.strip() == "":
146
- return "", history
147
-
148
- # Add user message to history
149
- if history is None:
150
- history = []
151
-
152
- history.append([user_msg, None])
153
- return "", history
154
-
155
- def bot_message(history):
156
- """Generate bot response"""
157
- if not history or history[-1][0] is None:
158
- return history
159
-
160
- user_msg = history[-1][0]
161
-
162
- # Get bot response
163
- results = search_answers(user_msg, top_k=1)
164
-
165
- if results:
166
- bot_response = results[0]['answer']
167
-
168
- # Add confidence indicator if similarity is low
169
- if results[0]['similarity'] < 0.3:
170
- bot_response = "**Akyiakyia:** Menya mmuae a ɛne wo nsɛmmisa no hyia koraa no. Saa nti, me de mmuae a ɛte saa na ɛbɛtumi aboa wo.\n\n" + bot_response
171
- else:
172
- bot_response = "Menya mmuae biara a ɛne wo nsɛmmisa no hyia. Yɛsrɛ wo sɛ bɔ mmɔden bio wɔ nsɛmmisa foforɔ so anaa kyerɛw wo nsɛmmisa no bio.\n\n_I couldn't find an answer to your question. Please try rephrasing or asking a different question._"
173
-
174
- history[-1][1] = bot_response
175
- return history
176
-
177
- def clear_chat():
178
- """Reset chat to welcome message"""
179
- return [[None, WELCOME_MESSAGE]]
180
 
181
  # Create Gradio interface with ChatGPT style
182
  with gr.Blocks(
 
183
  theme=gr.themes.Soft(
184
  primary_hue="purple",
185
  secondary_hue="blue",
186
- font=["Inter", "system-ui", "sans-serif"]
187
  ),
188
- title="Twi Akwahosan Boafoɔ | Twi Health Assistant",
189
- css="""
190
- #chatbot {
191
- min-height: 400px;
192
- max-height: 600px;
193
- overflow-y: auto;
194
- border: 1px solid #e0e0e0;
195
- border-radius: 10px;
196
- padding: 15px;
197
- background: #f9f9f9;
198
- }
199
-
200
- .message {
201
- padding: 12px 16px;
202
- border-radius: 18px;
203
- margin: 8px 0;
204
- max-width: 80%;
205
- }
206
-
207
- .user-message {
208
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
209
- color: white;
210
- margin-left: auto;
211
- }
212
-
213
- .bot-message {
214
- background: #ffffff;
215
- border: 1px solid #e0e0e0;
216
- color: #333;
217
- }
218
-
219
- .input-container {
220
- border-top: 1px solid #e0e0e0;
221
- padding-top: 20px;
222
- margin-top: 20px;
223
- }
224
-
225
- .header {
226
- text-align: center;
227
- padding: 20px;
228
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
229
- color: white;
230
- border-radius: 12px;
231
- margin-bottom: 20px;
232
- }
233
-
234
- .footer {
235
- text-align: center;
236
- margin-top: 20px;
237
- padding: 10px;
238
- color: #666;
239
- font-size: 0.9em;
240
- border-top: 1px solid #e0e0e0;
241
- }
242
-
243
- .examples {
244
- background: #f0f0f0;
245
- padding: 15px;
246
- border-radius: 10px;
247
- margin: 10px 0;
248
- }
249
-
250
- .example-btn {
251
- margin: 5px;
252
- background: #e0e0e0;
253
- border: none;
254
- border-radius: 20px;
255
- padding: 5px 15px;
256
- cursor: pointer;
257
- transition: background 0.3s;
258
- }
259
-
260
- .example-btn:hover {
261
- background: #d0d0d0;
262
- }
263
- """
264
  ) as demo:
265
 
266
  # Header
267
  gr.HTML("""
268
- <div class="header">
269
- <h1 style="margin:0; font-size: 2em; color: white;">🏥 Twi Akwahosan Boafoɔ</h1>
270
- <p style="margin:10px 0 0 0; opacity: 0.9; color: white;">Twi Health Information Assistant</p>
271
- <p style="margin:5px 0 0 0; font-size: 0.9em; opacity: 0.8; color: white;">
272
- Ask health questions in any language, get answers in Twi
273
- </p>
274
  </div>
275
  """)
276
 
277
- # Chatbot interface
278
  chatbot = gr.Chatbot(
279
  value=[[None, WELCOME_MESSAGE]],
280
  elem_id="chatbot",
281
  label="",
282
  show_label=False,
283
- height=500
 
284
  )
285
 
286
- # Chat input section
287
  with gr.Row():
288
- with gr.Column(scale=9):
289
- msg = gr.Textbox(
290
- placeholder="Kyerɛw wo nsɛmmisa wɔ ha... | Type your question here...",
291
- show_label=False,
292
- container=False,
293
- lines=2,
294
- elem_id="chat-input"
295
- )
296
- with gr.Column(scale=1):
297
- submit_btn = gr.Button("📤", variant="primary", size="lg")
298
 
299
- # Control buttons
300
  with gr.Row():
301
- clear_btn = gr.Button("🗑️ Firi Aseɛ Bio", variant="secondary")
302
- gr.HTML('<div style="flex-grow: 1;"></div>')
303
- gr.Markdown("**System Status:** 🟢 Ready" if model else "**System Status:** 🟡 Limited Mode")
304
 
305
- # Example questions
306
  with gr.Accordion("📝 Nhwɛsoɔ Nsɛmmisa | Example Questions", open=False):
307
- examples_html = """
308
- <div class="examples">
309
- <p><strong>Click any example to try:</strong></p>
310
- <div style="display: flex; flex-wrap: wrap; gap: 8px;">
311
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
- example_questions = [
314
- "Dɛn na menyɛ fa alcohol honufunom bere mu?",
315
- "Ɛyɛ dɛn meyi nyinsɛn adi ntɛm?",
316
- "Mɛnya ambulance service frɛ nɔma no?",
317
- "What should I do if I have malaria?",
318
- "Dɛn na memfa ahwɛ me tirim yadeɛ?",
319
- "How do I take care of a newborn baby?",
320
- "Nsuo dodow bɛn na ɛsɛ sɛ menom da biara?",
321
- "Pregnancy symptoms in first month",
322
- "Breastfeeding tips for new mothers",
323
- "Postpartum depression symptoms"
324
- ]
325
 
326
- for i, question in enumerate(example_questions):
327
- # Escape single quotes and backticks for JavaScript
328
- safe_question = question.replace("'", "\\'").replace("`", "\\`")
329
- examples_html += f'<button class="example-btn" onclick="document.querySelector(\'#chat-input textarea\').value = \'{safe_question}\'; document.querySelector(\'#chat-input textarea\').dispatchEvent(new Event(\'input\', {{bubbles: true}}));">{question[:40]}{"..." if len(question) > 40 else ""}</button>'
330
 
331
- examples_html += "</div></div>"
332
- gr.HTML(examples_html)
333
-
334
- # Information section
335
- with gr.Accordion("ℹ️ Nkyerɛkyerɛmu | Information", open=False):
336
- info_text = f"""
337
- ### 📊 Technical Information
338
 
339
- - **Embedding Model**: Multilingual E5-Large
340
- - **Search Engine**: FAISS vector database
341
- - **Index Size**: {len(metadata):,} Q&A pairs
342
- - **Supported Languages**: 100+ languages including Twi, English, Ga, Ewe, Hausa
343
 
344
- ### 🔒 Privacy & Security
345
 
346
- - Your questions are processed in real-time
347
- - No data is stored permanently
348
- - All processing happens on the server
349
 
350
- ### ⚠️ Important Notice
351
 
352
- **Disclaimer**: This system provides health information for educational purposes only. Always consult with qualified healthcare professionals for medical advice.
353
 
354
- **For emergencies**: Please call 112 (Ghana emergency number) or visit the nearest hospital.
355
- """
356
- gr.Markdown(info_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
 
358
- # Footer
359
- gr.HTML("""
360
- <div class="footer">
361
- <p>🇬🇭 Built for the Ghanaian Community | Powered by Multilingual E5 & FAISS</p>
362
- <p style="font-size: 0.8em; margin-top: 5px;">
363
- <em>"Akwaaba" means "Welcome" in Twi | Medaase pa ara! 🙏</em>
364
- </p>
365
- </div>
366
- """)
367
 
368
- # Event handlers with proper queue management
369
- msg.submit(
370
- fn=user_message,
371
- inputs=[msg, chatbot],
372
- outputs=[msg, chatbot],
373
- queue=True
374
- ).then(
375
- fn=bot_message,
376
- inputs=[chatbot],
377
- outputs=[chatbot],
378
- queue=True
379
  )
380
 
381
- submit_btn.click(
382
- fn=user_message,
383
- inputs=[msg, chatbot],
384
- outputs=[msg, chatbot],
385
- queue=True
386
- ).then(
387
- fn=bot_message,
388
- inputs=[chatbot],
389
- outputs=[chatbot],
390
- queue=True
391
  )
392
 
393
- clear_btn.click(
394
- fn=clear_chat,
395
- inputs=None,
396
- outputs=[chatbot],
397
- queue=True
398
- )
 
 
 
399
 
400
- # Launch the app with proper settings for Hugging Face Spaces
401
  if __name__ == "__main__":
402
- # Check if running in Hugging Face Spaces
403
- is_spaces = os.getenv('SPACE_ID') is not None
404
-
405
- # Launch with appropriate settings - FIXED: Set share=True for HF Spaces
406
- demo.launch(
407
- server_name="0.0.0.0",
408
- server_port=7860,
409
- share=True, # Enable share to avoid localhost issues
410
- show_error=True,
411
- debug=False,
412
- show_api=False, # Disable API to avoid JSON schema issues
413
- quiet=True, # Reduce console output
414
- enable_queue=True # Enable queue for better stability
415
- )
 
10
  import faiss
11
  import json
12
  import numpy as np
 
 
13
 
14
  # Load model and index at startup
15
  print("Loading model and index...")
16
  MODEL_NAME = 'intfloat/multilingual-e5-large'
17
+ model = SentenceTransformer(MODEL_NAME)
18
 
19
+ # Load FAISS index
20
+ index = faiss.read_index('faiss_index.bin')
21
+
22
+ # Load metadata
23
+ with open('metadata.json', 'r', encoding='utf-8') as f:
24
+ metadata = json.load(f)
25
+
26
+ print(f"Loaded {len(metadata):,} question-answer pairs")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  def search_answers(query, top_k=1):
29
  """
 
36
  Returns:
37
  List of top matching answers
38
  """
39
+ # Encode query with E5 prefix for query encoding
40
+ query_text = "query: " + query.strip()
41
+ query_embedding = model.encode(
42
+ [query_text],
43
+ normalize_embeddings=True
44
+ )
 
 
45
 
46
+ # Search in FAISS
47
+ distances, indices = index.search(query_embedding.astype('float32'), top_k)
48
+
49
+ # Prepare results
50
+ results = []
51
+ for idx, (similarity, index_pos) in enumerate(zip(distances[0], indices[0]), 1):
52
+ if index_pos < len(metadata):
53
+ item = metadata[index_pos]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  results.append({
55
+ 'rank': idx,
56
+ 'question': item['question'],
57
+ 'answer': item['answer'],
58
+ 'similarity': float(similarity)
59
  })
 
 
60
 
61
+ return results
 
 
 
 
 
 
 
62
 
63
+ # Welcome message in Twi
64
  WELCOME_MESSAGE = """Akwaaba! 👋
65
 
66
  Meyɛ Twi Akwahosan Boafoɔ. Metumi aboa wo wɔ nsɛmmisa ahorow a ɛfa akwahosan ho.
67
 
68
  Bisa me nsɛmmisa biara wɔ Twi anaa English mu, na mɛma wo mmuae wɔ Twi mu.
69
 
 
 
 
 
 
70
  ---
71
 
72
+ _Welcome! I'm your Twi Health Assistant. I can help you with various health-related questions. Ask me anything in Twi or English, and I'll provide answers in Twi._"""
73
+
74
+ # Create custom CSS for ChatGPT-like appearance
75
+ custom_css = """
76
+ #chatbot {
77
+ height: 600px;
78
+ overflow-y: auto;
79
+ }
80
+
81
+ .message {
82
+ padding: 12px 16px !important;
83
+ border-radius: 18px !important;
84
+ margin: 8px 0 !important;
85
+ }
86
+
87
+ #input-box textarea {
88
+ border-radius: 24px !important;
89
+ }
90
+
91
+ .contain {
92
+ max-width: 900px !important;
93
+ margin: auto !important;
94
+ }
95
+
96
+ footer {
97
+ display: none !important;
98
+ }
99
+
100
+ .chat-header {
101
+ text-align: center;
102
+ padding: 20px;
103
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
104
+ color: white;
105
+ border-radius: 12px;
106
+ margin-bottom: 20px;
107
+ }
108
+ """
 
 
 
 
 
 
 
109
 
110
  # Create Gradio interface with ChatGPT style
111
  with gr.Blocks(
112
+ css=custom_css,
113
  theme=gr.themes.Soft(
114
  primary_hue="purple",
115
  secondary_hue="blue",
116
+ font=gr.themes.GoogleFont("Inter")
117
  ),
118
+ title="Twi Akwahosan Boafoɔ | Twi Health Assistant"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  ) as demo:
120
 
121
  # Header
122
  gr.HTML("""
123
+ <div class="chat-header">
124
+ <h1 style="margin:0; font-size: 2em;">🏥 Twi Akwahosan Boafoɔ</h1>
125
+ <p style="margin:10px 0 0 0; opacity: 0.9;">Twi Health Information Assistant</p>
 
 
 
126
  </div>
127
  """)
128
 
129
+ # Chatbot interface - simplified without avatar_images to avoid bug
130
  chatbot = gr.Chatbot(
131
  value=[[None, WELCOME_MESSAGE]],
132
  elem_id="chatbot",
133
  label="",
134
  show_label=False,
135
+ bubble_full_width=False,
136
+ height=600
137
  )
138
 
139
+ # Input section
140
  with gr.Row():
141
+ msg = gr.Textbox(
142
+ placeholder="Kyerɛw wo nsɛmmisa wɔ ha... | Type your question here...",
143
+ show_label=False,
144
+ scale=9,
145
+ container=False,
146
+ elem_id="input-box"
147
+ )
148
+ submit_btn = gr.Button("📤", scale=1, variant="primary", size="lg")
 
 
149
 
150
+ # Clear button
151
  with gr.Row():
152
+ clear_btn = gr.Button("🗑️ Firi Aseɛ Bio | Start New Chat", size="sm")
 
 
153
 
154
+ # Example questions section
155
  with gr.Accordion("📝 Nhwɛsoɔ Nsɛmmisa | Example Questions", open=False):
156
+ gr.Examples(
157
+ examples=[
158
+ ["Dɛn na menyɛ fa alcohol ho wɔ nufunom bere mu?"],
159
+ ["Ɛyɛ dɛn meyi nyinsɛn adi ntɛm?"],
160
+ ["Mɛnya ambulance service frɛ nɔma no?"],
161
+ ["What should I do if I have malaria?"],
162
+ ["Dɛn na memfa ahwɛ me tirim yadeɛ?"],
163
+ ["How do I take care of a newborn baby?"],
164
+ ["Nsuo dodow bɛn na ɛsɛ sɛ menom da biara?"],
165
+ ],
166
+ inputs=msg,
167
+ label=""
168
+ )
169
+
170
+ # Information section
171
+ with gr.Accordion("ℹ️ Nkyerɛkyerɛmu | About This Assistant", open=False):
172
+ gr.Markdown("""
173
+ ### Sɛdeɛ Ɛyɛ Adwuma | How It Works
174
 
175
+ 1. **Kyerɛw wo nsɛmmisa** wɔ Twi anaa English mu
176
+ 2. **Sistɛm no bɛhwehwɛ** nsɛmmisa a ɛne wo de no hyia database no mu
177
+ 3. **Wonya mmuae** Twi mu ntɛm ara
 
 
 
 
 
 
 
 
 
178
 
179
+ ### 📊 Technical Details
 
 
 
180
 
181
+ - **Model**: Multilingual E5-Large (Semantic Search)
182
+ - **Database**: Health Q&A pairs in Twi
183
+ - **Retrieval**: FAISS vector similarity search
184
+ - **Languages**: Primarily Twi, with English support
 
 
 
185
 
186
+ ### 🔒 Ahobammɔ | Privacy
 
 
 
187
 
188
+ Wo nsɛmmisa ahorow no yɛ ahobammɔ na wɔmfa nkora so.
189
 
190
+ _Your questions are private and not stored permanently._
 
 
191
 
192
+ ### ⚠️ Kɔkɔbɔ | Important Notice
193
 
194
+ ɛyɛ emergency anaa yadeɛ a emu den a, ayaresabea anaa frɛ dokta.
195
 
196
+ _For emergencies or serious health conditions, please visit a hospital or call a doctor._
197
+ """)
198
+
199
+ # Event handlers
200
+ def user_message(user_msg, history):
201
+ """Handle user message submission"""
202
+ return "", history + [[user_msg, None]]
203
+
204
+ def bot_message(history):
205
+ """Generate bot response"""
206
+ if history[-1][1] is not None:
207
+ return history
208
+
209
+ user_msg = history[-1][0]
210
+
211
+ # Get bot response
212
+ results = search_answers(user_msg, top_k=1)
213
+
214
+ if results and results[0]['similarity'] > 0.3:
215
+ bot_response = results[0]['answer']
216
+ else:
217
+ bot_response = "Menya mmuae biara a ɛne wo nsɛmmisa no hyia. Yɛsrɛ wo sɛ bɔ mmɔden bio wɔ nsɛmmisa foforɔ so anaa kyerɛw wo nsɛmmisa no bio.\n\n_Menya mmuae a ɛne wo nsɛmmisa no hyia. Sɛ wobɛtumi akyerɛw wo nsɛmmisa no bio anaa bisa nsɛmmisa foforɔ a, ɛbɛboa._"
218
+
219
+ history[-1][1] = bot_response
220
+ return history
221
 
222
+ def clear_chat():
223
+ """Reset chat to welcome message"""
224
+ return [[None, WELCOME_MESSAGE]]
 
 
 
 
 
 
225
 
226
+ # Wire up events
227
+ msg.submit(user_message, [msg, chatbot], [msg, chatbot], queue=False).then(
228
+ bot_message, chatbot, chatbot
 
 
 
 
 
 
 
 
229
  )
230
 
231
+ submit_btn.click(user_message, [msg, chatbot], [msg, chatbot], queue=False).then(
232
+ bot_message, chatbot, chatbot
 
 
 
 
 
 
 
 
233
  )
234
 
235
+ clear_btn.click(clear_chat, None, chatbot, queue=False)
236
+
237
+ # Footer
238
+ gr.Markdown("""
239
+ ---
240
+ <div style="text-align: center; color: #666; font-size: 0.9em;">
241
+ <p>Powered by Multilingual E5 & FAISS | Yɛde Twi kasa reba anim 🇬🇭</p>
242
+ </div>
243
+ """)
244
 
245
+ # Launch the app
246
  if __name__ == "__main__":
247
+ demo.queue()
248
+ demo.launch()