waleedmohd commited on
Commit
f18ee53
·
verified ·
1 Parent(s): 6db1c75

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -335
app.py CHANGED
@@ -1,363 +1,99 @@
1
  import gradio as gr
2
- import re
3
- import json
4
- import time
5
- from datetime import datetime
6
 
7
- # Simple language detection function
8
- def simple_detect_language(text):
9
- arabic_pattern = re.compile(r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF]+')
10
- if arabic_pattern.search(text):
11
- return "ar"
12
- return "en"
13
 
14
- # Try to import transformers for Arabic NLP
15
- try:
16
- from transformers import pipeline
17
- arabic_nlp = pipeline("text-classification", model="papluca/xlm-roberta-base-language-detection")
18
- ARABIC_NLP_AVAILABLE = True
19
-
20
- def detect_language_with_nlp(text):
21
- result = arabic_nlp(text)
22
- return result[0]['label']
23
- except ImportError:
24
- ARABIC_NLP_AVAILABLE = False
25
-
26
- # Import customer service enhancements
27
- try:
28
- from customer_service_enhancements import (
29
- ENHANCED_CUSTOMER_SERVICE_PHRASES_AR,
30
- ENHANCED_CUSTOMER_SERVICE_PHRASES_EN,
31
- BANKING_FAQS_AR,
32
- BANKING_FAQS_EN,
33
- BANKING_GLOSSARY_AR,
34
- BANKING_GLOSSARY_EN,
35
- get_enhanced_response,
36
- handle_banking_faq,
37
- offer_satisfaction_survey,
38
- get_banking_term_definition
39
- )
40
- CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE = True
41
- except ImportError:
42
- CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE = False
43
- ENHANCED_CUSTOMER_SERVICE_PHRASES_AR = {
44
- "greeting": ["مرحبًا بك في بنك أم درمان الوطني! كيف يمكنني مساعدتك اليوم؟"],
45
- "thanks": ["شكرًا لتواصلك مع بنك أم درمان الوطني!"],
46
- "follow_up": ["هل هناك خدمة أخرى يمكنني مساعدتك بها؟"]
47
- }
48
- ENHANCED_CUSTOMER_SERVICE_PHRASES_EN = {
49
- "greeting": ["Welcome to Omdurman National Bank! How may I assist you today?"],
50
- "thanks": ["Thank you for contacting Omdurman National Bank!"],
51
- "follow_up": ["Is there anything else I can help you with?"]
52
- }
53
 
54
  # Omdurman National Bank-specific guidelines
55
- ONB_GUIDELINES_AR = {
56
  "balance": "يمكنك التحقق من رصيدك عبر الإنترنت أو عبر تطبيق الهاتف الخاص ببنك أم درمان الوطني.",
57
  "lost_card": "في حالة فقدان البطاقة، اتصل بالرقم 249-123-456-789 فورًا.",
58
  "loan": "شروط القرض تشمل الحد الأدنى للدخل (5000 جنيه سوداني) وتاريخ ائتماني جيد.",
59
  "transfer": "لتحويل الأموال، استخدم تطبيق الهاتف أو الخدمة المصرفية عبر الإنترنت.",
60
  "new_account": "لفتح حساب جديد، قم بزيارة أقرب فرع مع جواز سفرك أو هويتك الوطنية.",
61
  "interest_rates": "أسعار الفائدة على الودائع تتراوح بين 5% إلى 10% سنويًا.",
62
- "branches": "فروعنا موجودة في أم درمان، الخرطوم، وبورتسودان.",
63
  "working_hours": "ساعات العمل من 8 صباحًا إلى 3 مساءً من الأحد إلى الخميس.",
64
  "contact": "الاتصال بنا على الرقم 249-123-456-789 أو عبر البريد الإلكتروني [email protected]."
65
  }
66
 
67
- ONB_GUIDELINES_EN = {
68
- "balance": "You can check your balance online or via the ONB mobile app.",
69
- "lost_card": "In case of a lost card, call 249-123-456-789 immediately.",
70
- "loan": "Loan requirements include minimum income (5000 SDG) and good credit history.",
71
- "transfer": "To transfer funds, use the mobile app or online banking service.",
72
- "new_account": "To open a new account, visit your nearest branch with your passport or national ID.",
73
- "interest_rates": "Interest rates on deposits range from 5% to 10% annually.",
74
- "branches": "Our branches are located in Omdurman, Khartoum, and Port Sudan.",
75
- "working_hours": "Working hours are from 8 AM to 3 PM, Sunday to Thursday.",
76
- "contact": "Contact us at 249-123-456-789 or via email at [email protected]."
 
77
  }
78
 
79
- # Quick action buttons
80
- QUICK_ACTIONS_AR = [
81
- {"text": "تحقق من الرصيد", "intent": "balance"},
82
- {"text": "الإبلاغ عن بطاقة مفقودة", "intent": "lost_card"},
83
- {"text": "معلومات القرض", "intent": "loan"},
84
- {"text": "تحويل الأموال", "intent": "transfer"},
85
- {"text": "فتح حساب جديد", "intent": "new_account"},
86
- {"text": "أسعار الفائدة", "intent": "interest_rates"},
87
- {"text": "مواقع الفروع", "intent": "branches"},
88
- {"text": "ساعات العمل", "intent": "working_hours"},
89
- {"text": "اتصل بنا", "intent": "contact"}
90
- ]
91
-
92
- QUICK_ACTIONS_EN = [
93
- {"text": "Check Balance", "intent": "balance"},
94
- {"text": "Report Lost Card", "intent": "lost_card"},
95
- {"text": "Loan Information", "intent": "loan"},
96
- {"text": "Transfer Funds", "intent": "transfer"},
97
- {"text": "Open New Account", "intent": "new_account"},
98
- {"text": "Interest Rates", "intent": "interest_rates"},
99
- {"text": "Branch Locations", "intent": "branches"},
100
- {"text": "Working Hours", "intent": "working_hours"},
101
- {"text": "Contact Us", "intent": "contact"}
102
- ]
103
-
104
- # Function to get a random phrase
105
- def get_random_phrase(category, language):
106
- import random
107
- if language == "ar":
108
- return random.choice(ENHANCED_CUSTOMER_SERVICE_PHRASES_AR[category])
109
- else:
110
- return random.choice(ENHANCED_CUSTOMER_SERVICE_PHRASES_EN[category])
111
 
112
  def classify_intent(message: str):
113
- menu_keywords = ["menu", "options", "help", "قائمة", "خيارات", "مساعدة"]
114
- message_lower = message.lower()
115
-
116
- for keyword in menu_keywords:
117
- if keyword in message_lower:
118
- return "menu"
119
-
120
- for intent_key, keywords in INTENT_KEYWORDS.items():
121
- for keyword in keywords:
122
- if keyword.lower() in message_lower:
123
- return intent_key
124
-
125
- return "unknown"
126
 
127
- # Function to log customer interactions
128
- def log_interaction(user_message, bot_response, intent, language):
129
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
130
- log_entry = {
131
- "timestamp": timestamp,
132
- "user_message": user_message,
133
- "bot_response": bot_response,
134
- "intent": intent,
135
- "language": language
136
- }
137
-
138
- try:
139
- with open("interaction_logs.jsonl", "a") as f:
140
- f.write(json.dumps(log_entry) + "\n")
141
- except Exception as e:
142
- print(f"Error logging interaction: {e}")
143
-
144
- # Function to generate responses
145
  def respond(message: str):
146
- if not message.strip():
147
- return {
148
- "ar": "الرجاء كتابة سؤالك.",
149
- "en": "Please type your question."
150
- }
151
-
152
  # Detect language
153
- if ARABIC_NLP_AVAILABLE:
154
- language = detect_language_with_nlp(message)
155
- if language != "ar" and language != "en":
156
- language = "en"
157
- else:
158
- language = simple_detect_language(message)
159
-
160
- # Classify intent
161
- intent = classify_intent(message)
162
-
163
- # Prepare responses
164
- responses = {
165
- "ar": "",
166
- "en": ""
167
- }
168
 
169
- # Handle menu request
170
- if intent == "menu":
171
- responses["ar"] = MENU_AR
172
- responses["en"] = MENU_EN
173
- log_interaction(message, responses[language], "menu", language)
174
- return responses
175
 
176
- # Handle banking FAQ
177
- if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
178
- faq_answer = handle_banking_faq(message, language)
179
- if faq_answer:
180
- responses["ar"] = f"{get_random_phrase('greeting', 'ar')}<br><br>{faq_answer}<br><br>{get_random_phrase('follow_up', 'ar')}"
181
- responses["en"] = f"{get_random_phrase('greeting', 'en')}<br><br>{faq_answer}<br><br>{get_random_phrase('follow_up', 'en')}"
182
- log_interaction(message, responses[language], "faq", language)
183
- return responses
184
-
185
- # Handle banking term definition
186
- if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
187
- term_definition = get_banking_term_definition(message, language)
188
- if term_definition:
189
- responses["ar"] = f"{get_random_phrase('greeting', 'ar')}<br><br>{term_definition}<br><br>{get_random_phrase('follow_up', 'ar')}"
190
- responses["en"] = f"{get_random_phrase('greeting', 'en')}<br><br>{term_definition}<br><br>{get_random_phrase('follow_up', 'en')}"
191
- log_interaction(message, responses[language], "term", language)
192
- return responses
193
 
194
- # Handle recognized intents
195
  if intent != "unknown":
196
- if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
197
- responses["ar"] = get_enhanced_response(intent, "ar")
198
- responses["en"] = get_enhanced_response(intent, "en")
199
- else:
200
- responses["ar"] = f"{get_random_phrase('greeting', 'ar')}<br><br>{ONB_GUIDELINES_AR.get(intent, 'عذرًا، لم يتم التعرف على الخيار المحدد.')}<br><br>{get_random_phrase('follow_up', 'ar')}"
201
- responses["en"] = f"{get_random_phrase('greeting', 'en')}<br><br>{ONB_GUIDELINES_EN.get(intent, 'Sorry, the selected option was not recognized.')}<br><br>{get_random_phrase('follow_up', 'en')}"
202
- else:
203
- responses["ar"] = "عذرًا، لم أفهم سؤالك. إليك قائمة بالخدمات المتاحة:" + MENU_AR
204
- responses["en"] = "Sorry, I didn't understand your question. Here's a menu of available services:" + MENU_EN
205
-
206
- log_interaction(message, responses[language], intent, language)
207
- return responses
208
-
209
- # Function to handle message submission
210
- def on_submit(message, chat_history, lang, name):
211
- if not message.strip():
212
- return "", chat_history, name
213
-
214
- # Check if this is a name introduction
215
- name_patterns = [
216
- r"my name is (\w+)",
217
- r"i am (\w+)",
218
- r"i'm (\w+)",
219
- r"اسمي (\w+)",
220
- r"أنا (\w+)"
221
- ]
222
-
223
- for pattern in name_patterns:
224
- match = re.search(pattern, message.lower())
225
- if match:
226
- name = match.group(1)
227
- break
228
-
229
- # Add user message to chat history
230
- chat_history = chat_history + [[message, None]]
231
-
232
- # Get response
233
- responses = respond(message)
234
-
235
- # Select response based on language
236
- response = responses[lang]
237
-
238
- # Personalize response if name is available
239
- if name and CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
240
- if lang == "ar":
241
- response = response.replace("مرحبًا", f"مرحبًا {name}")
242
- else:
243
- response = response.replace("Welcome", f"Welcome {name}")
244
- response = response.replace("Hello", f"Hello {name}")
245
-
246
- # Update bot response in chat history
247
- chat_history[-1][1] = response
248
-
249
- return "", chat_history, name
250
-
251
- # Function to show menu
252
- def show_menu(chat_history, lang):
253
- menu_responses = {
254
- "ar": MENU_AR,
255
- "en": MENU_EN
256
- }
257
-
258
- # Get menu text
259
- menu_text = menu_responses[lang]
260
-
261
- # Add system message showing the menu
262
- chat_history = chat_history + [[None, menu_text.replace("\n", "<br>")]]
263
-
264
- return chat_history
265
-
266
- # Function to connect to live agent
267
- def connect_to_live_agent(chat_history, lang):
268
- message = "Connecting to a live customer service agent. Please wait a moment..." if lang == "en" else "جاري الاتصال بوكيل خدمة العملاء. يرجى الانتظار لحظة..."
269
- chat_history = chat_history + [[None, message]]
270
- return chat_history
271
-
272
- # Function to show satisfaction survey
273
- def show_satisfaction_survey(chat_history, lang):
274
- if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
275
- survey_html = offer_satisfaction_survey(lang)
276
- chat_history = chat_history + [[None, survey_html]]
277
- else:
278
- # Simple survey message if enhancements not available
279
- title = "استطلاع رضا العملاء" if lang == "ar" else "Customer Satisfaction Survey"
280
- message = f"<div class='satisfaction-survey'><h3>{title}</h3><p>{'نشكرك على استخدام المساعد المصرفي الافتراضي!' if lang == 'ar' else 'Thank you for using our virtual banking assistant!'}</p></div>"
281
- chat_history = chat_history + [[None, message]]
282
-
283
- return chat_history
284
-
285
- # Function to reset chat
286
- def reset_chat():
287
- return [], None # Clear chat history and reset user name
288
-
289
- # Function to initialize chat with welcome message
290
- def init_chat():
291
- welcome_ar = "مرحبًا بك في المساعد المصرفي الافتراضي لبنك أم درمان الوطني! يمكنك طرح أي سؤال حول خدماتنا المصرفية أو استخدام أزرار الإجراءات السريعة أدناه."
292
- welcome_en = "Welcome to Omdurman National Bank Virtual Banking Assistant! You can ask any question about our banking services or use the quick action buttons below."
293
-
294
- # Initialize chat with welcome messages
295
- chat_history = []
296
- chat_history.append([None, welcome_ar])
297
- chat_history.append([None, welcome_en])
298
-
299
- return chat_history
300
-
301
- # Gradio Interface
302
- with gr.Blocks() as demo:
303
- selected_lang = gr.State(value="ar")
304
- user_name = gr.State(value=None)
305
-
306
- with gr.Row():
307
- gr.Markdown("# Omdurman National Bank Virtual Assistant")
308
-
309
- with gr.Row():
310
- language_btn = gr.Radio(["العربية", "English"], value="العربية", label="Language")
311
-
312
- chatbot = gr.Chatbot(height=400, type="messages") # Updated to use the new format
313
-
314
- with gr.Row():
315
- text_input = gr.Textbox(placeholder="Type your question here", label="")
316
- submit_btn = gr.Button("Send", variant="primary")
317
-
318
- with gr.Row():
319
- menu_btn = gr.Button("Show Menu")
320
- live_agent_btn = gr.Button("Connect to Live Agent")
321
- survey_btn = gr.Button("Feedback")
322
- reset_btn = gr.Button("Reset Chat")
323
-
324
- # Link inputs and buttons to response functions
325
- submit_btn.click(
326
- fn=on_submit,
327
- inputs=[text_input, chatbot, selected_lang, user_name],
328
- outputs=[text_input, chatbot, user_name]
329
- )
330
-
331
- menu_btn.click(
332
- fn=show_menu,
333
- inputs=[chatbot, selected_lang],
334
- outputs=[chatbot]
335
- )
336
-
337
- live_agent_btn.click(
338
- fn=connect_to_live_agent,
339
- inputs=[chatbot, selected_lang],
340
- outputs=[chatbot]
341
- )
342
-
343
- survey_btn.click(
344
- fn=show_satisfaction_survey,
345
- inputs=[chatbot, selected_lang],
346
- outputs=[chatbot]
347
- )
348
-
349
- reset_btn.click(
350
- fn=reset_chat,
351
- inputs=[],
352
- outputs=[chatbot, user_name]
353
- )
354
-
355
- # Initialize chat
356
- demo.load(
357
- fn=init_chat,
358
- inputs=[],
359
- outputs=[chatbot]
360
- )
361
 
362
  if __name__ == "__main__":
363
- demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
 
 
 
 
 
1
  import gradio as gr
2
+ from transformers import pipeline
 
 
 
3
 
4
+ # Load Arabic NLP model for intent classification
5
+ intent_classifier = pipeline("text-classification", model="aubmindlab/bert-base-arabertv02")
 
 
 
 
6
 
7
+ # Load language detection model
8
+ language_detector = pipeline("text-classification", model="papluca/xlm-roberta-base-language-detection")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # Omdurman National Bank-specific guidelines
11
+ ONB_GUIDELINES = {
12
  "balance": "يمكنك التحقق من رصيدك عبر الإنترنت أو عبر تطبيق الهاتف الخاص ببنك أم درمان الوطني.",
13
  "lost_card": "في حالة فقدان البطاقة، اتصل بالرقم 249-123-456-789 فورًا.",
14
  "loan": "شروط القرض تشمل الحد الأدنى للدخل (5000 جنيه سوداني) وتاريخ ائتماني جيد.",
15
  "transfer": "لتحويل الأموال، استخدم تطبيق الهاتف أو الخدمة المصرفية عبر الإنترنت.",
16
  "new_account": "لفتح حساب جديد، قم بزيارة أقرب فرع مع جواز سفرك أو هويتك الوطنية.",
17
  "interest_rates": "أسعار الفائدة على الودائع تتراوح بين 5% إلى 10% سنويًا.",
18
+ "branches": "فروعنا موجودة في أم درمان، الخرطوم، وبورتسودان. زيارة موقعنا للتفاصيل.",
19
  "working_hours": "ساعات العمل من 8 صباحًا إلى 3 مساءً من الأحد إلى الخميس.",
20
  "contact": "الاتصال بنا على الرقم 249-123-456-789 أو عبر البريد الإلكتروني [email protected]."
21
  }
22
 
23
+ # Map intents to responses
24
+ INTENT_TO_RESPONSE = {
25
+ "balance": "balance",
26
+ "lost_card": "lost_card",
27
+ "loan": "loan",
28
+ "transfer": "transfer",
29
+ "new_account": "new_account",
30
+ "interest_rates": "interest_rates",
31
+ "branches": "branches",
32
+ "working_hours": "working_hours",
33
+ "contact": "contact"
34
  }
35
 
36
+ def detect_language(text):
37
+ # Use Hugging Face language detection model
38
+ result = language_detector(text)
39
+ language = result[0]['label']
40
+ return language
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  def classify_intent(message: str):
43
+ # Use NLP model to classify the user's intent
44
+ result = intent_classifier(message)
45
+ intent = result[0]['label']
46
+ return INTENT_TO_RESPONSE.get(intent, "unknown")
 
 
 
 
 
 
 
 
 
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  def respond(message: str):
 
 
 
 
 
 
49
  # Detect language
50
+ language = detect_language(message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ # If the language is not Arabic, return a default response
53
+ if language != "ar":
54
+ return "عذرًا، هذا المساعد يدعم اللغة العربية فقط. الرجاء إعادة الصياغة بالعربية."
 
 
 
55
 
56
+ # Classify the user's intent using NLP
57
+ intent = classify_intent(message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ # If intent is recognized, return the corresponding response
60
  if intent != "unknown":
61
+ return ONB_GUIDELINES.get(intent, "عذرًا، لم يتم التعرف على الخيار المحدد.")
62
+
63
+ # Fallback to keyword matching if NLP doesn't recognize the intent
64
+ for keyword, key in INTENT_TO_RESPONSE.items():
65
+ if keyword in message:
66
+ return ONB_GUIDELINES.get(key, "عذرًا، لم يتم التعرف على الخيار المحدد.")
67
+
68
+ # Default response if no intent or keyword is matched
69
+ return "عذرًا، لم أفهم سؤالك. الرجاء إعادة الصياغة أو اختيار أحد الخيارات التالية: " + ", ".join(INTENT_TO_RESPONSE.keys())
70
+
71
+ # Chat interface
72
+ with gr.Blocks(css=".gradio-container {direction: rtl;}") as demo:
73
+ gr.Markdown("# <center>بنك أم درمان الوطني - المساعد المصرفي</center>")
74
+
75
+ with gr.Tab("المحادثة"):
76
+ gr.Markdown("## اكتب سؤالك هنا:")
77
+
78
+ # Text input
79
+ text_input = gr.Textbox(label="السؤال")
80
+
81
+ # Submit button
82
+ submit_btn = gr.Button("إرسال")
83
+
84
+ # Output textbox for responses
85
+ output = gr.Textbox(label="الرد", interactive=False)
86
+
87
+ # Link inputs and button to response function
88
+ submit_btn.click(
89
+ fn=respond,
90
+ inputs=text_input,
91
+ outputs=output
92
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  if __name__ == "__main__":
95
+ demo.launch(
96
+ server_name="0.0.0.0",
97
+ server_port=7860,
98
+ share=True # Enable public link
99
+ )