Spaces:
Runtime error
Runtime error
File size: 16,394 Bytes
e6da03d 92c1e12 e6da03d 21fc809 e6da03d 196b3e3 8508e0f 9b52263 8508e0f 3dce584 5ec3426 3cab104 3dce584 5ec3426 3cab104 5ec3426 3cab104 5ec3426 72af144 5ec3426 72af144 e6da03d 3dce584 e6da03d 3dce584 8508e0f 3dce584 e6da03d 3dce584 9b52263 3dce584 e6da03d 3dce584 e6da03d 3dce584 3cab104 3dce584 5ec3426 3cab104 5ec3426 3dce584 5ec3426 8508e0f 658912b 5ec3426 3dce584 5ec3426 72af144 21fc809 3dce584 8508e0f 658912b 3dce584 5ec3426 3dce584 5ec3426 72af144 21fc809 e6da03d 196b3e3 e6da03d 196b3e3 e6da03d 3dce584 e6da03d 8508e0f 3dce584 5ec3426 21fc809 72af144 e6da03d 196b3e3 3dce584 e6da03d 3dce584 5ec3426 3dce584 196b3e3 21fc809 196b3e3 ab1685d 196b3e3 3dce584 196b3e3 e6da03d 196b3e3 e6da03d 21fc809 08c9450 21fc809 72af144 e6da03d d01ea44 e6da03d d01ea44 72af144 e6da03d 72af144 5ec3426 e6da03d 3dce584 e6da03d 5ec3426 196b3e3 8508e0f 3dce584 72af144 e6da03d fe22d3a 3dce584 21fc809 8508e0f 3dce584 3cab104 3dce584 9b52263 3cab104 5ec3426 e6da03d 3dce584 fe22d3a 196b3e3 72af144 e6da03d 196b3e3 e6da03d 196b3e3 72af144 e6da03d 3cab104 e6da03d 3cab104 e6da03d 3cab104 fe22d3a 3cab104 66a9f93 3cab104 72af144 e6da03d 72af144 e6da03d 3cab104 72af144 3cab104 7b91819 e6da03d f779dd3 196b3e3 f779dd3 3cab104 20f92b6 e6da03d 196b3e3 c97f1e2 e6da03d 3cab104 e6da03d 3cab104 e6da03d 3cab104 9b52263 196b3e3 e6da03d 196b3e3 9b52263 e6da03d 196b3e3 e6da03d 196b3e3 e6da03d 196b3e3 e6da03d 9b52263 3dce584 9b52263 3dce584 | 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 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | import pandas as pd
import gradio as gr
from gradio import ChatMessage
from src.constants import FULL_QUESTIONS, DEFAULT_GRADING_SYSTEM_DF, CUSTOM_CSS
from src.utils import generate_session_id, highlight_feedback, show_popup, reset_popup, generate_skills_evaluation_markdown
from src.api_calls import chatbot_api_call, feedback_api_call, ideal_answer_api_call, conversation_feedback_api_call
session_id = generate_session_id()
first_question_selected = False
current_turns = 0
interview_data_with_feedback = []
def enable_send_button(message, selected_question):
if selected_question and message.strip():
return gr.update(interactive=True), gr.update(label="Choose an interview question")
elif selected_question:
return gr.update(interactive=False), gr.update(label="Choose an interview question")
return gr.update(interactive=False), gr.update(label="Choose an interview question (Required)")
def handle_question_change(history, selected_question, conversation_mode):
global session_id, first_question_selected, current_turns, interview_data_with_feedback
current_turns = 0
interview_data_with_feedback = []
if conversation_mode == 'Interviewer':
updated_label = f"Conversation turns: {current_turns}"
feedback_box = gr.update(value=None)
else:
updated_label = "Multimodal Coach Agent"
feedback_box = gr.update(value=None, show_legend=False)
grading_system_df = gr.update(value=DEFAULT_GRADING_SYSTEM_DF, label="Insights")
if len(history) > 2:
first_question_selected = True
if first_question_selected:
session_id = generate_session_id()
transition_message = f"Alright, let's move on to the next question:\n\n{selected_question}"
new_history = [
ChatMessage(
role="user",
content="I'm ready for the next question now.",
),
ChatMessage(
role="assistant",
content=transition_message,
),
]
return new_history, gr.update(interactive=False), gr.update(interactive=True), gr.update(label=updated_label), feedback_box, grading_system_df
else:
if selected_question:
last_question = f"Great start! Here's your first question:\n\n{selected_question}"
else:
last_question = selected_question
if last_question != None:
history.append(
{
"role": "user",
"content": "One moment...",
}
)
history.append(
{
"role": "assistant",
"content": last_question,
}
)
return [entry for entry in history if entry["content"] is not None], gr.update(interactive=False), gr.update(interactive=True), gr.update(label=updated_label), feedback_box, grading_system_df
def reset_interface(conversation_mode):
global session_id, first_question_selected, current_turns, interview_data_with_feedback
first_question_selected = False
current_turns = 0
interview_data_with_feedback = []
if conversation_mode == "Interviewer":
chatbot_label = f"Conversation turns: {current_turns}"
session_id = generate_session_id()
user_greeting_message = "I've selected Interviewer mode, and I'm ready to begin."
chatbot_greeting_message = (
"Hello, and welcome to your interview for the Senior Product Manager position!\n\n"
"Select a question from the list above to begin."
)
slider_state = gr.update(interactive=True)
feedback_box = gr.update(value=None)
feedback_type_state = gr.update(interactive=True, value="Standard")
else:
chatbot_label = "Multimodal Coach Agent"
session_id = generate_session_id()
user_greeting_message = "Hey there! I've selected Coach mode. Let's dive in."
chatbot_greeting_message = (
"Hi!\n\n"
"Welcome to your interview preparation session for the Senior Product Manager role.\n\n"
"Please pick a question above to get started!"
)
slider_state = gr.update(interactive=False)
feedback_box = gr.update(value=None, show_legend=False)
feedback_type_state = gr.update(interactive=False, value=" ")
grading_system_df = gr.update(value=DEFAULT_GRADING_SYSTEM_DF, label="Insights")
include_company_name = gr.update(interactive=True, value=False)
include_resume_text = gr.update(interactive=True, value=False)
include_job_description = gr.update(interactive=True, value=True)
history = [
ChatMessage(
role="user",
content=user_greeting_message,
),
ChatMessage(
role="assistant",
content=chatbot_greeting_message,
)
]
return (
gr.update(value=history, label=chatbot_label),
gr.update(choices=FULL_QUESTIONS, value=None, label="Choose an interview question (Required)", interactive=True),
"",
gr.update(value="Send", interactive=False),
slider_state,
feedback_box,
feedback_type_state,
grading_system_df,
include_company_name,
include_resume_text,
include_job_description
)
# Gradio interface
def create_demo():
with gr.Blocks(css=CUSTOM_CSS) as demo:
gr.Markdown("# Talent Interview Prep - Conversational Model")
gr.Markdown("""### Please select a conversation mode to begin""")
with gr.Row(equal_height=True):
with gr.Column(scale=6):
conversation_mode = gr.Radio(
choices=["Interviewer", "Coach"],
label="""Choose "Interviewer" to simulate a real interview or "Coach" for guidance and feedback""",
info=""">**Important note:**\n>This has been *hardcoded* for a **Senior Product Manager** role.""",
value=None
)
with gr.Column(scale=2, variant="panel"):
include_company_name = gr.Checkbox(label="Include the company name in the request", value=False, interactive=False)
include_job_description = gr.Checkbox(label="Include the job description in the request", value=True, interactive=False)
include_resume_text = gr.Checkbox(label="Include the candidate's resume in the request", value=False, interactive=False)
conversation_turns_limit = gr.Slider(minimum=1, maximum=20, step=1, label="Choose the number of exchanges (turns) between you and the AI agent (1 min, 20 max)", value=5, interactive=False)
with gr.Row():
with gr.Column(scale=6):
question_dropdown = gr.Dropdown(choices=[], label="Choose an interview question")
with gr.Column(scale=2):
feedback_type_dropdown = gr.Dropdown(
choices=["Standard", "STAR"],
value=" ",
label="Select the feedback type",
interactive=False,
allow_custom_value=True
)
chatbot = gr.Chatbot(type="messages", label="""The Multimodal Chatbot will be ready once you select a mode""", show_copy_button=True)
with gr.Row(equal_height=True):
with gr.Column(scale=10):
msg = gr.Textbox(show_label=False, placeholder="Type a message...")
with gr.Column(min_width=50):
send_btn = gr.Button(value="Send\n", variant="primary", interactive=False, elem_id="fill-button")
gr.Markdown(" ")
gr.Markdown("---")
gr.Markdown("## Conversation Feedback")
feedback_box = gr.HighlightedText(
label="Breakdown",
show_legend=True,
color_map={"Strength": "green", "Area for Improvement": "orange", "Action Item": "blue"}
)
grading_system_df = gr.DataFrame(value=DEFAULT_GRADING_SYSTEM_DF, interactive=False, label="Insights", max_height=200, min_width=25)
msg.change(fn=enable_send_button, inputs=[msg, question_dropdown], outputs=[send_btn, question_dropdown])
question_dropdown.change(fn=enable_send_button, inputs=[msg, question_dropdown], outputs=[send_btn, question_dropdown])
question_dropdown.change(fn=handle_question_change, inputs=[chatbot, question_dropdown, conversation_mode], outputs=[chatbot, send_btn, msg, chatbot, feedback_box, grading_system_df])
def respond(message, history, conversation_mode, selected_question, conversation_turns_limit, feedback_type, include_company_name, include_resume_text, include_job_description):
global session_id, current_turns, interview_data_with_feedback
feedback_value = None
feedback_show_legend = False
criteria_feedback_df = DEFAULT_GRADING_SYSTEM_DF
if not message.strip():
return history, message
clean_question = selected_question.split(":", 1)[1] if ": " in selected_question else selected_question
bot_message, conversation_end_flag, chat_memory = chatbot_api_call(session_id, clean_question, message, conversation_mode, conversation_turns_limit, include_company_name, include_resume_text)
print(f"Conversation end? {conversation_end_flag}\n")
print(f"{chat_memory=}\n")
updated_label = f"Conversation turns: {current_turns}" if conversation_mode == 'Interviewer' else "Multimodal Coach Agent"
history.append(
ChatMessage(
role="user",
content=message,
)
)
history.append(
ChatMessage(
role="assistant",
content=bot_message,
)
)
if conversation_end_flag:
if conversation_mode == 'Interviewer':
feedback_output = conversation_feedback_api_call(chat_memory['messages'], feedback_type.lower(), include_resume_text, include_job_description)
feedback_show_legend, highlighted_feedback = highlight_feedback(feedback_output)
feedback_value = [("Whole conversation feedback\n\n", None)] + highlighted_feedback
criteria_feedback_data = feedback_output["criteria_feedback"]
skills_evaluation_data = feedback_output["skills_evaluation"]
if criteria_feedback_data:
criteria_feedback_df = pd.DataFrame(criteria_feedback_data)
criteria_feedback_df.rename(columns={
"question_criteria": "Question criteria",
"evaluation": "Evaluation"
}, inplace=True)
if skills_evaluation_data:
skills_evaluation = generate_skills_evaluation_markdown(skills_evaluation_data)
history.append(ChatMessage(
role="assistant",
content=skills_evaluation,
metadata={"title": "🛠️ Skills evaluation"}
))
print()
print(feedback_output)
print()
print(highlighted_feedback)
print()
print(criteria_feedback_df)
return (
history,
"",
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(label=updated_label),
gr.update(value=feedback_value, show_legend=feedback_show_legend),
gr.update(value=criteria_feedback_df, label="Insights")
)
if conversation_mode == 'Interviewer':
current_turns += 1
interview_data = chat_memory['messages'][:-1]
print(f"{interview_data=}\n")
feedback_output = feedback_api_call(interview_data, feedback_type.lower(), include_resume_text)
feedback_show_legend, highlighted_feedback = highlight_feedback(feedback_output)
feedback_value = [(f"{current_turns}º conversation turn feedback\n\n", None)] + highlighted_feedback
criteria_feedback_data = feedback_output["criteria_feedback"]
if criteria_feedback_data:
criteria_feedback_df = pd.DataFrame(criteria_feedback_data)
criteria_feedback_df.rename(columns={
"question_criteria": "Question criteria",
"evaluation": "Evaluation"
}, inplace=True)
print()
print(feedback_output)
print()
print(highlighted_feedback)
print()
print(criteria_feedback_df)
print()
interview_data_with_feedback.extend(interview_data)
interview_data_with_feedback.append({"type": "feedback", "content": feedback_output["feedback_text"]})
print(f"{interview_data_with_feedback=}\n")
ideal_answer = ideal_answer_api_call(interview_data_with_feedback, feedback_type.lower(), include_resume_text)
cleaned_ideal_answer = ideal_answer.replace("\\n", " ")
cleaned_ideal_answer_html = f"""<p style="text-align: left; font-size: 14px;">{cleaned_ideal_answer}</p>"""
print(cleaned_ideal_answer)
history.insert(-1, ChatMessage(
role="assistant",
content=cleaned_ideal_answer_html,
metadata={"title": "💡 Your last message framed as an ideal answer"}
))
updated_label = f"Conversation turns: {current_turns}" if conversation_mode == 'Interviewer' else "Multimodal Coach Agent"
return (
history,
"",
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(label=updated_label),
gr.update(value=feedback_value, show_legend=feedback_show_legend),
gr.update(value=criteria_feedback_df, label="Insights")
)
conversation_mode.change(fn=reset_interface, inputs=conversation_mode, outputs=[chatbot, question_dropdown, msg, send_btn, conversation_turns_limit, feedback_box, feedback_type_dropdown, grading_system_df, include_company_name, include_resume_text, include_job_description])
msg.submit(fn=respond, inputs=[msg, chatbot, conversation_mode, question_dropdown, conversation_turns_limit, feedback_type_dropdown, include_company_name, include_resume_text, include_job_description], outputs=[chatbot, msg, send_btn, msg, chatbot, feedback_box, grading_system_df])
send_btn.click(fn=respond, inputs=[msg, chatbot, conversation_mode, question_dropdown, conversation_turns_limit, feedback_type_dropdown, include_company_name, include_resume_text, include_job_description], outputs=[chatbot, msg, send_btn, msg, chatbot, feedback_box, grading_system_df])
popup = gr.HTML(label="Popup", elem_classes=["popup"])
include_company_name.change(
fn=lambda selected: show_popup(False, selected, False) if selected else reset_popup(),
inputs=include_company_name,
outputs=popup
)
include_job_description.change(
fn=lambda selected: show_popup(False, False, selected) if selected else reset_popup(),
inputs=include_job_description,
outputs=popup
)
include_resume_text.change(
fn=lambda selected: show_popup(selected, False, False) if selected else reset_popup(),
inputs=include_resume_text,
outputs=popup
)
return demo
print("Launching Gradio interface...")
app = create_demo().launch(share=False, inline=False)
|