student_sample_panel / PanelInterface.py
nat232's picture
Update PanelInterface.py
c25e379 verified
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/student_sample_panel.jpg", 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