import streamlit as st import json import time # Page configuration st.set_page_config( page_title="Manyue's Portfolio Chatbot", page_icon="🤖", layout="wide", initial_sidebar_state="collapsed" ) # Custom CSS for better UI st.markdown(""" """, unsafe_allow_html=True) # Initialize session state if 'messages' not in st.session_state: st.session_state.messages = [] if 'knowledge_base' not in st.session_state: st.session_state.knowledge_base = None def load_knowledge_base(): """Load the knowledge base from JSON file""" if st.session_state.knowledge_base is None: try: with open('knowledge_base.json', 'r', encoding='utf-8') as f: st.session_state.knowledge_base = json.load(f) except Exception as e: st.error(f"Error loading knowledge base: {str(e)}") st.session_state.knowledge_base = {} return st.session_state.knowledge_base def get_enhanced_context(query: str, knowledge_base: dict) -> dict: """Get relevant context with improved retrieval""" query_lower = query.lower() context = { "type": "general", "content": [], "relevant_sections": [] } # Project-related queries if any(word in query_lower for word in ["project", "build", "develop", "create", "make", "portfolio"]): context["type"] = "project" if "projects" in knowledge_base: for name, project in knowledge_base["projects"].items(): context["content"].append({ "title": name, "description": project.get("description", ""), "skills_used": project.get("skills_used", []), "status": project.get("status", "") }) # Skills and experience elif any(word in query_lower for word in ["skill", "experience", "know", "capable", "ability", "expert"]): context["type"] = "skill" if "skills" in knowledge_base.get("personal_details", {}): context["content"] = knowledge_base["personal_details"]["skills"] # Educational background elif any(word in query_lower for word in ["education", "study", "learn", "degree", "college", "university"]): context["type"] = "education" context["content"] = knowledge_base.get("education", {}) # Career and goals elif any(word in query_lower for word in ["goal", "plan", "future", "career", "aspiration"]): context["type"] = "career" context["content"] = { "short_term": knowledge_base.get("goals_and_aspirations", {}).get("short_term", []), "long_term": knowledge_base.get("goals_and_aspirations", {}).get("long_term", []) } # Personal background elif any(word in query_lower for word in ["background", "journey", "story", "transition"]): context["type"] = "background" context["content"] = knowledge_base.get("personal_journey", {}) # Add FAQ matches if available for qa in knowledge_base.get("frequently_asked_questions", []): if any(word in qa["question"].lower() for word in query_lower.split()): context["relevant_sections"].append({ "type": "faq", "question": qa["question"], "answer": qa["answer"] }) return context def generate_response(query: str, context: dict) -> str: """Generate natural response based on context""" response_parts = [] # Handle different types of queries if context["type"] == "project": response_parts.append("Let me tell you about my projects.") for project in context["content"]: response_parts.append(f"\n\n**{project['title']}**") response_parts.append(f"{project['description']}") if project['skills_used']: response_parts.append(f"\nSkills used: {', '.join(project['skills_used'])}") if project['status']: response_parts.append(f"\nStatus: {project['status']}") elif context["type"] == "skill": response_parts.append("Here are my key skills and experiences:") for skill, desc in context["content"].items(): response_parts.append(f"\n\n**{skill}**:\n{desc}") elif context["type"] == "education": response_parts.append("Regarding my educational background:") if "academic_background" in context["content"]: response_parts.append(context["content"]["academic_background"]) if "academic_achievements" in context["content"]: response_parts.append("\n\nAchievements:") for achievement in context["content"]["academic_achievements"]: response_parts.append(f"- {achievement}") elif context["type"] == "career": response_parts.append("Let me share my career goals:") response_parts.append("\n\n**Short-term goals:**") for goal in context["content"]["short_term"]: response_parts.append(f"- {goal}") response_parts.append("\n\n**Long-term goals:**") for goal in context["content"]["long_term"]: response_parts.append(f"- {goal}") elif context["type"] == "background": response_parts.append(context["content"].get("mindset", "")) response_parts.append("\n\n" + context["content"].get("motto_or_vision", "")) # Add any relevant FAQ information if context["relevant_sections"]: for section in context["relevant_sections"]: if section["type"] == "faq": response_parts.append(f"\n\n{section['answer']}") # Default response if no specific context matched if not response_parts: response_parts = ["I am Manyue, an aspiring AI/ML engineer. I can tell you about my projects, skills, education, or career goals. What would you like to know?"] return "\n".join(response_parts) def main(): st.title("💬 Chat with Manyue's Portfolio") st.write("Ask me about my skills, projects, education, or career goals!") # Load knowledge base knowledge_base = load_knowledge_base() # Create two columns for layout 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("What would you like to know?"): # Add user message st.session_state.messages.append({"role": "user", "content": prompt}) # Get context and generate response context = get_enhanced_context(prompt, knowledge_base) response = generate_response(prompt, context) # Display response with typing effect with st.chat_message("assistant"): st.markdown(response) # Add assistant response to history st.session_state.messages.append({"role": "assistant", "content": response}) with col2: st.subheader("Quick Questions") if st.button("📊 Tell me about your projects"): prompt = "What projects have you worked on?" st.session_state.messages.append({"role": "user", "content": prompt}) st.experimental_rerun() if st.button("💻 What are your technical skills?"): prompt = "What are your main technical skills?" st.session_state.messages.append({"role": "user", "content": prompt}) st.experimental_rerun() if st.button("🎓 Educational background?"): prompt = "Tell me about your education" st.session_state.messages.append({"role": "user", "content": prompt}) st.experimental_rerun() if st.button("🎯 What are your career goals?"): prompt = "What are your career goals?" st.session_state.messages.append({"role": "user", "content": prompt}) st.experimental_rerun() st.markdown("---") if st.button("🗑️ Clear Chat"): st.session_state.messages = [] st.experimental_rerun() if __name__ == "__main__": main()