Spaces:
Sleeping
Sleeping
import streamlit as st | |
from openai import OpenAI | |
import os | |
import pandas as pd | |
import numpy as np | |
from sentence_transformers import SentenceTransformer | |
from sklearn.metrics.pairwise import cosine_similarity | |
import torch | |
# Set up OpenAI client | |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
# Check if GPU is available | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
print(f"Using device: {device}") | |
# Load metadata and embeddings (ensure these files are in your working directory or update paths) | |
metadata_path = 'question_metadata.csv' # Update this path if needed | |
embeddings_path = 'question_dataset_embeddings.npy' # Update this path if needed | |
metadata = pd.read_csv(metadata_path) | |
embeddings = np.load(embeddings_path) | |
# Load the SentenceTransformer model | |
model = SentenceTransformer("all-MiniLM-L6-v2").to(device) | |
# Load prompts from files | |
with open("question_generation_prompt.txt", "r") as file: | |
question_generation_prompt = file.read() | |
with open("technical_interviewer_prompt.txt", "r") as file: | |
technical_interviewer_prompt = file.read() | |
st.title("Real-World Programming Question Mock Interview") | |
# Initialize session state variables | |
if "messages" not in st.session_state: | |
st.session_state.messages = [] | |
if "follow_up_mode" not in st.session_state: | |
st.session_state.follow_up_mode = False # Tracks whether we're in follow-up mode | |
if "generated_question" not in st.session_state: | |
st.session_state.generated_question = None # Stores the generated question for persistence | |
if "debug_logs" not in st.session_state: | |
st.session_state.debug_logs = [] # Stores debug logs for toggling | |
# Function to find the top 1 most similar question based on user input | |
def find_top_question(query): | |
# Generate embedding for the query | |
query_embedding = model.encode(query, convert_to_tensor=True, device=device).cpu().numpy() | |
# Reshape query_embedding to ensure it is a 2D array | |
query_embedding = query_embedding.reshape(1, -1) # Reshape to (1, n_features) | |
# Compute cosine similarity between query embedding and dataset embeddings | |
similarities = cosine_similarity(query_embedding, embeddings).flatten() # Flatten to get a 1D array of similarities | |
# Get the index of the most similar result (top 1) | |
top_index = similarities.argsort()[-1] # Index of highest similarity | |
# Retrieve metadata for the top result | |
top_result = metadata.iloc[top_index].copy() | |
top_result['similarity_score'] = similarities[top_index] | |
return top_result | |
# Function to generate response using OpenAI API with debugging logs | |
def generate_response(messages): | |
debug_log_entry = {"messages": messages} | |
st.session_state.debug_logs.append(debug_log_entry) # Store debug log | |
response = client.chat.completions.create( | |
model="o1-mini", | |
messages=messages, | |
) | |
return response.choices[0].message.content | |
# User input form for generating a new question | |
with st.form(key="input_form"): | |
company = st.text_input("Company", value="Google") # Default value: Google | |
difficulty = st.selectbox("Difficulty", ["Easy", "Medium", "Hard"], index=1) # Default: Medium | |
topic = st.text_input("Topic (e.g., Backtracking)", value="Backtracking") # Default: Backtracking | |
generate_button = st.form_submit_button(label="Generate") | |
if generate_button: | |
# Clear session state and start fresh with follow-up mode disabled | |
st.session_state.messages = [] | |
st.session_state.follow_up_mode = False | |
# Create a query from user inputs and find the most relevant question | |
query = f"{company} {difficulty} {topic}" | |
top_question = find_top_question(query) | |
# Prepare a detailed prompt for GPT using the top question's details | |
detailed_prompt = ( | |
f"Transform this LeetCode question into a real-world interview scenario:\n\n" | |
f"**Company**: {top_question['company']}\n" | |
f"**Question Name**: {top_question['questionName']}\n" | |
f"**Difficulty Level**: {top_question['difficulty level']}\n" | |
f"**Tags**: {top_question['Tags']}\n" | |
f"**Content**: {top_question['Content']}\n" | |
f"\nPlease create a real-world interview question based on this information." | |
) | |
# Generate response using GPT-4 with detailed prompt and debugging logs | |
response = generate_response([{"role": "assistant", "content": question_generation_prompt}, {"role": "user", "content": detailed_prompt}]) | |
# Store generated question in session state for persistence in sidebar | |
st.session_state.generated_question = response | |
# Enable follow-up mode after generating the initial question | |
st.session_state.follow_up_mode = True | |
# Display chat messages from history on app rerun (for subsequent conversation) | |
for message in st.session_state.messages: | |
with st.chat_message(message["role"]): | |
st.markdown(message["content"]) | |
# Chatbox for subsequent conversations with assistant (follow-up mode) | |
if st.session_state.follow_up_mode: | |
if user_input := st.chat_input("Continue your conversation or ask follow-up questions here:"): | |
# Display user message in chat message container and add to session history | |
with st.chat_message("user"): | |
st.markdown(user_input) | |
st.session_state.messages.append({"role": "user", "content": user_input}) | |
# Generate assistant's response based on follow-up input using technical_interviewer_prompt as system prompt | |
assistant_response = generate_response( | |
[{"role": "assistant", "content": technical_interviewer_prompt}] + st.session_state.messages | |
) | |
with st.chat_message("assistant"): | |
st.markdown(assistant_response) | |
st.session_state.messages.append({"role": "assistant", "content": assistant_response}) | |
# Sidebar content to display persistent generated question (left sidebar) | |
st.sidebar.markdown("## Generated Question") | |
if st.session_state.generated_question: | |
st.sidebar.markdown(st.session_state.generated_question) | |
else: | |
st.sidebar.markdown("_No question generated yet._") | |
st.sidebar.markdown(""" | |
## About | |
This is a Real-World Interview Question Generator powered by OpenAI's API. | |
Enter a company name, topic, and level of difficulty, and it will transform a relevant question into a real-world interview scenario! | |
Continue chatting with the assistant in the chatbox below. | |
""") | |
# Right sidebar toggleable debug logs | |
with st.expander("Debug Logs (Toggle On/Off)", expanded=False): | |
if len(st.session_state.debug_logs) > 0: | |
for log_entry in reversed(st.session_state.debug_logs): # Show most recent logs first | |
st.write(log_entry) |