Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import streamlit as st | |
| from huggingface_hub import InferenceClient | |
| from dotenv import load_dotenv | |
| import traceback | |
| # Load environment variables | |
| load_dotenv() | |
| hf_token = os.getenv("HUGGINGFACEHUB_API_TOKEN") | |
| # Setup Streamlit | |
| st.set_page_config(page_title="Interview Prep Bot", page_icon="π§ ", layout="centered") | |
| st.title("π Interview Preparation Chatbot") | |
| # Token check | |
| if not hf_token: | |
| st.error("Token not found. Check your .env file.") | |
| st.stop() | |
| model_id = "mistralai/Mixtral-8x7B-Instruct-v0.1" | |
| try: | |
| client = InferenceClient(model=model_id, token=hf_token) | |
| st.success("π Connected to Hugging Face Inference API.") | |
| except Exception as e: | |
| st.error(f"Failed to initialize InferenceClient: {e}") | |
| st.stop() | |
| # Debug reset button (useful once to fix corrupted state) | |
| if st.button("π Reset App"): | |
| for key in list(st.session_state.keys()): | |
| del st.session_state[key] | |
| st.rerun() | |
| # Sidebar topic & stats | |
| topics = [ | |
| "Machine Learning", | |
| "Data Structures", | |
| "Python", | |
| "Generative AI", | |
| "Computer Vision", | |
| "Deep Learning" | |
| ] | |
| st.sidebar.header("π Select Topic") | |
| topic = st.sidebar.selectbox("Topic:", topics) | |
| # Safely initialize session state | |
| if "questions" not in st.session_state or not isinstance(st.session_state.questions, list): | |
| st.session_state.questions = [] | |
| if "score" not in st.session_state or not isinstance(st.session_state.score, int): | |
| st.session_state.score = 0 | |
| if "correct_count" not in st.session_state or not isinstance(st.session_state.correct_count, int): | |
| st.session_state.correct_count = 0 | |
| if "incorrect_count" not in st.session_state or not isinstance(st.session_state.incorrect_count, int): | |
| st.session_state.incorrect_count = 0 | |
| if "active_question" not in st.session_state: | |
| st.session_state.active_question = None | |
| if "last_action" not in st.session_state: | |
| st.session_state.last_action = "" | |
| st.sidebar.markdown("---") | |
| st.sidebar.header("π Your Score") | |
| st.sidebar.markdown(f"**Questions:** {len(st.session_state.questions)}") | |
| st.sidebar.markdown(f"**Correct:** {st.session_state.correct_count}") | |
| st.sidebar.markdown(f"**Incorrect:** {st.session_state.incorrect_count}") | |
| st.sidebar.markdown(f"**Points:** {st.session_state.score}") | |
| # Fetch unique MCQ | |
| def fetch_mcq(topic, past_questions=None, max_retries=3): | |
| if past_questions is None: | |
| past_questions = set(q["question"] for q in st.session_state.questions) | |
| prompt_template = ( | |
| f"Generate a multiple-choice question about {topic}. " | |
| "Return only JSON with keys: question (string), options (4 strings), correct_index (0-based integer). " | |
| "Make the question unique and different from this list:\n" + | |
| json.dumps(list(past_questions)) | |
| ) | |
| for _ in range(max_retries): | |
| try: | |
| response = client.chat_completion( | |
| model=model_id, | |
| messages=[ | |
| {"role": "system", "content": "You are a helpful MCQ bot that returns JSON only."}, | |
| {"role": "user", "content": prompt_template} | |
| ] | |
| ) | |
| content = response.choices[0].message.get("content", "").strip() | |
| data = json.loads(content) | |
| new_question = data.get("question", "").strip() | |
| if new_question in past_questions: | |
| continue | |
| return { | |
| "question": new_question, | |
| "options": data["options"], | |
| "correct_index": data["correct_index"], | |
| "selected": None, | |
| "submitted": False | |
| } | |
| except Exception as e: | |
| st.error("β Error fetching MCQ") | |
| st.text(traceback.format_exc()) | |
| return None | |
| st.warning("β οΈ Couldn't generate a unique question after several tries.") | |
| return None | |
| # Handle logic based on last action | |
| if st.session_state.last_action == "submit": | |
| new_q = fetch_mcq(topic) | |
| if new_q: | |
| st.session_state.active_question = new_q | |
| st.session_state.last_action = "" | |
| # Render active question or show start button | |
| q = st.session_state.active_question | |
| if not q: | |
| if st.button("π§ Start Interview"): | |
| new_q = fetch_mcq(topic) | |
| if new_q: | |
| st.session_state.active_question = new_q | |
| else: | |
| st.markdown(f"### β {q['question']}") | |
| choice = st.radio( | |
| "Choose your answer:", | |
| range(4), | |
| format_func=lambda i: q["options"][i], | |
| index=q.get("selected", 0), | |
| key="answer", | |
| disabled=q["submitted"] | |
| ) | |
| st.session_state.active_question["selected"] = choice | |
| if not q["submitted"]: | |
| if st.button("β Submit Answer"): | |
| q["submitted"] = True | |
| if choice == q["correct_index"]: | |
| st.success("β Correct! +10 points") | |
| st.session_state.score += 10 | |
| st.session_state.correct_count += 1 | |
| else: | |
| correct_ans = q["options"][q["correct_index"]] | |
| st.error(f"β Incorrect. Correct answer: {correct_ans} (-10 points)") | |
| st.session_state.score -= 10 | |
| st.session_state.incorrect_count += 1 | |
| st.session_state.questions.append(q) | |
| st.session_state.last_action = "submit" | |
| st.rerun() # <== Force rerun after submission | |