# app.py # Pakistan AI Career Roadmap Bot # Interactive Streamlit Application β€” Dark Blue/Red Theme import streamlit as st from groq import Groq from dotenv import load_dotenv import os from prompts import ( SYSTEM_PROMPT, get_career_prompt, is_safe_input, is_safe_output ) from domains import ( get_all_domains, get_domain_info ) # ===================================== # LOAD API KEY # ===================================== load_dotenv() try: api_key = st.secrets["GROQ_API_KEY"] except: api_key = os.getenv("GROQ_API_KEY") client = Groq(api_key=api_key) # ===================================== # PAGE CONFIG # ===================================== st.set_page_config( page_title="Pakistan AI Career Bot", page_icon="πŸ€–", layout="wide" ) # ===================================== # GLOBAL CSS # ===================================== st.markdown(""" """, unsafe_allow_html=True) # ===================================== # DOMAIN ICONS # ===================================== DOMAIN_ICONS = { "Machine Learning Engineer": "🧠", "Deep Learning Engineer": "⚑", "Computer Vision Engineer": "πŸ‘οΈ", "NLP Engineer": "πŸ’¬", "MLOps Engineer": "βš™οΈ", "Data Scientist": "πŸ“Š", "Generative AI Engineer": "✨", "AI Research Engineer": "πŸ”¬" } # ===================================== # SESSION STATE # ===================================== defaults = { "messages": [{"role": "system", "content": SYSTEM_PROMPT}], "roadmap_generated": False, "selected_domain": None, "roadmap_text": "", "current_step": 1, "student_name": "", "form_data": {} } for k, v in defaults.items(): if k not in st.session_state: st.session_state[k] = v # ===================================== # HERO # ===================================== st.markdown("""
● Pakistan AI Career Roadmap Bot
Find Your Path in Artificial Intelligence
AI-powered personalized learning roadmaps for students β€” by Athar Abbas
""", unsafe_allow_html=True) # ===================================== # STEP TRACKER # ===================================== step = st.session_state.current_step labels = ["Domain", "Profile", "Generating", "Roadmap"] def sc(n): # circle class if n < step: return "done" if n == step: return "active" return "idle" def lc(n): # line class return "done-line" if n < step else "" nodes_html = "" for i, lbl in enumerate(labels, 1): nodes_html += f'
{i}
{lbl}
' if i < len(labels): nodes_html += f'
' st.markdown(f'
{nodes_html}
', unsafe_allow_html=True) st.markdown("
", unsafe_allow_html=True) # ====================================================== # STEP 1 β€” CHOOSE DOMAIN # ====================================================== if step == 1: st.markdown('
Choose Your AI Domain
', unsafe_allow_html=True) st.markdown('
Select the specialisation that excites you most β€” we\'ll build a roadmap around it.
', unsafe_allow_html=True) all_domains = get_all_domains() cols = st.columns(4) for i, dname in enumerate(all_domains): dinfo = get_domain_info(dname) icon = DOMAIN_ICONS.get(dname, "πŸ€–") chips = "".join([f'{s}' for s in dinfo["skills_required"][:3]]) with cols[i % 4]: st.markdown(f"""
{icon}
{dname}
{dinfo['description']}
{chips}
""", unsafe_allow_html=True) if st.button(f"Select {icon}", key=f"d{i}", use_container_width=True): st.session_state.selected_domain = dname st.session_state.current_step = 2 st.rerun() # ====================================================== # STEP 2 β€” STUDENT PROFILE # ====================================================== elif step == 2: dinfo = get_domain_info(st.session_state.selected_domain) icon = DOMAIN_ICONS.get(st.session_state.selected_domain, "πŸ€–") # Banner st.markdown(f"""
{icon}
{st.session_state.selected_domain}
{dinfo['description']}
""", unsafe_allow_html=True) # Stats (no salary, no duration) st.markdown(f"""
{len(dinfo['skills_required'])}
Core Skills
{len(dinfo['free_resources'])}
Free Resources
""", unsafe_allow_html=True) # Form st.markdown('
', unsafe_allow_html=True) st.markdown('
πŸ‘€ Tell Us About Yourself
', unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: name = st.text_input("Your Good Name", placeholder="e.g. Athar Abbas") education = st.selectbox("Current Education", [ "Matric / O-Levels", "FSc / A-Levels", "BS CS/IT/AI β€” 1st Semester", "BS CS/IT/AI β€” 2nd Semester", "BS CS/IT/AI β€” 3rd Semester", "BS CS/IT/AI β€” 4th Semester", "BS CS/IT/AI β€” 5th Semester", "BS CS/IT/AI β€” 6th Semester", "BS CS/IT/AI β€” 7th Semester", "BS CS/IT/AI β€” 8th Semester", "Fresh Graduate", "Working Professional", "Other" ]) with col2: experience = st.selectbox("Coding Experience Level", [ "Complete Beginner β€” No experience", "Beginner β€” Less than 6 months", "Intermediate β€” 6 months to 1 year", "Solid β€” 1 to 2 years", "Experienced β€” 2+ years" ]) skills = st.multiselect("Your Current Skills", [ "Python Basics", "Python Advanced", "Mathematics", "Statistics", "Machine Learning Basics", "Deep Learning", "Data Analysis", "SQL", "Web Development", "No Skills Yet" ]) st.markdown("
", unsafe_allow_html=True) st.markdown("
", unsafe_allow_html=True) c1, c2 = st.columns([1, 3]) with c1: if st.button("← Back", use_container_width=True): st.session_state.current_step = 1 st.rerun() with c2: if st.button("πŸš€ Generate My Roadmap", use_container_width=True): if not name.strip(): st.warning("⚠️ Please enter your name to continue.") else: st.session_state.student_name = name.strip() st.session_state.form_data = { "name": name.strip(), "education": education, "skills": skills, "experience": experience } st.session_state.current_step = 3 st.rerun() # ====================================================== # STEP 3 β€” GENERATING # ====================================================== elif step == 3: st.markdown("""
⚑
Building Your Roadmap
Analysing profile Β· cross-checking recommendations Β· writing plan
""", unsafe_allow_html=True) progress_bar = st.progress(0, text="Initialising…") form = st.session_state.form_data career_prompt = get_career_prompt( name = form["name"], education = form["education"], skills = ", ".join(form["skills"]) if form["skills"] else "No skills yet", domain = st.session_state.selected_domain, experience = form["experience"] ) if not is_safe_input(career_prompt): st.error("⚠️ Invalid input detected.") st.session_state.current_step = 2 st.rerun() st.session_state.messages.append({"role": "user", "content": career_prompt}) responses = [] for i in range(3): pct = (i + 1) * 30 msgs = [f"Generating roadmap β€” pass {i+1}/3…", "Cross-checking domain knowledge…", "Selecting best response…"] progress_bar.progress(pct, text=msgs[i]) resp = client.chat.completions.create( model = "llama-3.1-8b-instant", messages = st.session_state.messages, temperature= 0.3, max_tokens = 2000 ) responses.append(resp.choices[0].message.content) progress_bar.progress(100, text="βœ… Done!") best = max(responses, key=len) if not is_safe_output(best): st.error("⚠️ Something went wrong. Please try again.") st.session_state.current_step = 2 else: st.session_state.messages.append({"role": "assistant", "content": best}) st.session_state.roadmap_text = best st.session_state.roadmap_generated= True st.session_state.current_step = 4 st.rerun() # ====================================================== # STEP 4 β€” ROADMAP DISPLAY # ====================================================== elif step == 4: icon = DOMAIN_ICONS.get(st.session_state.selected_domain, "πŸ€–") dinfo = get_domain_info(st.session_state.selected_domain) name = st.session_state.student_name # Top row: title + download col_hdr, col_dl = st.columns([3, 1]) with col_hdr: st.markdown(f"""
{icon}
{st.session_state.selected_domain}
Roadmap for {name}
""", unsafe_allow_html=True) with col_dl: download_content = ( f"AI CAREER ROADMAP\n" f"For: {name}\n" f"Domain: {st.session_state.selected_domain}\n" f"{'─'*50}\n\n" f"{st.session_state.roadmap_text}\n\n" f"{'─'*50}\n" f"Generated by AI Career Roadmap Bot\n" ) st.markdown("
", unsafe_allow_html=True) st.download_button( label = "⬇️ Download Roadmap", data = download_content, file_name= f"AI_Roadmap_{name.replace(' ','_')}.txt", mime = "text/plain", use_container_width=True ) # Stats (no salary, no duration) st.markdown(f"""
{len(dinfo['skills_required'])}
Skills in Roadmap
{len(dinfo['pakistani_companies'])}
Hiring Companies
""", unsafe_allow_html=True) # Roadmap content β€” styled like Claude output st.markdown('
', unsafe_allow_html=True) st.markdown(st.session_state.roadmap_text) st.markdown("
", unsafe_allow_html=True) st.divider() # ── Follow-up chat ── st.markdown('
πŸ’¬ Ask Follow-up Questions
', unsafe_allow_html=True) st.markdown('
Have questions about your roadmap? Ask anything below.
', unsafe_allow_html=True) # show only follow-up messages (skip system + initial roadmap exchange) for msg in st.session_state.messages[3:]: with st.chat_message(msg["role"]): st.write(msg["content"]) user_q = st.chat_input("Ask about resources, skills, companies…") if user_q: if not is_safe_input(user_q): st.error("⚠️ Please ask career-related questions only.") else: st.session_state.messages.append({"role": "user", "content": user_q}) with st.spinner("Thinking…"): resp = client.chat.completions.create( model = "llama-3.1-8b-instant", messages = st.session_state.messages, temperature= 0.3, max_tokens = 1000 ) reply = resp.choices[0].message.content if not is_safe_output(reply): st.error("⚠️ Something went wrong.") else: st.session_state.messages.append({"role": "assistant", "content": reply}) st.rerun() st.divider() # Action buttons c1, c2 = st.columns(2) with c1: if st.button("πŸ”„ New Roadmap", use_container_width=True): for k, v in defaults.items(): st.session_state[k] = v st.rerun() with c2: if st.button("πŸ”€ Change Domain", use_container_width=True): st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}] st.session_state.roadmap_generated = False st.session_state.roadmap_text = "" st.session_state.selected_domain = None st.session_state.current_step = 1 st.rerun() # ── FOOTER ── st.markdown(""" """, unsafe_allow_html=True)