|
import streamlit as st |
|
import json |
|
import time |
|
|
|
|
|
st.set_page_config( |
|
page_title="Manyue's Portfolio Chatbot", |
|
page_icon="π€", |
|
layout="wide", |
|
initial_sidebar_state="collapsed" |
|
) |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
.chat-message { |
|
padding: 1.5rem; |
|
border-radius: 0.5rem; |
|
margin-bottom: 1rem; |
|
} |
|
.user-message { |
|
background-color: #e9ecef; |
|
} |
|
.bot-message { |
|
background-color: #f8f9fa; |
|
} |
|
.stButton>button { |
|
width: 100%; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
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": [] |
|
} |
|
|
|
|
|
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", "") |
|
}) |
|
|
|
|
|
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"] |
|
|
|
|
|
elif any(word in query_lower for word in ["education", "study", "learn", "degree", "college", "university"]): |
|
context["type"] = "education" |
|
context["content"] = knowledge_base.get("education", {}) |
|
|
|
|
|
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", []) |
|
} |
|
|
|
|
|
elif any(word in query_lower for word in ["background", "journey", "story", "transition"]): |
|
context["type"] = "background" |
|
context["content"] = knowledge_base.get("personal_journey", {}) |
|
|
|
|
|
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 = [] |
|
|
|
|
|
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", "")) |
|
|
|
|
|
if context["relevant_sections"]: |
|
for section in context["relevant_sections"]: |
|
if section["type"] == "faq": |
|
response_parts.append(f"\n\n{section['answer']}") |
|
|
|
|
|
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!") |
|
|
|
|
|
knowledge_base = load_knowledge_base() |
|
|
|
|
|
col1, col2 = st.columns([3, 1]) |
|
|
|
with col1: |
|
|
|
for message in st.session_state.messages: |
|
with st.chat_message(message["role"]): |
|
st.markdown(message["content"]) |
|
|
|
|
|
if prompt := st.chat_input("What would you like to know?"): |
|
|
|
st.session_state.messages.append({"role": "user", "content": prompt}) |
|
|
|
|
|
context = get_enhanced_context(prompt, knowledge_base) |
|
response = generate_response(prompt, context) |
|
|
|
|
|
with st.chat_message("assistant"): |
|
st.markdown(response) |
|
|
|
|
|
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() |