Spaces:
Runtime error
Runtime error
| 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) | |