HassanJalil commited on
Commit
f47f22c
·
verified ·
1 Parent(s): 744e789

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +153 -0
  2. app.py +1240 -0
  3. requirements.txt +28 -0
README.md ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Ashok 2.0 - Problem Solving Assistant
3
+ emoji: 🧠
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: streamlit
7
+ sdk_version: 1.29.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # 🧠 Ashok 2.0 - Learning Problem Solving Assistant
14
+
15
+ A smart, learning-enabled chatbot that specializes in problem-solving advice with an authentic Pakistani/Indian conversational style. Ashok learns from every conversation and gets smarter over time!
16
+
17
+ ## ✨ Key Features
18
+
19
+ ### 🎓 **Intelligent Learning System**
20
+ - **Learns from conversations**: Every helpful Q&A is remembered and used for future responses
21
+ - **Smart question filtering**: Automatically blocks silly questions with humorous "Abay Sallay" responses
22
+ - **Quality-based learning**: Only learns from meaningful problem-solving discussions
23
+ - **Source attribution**: Clearly shows whether advice comes from uploaded books or learned conversations
24
+
25
+ ### 📚 **Enhanced Knowledge Integration**
26
+ - **Upload PDF books**: Add problem-solving books to enhance Ashok's knowledge base
27
+ - **Multi-source responses**: Combines book knowledge with learned experiences
28
+ - **Chapter/page references**: Cites specific sources for credibility
29
+ - **Core frameworks**: Comes pre-loaded with essential problem-solving methodologies
30
+
31
+ ### 💬 **Authentic Conversational Style**
32
+ - **Bilingual charm**: Natural English-Urdu mixing ("yaar", "samjha", "bilkul")
33
+ - **Cultural authenticity**: Genuine Pakistani/Indian conversational patterns
34
+ - **Encouraging tone**: "Excellent question yaar!", "Bahut acha sawal!"
35
+ - **Practical focus**: Always provides actionable, real-world advice
36
+
37
+ ## 🚀 How to Use
38
+
39
+ ### 1. **Get Your API Key**
40
+ - Visit [Google AI Studio](https://makersuite.google.com/app/apikey)
41
+ - Sign in with your Google account
42
+ - Create a new API key (it's completely free!)
43
+ - Copy the key
44
+
45
+ ### 2. **Start Chatting**
46
+ - Enter your API key in the sidebar
47
+ - Ask detailed problem-solving questions
48
+ - Watch Ashok learn and improve with each conversation!
49
+
50
+ ### 3. **Optional: Upload Books**
51
+ - Upload PDF books about problem-solving, management, or leadership
52
+ - Ashok will process and integrate the content
53
+ - Get responses that reference specific chapters and pages
54
+
55
+ ## 💡 Example Questions
56
+
57
+ ### ✅ **Great Questions** (Ashok loves these!)
58
+ - *"How can I improve my team's decision-making process?"*
59
+ - *"What's the best approach to handle workplace conflicts?"*
60
+ - *"Can you explain effective problem-solving frameworks?"*
61
+ - *"How do I prioritize when everything seems urgent?"*
62
+ - *"What strategies work for managing difficult stakeholders?"*
63
+
64
+ ### ❌ **Silly Questions** (Get "Abay Sallay" responses!)
65
+ - *"Hi, how are you?"*
66
+ - *"What's your favorite color?"*
67
+ - *"Tell me a joke"*
68
+ - *"What's the weather like?"*
69
+
70
+ ## 🎯 Problem-Solving Topics Covered
71
+
72
+ - **Decision Making**: Frameworks, criteria, evaluation methods
73
+ - **Conflict Resolution**: Mediation, negotiation, win-win solutions
74
+ - **Team Management**: Leadership, communication, productivity
75
+ - **Strategic Thinking**: Planning, analysis, long-term vision
76
+ - **Creative Problem Solving**: Innovation, brainstorming, design thinking
77
+ - **Critical Thinking**: Analysis, evaluation, logical reasoning
78
+ - **Project Management**: Planning, execution, risk management
79
+
80
+ ## 🔧 Technical Features
81
+
82
+ ### **Smart Architecture**
83
+ - **FAISS vector database**: Fast, efficient similarity search
84
+ - **HuggingFace embeddings**: High-quality text understanding
85
+ - **Session persistence**: Knowledge retained during your visit
86
+ - **Quality scoring**: Automatic assessment of conversation value
87
+
88
+ ### **User Experience**
89
+ - **Real-time learning**: See when Ashok learns from your conversation
90
+ - **Knowledge statistics**: Track total documents, conversations, and learning progress
91
+ - **Source transparency**: Always know where information comes from
92
+ - **Responsive design**: Works great on desktop and mobile
93
+
94
+ ## 🛡️ Privacy & Security
95
+
96
+ - **No data storage**: Your conversations are only kept during your session
97
+ - **API key security**: Your key is never stored or logged
98
+ - **Local processing**: All AI processing happens through your own API key
99
+ - **Open source**: Full transparency in how your data is handled
100
+
101
+ ## 🎪 The "Abay Sallay" Experience
102
+
103
+ Ashok has a unique personality! Ask silly questions and you'll get authentic responses like:
104
+ - *"Abay Sallay! Don't waste my time with such bakwas. Ask me something related to problem solving yaar!"*
105
+ - *"Abay Sallay! This is a problem-solving platform. Be serious!"*
106
+ - *"Abay Sallay! Focus on real problems that need solving, samjha?"*
107
+
108
+ This isn't just for fun - it encourages users to ask meaningful, detailed questions that lead to better problem-solving advice!
109
+
110
+ ## 🔄 Local Development
111
+
112
+ Want to run this locally or customize it? Here's how:
113
+
114
+ ```bash
115
+ # Clone the repository
116
+ git clone <your-repo-url>
117
+ cd ashok-2.0
118
+
119
+ # Install dependencies
120
+ pip install -r requirements.txt
121
+
122
+ # Run locally
123
+ streamlit run app.py
124
+ ```
125
+
126
+ ### **For Persistent Learning** (Local Only)
127
+ The local version includes additional features:
128
+ - Knowledge base persists between sessions
129
+ - Automatic backups
130
+ - Advanced analytics
131
+ - Book pre-processing during deployment
132
+
133
+ ## 🤝 Contributing
134
+
135
+ Found a bug or have a suggestion? We'd love to hear from you!
136
+ - Improve the silly question detection
137
+ - Add new problem-solving frameworks
138
+ - Enhance the learning algorithms
139
+ - Suggest better "Abay Sallay" responses 😄
140
+
141
+ ## 📞 Support
142
+
143
+ If you encounter any issues:
144
+ 1. Check that your Gemini API key is valid
145
+ 2. Ensure you're asking problem-solving related questions
146
+ 3. Try refreshing the page if you see any errors
147
+ 4. For persistent issues, please report them in the community tab
148
+
149
+ ---
150
+
151
+ **🎯 Ready to solve problems with Ashok? Get your free API key and let's start! 🚀**
152
+
153
+ *Made with ❤️ for problem-solvers everywhere*
app.py ADDED
@@ -0,0 +1,1240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import google.generativeai as genai
3
+ from PyPDF2 import PdfReader
4
+ import os
5
+ import re
6
+ import json
7
+ import pickle
8
+ import hashlib
9
+ from datetime import datetime
10
+ from pathlib import Path
11
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
12
+ from langchain_huggingface.embeddings import HuggingFaceEmbeddings
13
+ from langchain_community.vectorstores import FAISS
14
+ from langchain.schema import Document
15
+ import tempfile
16
+ import warnings
17
+ import numpy as np
18
+ import shutil
19
+ import time
20
+ warnings.filterwarnings('ignore')
21
+
22
+ # Configure page
23
+ st.set_page_config(
24
+ page_title="Ashok 2.0 - AI Problem Solving Assistant",
25
+ page_icon="🧠",
26
+ layout="centered",
27
+ initial_sidebar_state="collapsed"
28
+ )
29
+
30
+ # World-class minimal UI styling
31
+ st.markdown("""
32
+ <style>
33
+ /* Import premium font */
34
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
35
+
36
+ /* Global Reset & Base */
37
+ .stApp {
38
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
39
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
40
+ }
41
+
42
+ .main .block-container {
43
+ padding-top: 2rem;
44
+ padding-bottom: 2rem;
45
+ max-width: 800px;
46
+ }
47
+
48
+ /* Hide Streamlit UI elements */
49
+ #MainMenu {visibility: hidden;}
50
+ footer {visibility: hidden;}
51
+ header {visibility: hidden;}
52
+ .stDeployButton {display: none;}
53
+
54
+ /* Main Heading */
55
+ .main-title {
56
+ font-size: 4rem;
57
+ font-weight: 700;
58
+ text-align: center;
59
+ background: linear-gradient(135deg, #1e40af 0%, #3b82f6 50%, #60a5fa 100%);
60
+ -webkit-background-clip: text;
61
+ -webkit-text-fill-color: transparent;
62
+ background-clip: text;
63
+ margin: 2rem 0 3rem 0;
64
+ letter-spacing: -0.02em;
65
+ line-height: 1.1;
66
+ }
67
+
68
+ /* API Key Setup Container */
69
+ .api-setup-container {
70
+ background: rgba(255, 255, 255, 0.9);
71
+ backdrop-filter: blur(10px);
72
+ border: 1px solid rgba(229, 231, 235, 0.6);
73
+ border-radius: 24px;
74
+ padding: 3rem;
75
+ margin: 2rem auto;
76
+ max-width: 500px;
77
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.05), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
78
+ text-align: center;
79
+ }
80
+
81
+ .api-setup-title {
82
+ font-size: 1.5rem;
83
+ font-weight: 600;
84
+ color: #1f2937;
85
+ margin-bottom: 1rem;
86
+ }
87
+
88
+ .api-setup-subtitle {
89
+ color: #6b7280;
90
+ margin-bottom: 2rem;
91
+ line-height: 1.6;
92
+ }
93
+
94
+ /* API Key Input Styling */
95
+ .stTextInput > div > div > input {
96
+ background: rgba(255, 255, 255, 0.8);
97
+ border: 2px solid rgba(229, 231, 235, 0.6);
98
+ border-radius: 16px;
99
+ padding: 1rem 1.5rem;
100
+ font-size: 1rem;
101
+ transition: all 0.3s ease;
102
+ backdrop-filter: blur(5px);
103
+ }
104
+
105
+ .stTextInput > div > div > input:focus {
106
+ border-color: #3b82f6;
107
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
108
+ outline: none;
109
+ background: rgba(255, 255, 255, 0.95);
110
+ }
111
+
112
+ .stTextInput label {
113
+ font-weight: 500;
114
+ color: #374151;
115
+ margin-bottom: 0.5rem;
116
+ }
117
+
118
+ /* Chat Interface */
119
+ .chat-container {
120
+ background: rgba(255, 255, 255, 0.7);
121
+ backdrop-filter: blur(10px);
122
+ border: 1px solid rgba(229, 231, 235, 0.4);
123
+ border-radius: 24px;
124
+ padding: 2rem;
125
+ margin: 2rem 0;
126
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.03), 0 4px 6px -2px rgba(0, 0, 0, 0.02);
127
+ }
128
+
129
+ /* Chat Messages */
130
+ .stChatMessage {
131
+ background: rgba(255, 255, 255, 0.9) !important;
132
+ border: 1px solid rgba(0, 0, 0, 0.08) !important;
133
+ border-radius: 16px !important;
134
+ margin-bottom: 1rem !important;
135
+ padding: 1.5rem !important;
136
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02) !important;
137
+ backdrop-filter: blur(5px) !important;
138
+ }
139
+
140
+ .stChatMessage[data-testid="chat-message-user"] {
141
+ background: rgba(248, 250, 252, 0.9) !important;
142
+ border-left: 3px solid #3b82f6 !important;
143
+ }
144
+
145
+ .stChatMessage[data-testid="chat-message-assistant"] {
146
+ background: rgba(255, 255, 255, 0.9) !important;
147
+ border-left: 3px solid #10b981 !important;
148
+ }
149
+
150
+ .stChatMessage .stMarkdown {
151
+ color: #1f2937 !important;
152
+ line-height: 1.6;
153
+ }
154
+
155
+ .stChatMessage .stMarkdown p {
156
+ color: #1f2937 !important;
157
+ margin-bottom: 0.5rem;
158
+ }
159
+
160
+ /* Chat Input */
161
+ .stChatInput > div {
162
+ background: rgba(255, 255, 255, 0.9);
163
+ border: 1px solid rgba(229, 231, 235, 0.6);
164
+ border-radius: 20px;
165
+ backdrop-filter: blur(10px);
166
+ }
167
+
168
+ .stChatInput input {
169
+ color: #1f2937 !important;
170
+ background: transparent !important;
171
+ border: none !important;
172
+ padding: 1rem 1.5rem !important;
173
+ }
174
+
175
+ .stChatInput input::placeholder {
176
+ color: #9ca3af !important;
177
+ }
178
+
179
+ /* Quick Actions */
180
+ .quick-actions-container {
181
+ background: rgba(255, 255, 255, 0.6);
182
+ backdrop-filter: blur(10px);
183
+ border: 1px solid rgba(229, 231, 235, 0.4);
184
+ border-radius: 20px;
185
+ padding: 2rem;
186
+ margin: 2rem 0;
187
+ }
188
+
189
+ .quick-actions-title {
190
+ font-size: 1.25rem;
191
+ font-weight: 600;
192
+ color: #1f2937;
193
+ text-align: center;
194
+ margin-bottom: 1.5rem;
195
+ }
196
+
197
+ .quick-action-grid {
198
+ display: grid;
199
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
200
+ gap: 1rem;
201
+ margin-top: 1rem;
202
+ }
203
+
204
+ .quick-action-item {
205
+ background: rgba(255, 255, 255, 0.8);
206
+ border: 1px solid rgba(229, 231, 235, 0.5);
207
+ border-radius: 16px;
208
+ padding: 1.5rem;
209
+ cursor: pointer;
210
+ transition: all 0.3s ease;
211
+ text-align: left;
212
+ backdrop-filter: blur(5px);
213
+ }
214
+
215
+ .quick-action-item:hover {
216
+ background: rgba(248, 250, 252, 0.9);
217
+ border-color: #3b82f6;
218
+ transform: translateY(-2px);
219
+ box-shadow: 0 8px 25px rgba(59, 130, 246, 0.1);
220
+ }
221
+
222
+ .quick-action-icon {
223
+ font-size: 1.5rem;
224
+ margin-bottom: 0.5rem;
225
+ }
226
+
227
+ .quick-action-title {
228
+ font-weight: 600;
229
+ color: #1f2937;
230
+ margin-bottom: 0.5rem;
231
+ font-size: 1rem;
232
+ }
233
+
234
+ .quick-action-desc {
235
+ color: #6b7280;
236
+ font-size: 0.9rem;
237
+ line-height: 1.5;
238
+ }
239
+
240
+ /* Control Panel */
241
+ .control-panel {
242
+ display: flex;
243
+ justify-content: center;
244
+ gap: 1rem;
245
+ margin: 2rem 0;
246
+ }
247
+
248
+ .control-button {
249
+ background: rgba(255, 255, 255, 0.8);
250
+ border: 1px solid rgba(229, 231, 235, 0.6);
251
+ border-radius: 12px;
252
+ padding: 0.75rem 1.5rem;
253
+ color: #374151;
254
+ font-weight: 500;
255
+ cursor: pointer;
256
+ transition: all 0.3s ease;
257
+ backdrop-filter: blur(5px);
258
+ }
259
+
260
+ .control-button:hover {
261
+ background: rgba(248, 250, 252, 0.9);
262
+ border-color: #3b82f6;
263
+ color: #1f2937;
264
+ transform: translateY(-1px);
265
+ }
266
+
267
+ /* Status Indicators */
268
+ .status-success {
269
+ background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(5, 150, 105, 0.1) 100%);
270
+ border: 1px solid rgba(16, 185, 129, 0.2);
271
+ border-radius: 16px;
272
+ padding: 1rem 1.5rem;
273
+ margin: 1rem 0;
274
+ color: #065f46;
275
+ font-weight: 500;
276
+ text-align: center;
277
+ backdrop-filter: blur(5px);
278
+ }
279
+
280
+ .status-warning {
281
+ background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(217, 119, 6, 0.1) 100%);
282
+ border: 1px solid rgba(245, 158, 11, 0.2);
283
+ border-radius: 16px;
284
+ padding: 1rem 1.5rem;
285
+ margin: 1rem 0;
286
+ color: #92400e;
287
+ font-weight: 500;
288
+ text-align: center;
289
+ backdrop-filter: blur(5px);
290
+ }
291
+
292
+ /* Learning Indicator */
293
+ .learning-indicator {
294
+ background: linear-gradient(135deg, rgba(16, 185, 129, 0.9) 0%, rgba(5, 150, 105, 0.9) 100%);
295
+ color: white;
296
+ padding: 1rem 1.5rem;
297
+ border-radius: 16px;
298
+ margin: 1rem 0;
299
+ font-weight: 500;
300
+ text-align: center;
301
+ box-shadow: 0 4px 6px rgba(16, 185, 129, 0.2);
302
+ backdrop-filter: blur(10px);
303
+ }
304
+
305
+ /* Typing Indicator */
306
+ .typing-indicator {
307
+ background: rgba(248, 250, 252, 0.9);
308
+ border: 1px solid rgba(229, 231, 235, 0.6);
309
+ border-radius: 16px;
310
+ padding: 1rem 1.5rem;
311
+ margin: 1rem 0;
312
+ display: flex;
313
+ align-items: center;
314
+ gap: 0.75rem;
315
+ color: #6b7280;
316
+ backdrop-filter: blur(5px);
317
+ }
318
+
319
+ .typing-dots {
320
+ display: flex;
321
+ gap: 4px;
322
+ }
323
+
324
+ .typing-dot {
325
+ width: 6px;
326
+ height: 6px;
327
+ border-radius: 50%;
328
+ background-color: #9ca3af;
329
+ animation: typing 1.4s infinite ease-in-out;
330
+ }
331
+
332
+ .typing-dot:nth-child(1) { animation-delay: -0.32s; }
333
+ .typing-dot:nth-child(2) { animation-delay: -0.16s; }
334
+
335
+ @keyframes typing {
336
+ 0%, 80%, 100% { transform: scale(0.8); opacity: 0.4; }
337
+ 40% { transform: scale(1); opacity: 1; }
338
+ }
339
+
340
+ /* Button Styling */
341
+ .stButton > button {
342
+ background: linear-gradient(135deg, rgba(59, 130, 246, 0.9) 0%, rgba(37, 99, 235, 0.9) 100%);
343
+ color: white !important;
344
+ border: none;
345
+ border-radius: 12px;
346
+ padding: 0.75rem 2rem;
347
+ font-weight: 500;
348
+ transition: all 0.3s ease;
349
+ backdrop-filter: blur(10px);
350
+ box-shadow: 0 4px 6px rgba(59, 130, 246, 0.2);
351
+ }
352
+
353
+ .stButton > button:hover {
354
+ background: linear-gradient(135deg, rgba(37, 99, 235, 0.9) 0%, rgba(29, 78, 216, 0.9) 100%);
355
+ transform: translateY(-1px);
356
+ box-shadow: 0 6px 12px rgba(59, 130, 246, 0.25);
357
+ }
358
+
359
+ /* API Key Guide */
360
+ .api-guide {
361
+ background: rgba(255, 255, 255, 0.6);
362
+ border: 1px solid rgba(229, 231, 235, 0.4);
363
+ border-radius: 16px;
364
+ padding: 1.5rem;
365
+ margin: 1.5rem 0;
366
+ backdrop-filter: blur(5px);
367
+ }
368
+
369
+ .api-guide-title {
370
+ font-weight: 600;
371
+ color: #1f2937;
372
+ margin-bottom: 1rem;
373
+ }
374
+
375
+ .api-guide-text {
376
+ color: #6b7280;
377
+ line-height: 1.6;
378
+ margin-bottom: 0.5rem;
379
+ }
380
+
381
+ .api-link {
382
+ color: #3b82f6;
383
+ text-decoration: none;
384
+ font-weight: 500;
385
+ transition: color 0.2s ease;
386
+ }
387
+
388
+ .api-link:hover {
389
+ color: #1d4ed8;
390
+ }
391
+
392
+ /* Responsive Design */
393
+ @media (max-width: 768px) {
394
+ .main-title {
395
+ font-size: 3rem;
396
+ }
397
+
398
+ .api-setup-container {
399
+ padding: 2rem;
400
+ margin: 1rem;
401
+ }
402
+
403
+ .quick-action-grid {
404
+ grid-template-columns: 1fr;
405
+ }
406
+
407
+ .control-panel {
408
+ flex-direction: column;
409
+ align-items: center;
410
+ }
411
+ }
412
+ </style>
413
+ """, unsafe_allow_html=True)
414
+
415
+ class PersistentHFKnowledgeBase:
416
+ """Persistent Knowledge Base with silent initialization"""
417
+
418
+ def __init__(self):
419
+ # Create persistent directories
420
+ self.data_dir = Path("./persistent_data")
421
+ self.data_dir.mkdir(exist_ok=True)
422
+
423
+ # File paths for persistence
424
+ self.vectorstore_path = self.data_dir / "vectorstore"
425
+ self.metadata_path = self.data_dir / "metadata.json"
426
+ self.conversations_path = self.data_dir / "conversations.json"
427
+ self.stats_path = self.data_dir / "stats.json"
428
+ self.init_flag_path = self.data_dir / "initialized.flag"
429
+
430
+ # Initialize components
431
+ self.embeddings = None
432
+ self.vectorstore = None
433
+ self.metadata = {}
434
+ self.conversations = []
435
+ self.stats = {}
436
+
437
+ # Initialize system silently
438
+ self.initialize_system()
439
+
440
+ def initialize_system(self):
441
+ """Initialize the complete system with silent book processing"""
442
+ try:
443
+ # Initialize embeddings first
444
+ self.init_embeddings()
445
+
446
+ # Check if system was already initialized
447
+ if self.init_flag_path.exists():
448
+ # Load existing knowledge base silently
449
+ self.load_existing_knowledge()
450
+ else:
451
+ # First time initialization - do it silently
452
+ self.first_time_initialization()
453
+
454
+ except Exception as e:
455
+ # Silent fallback initialization
456
+ self.fallback_initialization()
457
+
458
+ def init_embeddings(self):
459
+ """Initialize embeddings model with silent caching"""
460
+ if self.embeddings is None:
461
+ try:
462
+ cache_dir = self.data_dir / "embeddings_cache"
463
+ cache_dir.mkdir(exist_ok=True)
464
+
465
+ self.embeddings = HuggingFaceEmbeddings(
466
+ model_name="sentence-transformers/all-MiniLM-L6-v2",
467
+ cache_folder=str(cache_dir)
468
+ )
469
+ except Exception as e:
470
+ return False
471
+ return True
472
+
473
+ def first_time_initialization(self):
474
+ """Complete first-time setup with silent book processing"""
475
+ try:
476
+ # Initialize metadata
477
+ self.metadata = {
478
+ 'version': '2.0-minimal',
479
+ 'created_at': datetime.now().isoformat(),
480
+ 'last_updated': datetime.now().isoformat(),
481
+ 'total_documents': 0,
482
+ 'book_processed': False,
483
+ 'book_info': {},
484
+ 'initialization_complete': False
485
+ }
486
+
487
+ # Initialize stats
488
+ self.stats = {
489
+ 'total_queries': 0,
490
+ 'learning_sessions': 0,
491
+ 'book_chunks': 0,
492
+ 'conversation_chunks': 0,
493
+ 'silly_questions_blocked': 0
494
+ }
495
+
496
+ # Initialize conversations
497
+ self.conversations = []
498
+
499
+ # Process book if available (silently)
500
+ book_processed = self.process_startup_book()
501
+
502
+ # Create default knowledge if no book
503
+ if not book_processed:
504
+ self.create_default_knowledge()
505
+
506
+ # Mark as initialized
507
+ self.metadata['initialization_complete'] = True
508
+ self.save_all_data()
509
+
510
+ # Create initialization flag
511
+ with open(self.init_flag_path, 'w') as f:
512
+ f.write(f"Initialized on {datetime.now().isoformat()}")
513
+
514
+ except Exception as e:
515
+ self.fallback_initialization()
516
+
517
+ def process_startup_book(self):
518
+ """Process the book included with the deployment (silently)"""
519
+ book_paths = [
520
+ "book.pdf",
521
+ "problem_solving_book.pdf",
522
+ "default_book.pdf",
523
+ "ashok_book.pdf"
524
+ ]
525
+
526
+ for book_path in book_paths:
527
+ if Path(book_path).exists():
528
+ success = self.process_book_file(Path(book_path))
529
+ if success:
530
+ return True
531
+
532
+ return False
533
+
534
+ def process_book_file(self, book_path):
535
+ """Process a specific book file (silently)"""
536
+ try:
537
+ # Extract text from PDF
538
+ reader = PdfReader(str(book_path))
539
+ page_texts = []
540
+
541
+ for page_num, page in enumerate(reader.pages, 1):
542
+ page_text = page.extract_text()
543
+ if page_text.strip():
544
+ page_texts.append({
545
+ 'page': page_num,
546
+ 'text': page_text,
547
+ 'word_count': len(page_text.split())
548
+ })
549
+
550
+ if not page_texts:
551
+ return False
552
+
553
+ # Create book info
554
+ book_info = {
555
+ 'title': book_path.name,
556
+ 'path': str(book_path),
557
+ 'pages': len(page_texts),
558
+ 'processed_at': datetime.now().isoformat(),
559
+ 'source': 'deployment_book'
560
+ }
561
+
562
+ # Process content
563
+ success, message = self.process_book_content("", page_texts, book_info)
564
+
565
+ return success
566
+
567
+ except Exception as e:
568
+ return False
569
+
570
+ def create_default_knowledge(self):
571
+ """Create comprehensive default knowledge base"""
572
+ default_knowledge = [
573
+ {
574
+ "content": "Problem-solving methodology: 1) Problem Definition - Clearly articulate what needs to be solved, 2) Information Gathering - Collect relevant data and context, 3) Root Cause Analysis - Identify underlying causes, not just symptoms, 4) Solution Generation - Brainstorm multiple potential solutions, 5) Solution Evaluation - Assess feasibility, impact, and resources, 6) Implementation Planning - Create detailed action steps, 7) Execution and Monitoring - Implement and track progress, 8) Review and Learning - Evaluate outcomes and extract lessons.",
575
+ "metadata": {
576
+ "source": "core_knowledge",
577
+ "type": "framework",
578
+ "topic": "problem_solving_process",
579
+ "chapter": "Core Problem-Solving Framework"
580
+ }
581
+ },
582
+ {
583
+ "content": "Decision-making best practices: Use the DECIDE framework - D: Define the problem clearly, E: Establish criteria for solutions, C: Consider alternatives systematically, I: Identify best alternatives using criteria, D: Develop and implement action plan, E: Evaluate and monitor solution effectiveness. Always consider stakeholder impact, resource constraints, time limitations, and potential risks.",
584
+ "metadata": {
585
+ "source": "core_knowledge",
586
+ "type": "framework",
587
+ "topic": "decision_making",
588
+ "chapter": "Decision-Making Framework"
589
+ }
590
+ },
591
+ {
592
+ "content": "Conflict resolution strategies: 1) Active Listening - Understand all perspectives without judgment, 2) Identify Interests - Focus on underlying needs, not stated positions, 3) Find Common Ground - Identify shared goals and values, 4) Generate Options - Create win-win solutions collaboratively, 5) Use Objective Criteria - Apply fair standards for evaluation, 6) Separate People from Problems - Address issues, not personalities, 7) Maintain Relationships - Preserve working relationships while solving problems.",
593
+ "metadata": {
594
+ "source": "core_knowledge",
595
+ "type": "strategy",
596
+ "topic": "conflict_resolution",
597
+ "chapter": "Conflict Resolution Techniques"
598
+ }
599
+ },
600
+ {
601
+ "content": "Critical thinking skills development: Analysis (breaking complex information into components), Evaluation (assessing credibility and logical strength), Inference (drawing reasonable conclusions), Interpretation (understanding meaning and significance), Explanation (articulating reasoning clearly), Self-regulation (monitoring and correcting one's thinking). Practice questioning assumptions, considering multiple perspectives, examining evidence quality, and recognizing logical fallacies.",
602
+ "metadata": {
603
+ "source": "core_knowledge",
604
+ "type": "skills",
605
+ "topic": "critical_thinking",
606
+ "chapter": "Critical Thinking Development"
607
+ }
608
+ },
609
+ {
610
+ "content": "Team problem-solving dynamics: Establish psychological safety for open communication, define roles and responsibilities clearly, use structured problem-solving processes, encourage diverse perspectives, facilitate effective meetings, manage conflicts constructively, ensure equal participation, document decisions and action items, follow up on commitments, celebrate successes and learn from failures.",
611
+ "metadata": {
612
+ "source": "core_knowledge",
613
+ "type": "team_dynamics",
614
+ "topic": "team_problem_solving",
615
+ "chapter": "Team Collaboration for Problem Solving"
616
+ }
617
+ }
618
+ ]
619
+
620
+ # Create documents
621
+ documents = []
622
+ for item in default_knowledge:
623
+ doc = Document(
624
+ page_content=item["content"],
625
+ metadata=item["metadata"]
626
+ )
627
+ documents.append(doc)
628
+
629
+ # Create vectorstore
630
+ if documents and self.embeddings:
631
+ self.vectorstore = FAISS.from_documents(documents, self.embeddings)
632
+ self.stats['book_chunks'] = len(documents)
633
+ self.metadata['total_documents'] = len(documents)
634
+ self.metadata['book_processed'] = True
635
+ self.metadata['book_info'] = {
636
+ 'title': 'Core Problem-Solving Knowledge',
637
+ 'type': 'built_in',
638
+ 'chunks': len(documents)
639
+ }
640
+ return True
641
+ return False
642
+
643
+ def load_existing_knowledge(self):
644
+ """Load existing knowledge base from persistent storage"""
645
+ try:
646
+ # Load metadata
647
+ if self.metadata_path.exists():
648
+ with open(self.metadata_path, 'r') as f:
649
+ self.metadata = json.load(f)
650
+
651
+ # Load stats
652
+ if self.stats_path.exists():
653
+ with open(self.stats_path, 'r') as f:
654
+ self.stats = json.load(f)
655
+
656
+ # Load conversations
657
+ if self.conversations_path.exists():
658
+ with open(self.conversations_path, 'r') as f:
659
+ self.conversations = json.load(f)
660
+
661
+ # Load vectorstore
662
+ if self.vectorstore_path.exists() and self.embeddings:
663
+ self.vectorstore = FAISS.load_local(
664
+ str(self.vectorstore_path),
665
+ self.embeddings,
666
+ allow_dangerous_deserialization=True
667
+ )
668
+ return True
669
+ except Exception as e:
670
+ return False
671
+ return False
672
+
673
+ def save_all_data(self):
674
+ """Save all knowledge base data to persistent storage"""
675
+ try:
676
+ # Save metadata
677
+ self.metadata['last_updated'] = datetime.now().isoformat()
678
+ with open(self.metadata_path, 'w') as f:
679
+ json.dump(self.metadata, f, indent=2)
680
+
681
+ # Save stats
682
+ with open(self.stats_path, 'w') as f:
683
+ json.dump(self.stats, f, indent=2)
684
+
685
+ # Save conversations
686
+ with open(self.conversations_path, 'w') as f:
687
+ json.dump(self.conversations, f, indent=2)
688
+
689
+ # Save vectorstore
690
+ if self.vectorstore:
691
+ self.vectorstore.save_local(str(self.vectorstore_path))
692
+
693
+ return True
694
+ except Exception as e:
695
+ return False
696
+
697
+ def fallback_initialization(self):
698
+ """Fallback initialization if main process fails"""
699
+ self.create_default_knowledge()
700
+ self.metadata = {'fallback': True, 'created_at': datetime.now().isoformat()}
701
+ self.stats = {'total_queries': 0, 'learning_sessions': 0, 'book_chunks': 0, 'conversation_chunks': 0, 'silly_questions_blocked': 0}
702
+ self.conversations = []
703
+
704
+ def process_book_content(self, text, page_texts, book_info):
705
+ """Process book content and add to knowledge base"""
706
+ try:
707
+ # Text splitter
708
+ text_splitter = RecursiveCharacterTextSplitter(
709
+ chunk_size=800,
710
+ chunk_overlap=150,
711
+ length_function=len,
712
+ separators=["\n\n", "\n", ".", "!", "?", ",", " ", ""]
713
+ )
714
+
715
+ # Create documents
716
+ documents = []
717
+ for page_info in page_texts:
718
+ page_text = page_info['text']
719
+ chapter_title = self._extract_chapter_title(page_text.split('\n'))
720
+
721
+ doc = Document(
722
+ page_content=page_text,
723
+ metadata={
724
+ "source": "book",
725
+ "type": "book_content",
726
+ "page": page_info['page'],
727
+ "chapter": chapter_title,
728
+ "word_count": page_info['word_count'],
729
+ "book_title": book_info.get('title', 'Problem Solving Book'),
730
+ "processed_at": datetime.now().isoformat()
731
+ }
732
+ )
733
+ documents.append(doc)
734
+
735
+ # Split into chunks
736
+ chunks = text_splitter.split_documents(documents)
737
+
738
+ # Add to vectorstore
739
+ if self.vectorstore is None:
740
+ self.vectorstore = FAISS.from_documents(chunks, self.embeddings)
741
+ else:
742
+ new_vectorstore = FAISS.from_documents(chunks, self.embeddings)
743
+ self.vectorstore.merge_from(new_vectorstore)
744
+
745
+ # Update metadata
746
+ self.metadata['book_processed'] = True
747
+ self.metadata['book_info'] = book_info
748
+ self.metadata['total_documents'] += len(chunks)
749
+ self.stats['book_chunks'] += len(chunks)
750
+
751
+ return True, f"Successfully processed {len(chunks)} chunks from {len(page_texts)} pages!"
752
+
753
+ except Exception as e:
754
+ return False, f"Error processing book: {str(e)}"
755
+
756
+ def add_conversation_to_knowledge(self, question, answer):
757
+ """Add conversation to persistent knowledge base (auto-save)"""
758
+ if len(question.strip()) < 10 or len(answer.strip()) < 20:
759
+ return False
760
+
761
+ try:
762
+ conversation_text = f"Question: {question}\n\nAnswer: {answer}"
763
+
764
+ doc = Document(
765
+ page_content=conversation_text,
766
+ metadata={
767
+ "source": "learned_conversation",
768
+ "type": "qa_pair",
769
+ "question": question,
770
+ "answer_preview": answer[:200] + "..." if len(answer) > 200 else answer,
771
+ "conversation_id": hashlib.md5(conversation_text.encode()).hexdigest()[:8],
772
+ "added_at": datetime.now().isoformat(),
773
+ "quality_score": self._calculate_quality_score(question, answer)
774
+ }
775
+ )
776
+
777
+ # Add to vectorstore
778
+ if self.vectorstore is None:
779
+ self.vectorstore = FAISS.from_documents([doc], self.embeddings)
780
+ else:
781
+ new_vectorstore = FAISS.from_documents([doc], self.embeddings)
782
+ self.vectorstore.merge_from(new_vectorstore)
783
+
784
+ # Store conversation
785
+ self.conversations.append({
786
+ 'question': question,
787
+ 'answer': answer,
788
+ 'timestamp': datetime.now().isoformat(),
789
+ 'learned': True
790
+ })
791
+
792
+ # Update stats
793
+ self.stats['conversation_chunks'] += 1
794
+ self.stats['learning_sessions'] += 1
795
+ self.metadata['total_documents'] += 1
796
+
797
+ # Auto-save to persistent storage
798
+ self.save_all_data()
799
+
800
+ return True
801
+
802
+ except Exception as e:
803
+ return False
804
+
805
+ def search_knowledge_base(self, query, k=5):
806
+ """Search the persistent knowledge base"""
807
+ if self.vectorstore is None:
808
+ return []
809
+
810
+ try:
811
+ self.stats['total_queries'] += 1
812
+ docs = self.vectorstore.similarity_search_with_score(query, k=k)
813
+
814
+ results = []
815
+ for doc, score in docs:
816
+ result = {
817
+ 'content': doc.page_content,
818
+ 'source': doc.metadata.get('source', 'unknown'),
819
+ 'type': doc.metadata.get('type', 'unknown'),
820
+ 'page': doc.metadata.get('page', 'N/A'),
821
+ 'chapter': doc.metadata.get('chapter', 'Unknown Section'),
822
+ 'similarity_score': float(score),
823
+ 'metadata': doc.metadata
824
+ }
825
+ results.append(result)
826
+
827
+ return results
828
+
829
+ except Exception as e:
830
+ return []
831
+
832
+ def _extract_chapter_title(self, lines):
833
+ """Extract chapter title from text lines"""
834
+ for line in lines[:10]:
835
+ line = line.strip()
836
+ if line and len(line) < 100:
837
+ if re.match(r'(chapter|section|part|unit)\s+\d+', line.lower()):
838
+ return line
839
+ if line.isupper() or line.istitle():
840
+ return line
841
+ return "General Content"
842
+
843
+ def _calculate_quality_score(self, question, answer):
844
+ """Calculate conversation quality score"""
845
+ score = 0
846
+
847
+ # Question quality
848
+ if len(question.split()) >= 5: score += 1
849
+ if any(word in question.lower() for word in ['how', 'what', 'why', 'strategy', 'problem']): score += 1
850
+ if '?' in question: score += 1
851
+
852
+ # Answer quality
853
+ if len(answer.split()) >= 20: score += 1
854
+ if any(word in answer.lower() for word in ['approach', 'solution', 'method', 'step']): score += 1
855
+
856
+ return min(score, 5)
857
+
858
+ class AshokMinimalChatbot:
859
+ def __init__(self):
860
+ self.knowledge_base = PersistentHFKnowledgeBase()
861
+
862
+ def is_silly_question(self, question):
863
+ """Detect silly or irrelevant questions"""
864
+ question_lower = question.lower().strip()
865
+
866
+ if len(question_lower) < 3:
867
+ return True
868
+
869
+ # Greeting patterns
870
+ greeting_patterns = [
871
+ r'\b(hello|hi|hey|salam|namaste|adab)\b',
872
+ r'\b(good morning|evening|afternoon)\b',
873
+ r'\b(how are you|kaise ho|kya hal)\b',
874
+ r'\b(what.*your name|who are you)\b'
875
+ ]
876
+
877
+ # Silly keywords
878
+ silly_keywords = [
879
+ 'stupid', 'dumb', 'joke', 'funny', 'lol', 'weather', 'movie',
880
+ 'song', 'game', 'gossip', 'love', 'dating', 'facebook',
881
+ 'instagram', 'politics', 'religion', 'age', 'appearance'
882
+ ]
883
+
884
+ # Problem-solving keywords
885
+ good_keywords = [
886
+ 'problem', 'solve', 'solution', 'strategy', 'approach',
887
+ 'method', 'challenge', 'decision', 'plan', 'analyze',
888
+ 'conflict', 'team', 'work', 'project', 'manage'
889
+ ]
890
+
891
+ # Check patterns
892
+ for pattern in greeting_patterns:
893
+ if re.search(pattern, question_lower):
894
+ return True
895
+
896
+ # Score keywords
897
+ good_score = sum(1 for keyword in good_keywords if keyword in question_lower)
898
+ if good_score >= 2:
899
+ return False
900
+
901
+ silly_score = sum(1 for keyword in silly_keywords if keyword in question_lower)
902
+ if silly_score >= 1:
903
+ return True
904
+
905
+ # Check structure
906
+ question_words = ['what', 'how', 'why', 'when', 'where', 'can', 'should']
907
+ has_question_word = any(word in question_lower.split() for word in question_words)
908
+ word_count = len(question_lower.split())
909
+
910
+ if word_count < 4 and not has_question_word:
911
+ return True
912
+
913
+ return False
914
+
915
+ def generate_response(self, question, api_key):
916
+ """Generate response using Gemini"""
917
+ try:
918
+ # Check for silly questions
919
+ if self.is_silly_question(question):
920
+ self.knowledge_base.stats['silly_questions_blocked'] += 1
921
+
922
+ silly_responses = [
923
+ "Abay Sallay! Don't waste my time with such bakwas. Ask me something related to problem solving yaar!",
924
+ "Abay Sallay! Ye kya timepass hai? I'm here to help with problem solving, not for chit-chat. Be serious!",
925
+ "Abay Sallay! Focus on real problems that need solving, samjha? Ask about strategies and approaches!",
926
+ "Abay Sallay! This is a problem-solving platform. Ask me about challenges, decisions, ya conflict resolution!",
927
+ "Abay Sallay! Tumhara dimagh kahan hai? Ask meaningful questions about problem-solving techniques, yaar!"
928
+ ]
929
+
930
+ import random
931
+ return random.choice(silly_responses), False
932
+
933
+ # Configure Gemini
934
+ genai.configure(api_key=api_key)
935
+ model = genai.GenerativeModel('gemini-2.0-flash')
936
+
937
+ # Search knowledge base
938
+ relevant_results = self.knowledge_base.search_knowledge_base(question, k=5)
939
+
940
+ # Build context
941
+ context = ""
942
+ references = []
943
+
944
+ if relevant_results:
945
+ context = "=== RELEVANT KNOWLEDGE ===\n\n"
946
+ for i, result in enumerate(relevant_results, 1):
947
+ source_type = result['type']
948
+ if source_type == 'book_content':
949
+ context += f"**Reference {i}** (Chapter: {result['chapter']}, Page: {result['page']}):\n"
950
+ elif source_type == 'qa_pair':
951
+ context += f"**Learning {i}** (From past conversations):\n"
952
+ else:
953
+ context += f"**Framework {i}** (Core knowledge):\n"
954
+
955
+ context += f"{result['content']}\n\n"
956
+ references.append(result)
957
+
958
+ # Create prompt
959
+ prompt = f"""
960
+ You are Ashok, a problem-solving expert with Pakistani/Indian conversational style.
961
+
962
+ Your characteristics:
963
+ 1. Mix English with Urdu naturally: "yaar", "acha", "bilkul", "samjha", "dekho"
964
+ 2. Enthusiastic responses: "Excellent question yaar!" or "Bahut acha sawal!"
965
+ 3. Reference knowledge sources when available
966
+ 4. Provide practical, actionable advice
967
+ 5. Encouraging and professional tone
968
+
969
+ {context}
970
+
971
+ User Question: {question}
972
+
973
+ Provide a comprehensive, practical response using your characteristic style.
974
+ Reference the knowledge sources when relevant and give actionable steps.
975
+ """
976
+
977
+ response = model.generate_content(prompt)
978
+ final_response = response.text
979
+
980
+ # Add clean references section
981
+ if references:
982
+ final_response += "\n\n**Knowledge Sources:**\n"
983
+ for ref in references:
984
+ if ref['type'] == 'book_content':
985
+ final_response += f"• Book: {ref['chapter']} (Page {ref['page']})\n"
986
+ elif ref['type'] == 'qa_pair':
987
+ final_response += f"• Previous Learning\n"
988
+ else:
989
+ final_response += f"• Core Framework: {ref['metadata'].get('topic', 'Problem-solving')}\n"
990
+
991
+ return final_response, True
992
+
993
+ except Exception as e:
994
+ return f"Sorry yaar, I encountered an error: {str(e)}. Please check your API key and try again!", False
995
+
996
+ def show_typing_indicator():
997
+ """Show typing indicator"""
998
+ st.markdown("""
999
+ <div class="typing-indicator">
1000
+ <span>Ashok is thinking</span>
1001
+ <div class="typing-dots">
1002
+ <div class="typing-dot"></div>
1003
+ <div class="typing-dot"></div>
1004
+ <div class="typing-dot"></div>
1005
+ </div>
1006
+ </div>
1007
+ """, unsafe_allow_html=True)
1008
+
1009
+ def show_api_setup():
1010
+ """Show API key setup interface"""
1011
+ st.markdown("""
1012
+ <div class="api-setup-container">
1013
+ <div class="api-setup-title">Welcome to Ashok 2.0</div>
1014
+ <div class="api-setup-subtitle">To get started, please enter your Gemini API key</div>
1015
+ </div>
1016
+ """, unsafe_allow_html=True)
1017
+
1018
+ # API key input
1019
+ api_key = st.text_input(
1020
+ "Gemini API Key",
1021
+ type="password",
1022
+ placeholder="Enter your API key here...",
1023
+ label_visibility="collapsed"
1024
+ )
1025
+
1026
+ # API guide
1027
+ st.markdown("""
1028
+ <div class="api-guide">
1029
+ <div class="api-guide-title">How to get your free API key:</div>
1030
+ <div class="api-guide-text">1. Visit <a href="https://makersuite.google.com/app/apikey" target="_blank" class="api-link">Google AI Studio</a></div>
1031
+ <div class="api-guide-text">2. Sign in with your Google account</div>
1032
+ <div class="api-guide-text">3. Click "Create API Key"</div>
1033
+ <div class="api-guide-text">4. Copy and paste the key above</div>
1034
+ </div>
1035
+ """, unsafe_allow_html=True)
1036
+
1037
+ return api_key
1038
+
1039
+ def show_quick_actions():
1040
+ """Show enhanced quick action buttons"""
1041
+ st.markdown("""
1042
+ <div class="quick-actions-container">
1043
+ <div class="quick-actions-title">Quick Start Questions</div>
1044
+ <div class="quick-action-grid">
1045
+ """, unsafe_allow_html=True)
1046
+
1047
+ # Quick action data
1048
+ actions = [
1049
+ {
1050
+ "icon": "🎯",
1051
+ "title": "Task Prioritization",
1052
+ "desc": "Learn how to prioritize when everything seems urgent",
1053
+ "question": "How do I prioritize tasks when everything seems urgent and important?"
1054
+ },
1055
+ {
1056
+ "icon": "🤝",
1057
+ "title": "Conflict Resolution",
1058
+ "desc": "Effective strategies for resolving team conflicts",
1059
+ "question": "What's the best approach to resolve conflicts in my team?"
1060
+ },
1061
+ {
1062
+ "icon": "⚡",
1063
+ "title": "Decision Making",
1064
+ "desc": "Improve your decision-making process",
1065
+ "question": "How can I improve my decision-making process for complex problems?"
1066
+ },
1067
+ {
1068
+ "icon": "🎪",
1069
+ "title": "Difficult People",
1070
+ "desc": "Handle challenging stakeholders professionally",
1071
+ "question": "How do I deal with difficult stakeholders effectively?"
1072
+ },
1073
+ {
1074
+ "icon": "🔄",
1075
+ "title": "Change Management",
1076
+ "desc": "Navigate organizational changes smoothly",
1077
+ "question": "How can I help my team adapt to organizational changes?"
1078
+ },
1079
+ {
1080
+ "icon": "💡",
1081
+ "title": "Creative Solutions",
1082
+ "desc": "Generate innovative solutions to problems",
1083
+ "question": "What techniques can I use to think more creatively about problems?"
1084
+ }
1085
+ ]
1086
+
1087
+ # Create columns for actions
1088
+ cols = st.columns(2)
1089
+ for i, action in enumerate(actions):
1090
+ with cols[i % 2]:
1091
+ if st.button(
1092
+ f"{action['icon']} {action['title']}",
1093
+ key=f"action_{i}",
1094
+ help=action['desc'],
1095
+ use_container_width=True
1096
+ ):
1097
+ st.session_state.auto_question = action['question']
1098
+ st.rerun()
1099
+
1100
+ st.markdown("</div></div>", unsafe_allow_html=True)
1101
+
1102
+ def test_api_key(api_key):
1103
+ """Test if API key is valid"""
1104
+ try:
1105
+ genai.configure(api_key=api_key)
1106
+ model = genai.GenerativeModel('gemini-2.0-flash')
1107
+ test_response = model.generate_content("Hello")
1108
+ return True
1109
+ except Exception as e:
1110
+ return False
1111
+
1112
+ # Global instance for the app
1113
+ @st.cache_resource
1114
+ def get_chatbot():
1115
+ """Get cached chatbot instance"""
1116
+ return AshokMinimalChatbot()
1117
+
1118
+ def main():
1119
+ # Get cached chatbot instance
1120
+ chatbot = get_chatbot()
1121
+
1122
+ # Initialize session state
1123
+ if 'messages' not in st.session_state:
1124
+ st.session_state.messages = []
1125
+
1126
+ if 'auto_question' not in st.session_state:
1127
+ st.session_state.auto_question = None
1128
+
1129
+ if 'api_key_valid' not in st.session_state:
1130
+ st.session_state.api_key_valid = False
1131
+
1132
+ # Main title
1133
+ st.markdown('<h1 class="main-title">ASHOK 2.0</h1>', unsafe_allow_html=True)
1134
+
1135
+ # API Key Setup Phase
1136
+ if not st.session_state.api_key_valid:
1137
+ api_key = show_api_setup()
1138
+
1139
+ if api_key:
1140
+ if test_api_key(api_key):
1141
+ st.session_state.api_key = api_key
1142
+ st.session_state.api_key_valid = True
1143
+ st.markdown("""
1144
+ <div class="status-success">
1145
+ API key configured successfully! Ready to chat.
1146
+ </div>
1147
+ """, unsafe_allow_html=True)
1148
+ time.sleep(1)
1149
+ st.rerun()
1150
+ else:
1151
+ st.markdown("""
1152
+ <div class="status-warning">
1153
+ Invalid API key. Please check and try again.
1154
+ </div>
1155
+ """, unsafe_allow_html=True)
1156
+
1157
+ # Main Chat Interface Phase
1158
+ else:
1159
+ api_key = st.session_state.api_key
1160
+
1161
+ # Handle auto questions from quick actions
1162
+ if st.session_state.auto_question:
1163
+ # Add user message
1164
+ st.session_state.messages.append({"role": "user", "content": st.session_state.auto_question})
1165
+
1166
+ # Generate response
1167
+ with st.spinner("Processing your question..."):
1168
+ response, is_helpful = chatbot.generate_response(st.session_state.auto_question, api_key)
1169
+ st.session_state.messages.append({"role": "assistant", "content": response})
1170
+
1171
+ # Auto-learn from helpful conversations
1172
+ if is_helpful and not chatbot.is_silly_question(st.session_state.auto_question):
1173
+ chatbot.knowledge_base.add_conversation_to_knowledge(st.session_state.auto_question, response)
1174
+
1175
+ # Clear auto question
1176
+ st.session_state.auto_question = None
1177
+ st.rerun()
1178
+
1179
+ # Display chat history
1180
+ if st.session_state.messages:
1181
+ st.markdown('<div class="chat-container">', unsafe_allow_html=True)
1182
+ for message in st.session_state.messages:
1183
+ with st.chat_message(message["role"]):
1184
+ st.markdown(message["content"])
1185
+ st.markdown('</div>', unsafe_allow_html=True)
1186
+
1187
+ # Chat input
1188
+ if prompt := st.chat_input("Ask about problem-solving strategies...", key="main_chat"):
1189
+ # Add user message
1190
+ st.session_state.messages.append({"role": "user", "content": prompt})
1191
+ with st.chat_message("user"):
1192
+ st.markdown(prompt)
1193
+
1194
+ # Generate response with typing indicator
1195
+ with st.chat_message("assistant"):
1196
+ # Show typing indicator
1197
+ typing_placeholder = st.empty()
1198
+ with typing_placeholder:
1199
+ show_typing_indicator()
1200
+
1201
+ # Simulate typing delay
1202
+ time.sleep(1)
1203
+
1204
+ # Clear typing indicator and show response
1205
+ typing_placeholder.empty()
1206
+
1207
+ with st.spinner("Processing..."):
1208
+ response, is_helpful = chatbot.generate_response(prompt, api_key)
1209
+ st.markdown(response)
1210
+
1211
+ # Add to chat history
1212
+ st.session_state.messages.append({"role": "assistant", "content": response})
1213
+
1214
+ # Auto-learn from helpful conversations
1215
+ if is_helpful and not chatbot.is_silly_question(prompt):
1216
+ learned = chatbot.knowledge_base.add_conversation_to_knowledge(prompt, response)
1217
+ if learned:
1218
+ st.markdown(
1219
+ '<div class="learning-indicator">Knowledge updated - This conversation has been learned!</div>',
1220
+ unsafe_allow_html=True
1221
+ )
1222
+
1223
+ # Show quick actions if no messages yet
1224
+ if not st.session_state.messages:
1225
+ show_quick_actions()
1226
+
1227
+ # Control panel
1228
+ if st.session_state.messages:
1229
+ st.markdown("""
1230
+ <div class="control-panel">
1231
+ """, unsafe_allow_html=True)
1232
+
1233
+ if st.button("Clear Chat", key="clear_chat"):
1234
+ st.session_state.messages = []
1235
+ st.rerun()
1236
+
1237
+ st.markdown("</div>", unsafe_allow_html=True)
1238
+
1239
+ if __name__ == "__main__":
1240
+ main()
requirements.txt ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Streamlit and Core
2
+ streamlit==1.29.0
3
+ google-generativeai==0.3.2
4
+
5
+ # PDF Processing
6
+ PyPDF2==3.0.1
7
+
8
+ # LangChain (minimal for HF Spaces)
9
+ langchain-core==0.1.52
10
+ langchain-text-splitters==0.0.1
11
+ langchain-huggingface==0.0.1
12
+ langchain-community==0.0.29
13
+
14
+ # Vector Store and Embeddings
15
+ sentence-transformers==2.2.2
16
+ faiss-cpu==1.7.4
17
+ huggingface-hub==0.19.4
18
+ transformers==4.36.2
19
+
20
+ # Core Dependencies
21
+ torch==2.1.2
22
+ numpy==1.24.3
23
+ pandas==2.0.3
24
+ pydantic==2.5.2
25
+
26
+ # Additional utilities for persistent storage
27
+ python-dateutil==2.8.2
28
+ pathlib2>=2.3.0