File size: 7,713 Bytes
11926bf
f433859
11926bf
1daa69a
30bd009
171e455
11926bf
d42ee28
 
695d8b3
 
 
2806a0b
30bd009
 
 
0c48119
f433859
 
 
30bd009
 
 
7ba641c
1812db4
 
 
f433859
2806a0b
 
 
b732bbd
2806a0b
 
d4504ab
b732bbd
2806a0b
 
 
 
 
 
b732bbd
2806a0b
 
 
 
 
 
b732bbd
2806a0b
 
 
 
 
 
b732bbd
 
ff8b90e
 
 
 
b732bbd
 
 
11926bf
 
f433859
30bd009
6253bf9
b92d360
3d596d7
f4822ad
7ba641c
11926bf
1812db4
334eb8c
1812db4
11926bf
 
5c04c29
 
11926bf
3a9c96d
1812db4
11926bf
 
 
1812db4
 
b732bbd
11926bf
 
 
 
 
 
 
3a9c96d
1812db4
11926bf
d3208c7
 
 
 
6bb469d
d3208c7
 
6bb469d
d3208c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a2c5200
d3208c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bb469d
d3208c7
dc1b89f
 
 
08832c7
1812db4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import gradio as gr
import pandas as pd
import logging
import json
import os
from Config import Config

from InteractiveInterviewChatbot import *

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


def load_panelists_from_excel(file_path=None):
    if file_path is None:
        file_path = Config.hugging_face_excel_file
    df = pd.read_excel(file_path, sheet_name="panelist_details")
    return df.to_dict(orient="records")


def load_ui_texts_from_excel(file_path=None):
    if file_path is None:
        file_path = Config.hugging_face_excel_file
    df = pd.read_excel(file_path, sheet_name="ui_texts")
    return dict(zip(df['key'], df['value']))


def build_interface(respondent_agents_dict, processor_llm):
    def chatbot_interface(message, history=None):
        if history is None or not isinstance(history, dict):
            history = {"chat": [], "last_respondent_agent": None}

        last_respondent_agent = history.get("last_respondent_agent")
        logging.info(f"User message received: {message}")
        logging.info(f"Last respondent agent: {last_respondent_agent}")

        try:
            responses = ask_interview_question(respondent_agents_dict, last_respondent_agent, message, processor_llm)
            logging.info(f"Interview responses: {responses}")
        except Exception as e:
            logging.error(f"Error during interview processing: {e}")
            responses = [("System", "Sorry, something went wrong.")]

        if isinstance(responses, str):
            responses = [("System", responses)]
        elif isinstance(responses, list):
            responses = [(r.get("agent", "Unknown"), r.get("response", str(r))) if isinstance(r, dict) else ("Unknown", str(r)) for r in responses]
        else:
            responses = [("Unknown", str(responses))]

        for agent, response in responses:
            history["chat"].append({
                "user": message,
                "agent": agent,
                "response": response
            })
            history["last_respondent_agent"] = agent

        chat_ui = []
        for entry in history["chat"]:
            chat_ui.append({"role": "user", "content": entry["user"]})
            chat_ui.append({"role": "assistant", "content": entry["response"]})

        return chat_ui, "", history

    logging.info("Building Gradio interface...")

    # Load panelists from Excel
    panelists = load_panelists_from_excel()
    bios_js_object = {p["ID"]: f"<b>{p['Name']}</b><br>{p['Description']}<br><br>{p['Bio']}" for p in panelists}
    panel_html = "".join(
        f"<p><a href='javascript:void(0);' onclick='showModal(event, \"{p['ID']}\"); return false;'><b>{p['Name']}</b></a> – {p['Description']}</p>"
        for p in panelists
    )

    # Load UI texts from Excel
    ui_texts = load_ui_texts_from_excel()

    with gr.Blocks(css="assets/custom.css") as demo:
        with gr.Row(elem_classes="logo-row"):
            gr.Image("static/Header_Image.png", height=300, width=600, show_label=False, elem_id="logo")
            
        with gr.Row(elem_classes="welcome-section"):
            with gr.Column():
                gr.Markdown(ui_texts["welcome_markdown"])

        with gr.Row():
            with gr.Column(scale=1, elem_classes="bio-section"):
                gr.HTML(ui_texts["recommended_topics_html"])
                gr.HTML(ui_texts["panelist_intro_html"].replace("{panel_html}", panel_html))

            with gr.Column(scale=3):
                chatbot = gr.Chatbot(label="Panel Discussion", height=400, type="messages")
                msg = gr.Textbox(placeholder="Ask your question to the panel here...")
                history = gr.State([])
                msg.submit(chatbot_interface, [msg, history], [chatbot, msg, history])

        with gr.Row(elem_classes="footer-row"):
            with gr.Column():
                gr.Markdown(ui_texts["footer_html"])

        # Inject the bios object for the modal JS
        bios_json = json.dumps(bios_js_object)
        prohibited_topics = ui_texts.get("prohibited_topics_html", "")
        modal_script = f"""
<script>
const bios = {bios_json};
function showModal(event, name) {{
    event.preventDefault();
    const modal = document.getElementById('bioModal');
    const backdrop = document.getElementById('modalBackdrop');
    const closeButton = document.getElementById('closeButton');
    const bioContent = document.getElementById('bioContent');
    bioContent.innerHTML = bios[name] || 'Bio not found.';
    modal.style.display = 'block';
    backdrop.style.display = 'block';
    const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
    if (prefersDark) {{
        modal.style.backgroundColor = '#1e1e1e';
        modal.style.color = '#ffffff';
        modal.style.border = '1px solid #444';
        modal.style.boxShadow = '0px 4px 6px rgba(0, 0, 0, 0.8)';
        closeButton.style.backgroundColor = '#007bff';
        closeButton.style.color = 'white';
        backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
    }} else {{
        modal.style.backgroundColor = '#ffffff';
        modal.style.color = '#000000';
        modal.style.border = '1px solid #ccc';
        modal.style.boxShadow = '0px 4px 6px rgba(0, 0, 0, 0.2)';
        closeButton.style.backgroundColor = '#007bff';
        closeButton.style.color = 'white';
        backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
    }}
    closeButton.style.marginTop = '10px';
    closeButton.style.padding = '5px 10px';
    closeButton.style.border = 'none';
    closeButton.style.borderRadius = '5px';
    closeButton.style.cursor = 'pointer';
}}
function closeModal() {{
    document.getElementById('bioModal').style.display = 'none';
    document.getElementById('modalBackdrop').style.display = 'none';
}}
function showTopicsModal(event) {{
    event.preventDefault();
    const modal = document.getElementById('topicsModal');
    const backdrop = document.getElementById('topicsBackdrop');
    const closeButton = document.getElementById('closeTopicsButton');
    const topicsContent = document.getElementById('topicsContent');
    topicsContent.innerHTML = `{prohibited_topics}`;
    modal.style.display = 'block';
    backdrop.style.display = 'block';
    const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
    if (prefersDark) {{
        modal.style.backgroundColor = '#1e1e1e';
        modal.style.color = '#ffffff';
        modal.style.border = '1px solid #444';
        modal.style.boxShadow = '0px 4px 6px rgba(0, 0, 0, 0.8)';
        closeButton.style.backgroundColor = '#007bff';
        closeButton.style.color = 'white';
        backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
    }} else {{
        modal.style.backgroundColor = '#ffffff';
        modal.style.color = '#000000';
        modal.style.border = '1px solid #ccc';
        modal.style.boxShadow = '0px 4px 6px rgba(0, 0, 0, 0.2)';
        closeButton.style.backgroundColor = '#007bff';
        closeButton.style.color = 'white';
        backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
    }}
    closeButton.style.marginTop = '10px';
    closeButton.style.padding = '5px 10px';
    closeButton.style.border = 'none';
    closeButton.style.borderRadius = '5px';
    closeButton.style.cursor = 'pointer';
}}
function closeTopicsModal() {{
    document.getElementById('topicsModal').style.display = 'none';
    document.getElementById('topicsBackdrop').style.display = 'none';
}}
</script>
"""
        gr.HTML(modal_script)

    logging.info("Interface build complete.")
    return demo