import streamlit as st import json from typing import Dict, List, Any import re def format_project_response(project: dict, include_status: bool = True) -> str: """Format a project description with proper status handling""" response = [f"• {project['name']}:"] response.append(f" - {project['description']}") if 'skills_used' in project: response.append(f" - Technologies: {', '.join(project['skills_used'])}") if include_status and 'status' in project: if 'development' in project['status'].lower() or 'progress' in project['status'].lower(): response.append(f" - Currently {project['status']}") if 'confidentiality_note' in project: response.append(f" - Note: {project['confidentiality_note']}") return '\n'.join(response) def analyze_job_requirements(text: str, knowledge_base: dict) -> Dict[str, List[str]]: """Analyze job requirements and match with skills""" text_lower = text.lower() # Extract skills from knowledge base my_skills = { 'technical': [skill.lower() for skill in knowledge_base['skills']['technical_skills']['machine_learning']['core'] + knowledge_base['skills']['technical_skills']['programming']['primary'] + knowledge_base['skills']['technical_skills']['data']['databases']], 'tools': [tool.lower() for tool in knowledge_base['skills']['technical_skills']['programming']['tools'] + knowledge_base['skills']['technical_skills']['deployment']['web']], 'soft_skills': [skill['skill'].lower() for skill in knowledge_base['skills']['soft_skills']] } # Find matching skills in job description matches = { 'technical_matches': [skill for skill in my_skills['technical'] if skill in text_lower], 'tool_matches': [tool for tool in my_skills['tools'] if tool in text_lower], 'soft_skill_matches': [skill for skill in my_skills['soft_skills'] if skill in text_lower] } return matches def find_relevant_projects(requirements: str, projects: List[dict]) -> List[dict]: """Find projects relevant to job requirements""" req_lower = requirements.lower() relevant_projects = [] for project in projects: # Check if project skills or description match requirements if any(skill.lower() in req_lower for skill in project['skills_used']) or \ any(word in project['description'].lower() for word in req_lower.split()): relevant_projects.append(project) return relevant_projects[:2] # Return top 2 most relevant projects def add_relevant_links(response: str, query: str, knowledge_base: dict) -> str: """Add relevant links based on query context""" query_lower = query.lower() links = [] # Add portfolio link for project-related queries if any(word in query_lower for word in ['project', 'portfolio', 'work']): links.append(f"\nView my complete portfolio: {knowledge_base['personal_details']['online_presence']['portfolio']}") # Add blog link for technical queries if any(word in query_lower for word in ['machine learning', 'ml', 'algorithm', 'knn']): for post in knowledge_base['personal_details']['online_presence']['blog_posts']: if 'link' in post and any(word in post['title'].lower() for word in query_lower.split()): links.append(f"\nRelated blog post: {post['link']}") break # Add LinkedIn for professional background queries if any(word in query_lower for word in ['background', 'experience', 'work']): links.append(f"\nConnect with me: {knowledge_base['personal_details']['online_presence']['linkedin']}") if links: response += '\n\n' + '\n'.join(links) return response def generate_response(query: str, knowledge_base: dict) -> str: """Generate enhanced responses using the knowledge base""" query_lower = query.lower() # Handle project listing requests if any(word in query_lower for word in ['list', 'project', 'portfolio', 'built', 'created', 'developed']): response_parts = ["Here are my key projects:"] # Major Projects (under development) response_parts.append("\nMajor Projects (In Development):") for project in knowledge_base['projects']['major_projects']: response_parts.append(format_project_response(project)) # Algorithm Implementation Projects (completed) response_parts.append("\nCompleted Algorithm Implementation Projects:") for project in knowledge_base['projects']['algorithm_practice_projects']: response_parts.append(format_project_response(project, include_status=False)) response = '\n'.join(response_parts) return add_relevant_links(response, query, knowledge_base) # Handle job description analysis elif len(query.split()) > 20 and any(phrase in query_lower for phrase in ['requirements', 'qualifications', 'looking for', 'job description']): skill_matches = analyze_job_requirements(query, knowledge_base) relevant_projects = find_relevant_projects(query, knowledge_base['projects']['major_projects']) response_parts = ["Based on the job requirements, here's how my profile aligns:"] # Technical Skills Match if skill_matches['technical_matches']: response_parts.append("\n• Technical Skills Match:") for skill in skill_matches['technical_matches']: response_parts.append(f" - Strong proficiency in {skill}") # Tools and Technologies if skill_matches['tool_matches']: response_parts.append("\n• Relevant Tools/Technologies:") for tool in skill_matches['tool_matches']: response_parts.append(f" - Experience with {tool}") # Relevant Projects if relevant_projects: response_parts.append("\n• Relevant Project Experience:") for project in relevant_projects: response_parts.append(format_project_response(project)) # Education and Background response_parts.append("\n• Education and Background:") response_parts.append(" - Currently pursuing advanced AI/ML education in Canada") response_parts.append(" - Unique background combining commerce and technology") response_parts.append(" - Strong foundation in practical ML implementation") response = '\n'.join(response_parts) return add_relevant_links(response, query, knowledge_base) # Handle background/story queries elif any(word in query_lower for word in ['background', 'journey', 'story', 'transition']): transition_story = next((qa['answer'] for qa in knowledge_base['frequently_asked_questions'] if 'transition' in qa['question'].lower()), '') response_parts = [ "My Journey from Commerce to ML/AI:", "• Education Background:", f" - {knowledge_base['education']['undergraduate']['course_name']} from {knowledge_base['education']['undergraduate']['institution']}", "• Career Transition:", " - Started as a Programmer Trainee at Cognizant", f" - {transition_story[:200]}...", "• Current Path:", " - Pursuing AI/ML education in Canada", " - Building practical ML projects", "• Future Goals:", " - Aiming to become an ML Engineer in Canada", " - Focus on innovative AI solutions" ] response = '\n'.join(response_parts) return add_relevant_links(response, query, knowledge_base) # Handle skill-specific queries elif any(word in query_lower for word in ['skill', 'know', 'technology', 'stack']): tech_skills = knowledge_base['skills']['technical_skills'] response_parts = ["My Technical Expertise:"] # ML/AI Skills response_parts.append("\n• Machine Learning & AI:") response_parts.append(f" - Core: {', '.join(tech_skills['machine_learning']['core'])}") response_parts.append(f" - Frameworks: {', '.join(tech_skills['machine_learning']['frameworks'])}") # Programming & Tools response_parts.append("\n• Programming & Development:") response_parts.append(f" - Languages: {', '.join(tech_skills['programming']['primary'])}") response_parts.append(f" - Tools: {', '.join(tech_skills['programming']['tools'])}") # Data & Analytics response_parts.append("\n• Data & Analytics:") response_parts.append(f" - Databases: {', '.join(tech_skills['data']['databases'])}") response_parts.append(f" - Visualization: {', '.join(tech_skills['data']['visualization'])}") response = '\n'.join(response_parts) return add_relevant_links(response, query, knowledge_base) # Handle default/unknown queries return (f"I'm {knowledge_base['personal_details']['full_name']}, " f"{knowledge_base['personal_details']['professional_summary']}\n\n" "You can ask me about:\n" "• My projects and portfolio\n" "• My journey from commerce to ML/AI\n" "• My technical skills and experience\n" "• My fit for ML/AI roles\n" "Or paste a job description to see how my profile matches!") def main(): st.title("💬 Chat with Manyue's Portfolio") # Initialize session state if "messages" not in st.session_state: st.session_state.messages = [] if "knowledge_base" not in st.session_state: try: with open('knowledge_base.json', 'r', encoding='utf-8') as f: st.session_state.knowledge_base = json.load(f) except FileNotFoundError: st.error("Knowledge base file not found.") return # Display welcome message if "displayed_welcome" not in st.session_state: st.write(""" Hi! I'm Manyue's AI assistant. I can tell you about: - My journey from commerce to ML/AI - My technical skills and projects - My fit for ML/AI roles - You can also paste job descriptions to see how my profile matches! """) st.session_state.displayed_welcome = True # Create two columns col1, col2 = st.columns([3, 1]) with col1: # Display chat messages for message in st.session_state.messages: with st.chat_message(message["role"]): st.markdown(message["content"]) # Chat input if prompt := st.chat_input("Ask me anything or paste a job description..."): # Add user message st.session_state.messages.append({"role": "user", "content": prompt}) # Generate and display response with st.chat_message("assistant"): response = generate_response(prompt, st.session_state.knowledge_base) st.markdown(response) st.session_state.messages.append({"role": "assistant", "content": response}) st.rerun() with col2: st.subheader("Quick Questions") example_questions = [ "Tell me about your ML projects", "What are your technical skills?", "Why should we hire you as an ML Engineer?", "What's your journey into ML?", "Paste a job description to see how I match!" ] for question in example_questions: if st.button(question): st.session_state.messages.append({"role": "user", "content": question}) st.rerun() st.markdown("---") if st.button("Clear Chat"): st.session_state.messages = [] st.rerun() if __name__ == "__main__": main()