Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -485,79 +485,8 @@ a:hover {
|
|
485 |
}
|
486 |
"""
|
487 |
|
488 |
-
#
|
489 |
-
|
490 |
-
function simulateTyping(message, elementId, delay = 30) {
|
491 |
-
const element = document.getElementById(elementId);
|
492 |
-
if (!element) return;
|
493 |
-
|
494 |
-
element.innerHTML = "";
|
495 |
-
let i = 0;
|
496 |
-
|
497 |
-
function type() {
|
498 |
-
if (i < message.length) {
|
499 |
-
element.innerHTML += message.charAt(i);
|
500 |
-
i++;
|
501 |
-
setTimeout(type, delay);
|
502 |
-
}
|
503 |
-
}
|
504 |
-
|
505 |
-
type();
|
506 |
-
}
|
507 |
-
|
508 |
-
// Function to show typing indicator
|
509 |
-
function showTypingIndicator() {
|
510 |
-
const chatbox = document.getElementById('chatbox');
|
511 |
-
if (!chatbox) return;
|
512 |
-
|
513 |
-
const typingIndicator = document.createElement('div');
|
514 |
-
typingIndicator.className = 'typing-indicator';
|
515 |
-
typingIndicator.id = 'typing-indicator';
|
516 |
-
typingIndicator.innerHTML = '<span></span><span></span><span></span>';
|
517 |
-
|
518 |
-
chatbox.appendChild(typingIndicator);
|
519 |
-
chatbox.scrollTop = chatbox.scrollHeight;
|
520 |
-
}
|
521 |
-
|
522 |
-
// Function to hide typing indicator
|
523 |
-
function hideTypingIndicator() {
|
524 |
-
const typingIndicator = document.getElementById('typing-indicator');
|
525 |
-
if (typingIndicator) {
|
526 |
-
typingIndicator.remove();
|
527 |
-
}
|
528 |
-
}
|
529 |
-
|
530 |
-
// Function to connect with a live agent
|
531 |
-
function connectLiveAgent() {
|
532 |
-
alert('Connecting to a live customer service agent. Please wait a moment...');
|
533 |
-
// In a real implementation, this would initiate a connection to a live agent system
|
534 |
-
}
|
535 |
-
|
536 |
-
// Function to show satisfaction survey
|
537 |
-
function showSatisfactionSurvey(surveyHtml) {
|
538 |
-
const chatbox = document.getElementById('chatbox');
|
539 |
-
if (!chatbox) return;
|
540 |
-
|
541 |
-
const surveyDiv = document.createElement('div');
|
542 |
-
surveyDiv.innerHTML = surveyHtml;
|
543 |
-
|
544 |
-
chatbox.appendChild(surveyDiv);
|
545 |
-
chatbox.scrollTop = chatbox.scrollHeight;
|
546 |
-
}
|
547 |
-
|
548 |
-
// Function to submit survey
|
549 |
-
function submitSurvey() {
|
550 |
-
const form = document.getElementById('satisfaction-form');
|
551 |
-
if (!form) return;
|
552 |
-
|
553 |
-
// In a real implementation, this would send the survey data to a server
|
554 |
-
alert('Thank you for your feedback!');
|
555 |
-
form.style.display = 'none';
|
556 |
-
}
|
557 |
-
"""
|
558 |
-
|
559 |
-
# Chat interface with enhanced UI
|
560 |
-
with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
561 |
# Store conversation history
|
562 |
state = gr.State(value=[])
|
563 |
# Store selected language
|
@@ -579,7 +508,7 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
579 |
)
|
580 |
|
581 |
with gr.Row(elem_classes="chat-container"):
|
582 |
-
|
583 |
|
584 |
# Quick action buttons (will be populated based on language)
|
585 |
with gr.Row(elem_classes="quick-actions", visible=True) as quick_actions_container:
|
@@ -634,36 +563,10 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
634 |
outputs=outputs
|
635 |
)
|
636 |
|
637 |
-
#
|
638 |
-
def add_message_to_chat(message, is_user, lang):
|
639 |
-
# Create a JavaScript function to add the message to the chat
|
640 |
-
alignment = "right" if (is_user or (not is_user and lang == "ar")) else "left"
|
641 |
-
background = "#e6f7ff" if is_user else "#f0f0f0"
|
642 |
-
|
643 |
-
js_code = f"""
|
644 |
-
(function() {{
|
645 |
-
const chatbox = document.getElementById('chatbox').querySelector('div');
|
646 |
-
const messageDiv = document.createElement('div');
|
647 |
-
messageDiv.style.padding = '1rem';
|
648 |
-
messageDiv.style.borderRadius = '10px';
|
649 |
-
messageDiv.style.marginBottom = '1rem';
|
650 |
-
messageDiv.style.maxWidth = '80%';
|
651 |
-
messageDiv.style.backgroundColor = '{background}';
|
652 |
-
messageDiv.style.marginLeft = alignment === "right" ? "auto" : "0";
|
653 |
-
messageDiv.style.marginRight = alignment === "left" ? "auto" : "0";
|
654 |
-
messageDiv.style.textAlign = alignment;
|
655 |
-
messageDiv.innerHTML = `{message}`;
|
656 |
-
chatbox.appendChild(messageDiv);
|
657 |
-
chatbox.scrollTop = chatbox.scrollHeight;
|
658 |
-
}})();
|
659 |
-
"""
|
660 |
-
|
661 |
-
return js_code
|
662 |
-
|
663 |
-
# Handle message submission with typing effect
|
664 |
def on_submit(message, chat_history, lang, name):
|
665 |
if not message.strip():
|
666 |
-
return "", chat_history,
|
667 |
|
668 |
# Check if this is a name introduction
|
669 |
name_patterns = [
|
@@ -680,11 +583,8 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
680 |
name = match.group(1)
|
681 |
break
|
682 |
|
683 |
-
# Add user message to chat
|
684 |
-
|
685 |
-
|
686 |
-
# Show typing indicator
|
687 |
-
typing_js = "showTypingIndicator();"
|
688 |
|
689 |
# Get response
|
690 |
responses = respond(message)
|
@@ -700,18 +600,10 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
700 |
response = response.replace("Welcome", f"Welcome {name}")
|
701 |
response = response.replace("Hello", f"Hello {name}")
|
702 |
|
703 |
-
#
|
704 |
-
|
705 |
-
setTimeout(function() {{
|
706 |
-
hideTypingIndicator();
|
707 |
-
{add_message_to_chat(response, False, lang)}
|
708 |
-
}}, 1000);
|
709 |
-
"""
|
710 |
-
|
711 |
-
# Combine all JavaScript
|
712 |
-
combined_js = user_js + typing_js + bot_js
|
713 |
|
714 |
-
return "", chat_history,
|
715 |
|
716 |
# Handle menu button click
|
717 |
def show_menu(chat_history, lang):
|
@@ -724,9 +616,9 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
724 |
menu_text = menu_responses[lang]
|
725 |
|
726 |
# Add system message showing the menu
|
727 |
-
|
728 |
|
729 |
-
return chat_history
|
730 |
|
731 |
# Handle quick action button clicks
|
732 |
def handle_quick_action(button_index, chat_history, lang, name):
|
@@ -736,6 +628,10 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
736 |
if button_index < len(quick_actions):
|
737 |
# Get the intent for this button
|
738 |
intent = quick_actions[button_index]["intent"]
|
|
|
|
|
|
|
|
|
739 |
|
740 |
# Get the response for this intent
|
741 |
if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
|
@@ -775,130 +671,91 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
775 |
response = response.replace("Welcome", f"Welcome {name}")
|
776 |
response = response.replace("Hello", f"Hello {name}")
|
777 |
|
778 |
-
#
|
779 |
-
|
780 |
-
user_js = add_message_to_chat(button_text, True, lang)
|
781 |
-
|
782 |
-
# Show typing indicator
|
783 |
-
typing_js = "showTypingIndicator();"
|
784 |
-
|
785 |
-
# Hide typing indicator and add bot response
|
786 |
-
bot_js = f"""
|
787 |
-
setTimeout(function() {{
|
788 |
-
hideTypingIndicator();
|
789 |
-
{add_message_to_chat(response, False, lang)}
|
790 |
-
}}, 1000);
|
791 |
-
"""
|
792 |
-
|
793 |
-
# Combine all JavaScript
|
794 |
-
combined_js = user_js + typing_js + bot_js
|
795 |
|
796 |
# Log the interaction
|
797 |
log_interaction(button_text, response, intent, lang)
|
798 |
|
799 |
-
|
800 |
-
|
801 |
-
return chat_history, ""
|
802 |
|
803 |
# Handle live agent button click
|
804 |
-
def connect_to_live_agent():
|
805 |
-
|
|
|
|
|
806 |
|
807 |
# Handle satisfaction survey button click
|
808 |
-
def show_satisfaction_survey(lang):
|
809 |
if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
|
810 |
survey_html = offer_satisfaction_survey(lang)
|
811 |
-
|
812 |
else:
|
813 |
-
# Simple survey
|
814 |
title = "استطلاع رضا العملاء" if lang == "ar" else "Customer Satisfaction Survey"
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
<div class="satisfaction-survey" dir="{('rtl' if lang == 'ar' else 'ltr')}">
|
820 |
-
<h3>{title}</h3>
|
821 |
-
<p>{intro}</p>
|
822 |
-
<button onclick="submitSurvey()" class="survey-submit">{submit}</button>
|
823 |
-
</div>
|
824 |
-
"""
|
825 |
-
|
826 |
-
return f"showSatisfactionSurvey(`{survey_html}`);"
|
827 |
|
828 |
# Link inputs and button to response function
|
829 |
submit_btn.click(
|
830 |
fn=on_submit,
|
831 |
-
inputs=[text_input,
|
832 |
-
outputs=[text_input,
|
833 |
)
|
834 |
|
835 |
# Link menu button to show menu function
|
836 |
menu_btn.click(
|
837 |
fn=show_menu,
|
838 |
-
inputs=[
|
839 |
-
outputs=[
|
840 |
)
|
841 |
|
842 |
# Link live agent button to connect function
|
843 |
live_agent_btn.click(
|
844 |
fn=connect_to_live_agent,
|
845 |
-
inputs=[],
|
846 |
-
outputs=[
|
847 |
)
|
848 |
|
849 |
# Link survey button to show survey function
|
850 |
survey_btn.click(
|
851 |
fn=show_satisfaction_survey,
|
852 |
-
inputs=[selected_lang],
|
853 |
-
outputs=[
|
854 |
)
|
855 |
|
856 |
# Link quick action buttons to handler function
|
857 |
for i, button in enumerate(quick_action_buttons):
|
858 |
button.click(
|
859 |
-
fn=lambda idx=i,
|
860 |
-
inputs=[
|
861 |
-
outputs=[
|
862 |
)
|
863 |
|
864 |
# Also trigger on Enter key
|
865 |
text_input.submit(
|
866 |
fn=on_submit,
|
867 |
-
inputs=[text_input,
|
868 |
-
outputs=[text_input,
|
869 |
)
|
870 |
|
871 |
# Initialize the chat with a welcome message
|
872 |
-
def init_chat(
|
873 |
-
#
|
874 |
-
welcome_ar = ""
|
875 |
-
|
876 |
-
<img src='https://via.placeholder.com/150?text=ONB+Logo' alt='ONB Logo' style='max-width: 150px;'>
|
877 |
-
<h3>مرحبًا بك في المساعد المصرفي الافتراضي لبنك أم درمان الوطني!</h3>
|
878 |
-
<p>يمكنك طرح أي سؤال حول خدماتنا المصرفية أو استخدام أزرار الإجراءات السريعة أدناه.</p>
|
879 |
-
</div>
|
880 |
-
"""
|
881 |
-
|
882 |
-
welcome_en = """
|
883 |
-
<div style='text-align: center; margin-bottom: 20px;'>
|
884 |
-
<img src='https://via.placeholder.com/150?text=ONB+Logo' alt='ONB Logo' style='max-width: 150px;'>
|
885 |
-
<h3>Welcome to Omdurman National Bank Virtual Banking Assistant!</h3>
|
886 |
-
<p>You can ask any question about our banking services or use the quick action buttons below.</p>
|
887 |
-
</div>
|
888 |
-
"""
|
889 |
|
890 |
-
|
|
|
|
|
|
|
891 |
|
892 |
-
#
|
893 |
-
|
894 |
-
(function() {{
|
895 |
-
const chatbox = document.getElementById('chatbox').querySelector('div');
|
896 |
-
chatbox.innerHTML = `{welcome_message}`;
|
897 |
-
}})();
|
898 |
-
"""
|
899 |
|
900 |
-
# Update
|
901 |
-
quick_actions = QUICK_ACTIONS_AR if lang == "ar" else QUICK_ACTIONS_EN
|
902 |
button_updates = []
|
903 |
for i, button in enumerate(quick_action_buttons):
|
904 |
if i < len(quick_actions):
|
@@ -906,13 +763,13 @@ with gr.Blocks(css=custom_css, js=custom_js) as demo:
|
|
906 |
else:
|
907 |
button_updates.append(gr.Button.update(visible=False))
|
908 |
|
909 |
-
return [
|
910 |
|
911 |
# Initialize the chat when the app starts
|
912 |
demo.load(
|
913 |
-
fn=
|
914 |
inputs=[],
|
915 |
-
outputs=[
|
916 |
)
|
917 |
|
918 |
if __name__ == "__main__":
|
|
|
485 |
}
|
486 |
"""
|
487 |
|
488 |
+
# Chat interface with simplified UI for Hugging Face
|
489 |
+
with gr.Blocks(css=custom_css) as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
490 |
# Store conversation history
|
491 |
state = gr.State(value=[])
|
492 |
# Store selected language
|
|
|
508 |
)
|
509 |
|
510 |
with gr.Row(elem_classes="chat-container"):
|
511 |
+
chatbot = gr.Chatbot(height=400)
|
512 |
|
513 |
# Quick action buttons (will be populated based on language)
|
514 |
with gr.Row(elem_classes="quick-actions", visible=True) as quick_actions_container:
|
|
|
563 |
outputs=outputs
|
564 |
)
|
565 |
|
566 |
+
# Handle message submission
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
def on_submit(message, chat_history, lang, name):
|
568 |
if not message.strip():
|
569 |
+
return "", chat_history, name
|
570 |
|
571 |
# Check if this is a name introduction
|
572 |
name_patterns = [
|
|
|
583 |
name = match.group(1)
|
584 |
break
|
585 |
|
586 |
+
# Add user message to chat history
|
587 |
+
chat_history.append([message, None])
|
|
|
|
|
|
|
588 |
|
589 |
# Get response
|
590 |
responses = respond(message)
|
|
|
600 |
response = response.replace("Welcome", f"Welcome {name}")
|
601 |
response = response.replace("Hello", f"Hello {name}")
|
602 |
|
603 |
+
# Update bot response in chat history
|
604 |
+
chat_history[-1][1] = response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
605 |
|
606 |
+
return "", chat_history, name
|
607 |
|
608 |
# Handle menu button click
|
609 |
def show_menu(chat_history, lang):
|
|
|
616 |
menu_text = menu_responses[lang]
|
617 |
|
618 |
# Add system message showing the menu
|
619 |
+
chat_history.append([None, menu_text.replace("\n", "<br>")])
|
620 |
|
621 |
+
return chat_history
|
622 |
|
623 |
# Handle quick action button clicks
|
624 |
def handle_quick_action(button_index, chat_history, lang, name):
|
|
|
628 |
if button_index < len(quick_actions):
|
629 |
# Get the intent for this button
|
630 |
intent = quick_actions[button_index]["intent"]
|
631 |
+
button_text = quick_actions[button_index]["text"]
|
632 |
+
|
633 |
+
# Add button text as user message
|
634 |
+
chat_history.append([button_text, None])
|
635 |
|
636 |
# Get the response for this intent
|
637 |
if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
|
|
|
671 |
response = response.replace("Welcome", f"Welcome {name}")
|
672 |
response = response.replace("Hello", f"Hello {name}")
|
673 |
|
674 |
+
# Update bot response in chat history
|
675 |
+
chat_history[-1][1] = response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
676 |
|
677 |
# Log the interaction
|
678 |
log_interaction(button_text, response, intent, lang)
|
679 |
|
680 |
+
return chat_history
|
|
|
|
|
681 |
|
682 |
# Handle live agent button click
|
683 |
+
def connect_to_live_agent(chat_history, lang):
|
684 |
+
message = "Connecting to a live customer service agent. Please wait a moment..." if lang == "en" else "جاري الاتصال بوكيل خدمة العملاء. يرجى الانتظار لحظة..."
|
685 |
+
chat_history.append([None, message])
|
686 |
+
return chat_history
|
687 |
|
688 |
# Handle satisfaction survey button click
|
689 |
+
def show_satisfaction_survey(chat_history, lang):
|
690 |
if CUSTOMER_SERVICE_ENHANCEMENTS_AVAILABLE:
|
691 |
survey_html = offer_satisfaction_survey(lang)
|
692 |
+
chat_history.append([None, survey_html])
|
693 |
else:
|
694 |
+
# Simple survey message if enhancements not available
|
695 |
title = "استطلاع رضا العملاء" if lang == "ar" else "Customer Satisfaction Survey"
|
696 |
+
message = f"<div class='satisfaction-survey'><h3>{title}</h3><p>{'نشكرك على استخدام المساعد المصرفي الافتراضي!' if lang == 'ar' else 'Thank you for using our virtual banking assistant!'}</p></div>"
|
697 |
+
chat_history.append([None, message])
|
698 |
+
|
699 |
+
return chat_history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
700 |
|
701 |
# Link inputs and button to response function
|
702 |
submit_btn.click(
|
703 |
fn=on_submit,
|
704 |
+
inputs=[text_input, chatbot, selected_lang, user_name],
|
705 |
+
outputs=[text_input, chatbot, user_name]
|
706 |
)
|
707 |
|
708 |
# Link menu button to show menu function
|
709 |
menu_btn.click(
|
710 |
fn=show_menu,
|
711 |
+
inputs=[chatbot, selected_lang],
|
712 |
+
outputs=[chatbot]
|
713 |
)
|
714 |
|
715 |
# Link live agent button to connect function
|
716 |
live_agent_btn.click(
|
717 |
fn=connect_to_live_agent,
|
718 |
+
inputs=[chatbot, selected_lang],
|
719 |
+
outputs=[chatbot]
|
720 |
)
|
721 |
|
722 |
# Link survey button to show survey function
|
723 |
survey_btn.click(
|
724 |
fn=show_satisfaction_survey,
|
725 |
+
inputs=[chatbot, selected_lang],
|
726 |
+
outputs=[chatbot]
|
727 |
)
|
728 |
|
729 |
# Link quick action buttons to handler function
|
730 |
for i, button in enumerate(quick_action_buttons):
|
731 |
button.click(
|
732 |
+
fn=lambda idx=i, chat=chatbot, lang=selected_lang, name=user_name: handle_quick_action(idx, chat, lang, name),
|
733 |
+
inputs=[chatbot, selected_lang, user_name],
|
734 |
+
outputs=[chatbot]
|
735 |
)
|
736 |
|
737 |
# Also trigger on Enter key
|
738 |
text_input.submit(
|
739 |
fn=on_submit,
|
740 |
+
inputs=[text_input, chatbot, selected_lang, user_name],
|
741 |
+
outputs=[text_input, chatbot, user_name]
|
742 |
)
|
743 |
|
744 |
# Initialize the chat with a welcome message
|
745 |
+
def init_chat():
|
746 |
+
# Welcome message in both languages
|
747 |
+
welcome_ar = "مرحبًا بك في المساعد المصرفي الافتراضي لبنك أم درمان الوطني! يمكنك طرح أي سؤال حول خدماتنا المصرفية أو استخدام أزرار الإجراءات السريعة أدناه."
|
748 |
+
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."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
749 |
|
750 |
+
# Initialize chat with welcome messages
|
751 |
+
chat_history = []
|
752 |
+
chat_history.append([None, welcome_ar])
|
753 |
+
chat_history.append([None, welcome_en])
|
754 |
|
755 |
+
# Get the appropriate quick actions for Arabic (default)
|
756 |
+
quick_actions = QUICK_ACTIONS_AR
|
|
|
|
|
|
|
|
|
|
|
757 |
|
758 |
+
# Update button visibility and text
|
|
|
759 |
button_updates = []
|
760 |
for i, button in enumerate(quick_action_buttons):
|
761 |
if i < len(quick_actions):
|
|
|
763 |
else:
|
764 |
button_updates.append(gr.Button.update(visible=False))
|
765 |
|
766 |
+
return [chat_history] + button_updates
|
767 |
|
768 |
# Initialize the chat when the app starts
|
769 |
demo.load(
|
770 |
+
fn=init_chat,
|
771 |
inputs=[],
|
772 |
+
outputs=[chatbot] + quick_action_buttons
|
773 |
)
|
774 |
|
775 |
if __name__ == "__main__":
|