opinder2906 commited on
Commit
2567133
·
verified ·
1 Parent(s): 7d9841e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -44
app.py CHANGED
@@ -10,9 +10,8 @@ import gradio as gr
10
  import speech_recognition as sr
11
  import json
12
 
13
- # Dummy vocab and label encoder
14
- vocab = {'<PAD>': 0, '<UNK>': 1, 'i': 2, 'am': 3, 'feeling': 4, 'sad': 5, 'happy': 6,
15
- 'angry': 7, 'love': 8, 'stressed': 9, 'anxious': 10}
16
  MAX_LEN = 16
17
 
18
  class DummyLabelEncoder:
@@ -34,46 +33,73 @@ class DummyModel(nn.Module):
34
  return self.fc(x)
35
 
36
  model = DummyModel()
37
- model.eval()
38
 
39
  def preprocess_input(text):
40
  tokens = text.lower().split()
41
  encoded = [vocab.get(token, vocab['<UNK>']) for token in tokens]
42
  padded = encoded[:MAX_LEN] + [vocab['<PAD>']] * max(0, MAX_LEN - len(encoded))
43
- return torch.tensor([padded], dtype=torch.long)
44
 
45
- # Load solutions CSV from Google Drive
46
- file_id = "1yVJh_NVL4Y4YqEXGym47UCK5ZNZgVZYv" # replace with your CSV file ID
47
  url = f"https://drive.google.com/uc?export=download&id={file_id}"
48
  response = requests.get(url)
49
  csv_text = response.text
 
50
  if csv_text.strip().startswith('<'):
51
- raise Exception("ERROR: Google Drive link is not returning CSV! Check sharing settings.")
 
52
  solutions_df = pd.read_csv(StringIO(csv_text), header=0, on_bad_lines='skip')
 
53
  used_solutions = {emotion: set() for emotion in solutions_df['emotion'].unique()}
54
 
55
- negative_words = ["not", "bad", "sad", "anxious", "anxiety", "depressed", "upset", "shit", "stress",
56
- "worried", "unwell", "struggling", "low", "down", "terrible", "awful",
57
- "nervous", "panic", "afraid", "scared", "tense", "overwhelmed", "fear", "uneasy"]
 
 
 
58
 
59
  responses = {
60
- "sadness": ["It’s okay to feel down sometimes. I’m here to support you.",
61
- "I'm really sorry you're going through this. Want to talk more about it?",
62
- "You're not alone I’m here for you."],
63
- "anger": ["That must have been frustrating. Want to vent about it?",
64
- "It's okay to feel this way. I'm listening.",
65
- "Would it help to talk through it?"],
66
- "love": ["That’s beautiful to hear! What made you feel that way?",
67
- "Its amazing to experience moments like that.",
68
- "Sounds like something truly meaningful."],
69
- "happiness": ["That's awesome! What’s bringing you joy today?",
70
- "I love hearing good news. 😊",
71
- "Yay! Want to share more about it?"],
72
- "neutral": ["Got it. Im here if you want to dive deeper.",
73
- "Thanks for sharing that. Tell me more if you’d like.",
74
- "I’m listening. How else can I support you?"]
 
 
 
 
 
 
 
 
 
 
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def get_unique_solution(emotion):
78
  available = solutions_df[solutions_df['emotion'] == emotion]
79
  unused = available[~available['solution'].isin(used_solutions[emotion])]
@@ -84,24 +110,23 @@ def get_unique_solution(emotion):
84
  used_solutions[emotion].add(solution_row['solution'])
85
  return solution_row['solution']
86
 
87
- def correct_spelling(text):
88
- return str(TextBlob(text).correct())
89
-
90
- def is_negative_input(text):
91
- text_lower = text.lower()
92
- return any(word in text_lower for word in negative_words)
93
-
94
  def get_emotion(user_input):
95
  if is_negative_input(user_input):
96
  return "sadness"
 
97
  x = preprocess_input(user_input)
 
98
  with torch.no_grad():
99
- logits = model(x)
100
- probs = F.softmax(logits, dim=1)
101
- prob, idx = torch.max(probs, dim=1)
102
  pred_emotion = le.classes_[idx.item()]
103
  if prob.item() < 0.6:
104
  return "neutral"
 
 
 
 
105
  return pred_emotion
106
 
107
  def audio_to_text(audio_file):
@@ -111,10 +136,12 @@ def audio_to_text(audio_file):
111
  with sr.AudioFile(audio_file) as source:
112
  audio = recog.record(source)
113
  try:
114
- return recog.recognize_google(audio)
 
115
  except Exception:
116
  return ""
117
 
 
118
  GLOBAL_CONVO_HISTORY = []
119
  USER_FEEDBACK_STATE = {}
120
 
@@ -125,13 +152,13 @@ def emoti_chat(audio, text, history_json=""):
125
  user_input = audio_to_text(audio)
126
  else:
127
  user_input = ""
128
-
129
  if not user_input.strip():
130
  return "Please say something or type your message.", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""
131
 
132
  user_input = correct_spelling(user_input)
133
 
134
- if user_input.lower().strip() in ["exit", "quit", "goodbye", "bye", "close"]:
 
135
  return "Take care! I’m here whenever you want to talk. 👋", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), gr.update(visible=False)
136
 
137
  user_id = "default_user"
@@ -157,7 +184,6 @@ def emoti_chat(audio, text, history_json=""):
157
  suggestion = get_unique_solution("neutral")
158
 
159
  reply = f"{support}\n\nHere's a suggestion for you: {suggestion}\nDid this help? (yes/no/skip)"
160
-
161
  GLOBAL_CONVO_HISTORY.append({
162
  "user_input": user_input,
163
  "emotion": pred_emotion,
@@ -168,19 +194,21 @@ def emoti_chat(audio, text, history_json=""):
168
  USER_FEEDBACK_STATE[user_id] = {"emotion": pred_emotion, "pending": True}
169
  return reply, json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""
170
 
 
171
  iface = gr.Interface(
172
  fn=emoti_chat,
173
  inputs=[
174
  gr.Audio(type="filepath", label="🎤 Speak your message"),
175
  gr.Textbox(lines=2, placeholder="Or type your message here...", label="💬 Type message"),
176
- gr.Textbox(lines=1, value="", visible=False)
177
  ],
178
  outputs=[
179
  gr.Textbox(label="EmotiBot Reply"),
180
- gr.Textbox(label="Conversation History (JSON)", visible=False)
181
  ],
182
  title="EmotiBot Connect",
183
- description="Talk to EmotiBot using your voice or by typing. Detects your emotion, gives suggestions, and keeps history!"
184
  )
185
 
186
- iface.launch()
 
 
10
  import speech_recognition as sr
11
  import json
12
 
13
+ # ----- Dummy Model and vocab -----
14
+ vocab = {'<PAD>': 0, '<UNK>': 1, 'i': 2, 'am': 3, 'feeling': 4, 'sad': 5, 'happy': 6, 'angry': 7, 'love': 8, 'stressed': 9, 'anxious': 10}
 
15
  MAX_LEN = 16
16
 
17
  class DummyLabelEncoder:
 
33
  return self.fc(x)
34
 
35
  model = DummyModel()
 
36
 
37
  def preprocess_input(text):
38
  tokens = text.lower().split()
39
  encoded = [vocab.get(token, vocab['<UNK>']) for token in tokens]
40
  padded = encoded[:MAX_LEN] + [vocab['<PAD>']] * max(0, MAX_LEN - len(encoded))
41
+ return torch.tensor([padded], dtype=torch.long).to(next(model.parameters()).device)
42
 
43
+ # ----- Load CSV from Google Drive -----
44
+ file_id = "1yVJh_NVL4Y4YqEXGym47UCK5ZNZgVZYv"
45
  url = f"https://drive.google.com/uc?export=download&id={file_id}"
46
  response = requests.get(url)
47
  csv_text = response.text
48
+
49
  if csv_text.strip().startswith('<'):
50
+ raise Exception("ERROR: Google Drive link is not returning CSV! Check your sharing settings.")
51
+
52
  solutions_df = pd.read_csv(StringIO(csv_text), header=0, on_bad_lines='skip')
53
+
54
  used_solutions = {emotion: set() for emotion in solutions_df['emotion'].unique()}
55
 
56
+ # ----- Data and responses -----
57
+ negative_words = [
58
+ "not", "bad", "sad", "anxious", "anxiety", "depressed", "upset", "shit", "stress",
59
+ "worried", "unwell", "struggling", "low", "down", "terrible", "awful",
60
+ "nervous", "panic", "afraid", "scared", "tense", "overwhelmed", "fear", "uneasy"
61
+ ]
62
 
63
  responses = {
64
+ "sadness": [
65
+ "It’s okay to feel down sometimes. I’m here to support you.",
66
+ "I'm really sorry you're going through this. Want to talk more about it?",
67
+ "You're not alone I’m here for you."
68
+ ],
69
+ "anger": [
70
+ "That must have been frustrating. Want to vent about it?",
71
+ "It's okay to feel this way. I'm listening.",
72
+ "Would it help to talk through it?"
73
+ ],
74
+ "love": [
75
+ "That’s beautiful to hear! What made you feel that way?",
76
+ "Its amazing to experience moments like that.",
77
+ "Sounds like something truly meaningful."
78
+ ],
79
+ "happiness": [
80
+ "That's awesome! What’s bringing you joy today?",
81
+ "I love hearing good news. 😊",
82
+ "Yay! Want to share more about it?"
83
+ ],
84
+ "neutral": [
85
+ "Got it. I’m here if you want to dive deeper.",
86
+ "Thanks for sharing that. Tell me more if you’d like.",
87
+ "I’m listening. How else can I support you?"
88
+ ]
89
  }
90
 
91
+ # --- Helper functions ---
92
+
93
+ def correct_spelling(text):
94
+ return str(TextBlob(text).correct())
95
+
96
+ def get_sentiment(text):
97
+ return TextBlob(text).sentiment.polarity
98
+
99
+ def is_negative_input(text):
100
+ text_lower = text.lower()
101
+ return any(word in text_lower for word in negative_words)
102
+
103
  def get_unique_solution(emotion):
104
  available = solutions_df[solutions_df['emotion'] == emotion]
105
  unused = available[~available['solution'].isin(used_solutions[emotion])]
 
110
  used_solutions[emotion].add(solution_row['solution'])
111
  return solution_row['solution']
112
 
 
 
 
 
 
 
 
113
  def get_emotion(user_input):
114
  if is_negative_input(user_input):
115
  return "sadness"
116
+ sentiment = get_sentiment(user_input)
117
  x = preprocess_input(user_input)
118
+ model.train()
119
  with torch.no_grad():
120
+ probs = torch.stack([F.softmax(model(x), dim=1) for _ in range(5)])
121
+ avg_probs = probs.mean(dim=0)
122
+ prob, idx = torch.max(avg_probs, dim=1)
123
  pred_emotion = le.classes_[idx.item()]
124
  if prob.item() < 0.6:
125
  return "neutral"
126
+ if sentiment < -0.25 and pred_emotion == "happiness":
127
+ return "sadness"
128
+ if sentiment > 0.25 and pred_emotion == "sadness":
129
+ return "happiness"
130
  return pred_emotion
131
 
132
  def audio_to_text(audio_file):
 
136
  with sr.AudioFile(audio_file) as source:
137
  audio = recog.record(source)
138
  try:
139
+ text = recog.recognize_google(audio)
140
+ return text
141
  except Exception:
142
  return ""
143
 
144
+ # ----- Chat function -----
145
  GLOBAL_CONVO_HISTORY = []
146
  USER_FEEDBACK_STATE = {}
147
 
 
152
  user_input = audio_to_text(audio)
153
  else:
154
  user_input = ""
 
155
  if not user_input.strip():
156
  return "Please say something or type your message.", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""
157
 
158
  user_input = correct_spelling(user_input)
159
 
160
+ exit_phrases = ["exit", "quit", "goodbye", "bye", "close"]
161
+ if user_input.lower().strip() in exit_phrases:
162
  return "Take care! I’m here whenever you want to talk. 👋", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), gr.update(visible=False)
163
 
164
  user_id = "default_user"
 
184
  suggestion = get_unique_solution("neutral")
185
 
186
  reply = f"{support}\n\nHere's a suggestion for you: {suggestion}\nDid this help? (yes/no/skip)"
 
187
  GLOBAL_CONVO_HISTORY.append({
188
  "user_input": user_input,
189
  "emotion": pred_emotion,
 
194
  USER_FEEDBACK_STATE[user_id] = {"emotion": pred_emotion, "pending": True}
195
  return reply, json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""
196
 
197
+ # ---- Gradio interface ----
198
  iface = gr.Interface(
199
  fn=emoti_chat,
200
  inputs=[
201
  gr.Audio(type="filepath", label="🎤 Speak your message"),
202
  gr.Textbox(lines=2, placeholder="Or type your message here...", label="💬 Type message"),
203
+ gr.Textbox(lines=1, value="", visible=False) # hidden, history state
204
  ],
205
  outputs=[
206
  gr.Textbox(label="EmotiBot Reply"),
207
+ gr.Textbox(label="Hidden", visible=False)
208
  ],
209
  title="EmotiBot Connect",
210
+ description="Talk to EmotiBot using your voice or by typing. Detects your emotion, gives dynamic suggestions, remembers your feedback, and keeps a conversation history! Type 'exit' to leave."
211
  )
212
 
213
+ if __name__ == "__main__":
214
+ iface.launch(debug=True)