Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -617,6 +617,17 @@ AVATAR_HTML = """
|
|
| 617 |
</div>
|
| 618 |
"""
|
| 619 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
def build_app():
|
| 621 |
# Pre-load welcome audio once
|
| 622 |
print("⏳ Generating welcome audio…")
|
|
@@ -626,9 +637,10 @@ def build_app():
|
|
| 626 |
with gr.Blocks(css=CSS, title="Reem — Virtual Call Centre") as demo:
|
| 627 |
|
| 628 |
# ── State ──────────────────────────────────────────────────────
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
|
|
|
| 632 |
|
| 633 |
# ── Hero ───────────────────────────────────────────────────────
|
| 634 |
gr.HTML("""
|
|
@@ -761,21 +773,22 @@ def build_app():
|
|
| 761 |
|
| 762 |
# ── Language selection helpers ─────────────────────────────────
|
| 763 |
def _set_language(code, memory):
|
|
|
|
| 764 |
confirm_text = LANGUAGE_CONFIRMATION[code]
|
| 765 |
audio_path = tts_to_file(confirm_text, code)
|
| 766 |
lang_names = {"en": "English", "ar": "العربية", "ur": "اردو"}
|
| 767 |
badge = f"🗣️ Language: **{lang_names.get(code, code)}**"
|
| 768 |
-
# Return: lang_state, hide lang_group, show chat_group, badge, audio, memory
|
| 769 |
return (
|
| 770 |
code,
|
| 771 |
-
gr.update(visible=False),
|
| 772 |
-
gr.update(visible=True),
|
| 773 |
badge,
|
| 774 |
audio_path,
|
| 775 |
memory,
|
| 776 |
)
|
| 777 |
|
| 778 |
def handle_lang_mic(audio, memory):
|
|
|
|
| 779 |
if audio is None:
|
| 780 |
return ("", gr.update(), gr.update(), "", None, memory)
|
| 781 |
sr, data = audio
|
|
@@ -816,6 +829,7 @@ def build_app():
|
|
| 816 |
|
| 817 |
# ── Voice input ────────────────────────────────────────────────
|
| 818 |
def handle_voice(audio, lang_code, memory, history):
|
|
|
|
| 819 |
if audio is None:
|
| 820 |
return history, None, memory, ""
|
| 821 |
sr, data = audio
|
|
@@ -829,7 +843,7 @@ def build_app():
|
|
| 829 |
if not transcript or len(transcript.strip()) < 3:
|
| 830 |
return history, None, memory, "⚠️ No clear speech detected."
|
| 831 |
_, new_history, audio_path = process_query(
|
| 832 |
-
transcript, memory, lang_code, history)
|
| 833 |
mem_info_txt = _mem_info(memory)
|
| 834 |
return new_history, audio_path, memory, mem_info_txt
|
| 835 |
|
|
@@ -841,10 +855,11 @@ def build_app():
|
|
| 841 |
|
| 842 |
# ── Text input ────────────────────────────────────────────────
|
| 843 |
def handle_text(text, lang_code, memory, history):
|
|
|
|
| 844 |
if not text or not text.strip():
|
| 845 |
return history, None, memory, "", ""
|
| 846 |
_, new_history, audio_path = process_query(
|
| 847 |
-
text, memory, lang_code, history)
|
| 848 |
mem_info_txt = _mem_info(memory)
|
| 849 |
return new_history, audio_path, memory, mem_info_txt, ""
|
| 850 |
|
|
|
|
| 617 |
</div>
|
| 618 |
"""
|
| 619 |
|
| 620 |
+
def _init_state(memory, lang, history):
|
| 621 |
+
"""Ensure state values are never None."""
|
| 622 |
+
if memory is None:
|
| 623 |
+
memory = ConversationMemory()
|
| 624 |
+
if lang is None:
|
| 625 |
+
lang = ""
|
| 626 |
+
if history is None:
|
| 627 |
+
history = []
|
| 628 |
+
return memory, lang, history
|
| 629 |
+
|
| 630 |
+
|
| 631 |
def build_app():
|
| 632 |
# Pre-load welcome audio once
|
| 633 |
print("⏳ Generating welcome audio…")
|
|
|
|
| 637 |
with gr.Blocks(css=CSS, title="Reem — Virtual Call Centre") as demo:
|
| 638 |
|
| 639 |
# ── State ──────────────────────────────────────────────────────
|
| 640 |
+
# Use None defaults — Gradio cannot hash complex objects
|
| 641 |
+
memory_state = gr.State(None)
|
| 642 |
+
lang_state = gr.State(None)
|
| 643 |
+
chat_history = gr.State(None)
|
| 644 |
|
| 645 |
# ── Hero ───────────────────────────────────────────────────────
|
| 646 |
gr.HTML("""
|
|
|
|
| 773 |
|
| 774 |
# ── Language selection helpers ─────────────────────────────────
|
| 775 |
def _set_language(code, memory):
|
| 776 |
+
memory, _, _ = _init_state(memory, None, None)
|
| 777 |
confirm_text = LANGUAGE_CONFIRMATION[code]
|
| 778 |
audio_path = tts_to_file(confirm_text, code)
|
| 779 |
lang_names = {"en": "English", "ar": "العربية", "ur": "اردو"}
|
| 780 |
badge = f"🗣️ Language: **{lang_names.get(code, code)}**"
|
|
|
|
| 781 |
return (
|
| 782 |
code,
|
| 783 |
+
gr.update(visible=False),
|
| 784 |
+
gr.update(visible=True),
|
| 785 |
badge,
|
| 786 |
audio_path,
|
| 787 |
memory,
|
| 788 |
)
|
| 789 |
|
| 790 |
def handle_lang_mic(audio, memory):
|
| 791 |
+
memory, _, _ = _init_state(memory, None, None)
|
| 792 |
if audio is None:
|
| 793 |
return ("", gr.update(), gr.update(), "", None, memory)
|
| 794 |
sr, data = audio
|
|
|
|
| 829 |
|
| 830 |
# ── Voice input ────────────────────────────────────────────────
|
| 831 |
def handle_voice(audio, lang_code, memory, history):
|
| 832 |
+
memory, lang_code, history = _init_state(memory, lang_code, history)
|
| 833 |
if audio is None:
|
| 834 |
return history, None, memory, ""
|
| 835 |
sr, data = audio
|
|
|
|
| 843 |
if not transcript or len(transcript.strip()) < 3:
|
| 844 |
return history, None, memory, "⚠️ No clear speech detected."
|
| 845 |
_, new_history, audio_path = process_query(
|
| 846 |
+
transcript, memory, lang_code or "en", history)
|
| 847 |
mem_info_txt = _mem_info(memory)
|
| 848 |
return new_history, audio_path, memory, mem_info_txt
|
| 849 |
|
|
|
|
| 855 |
|
| 856 |
# ── Text input ────────────────────────────────────────────────
|
| 857 |
def handle_text(text, lang_code, memory, history):
|
| 858 |
+
memory, lang_code, history = _init_state(memory, lang_code, history)
|
| 859 |
if not text or not text.strip():
|
| 860 |
return history, None, memory, "", ""
|
| 861 |
_, new_history, audio_path = process_query(
|
| 862 |
+
text, memory, lang_code or "en", history)
|
| 863 |
mem_info_txt = _mem_info(memory)
|
| 864 |
return new_history, audio_path, memory, mem_info_txt, ""
|
| 865 |
|