File size: 7,309 Bytes
555d77a
d4c83d2
555d77a
9d504d6
 
 
a2c958a
9d504d6
f54e1ed
555d77a
d4c83d2
 
555d77a
f54e1ed
 
 
9d504d6
 
 
 
 
a2c958a
 
9d504d6
 
 
 
 
 
ba65c08
c050106
 
 
 
 
 
555d77a
1535def
9d504d6
777cd06
555d77a
c050106
 
 
 
555d77a
777cd06
 
 
07b37ec
 
 
f54e1ed
 
 
9d504d6
 
 
33552fd
f54e1ed
 
9d504d6
33552fd
9d504d6
 
 
c050106
07b37ec
 
9d504d6
d4c83d2
a2c958a
c050106
555d77a
07b37ec
d4c83d2
555d77a
f54e1ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1535def
 
f54e1ed
 
 
1535def
 
555d77a
1535def
c050106
 
1535def
 
 
9d504d6
 
 
 
 
 
 
 
 
 
 
f54e1ed
 
 
d903541
f54e1ed
 
c050106
555d77a
c050106
1535def
 
 
c050106
 
 
 
 
 
 
f54e1ed
82f5d13
c050106
 
f54e1ed
 
c050106
f54e1ed
 
 
 
c050106
f54e1ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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
import requests

# Set up OpenAI client
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# Set up ElevenLabs API key
ELEVENLABS_API_KEY = "your_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

if "code_output" not in st.session_state:
    st.session_state.code_output = None  # Stores the output of executed Python code

# Function to find the top 1 most similar question based on user input
def find_top_question(query):
    query_embedding = model.encode(query, convert_to_tensor=True, device=device).cpu().numpy()
    query_embedding = query_embedding.reshape(1, -1)  # Reshape to (1, n_features)
    similarities = cosine_similarity(query_embedding, embeddings).flatten()
    top_index = similarities.argsort()[-1]
    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

# Function to generate audio using ElevenLabs API
def generate_audio(text):
    url = "https://api.elevenlabs.io/v1/text-to-speech"
    headers = {
        "xi-api-key": ELEVENLABS_API_KEY,
        "content-type": "application/json"
    }
    payload = {
        "text": text,
        "voice_id": "21m00tcm4tlvdq8ikwam",  # Default voice ID; replace with desired voice ID.
        "voice_settings": {
            "similarity_boost": 0.85,
            "stability": 0.5
        }
    }
    
    response = requests.post(url, headers=headers, json=payload)
    
    if response.status_code == 200:
        audio_file_path = f"assistant_response.mp3"
        with open(audio_file_path, "wb") as audio_file:
            audio_file.write(response.content)
        return audio_file_path
    else:
        st.error(f"Error generating audio: {response.status_code} - {response.text}")
        return None

# User input form for generating a new question
with st.form(key="input_form"):
    company = st.text_input("Company", value="Google")
    difficulty = st.selectbox("Difficulty", ["Easy", "Medium", "Hard"], index=1)
    topic = st.text_input("Topic (e.g., Backtracking)", value="Backtracking")
    
    generate_button = st.form_submit_button(label="Generate")

if generate_button:
    st.session_state.messages = []
    st.session_state.follow_up_mode = False
    
    query = f"{company} {difficulty} {topic}"
    top_question = find_top_question(query)
    
    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."
    )
    
    response_text = generate_response([{"role": "assistant", "content": question_generation_prompt}, {"role": "user", "content": detailed_prompt}])
    
    st.session_state.generated_question = response_text

    st.session_state.messages.append({"role": "assistant", "content": response_text})
    
    st.session_state.follow_up_mode = True

for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

if st.session_state.follow_up_mode:
    if user_input := st.chat_input("Continue your conversation or ask follow-up questions here:"):
        with st.chat_message("user"):
            st.markdown(user_input)
        
        st.session_state.messages.append({"role": "user", "content": user_input})

        assistant_response_text = generate_response(
            [{"role": "assistant", "content": technical_interviewer_prompt}] + st.session_state.messages
        )

        assistant_audio_path = generate_audio(assistant_response_text)

        with st.chat_message("assistant"):
            st.markdown(assistant_response_text)
            if assistant_audio_path:
                audio_bytes = open(assistant_audio_path, "rb").read()
                st.audio(audio_bytes, format="audio/mp3")
        
        st.session_state.messages.append({"role": "assistant", "content": assistant_response_text})

# Left Sidebar: Generated Question and Code Box
with st.sidebar:
    # Top Half: Generated Question
    st.markdown("## Generated Question")
    if st.session_state.generated_question:
        st.markdown(st.session_state.generated_question)
    else:
        st.markdown("_No question generated yet._")

    # Divider between sections
    st.markdown("---")

    # Bottom Half: Python Code Box
    st.markdown("## Python Code Interpreter")
    
    code_input = st.text_area("Write your Python code here:")
    
    col1, col2 = st.columns(2)
    
    with col1:
        if st.button("Run Code"):
            try:
                exec_globals = {}
                exec(code_input, exec_globals)  # Execute user-provided code safely within its own scope.
                output_key_values = {k: v for k, v in exec_globals.items() if k != "__builtins__"}
                if output_key_values:
                    output_strs = [f"{key}: {value}" for key, value in output_key_values.items()]
                    output_display_strs = "\n".join(output_strs)
                    output_display_strs += "\nCode executed successfully!"
                    print(output_display_strs)

            except Exception as e: