Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
# app.py
|
2 |
import streamlit as st
|
3 |
from groq import Groq
|
4 |
-
from textblob import TextBlob
|
5 |
from transformers import pipeline
|
6 |
import re
|
7 |
import random
|
@@ -9,96 +8,90 @@ from datetime import datetime
|
|
9 |
from reportlab.lib.pagesizes import letter
|
10 |
from reportlab.pdfgen import canvas
|
11 |
import io
|
|
|
|
|
12 |
|
13 |
-
# Initialize components
|
14 |
try:
|
15 |
groq_client = Groq(api_key=st.secrets["GROQ_API_KEY"])
|
16 |
except KeyError:
|
17 |
-
st.error("GROQ_API_KEY missing in secrets!
|
18 |
st.stop()
|
19 |
|
20 |
-
#
|
21 |
try:
|
22 |
-
|
23 |
-
|
24 |
-
"zero-shot-classification",
|
25 |
-
model="facebook/bart-large-mnli"
|
26 |
-
)
|
27 |
-
|
28 |
-
# Emotion detection model
|
29 |
-
emotion_classifier = pipeline(
|
30 |
-
"text-classification",
|
31 |
-
model="j-hartmann/emotion-english-distilroberta-base"
|
32 |
-
)
|
33 |
except Exception as e:
|
34 |
st.error(f"Model loading error: {str(e)}")
|
35 |
st.stop()
|
36 |
|
37 |
# Configure Streamlit
|
38 |
-
st.set_page_config(page_title="π§
|
39 |
|
40 |
# Custom CSS
|
41 |
st.markdown("""
|
42 |
<style>
|
43 |
-
@keyframes
|
44 |
-
0% {
|
45 |
-
|
46 |
-
|
47 |
-
60% { color: #00ff00; }
|
48 |
-
80% { color: #0000ff; }
|
49 |
-
100% { color: #ff00ff; }
|
50 |
}
|
51 |
.personality-title {
|
52 |
-
animation:
|
53 |
-
font-size: 2.5em !important;
|
54 |
}
|
55 |
-
.
|
56 |
-
|
57 |
border-radius: 15px;
|
58 |
-
|
59 |
-
|
60 |
-
.tip-box {
|
61 |
-
border-left: 4px solid #4CAF50;
|
62 |
-
padding: 10px 15px;
|
63 |
-
margin: 10px 0;
|
64 |
background: #f8f9fa;
|
65 |
-
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
</style>
|
68 |
""", unsafe_allow_html=True)
|
69 |
|
70 |
-
#
|
71 |
-
OCEAN_TRAITS = {
|
72 |
-
"openness": ["curious", "creative", "adventurous"],
|
73 |
-
"conscientiousness": ["organized", "responsible", "disciplined"],
|
74 |
-
"extraversion": ["outgoing", "energetic", "sociable"],
|
75 |
-
"agreeableness": ["friendly", "compassionate", "cooperative"],
|
76 |
-
"neuroticism": ["sensitive", "nervous", "emotional"]
|
77 |
-
}
|
78 |
-
|
79 |
QUESTION_BANK = [
|
80 |
-
{"text": "
|
81 |
-
{"text": "
|
82 |
-
{"text": "
|
83 |
-
{"text": "
|
84 |
-
{"text": "
|
|
|
|
|
|
|
85 |
]
|
86 |
|
87 |
-
def
|
88 |
-
"""
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
""
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
"""
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
response = groq_client.chat.completions.create(
|
104 |
model="mixtral-8x7b-32768",
|
@@ -107,202 +100,72 @@ Make it inspirational and include an emoji."""
|
|
107 |
)
|
108 |
return response.choices[0].message.content
|
109 |
|
110 |
-
def generate_tips(traits):
|
111 |
-
"""Generate evidence-based psychological tips for all traits"""
|
112 |
-
tips = []
|
113 |
-
|
114 |
-
# Openness
|
115 |
-
if traits.get('openness', 0) > 0.7:
|
116 |
-
tips.extend([
|
117 |
-
"π¨ Creative boost: Try 'morning pages' - write 3 stream-of-consciousness pages each morning",
|
118 |
-
"π Novelty diet: Schedule one new experience weekly (new route, food, or activity)"
|
119 |
-
])
|
120 |
-
else:
|
121 |
-
tips.append("π Structured exploration: Try a 'learning hour' weekly on a fixed schedule about random topics")
|
122 |
-
|
123 |
-
# Conscientiousness
|
124 |
-
if traits.get('conscientiousness', 0) > 0.6:
|
125 |
-
tips.extend([
|
126 |
-
"β±οΈ Time boxing: Use the 52/17 rule (52 mins work, 17 mins break) for optimal productivity",
|
127 |
-
"π¦ Declutter challenge: Remove 10 unnecessary items from your workspace daily"
|
128 |
-
])
|
129 |
-
else:
|
130 |
-
tips.extend([
|
131 |
-
"π― Micro-goals: Break tasks into 5-minute chunks with immediate rewards",
|
132 |
-
"π
Habit stacking: Attach new habits to existing routines (e.g., meditate after brushing teeth)"
|
133 |
-
])
|
134 |
-
|
135 |
-
# Extraversion
|
136 |
-
if traits.get('extraversion', 0) > 0.6:
|
137 |
-
tips.extend([
|
138 |
-
"π₯ Energy sharing: Schedule weekly 'idea exchanges' with friends",
|
139 |
-
"π€ Social charging: Host monthly themed dinners to fuel your social battery"
|
140 |
-
])
|
141 |
-
else:
|
142 |
-
tips.extend([
|
143 |
-
"π Reflection ritual: Keep an 'insight journal' for deep thinking sessions",
|
144 |
-
"π§ Solo innovation: Try monthly 'solo design sprints' for personal projects"
|
145 |
-
])
|
146 |
-
|
147 |
-
# Agreeableness
|
148 |
-
if traits.get('agreeableness', 0) > 0.6:
|
149 |
-
tips.extend([
|
150 |
-
"π‘οΈ Boundary practice: Start sentences with 'I choose to...' instead of 'I have to...'",
|
151 |
-
"πͺ Diplomatic assertiveness: Use the 'DESC' script (Describe, Express, Specify, Consequences)"
|
152 |
-
])
|
153 |
-
else:
|
154 |
-
tips.extend([
|
155 |
-
"π€ Perspective walks: Have weekly conversations where you only ask questions",
|
156 |
-
"β€οΈ Compassion training: Practice daily '3-good-things' gratitude journaling"
|
157 |
-
])
|
158 |
-
|
159 |
-
# Neuroticism
|
160 |
-
if traits.get('neuroticism', 0) > 0.6:
|
161 |
-
tips.extend([
|
162 |
-
"π Anxiety containment: Create a 'worry window' (15 mins/day dedicated to problem-solving)",
|
163 |
-
"π Emotional surfing: Practice observing feelings like waves (notice-name-allow technique)"
|
164 |
-
])
|
165 |
-
else:
|
166 |
-
tips.extend([
|
167 |
-
"π Vulnerability practice: Share one authentic feeling daily with someone",
|
168 |
-
"π§ Comfort zone challenges: Do something mildly uncomfortable weekly"
|
169 |
-
])
|
170 |
-
|
171 |
-
# General well-being tips
|
172 |
-
tips.extend([
|
173 |
-
"π€ Sleep hygiene: Follow 10-3-2-1-0 formula (10h before bed: caffeine, 3h: food, 2h: work, 1h: screens, 0 snooze)",
|
174 |
-
"π§ Cognitive refueling: Practice 20-20-20 rule (every 20 mins, look 20 ft away for 20 sec)",
|
175 |
-
"β€οΈ Self-compassion break: When stressed, say 'This is hard, but I'm doing my best'"
|
176 |
-
])
|
177 |
-
|
178 |
-
return tips[:15] # Return top 15 most relevant tips
|
179 |
-
|
180 |
-
def create_pdf_report(report):
|
181 |
-
"""Generate downloadable PDF report"""
|
182 |
-
buffer = io.BytesIO()
|
183 |
-
p = canvas.Canvas(buffer, pagesize=letter)
|
184 |
-
|
185 |
-
p.setFont("Helvetica-Bold", 16)
|
186 |
-
p.drawString(100, 750, "π Psychological Profile Report π")
|
187 |
-
p.setFont("Helvetica", 12)
|
188 |
-
|
189 |
-
y_position = 700
|
190 |
-
content = [
|
191 |
-
f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M')}",
|
192 |
-
"",
|
193 |
-
"Personality Traits:",
|
194 |
-
*[f"- {trait.upper()}: {score:.2f}" for trait, score in report['traits'].items()],
|
195 |
-
"",
|
196 |
-
"Emotional Analysis:",
|
197 |
-
*[f"- {emo['label']}: {emo['score']:.2f}" for emo in report['emotions']],
|
198 |
-
"",
|
199 |
-
"Personalized Quote:",
|
200 |
-
report['quote'],
|
201 |
-
"",
|
202 |
-
"Growth Tips:",
|
203 |
-
*[f"{i+1}. {tip}" for i, tip in enumerate(report['tips'])]
|
204 |
-
]
|
205 |
-
|
206 |
-
for line in content:
|
207 |
-
p.drawString(100, y_position, line)
|
208 |
-
y_position -= 15
|
209 |
-
|
210 |
-
p.save()
|
211 |
-
buffer.seek(0)
|
212 |
-
return buffer
|
213 |
-
|
214 |
# Session state management
|
215 |
-
if '
|
216 |
-
st.session_state.
|
217 |
if 'current_q' not in st.session_state:
|
218 |
st.session_state.current_q = 0
|
|
|
|
|
219 |
|
220 |
# Main UI
|
221 |
-
st.title("π§
|
222 |
-
st.markdown("### Your
|
223 |
-
|
224 |
-
# Progress tracker
|
225 |
-
progress = st.session_state.current_q / len(QUESTION_BANK)
|
226 |
-
st.markdown(f"""
|
227 |
-
<div style="background: #f0f2f6; border-radius: 15px; padding: 5px;">
|
228 |
-
<div class="progress-bar" style="width: {progress*100}%; height: 25px;"></div>
|
229 |
-
</div>
|
230 |
-
""", unsafe_allow_html=True)
|
231 |
|
232 |
-
#
|
233 |
-
if st.session_state.current_q < len(
|
234 |
-
q =
|
235 |
|
236 |
with st.chat_message("assistant"):
|
237 |
-
st.markdown(f"
|
|
|
|
|
|
|
|
|
|
|
238 |
user_input = st.text_input("Your response:", key=f"q{st.session_state.current_q}")
|
239 |
|
240 |
if st.button("Next β‘οΈ"):
|
241 |
-
st.session_state.responses.append(user_input)
|
242 |
st.session_state.current_q += 1
|
243 |
st.rerun()
|
244 |
else:
|
245 |
-
# Generate report
|
246 |
-
combined_text = "
|
247 |
-
traits =
|
248 |
-
emotions = analyze_emotions(combined_text)
|
249 |
-
|
250 |
-
report = {
|
251 |
-
"traits": traits,
|
252 |
-
"emotions": emotions,
|
253 |
-
"quote": generate_quote(traits),
|
254 |
-
"tips": generate_tips(traits)
|
255 |
-
}
|
256 |
|
257 |
st.balloons()
|
258 |
-
st.markdown(f"## <div class='personality-title'>π Your
|
259 |
|
260 |
-
#
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
|
266 |
-
#
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
st.markdown("### π¬ Personalized Wisdom")
|
276 |
-
st.success(f'"{report["quote"]}"')
|
277 |
-
with col2:
|
278 |
-
st.markdown("### π οΈ Actionable Psychology Hacks")
|
279 |
-
for i, tip in enumerate(report['tips']):
|
280 |
st.markdown(f"""
|
281 |
-
<div class="
|
282 |
-
<
|
|
|
|
|
283 |
</div>
|
284 |
""", unsafe_allow_html=True)
|
285 |
-
|
286 |
-
# PDF Report
|
287 |
-
pdf_buffer = create_pdf_report(report)
|
288 |
-
st.download_button(
|
289 |
-
"π₯ Download Full Report",
|
290 |
-
data=pdf_buffer,
|
291 |
-
file_name="psych_profile.pdf",
|
292 |
-
mime="application/pdf"
|
293 |
-
)
|
294 |
|
295 |
# Sidebar
|
296 |
with st.sidebar:
|
297 |
-
st.markdown("## π
|
298 |
st.markdown("""
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
- Zero-shot personality classification
|
306 |
-
- Emotion recognition (RoBERTa)
|
307 |
-
- Cognitive behavioral therapy principles
|
308 |
-
""")
|
|
|
1 |
# app.py
|
2 |
import streamlit as st
|
3 |
from groq import Groq
|
|
|
4 |
from transformers import pipeline
|
5 |
import re
|
6 |
import random
|
|
|
8 |
from reportlab.lib.pagesizes import letter
|
9 |
from reportlab.pdfgen import canvas
|
10 |
import io
|
11 |
+
import torch
|
12 |
+
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
13 |
|
14 |
+
# Initialize components
|
15 |
try:
|
16 |
groq_client = Groq(api_key=st.secrets["GROQ_API_KEY"])
|
17 |
except KeyError:
|
18 |
+
st.error("GROQ_API_KEY missing in secrets!")
|
19 |
st.stop()
|
20 |
|
21 |
+
# Load personality model
|
22 |
try:
|
23 |
+
personality_model = AutoModelForSequenceClassification.from_pretrained("KevSun/Personality_LM", ignore_mismatched_sizes=True)
|
24 |
+
personality_tokenizer = AutoTokenizer.from_pretrained("KevSun/Personality_LM")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
except Exception as e:
|
26 |
st.error(f"Model loading error: {str(e)}")
|
27 |
st.stop()
|
28 |
|
29 |
# Configure Streamlit
|
30 |
+
st.set_page_config(page_title="π§ PsychBot Pro", layout="wide", page_icon="π€")
|
31 |
|
32 |
# Custom CSS
|
33 |
st.markdown("""
|
34 |
<style>
|
35 |
+
@keyframes float {
|
36 |
+
0% { transform: translateY(0px); }
|
37 |
+
50% { transform: translateY(-20px); }
|
38 |
+
100% { transform: translateY(0px); }
|
|
|
|
|
|
|
39 |
}
|
40 |
.personality-title {
|
41 |
+
animation: float 3s ease-in-out infinite;
|
|
|
42 |
}
|
43 |
+
.social-post {
|
44 |
+
border: 1px solid #e0e0e0;
|
45 |
border-radius: 15px;
|
46 |
+
padding: 20px;
|
47 |
+
margin: 15px 0;
|
|
|
|
|
|
|
|
|
48 |
background: #f8f9fa;
|
49 |
+
}
|
50 |
+
.platform-selector {
|
51 |
+
display: flex;
|
52 |
+
gap: 10px;
|
53 |
+
margin: 20px 0;
|
54 |
}
|
55 |
</style>
|
56 |
""", unsafe_allow_html=True)
|
57 |
|
58 |
+
# Enhanced question bank
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
QUESTION_BANK = [
|
60 |
+
{"text": "If you were a pizza topping, what would you be and why? π", "type": "funny", "trait": "openness"},
|
61 |
+
{"text": "How do you typically handle criticism? π¬", "type": "serious", "trait": "neuroticism"},
|
62 |
+
{"text": "Describe your ideal superpower and how you'd use it π¦Έ", "type": "funny", "trait": "openness"},
|
63 |
+
{"text": "What's your approach to meeting new people? π₯", "type": "serious", "trait": "extraversion"},
|
64 |
+
{"text": "If your life was a movie genre, what would it be? π₯", "type": "funny", "trait": "neuroticism"},
|
65 |
+
{"text": "How do you make important decisions? π€", "type": "serious", "trait": "conscientiousness"},
|
66 |
+
{"text": "What animal best represents your personality? πΎ", "type": "funny", "trait": "agreeableness"},
|
67 |
+
{"text": "How do you recharge after a stressful day? π§", "type": "serious", "trait": "neuroticism"}
|
68 |
]
|
69 |
|
70 |
+
def get_dynamic_questions():
|
71 |
+
"""Generate random mix of funny/serious questions"""
|
72 |
+
random.shuffle(QUESTION_BANK)
|
73 |
+
return random.sample(QUESTION_BANK, 5)
|
74 |
+
|
75 |
+
def analyze_personality(text):
|
76 |
+
"""Predict personality traits using LM"""
|
77 |
+
inputs = personality_tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
78 |
+
with torch.no_grad():
|
79 |
+
outputs = personality_model(**inputs)
|
80 |
+
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
|
81 |
+
traits = ["openness", "conscientiousness", "extraversion", "agreeableness", "neuroticism"]
|
82 |
+
return {trait: float(prob) for trait, prob in zip(traits, probs[0])}
|
83 |
+
|
84 |
+
def generate_social_post(platform, traits):
|
85 |
+
"""Generate platform-specific social post"""
|
86 |
+
prompts = {
|
87 |
+
"instagram": "Create an Instagram post with 3 emojis and 2 hashtags about:",
|
88 |
+
"linkedin": "Create a professional LinkedIn post about personal growth with 1 emoji:",
|
89 |
+
"facebook": "Create a friendly Facebook post with 2 emojis:",
|
90 |
+
"whatsapp": "Create a casual WhatsApp status with 2 emojis:"
|
91 |
+
}
|
92 |
+
prompt = f"""{prompts[platform]}
|
93 |
+
My personality strengths: {traits}
|
94 |
+
Make it {['playful and visual', 'professional', 'friendly', 'casual'][list(prompts.keys()).index(platform)]}"""
|
95 |
|
96 |
response = groq_client.chat.completions.create(
|
97 |
model="mixtral-8x7b-32768",
|
|
|
100 |
)
|
101 |
return response.choices[0].message.content
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
# Session state management
|
104 |
+
if 'questions' not in st.session_state:
|
105 |
+
st.session_state.questions = get_dynamic_questions()
|
106 |
if 'current_q' not in st.session_state:
|
107 |
st.session_state.current_q = 0
|
108 |
+
if 'show_post' not in st.session_state:
|
109 |
+
st.session_state.show_post = False
|
110 |
|
111 |
# Main UI
|
112 |
+
st.title("π§ PsychBot Pro")
|
113 |
+
st.markdown("### Your AI Personality Companion π€π¬")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
115 |
+
# Dynamic question flow
|
116 |
+
if st.session_state.current_q < len(st.session_state.questions):
|
117 |
+
q = st.session_state.questions[st.session_state.current_q]
|
118 |
|
119 |
with st.chat_message("assistant"):
|
120 |
+
st.markdown(f"#### {q['text']}")
|
121 |
+
if q['type'] == "funny":
|
122 |
+
st.markdown("π *Let's have some fun!*")
|
123 |
+
else:
|
124 |
+
st.markdown("π€ *Take your time...*")
|
125 |
+
|
126 |
user_input = st.text_input("Your response:", key=f"q{st.session_state.current_q}")
|
127 |
|
128 |
if st.button("Next β‘οΈ"):
|
|
|
129 |
st.session_state.current_q += 1
|
130 |
st.rerun()
|
131 |
else:
|
132 |
+
# Generate personality report
|
133 |
+
combined_text = " ".join([st.session_state[f"q{i}"] for i in range(len(st.session_state.questions))])
|
134 |
+
traits = analyze_personality(combined_text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
st.balloons()
|
137 |
+
st.markdown(f"## <div class='personality-title'>π Your Personality Report</div>", unsafe_allow_html=True)
|
138 |
|
139 |
+
# Personality visualization
|
140 |
+
cols = st.columns(5)
|
141 |
+
traits = {k: v for k, v in sorted(traits.items(), key=lambda item: item[1], reverse=True)}
|
142 |
+
for i, (trait, score) in enumerate(traits.items()):
|
143 |
+
cols[i].metric(label=trait.upper(), value=f"{score*100:.0f}%")
|
144 |
|
145 |
+
# Social post generation
|
146 |
+
if st.button("π± Generate Social Media Post"):
|
147 |
+
st.session_state.show_post = True
|
148 |
+
|
149 |
+
if st.session_state.show_post:
|
150 |
+
platforms = ["instagram", "linkedin", "facebook", "whatsapp"]
|
151 |
+
selected = st.radio("Choose platform:", platforms, horizontal=True)
|
152 |
+
|
153 |
+
if post := generate_social_post(selected, traits):
|
|
|
|
|
|
|
|
|
|
|
154 |
st.markdown(f"""
|
155 |
+
<div class="social-post">
|
156 |
+
<h4>π¨ {selected.capitalize()} Post Draft</h4>
|
157 |
+
<p>{post}</p>
|
158 |
+
<button onclick="navigator.clipboard.writeText(`{post}`)">π Copy</button>
|
159 |
</div>
|
160 |
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
# Sidebar
|
163 |
with st.sidebar:
|
164 |
+
st.markdown("## π Features")
|
165 |
st.markdown("""
|
166 |
+
- π Dynamic personality assessment
|
167 |
+
- π€ AI-generated social posts
|
168 |
+
- π Visual trait analysis
|
169 |
+
- π¬ Mix of fun/serious questions
|
170 |
+
""")
|
171 |
+
st.image("https://i.imgur.com/7Q4X4yN.png", width=200)
|
|
|
|
|
|
|
|