File size: 8,671 Bytes
352d473
c672d1b
35e8298
352d473
35e8298
 
f73c0d1
35e8298
f73c0d1
 
35e8298
352d473
f73c0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35e8298
 
c672d1b
f73c0d1
 
473251f
c672d1b
35e8298
f73c0d1
 
 
 
 
 
 
 
473251f
f73c0d1
 
35e8298
f73c0d1
 
 
 
 
35e8298
f73c0d1
 
 
35e8298
f73c0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35e8298
f73c0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c672d1b
35e8298
f73c0d1
 
352d473
35e8298
 
 
 
f73c0d1
352d473
35e8298
f73c0d1
35e8298
 
 
 
f73c0d1
35e8298
f73c0d1
35e8298
 
f73c0d1
 
 
35e8298
f73c0d1
35e8298
 
 
f73c0d1
35e8298
 
 
f73c0d1
 
 
 
35e8298
f73c0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
35e8298
 
f73c0d1
 
 
35e8298
352d473
35e8298
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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("""
<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)

# 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()