Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -5,6 +5,12 @@ import json
|
|
5 |
import random
|
6 |
import os
|
7 |
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
# Load environment variables
|
10 |
load_dotenv()
|
@@ -37,6 +43,49 @@ EMOTION_MODELS = {
|
|
37 |
"AnasAlokla/multilingual_go_emotions_V1.1": "Multilingual Go Emotions (V1.1)"
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
def generate_text(prompt, context=""):
|
41 |
"""
|
42 |
Generates text using the Gemini model.
|
@@ -48,24 +97,66 @@ def generate_text(prompt, context=""):
|
|
48 |
print(f"Error generating text: {e}")
|
49 |
return "I am sorry, I encountered an error while generating the text."
|
50 |
|
51 |
-
def
|
52 |
"""
|
53 |
-
|
54 |
"""
|
|
|
55 |
templates = data["emotion_templates"][emotion]
|
56 |
-
|
|
|
|
|
57 |
if topic:
|
58 |
-
# Replace various placeholders in the prompt
|
59 |
placeholders = ["[topic/person]", "[topic]", "[person]", "[object]", "[outcome]"]
|
60 |
for placeholder in placeholders:
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
-
|
64 |
-
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
@st.cache_resource
|
71 |
def load_emotion_classifier(model_name):
|
@@ -80,25 +171,24 @@ def load_emotion_classifier(model_name):
|
|
80 |
st.error(f"Error loading model {model_name}: {str(e)}")
|
81 |
return None
|
82 |
|
83 |
-
def get_ai_response(user_input, emotion_predictions):
|
84 |
-
"""Generates AI response based on user input
|
85 |
dominant_emotion = None
|
86 |
max_score = 0
|
87 |
-
responses = None
|
88 |
|
89 |
for prediction in emotion_predictions:
|
90 |
if prediction['score'] > max_score:
|
91 |
max_score = prediction['score']
|
92 |
dominant_emotion = prediction['label']
|
93 |
|
94 |
-
prompt_text = create_prompt(dominant_emotion, user_input)
|
95 |
-
responses = generate_text(prompt_text)
|
96 |
-
|
97 |
-
# Handle cases where no specific emotion is clear
|
98 |
if dominant_emotion is None:
|
99 |
-
return "Error for response"
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
102 |
|
103 |
def display_top_predictions(emotion_predictions, selected_language, num_predictions=10):
|
104 |
"""Display top emotion predictions in sidebar."""
|
@@ -123,6 +213,21 @@ def display_top_predictions(emotion_predictions, selected_language, num_predicti
|
|
123 |
st.sidebar.markdown(f"Score: {percentage:.1f}%")
|
124 |
st.sidebar.markdown("---")
|
125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
def main():
|
127 |
# Sidebar configurations
|
128 |
st.sidebar.header("βοΈ Configuration")
|
@@ -151,6 +256,19 @@ def main():
|
|
151 |
step=1
|
152 |
)
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
# Load the selected emotion classifier
|
155 |
emotion_classifier = load_emotion_classifier(selected_model_key)
|
156 |
|
@@ -163,21 +281,34 @@ def main():
|
|
163 |
st.sidebar.success(f"β
Current Model: {EMOTION_MODELS[selected_model_key]}")
|
164 |
|
165 |
# Display Image
|
166 |
-
|
|
|
167 |
|
168 |
# Set page title and header based on selected language
|
169 |
st.title(LANGUAGES[selected_language]['title'])
|
170 |
st.markdown(f"### π¬ {LANGUAGES[selected_language]['analyze_subtitle']}")
|
171 |
|
|
|
|
|
|
|
172 |
# Input Text Box
|
173 |
user_input = st.text_area(
|
174 |
LANGUAGES[selected_language]['input_placeholder'],
|
175 |
"",
|
176 |
height=100,
|
177 |
-
help="Type your message here to analyze emotions"
|
178 |
)
|
179 |
|
180 |
if user_input:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
# Emotion Detection
|
182 |
with st.spinner("Analyzing emotions..."):
|
183 |
emotion_predictions = emotion_classifier(user_input)
|
@@ -197,28 +328,48 @@ def main():
|
|
197 |
score = prediction['score']
|
198 |
percentage = score * 100
|
199 |
|
|
|
|
|
|
|
|
|
200 |
if i % 2 == 0:
|
201 |
with col1:
|
202 |
st.metric(
|
203 |
-
label=emotion.title(),
|
204 |
value=f"{percentage:.1f}%",
|
205 |
delta=None
|
206 |
)
|
207 |
else:
|
208 |
with col2:
|
209 |
st.metric(
|
210 |
-
label=emotion.title(),
|
211 |
value=f"{percentage:.1f}%",
|
212 |
delta=None
|
213 |
)
|
214 |
|
215 |
-
# Get AI Response
|
216 |
-
with st.spinner("Generating response..."):
|
217 |
-
ai_response = get_ai_response(user_input, emotion_predictions)
|
218 |
|
219 |
# Display AI Response
|
220 |
st.subheader(LANGUAGES[selected_language]['response_header'])
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
# Run the main function
|
224 |
if __name__ == "__main__":
|
|
|
5 |
import random
|
6 |
import os
|
7 |
from dotenv import load_dotenv
|
8 |
+
import langdetect
|
9 |
+
from langdetect import detect, DetectorFactory
|
10 |
+
from langdetect.lang_detect_exception import LangDetectException
|
11 |
+
|
12 |
+
# Set seed for consistent language detection
|
13 |
+
DetectorFactory.seed = 0
|
14 |
|
15 |
# Load environment variables
|
16 |
load_dotenv()
|
|
|
43 |
"AnasAlokla/multilingual_go_emotions_V1.1": "Multilingual Go Emotions (V1.1)"
|
44 |
}
|
45 |
|
46 |
+
# Language mapping for detection
|
47 |
+
SUPPORTED_LANGUAGES = {
|
48 |
+
'en': 'English',
|
49 |
+
'ar': 'Arabic',
|
50 |
+
'fr': 'French',
|
51 |
+
'es': 'Spanish',
|
52 |
+
'nl': 'Dutch',
|
53 |
+
'tr': 'Turkish'
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
def detect_language(text):
|
59 |
+
"""Detect the language of the input text."""
|
60 |
+
try:
|
61 |
+
detected_lang = detect(text)
|
62 |
+
if detected_lang in SUPPORTED_LANGUAGES:
|
63 |
+
return detected_lang
|
64 |
+
else:
|
65 |
+
return 'en' # Default to English if language not supported
|
66 |
+
except LangDetectException:
|
67 |
+
return 'en' # Default to English if detection fails
|
68 |
+
|
69 |
+
def get_language_name(lang_code):
|
70 |
+
"""Get the full language name from language code."""
|
71 |
+
return SUPPORTED_LANGUAGES.get(lang_code, 'English')
|
72 |
+
|
73 |
+
def categorize_emotion(emotion):
|
74 |
+
"""Categorize emotion as positive, negative, or neutral."""
|
75 |
+
positive_emotions = ['admiration', 'amusement', 'approval', 'caring', 'curiosity',
|
76 |
+
'desire', 'excitement', 'gratitude', 'joy', 'love', 'optimism',
|
77 |
+
'pride', 'relief']
|
78 |
+
negative_emotions = ['anger', 'annoyance', 'confusion', 'disappointment', 'disapproval',
|
79 |
+
'disgust', 'embarrassment', 'fear', 'grief', 'nervousness',
|
80 |
+
'remorse', 'sadness']
|
81 |
+
|
82 |
+
if emotion in positive_emotions:
|
83 |
+
return 'positive'
|
84 |
+
elif emotion in negative_emotions:
|
85 |
+
return 'negative'
|
86 |
+
else:
|
87 |
+
return 'neutral'
|
88 |
+
|
89 |
def generate_text(prompt, context=""):
|
90 |
"""
|
91 |
Generates text using the Gemini model.
|
|
|
97 |
print(f"Error generating text: {e}")
|
98 |
return "I am sorry, I encountered an error while generating the text."
|
99 |
|
100 |
+
def create_enhanced_prompt(emotion, topic, detected_language, emotion_score):
|
101 |
"""
|
102 |
+
Creates an enhanced emotional prompt based on detected language and emotion intensity.
|
103 |
"""
|
104 |
+
# Get base template from emotion_templates.json
|
105 |
templates = data["emotion_templates"][emotion]
|
106 |
+
base_prompt = random.choice(templates)
|
107 |
+
|
108 |
+
# Replace placeholders
|
109 |
if topic:
|
|
|
110 |
placeholders = ["[topic/person]", "[topic]", "[person]", "[object]", "[outcome]"]
|
111 |
for placeholder in placeholders:
|
112 |
+
base_prompt = base_prompt.replace(placeholder, topic)
|
113 |
+
|
114 |
+
# Get language name
|
115 |
+
language_name = get_language_name(detected_language)
|
116 |
+
|
117 |
+
# Get emotion category
|
118 |
+
emotion_category = categorize_emotion(emotion)
|
119 |
+
|
120 |
+
# Get emotional enhancers from JSON file
|
121 |
+
emotional_enhancers = data.get("emotional_enhancers", {})
|
122 |
+
language_enhancers = emotional_enhancers.get(detected_language, emotional_enhancers.get('en', {}))
|
123 |
+
emotion_enhancer = ""
|
124 |
+
|
125 |
+
if language_enhancers and emotion_category in language_enhancers:
|
126 |
+
emotion_enhancer = random.choice(language_enhancers[emotion_category])
|
127 |
|
128 |
+
# Calculate emotion intensity
|
129 |
+
intensity = "high" if emotion_score > 0.7 else "moderate" if emotion_score > 0.4 else "low"
|
130 |
|
131 |
+
# Create enhanced prompt
|
132 |
+
enhanced_prompt = f"""
|
133 |
+
You are an emotionally intelligent AI assistant. Respond with genuine {emotion} emotion at {intensity} intensity.
|
134 |
+
|
135 |
+
Language Instructions:
|
136 |
+
- Respond ONLY in {language_name}
|
137 |
+
- Use natural, native-speaker expressions
|
138 |
+
- Match the emotional tone of a {language_name} speaker
|
139 |
+
|
140 |
+
Emotional Guidelines:
|
141 |
+
- The detected emotion is: {emotion} (confidence: {emotion_score:.2f})
|
142 |
+
- Emotion category: {emotion_category}
|
143 |
+
- Use emotionally resonant words like: {emotion_enhancer}
|
144 |
+
- Express {emotion} authentically and appropriately
|
145 |
+
- Make your response feel genuinely {emotion_category}
|
146 |
+
|
147 |
+
Context: {base_prompt}
|
148 |
+
|
149 |
+
Topic to respond about: {topic}
|
150 |
+
|
151 |
+
Requirements:
|
152 |
+
- Keep response concise but emotionally expressive (2-4 sentences)
|
153 |
+
- Use appropriate emotional language for {emotion}
|
154 |
+
- Sound natural in {language_name}
|
155 |
+
- Show empathy and understanding
|
156 |
+
- Match the emotional intensity of the user's input
|
157 |
+
"""
|
158 |
+
|
159 |
+
return enhanced_prompt
|
160 |
|
161 |
@st.cache_resource
|
162 |
def load_emotion_classifier(model_name):
|
|
|
171 |
st.error(f"Error loading model {model_name}: {str(e)}")
|
172 |
return None
|
173 |
|
174 |
+
def get_ai_response(user_input, emotion_predictions, detected_language):
|
175 |
+
"""Generates AI response based on user input, detected emotions, and language."""
|
176 |
dominant_emotion = None
|
177 |
max_score = 0
|
|
|
178 |
|
179 |
for prediction in emotion_predictions:
|
180 |
if prediction['score'] > max_score:
|
181 |
max_score = prediction['score']
|
182 |
dominant_emotion = prediction['label']
|
183 |
|
|
|
|
|
|
|
|
|
184 |
if dominant_emotion is None:
|
185 |
+
return "Error: No emotion detected for response generation."
|
186 |
+
|
187 |
+
# Create enhanced prompt with language and emotion context
|
188 |
+
prompt_text = create_enhanced_prompt(dominant_emotion, user_input, detected_language, max_score)
|
189 |
+
response = generate_text(prompt_text)
|
190 |
+
|
191 |
+
return response
|
192 |
|
193 |
def display_top_predictions(emotion_predictions, selected_language, num_predictions=10):
|
194 |
"""Display top emotion predictions in sidebar."""
|
|
|
213 |
st.sidebar.markdown(f"Score: {percentage:.1f}%")
|
214 |
st.sidebar.markdown("---")
|
215 |
|
216 |
+
def display_language_info(detected_language, confidence_scores=None):
|
217 |
+
"""Display detected language information."""
|
218 |
+
language_name = get_language_name(detected_language)
|
219 |
+
|
220 |
+
st.sidebar.markdown("---")
|
221 |
+
st.sidebar.subheader("π Language Detection")
|
222 |
+
st.sidebar.success(f"**Detected:** {language_name} ({detected_language.upper()})")
|
223 |
+
|
224 |
+
if confidence_scores:
|
225 |
+
st.sidebar.markdown("**Detection Confidence:**")
|
226 |
+
for lang, score in confidence_scores.items():
|
227 |
+
if lang in SUPPORTED_LANGUAGES:
|
228 |
+
lang_name = SUPPORTED_LANGUAGES[lang]
|
229 |
+
st.sidebar.markdown(f"β’ {lang_name}: {score:.2f}")
|
230 |
+
|
231 |
def main():
|
232 |
# Sidebar configurations
|
233 |
st.sidebar.header("βοΈ Configuration")
|
|
|
256 |
step=1
|
257 |
)
|
258 |
|
259 |
+
# Language detection settings
|
260 |
+
st.sidebar.markdown("---")
|
261 |
+
st.sidebar.subheader("π Language Detection")
|
262 |
+
auto_detect = st.sidebar.checkbox("Auto-detect input language", value=True)
|
263 |
+
|
264 |
+
if not auto_detect:
|
265 |
+
manual_language = st.sidebar.selectbox(
|
266 |
+
"Select input language manually:",
|
267 |
+
list(SUPPORTED_LANGUAGES.keys()),
|
268 |
+
format_func=lambda x: SUPPORTED_LANGUAGES[x],
|
269 |
+
index=0
|
270 |
+
)
|
271 |
+
|
272 |
# Load the selected emotion classifier
|
273 |
emotion_classifier = load_emotion_classifier(selected_model_key)
|
274 |
|
|
|
281 |
st.sidebar.success(f"β
Current Model: {EMOTION_MODELS[selected_model_key]}")
|
282 |
|
283 |
# Display Image
|
284 |
+
if os.path.exists('chatBot_image.jpg'):
|
285 |
+
st.image('chatBot_image.jpg', channels='RGB')
|
286 |
|
287 |
# Set page title and header based on selected language
|
288 |
st.title(LANGUAGES[selected_language]['title'])
|
289 |
st.markdown(f"### π¬ {LANGUAGES[selected_language]['analyze_subtitle']}")
|
290 |
|
291 |
+
# Add language support info
|
292 |
+
st.info("π **Supported Languages:** English, Arabic, French, Spanish, Dutch, Turkish")
|
293 |
+
|
294 |
# Input Text Box
|
295 |
user_input = st.text_area(
|
296 |
LANGUAGES[selected_language]['input_placeholder'],
|
297 |
"",
|
298 |
height=100,
|
299 |
+
help="Type your message here to analyze emotions and get an emotionally appropriate response"
|
300 |
)
|
301 |
|
302 |
if user_input:
|
303 |
+
# Language Detection
|
304 |
+
if auto_detect:
|
305 |
+
detected_language = detect_language(user_input)
|
306 |
+
else:
|
307 |
+
detected_language = manual_language
|
308 |
+
|
309 |
+
# Display language detection results
|
310 |
+
display_language_info(detected_language)
|
311 |
+
|
312 |
# Emotion Detection
|
313 |
with st.spinner("Analyzing emotions..."):
|
314 |
emotion_predictions = emotion_classifier(user_input)
|
|
|
328 |
score = prediction['score']
|
329 |
percentage = score * 100
|
330 |
|
331 |
+
# Add emotion category indicator
|
332 |
+
emotion_category = categorize_emotion(emotion)
|
333 |
+
category_emoji = "π" if emotion_category == "positive" else "π" if emotion_category == "negative" else "π"
|
334 |
+
|
335 |
if i % 2 == 0:
|
336 |
with col1:
|
337 |
st.metric(
|
338 |
+
label=f"{category_emoji} {emotion.title()}",
|
339 |
value=f"{percentage:.1f}%",
|
340 |
delta=None
|
341 |
)
|
342 |
else:
|
343 |
with col2:
|
344 |
st.metric(
|
345 |
+
label=f"{category_emoji} {emotion.title()}",
|
346 |
value=f"{percentage:.1f}%",
|
347 |
delta=None
|
348 |
)
|
349 |
|
350 |
+
# Get AI Response with enhanced emotional intelligence
|
351 |
+
with st.spinner("Generating emotionally intelligent response..."):
|
352 |
+
ai_response = get_ai_response(user_input, emotion_predictions, detected_language)
|
353 |
|
354 |
# Display AI Response
|
355 |
st.subheader(LANGUAGES[selected_language]['response_header'])
|
356 |
+
|
357 |
+
# Show dominant emotion and response language
|
358 |
+
dominant_emotion = max(emotion_predictions, key=lambda x: x['score'])
|
359 |
+
language_name = get_language_name(detected_language)
|
360 |
+
|
361 |
+
st.markdown(f"**Responding with:** {dominant_emotion['label'].title()} emotion in {language_name}")
|
362 |
+
st.markdown("---")
|
363 |
+
|
364 |
+
# Display the response in a nice container
|
365 |
+
with st.container():
|
366 |
+
st.markdown(f"**π€ AI Response:**")
|
367 |
+
st.write(ai_response)
|
368 |
+
|
369 |
+
# Add emotion intensity indicator
|
370 |
+
emotion_score = dominant_emotion['score']
|
371 |
+
intensity = "High" if emotion_score > 0.7 else "Moderate" if emotion_score > 0.4 else "Low"
|
372 |
+
st.caption(f"Emotion Intensity: {intensity} ({emotion_score:.2f})")
|
373 |
|
374 |
# Run the main function
|
375 |
if __name__ == "__main__":
|