Chandima Prabhath commited on
Commit
1ef8ab5
Β·
1 Parent(s): 8dc8276

Refactor message handling to use _fn_send_text for consistent text and audio responses; update voice reply prompt for a playful tone.

Browse files
Files changed (1) hide show
  1. app.py +54 -46
app.py CHANGED
@@ -86,6 +86,7 @@ class BotClient:
86
  files = [("file",(os.path.basename(file_path),f,mime))]
87
  return self.send(endpoint,payload,files=files)
88
 
 
89
  BotConfig.validate()
90
  client = BotClient(BotConfig)
91
 
@@ -115,11 +116,11 @@ for _ in range(4):
115
 
116
  def _fn_summarize(mid, cid, text):
117
  s = generate_llm(f"Summarize:\n\n{text}")
118
- client.send_message(mid,cid,s)
119
 
120
  def _fn_translate(mid, cid, lang, text):
121
  r = generate_llm(f"Translate to {lang}:\n\n{text}")
122
- client.send_message(mid,cid,r)
123
 
124
  def _fn_joke(mid, cid):
125
  try:
@@ -127,82 +128,92 @@ def _fn_joke(mid, cid):
127
  joke = f"{j['setup']}\n\n{j['punchline']}"
128
  except:
129
  joke = generate_llm("Tell me a short joke.")
130
- client.send_message(mid,cid,joke)
131
 
132
- def _fn_weather(mid,cid,loc):
133
  raw = requests.get(f"http://sl.wttr.in/{loc}?format=4",timeout=5).text
134
  r = generate_llm(f"Give a weather report in Β°C:\n\n{raw}")
135
- client.send_message(mid,cid,r)
136
- task_queue.put({"type":"audio","message_id":mid,"chat_id":cid,"prompt":r})
137
 
138
- def _fn_inspire(mid,cid):
139
- q = generate_llm("Give me a unique random short inspirational quote.")
140
- client.send_message(mid,cid,f"✨ {q}")
141
 
142
- def _fn_meme(mid,cid,txt):
143
- client.send_message(mid,cid,"🎨 Generating meme…")
144
  task_queue.put({"type":"image","message_id":mid,"chat_id":cid,"prompt":f"meme: {txt}"})
145
 
146
- def _fn_poll_create(mid,cid,question,options):
147
  votes = {i+1:0 for i in range(len(options))}
148
  polls[cid] = {"question":question,"options":options,"votes":votes,"voters":{}}
149
  text = f"πŸ“Š *Poll:* {question}\n" + "\n".join(f"{i+1}. {o}" for i,o in enumerate(options))
150
- client.send_message(mid,cid,text)
151
 
152
- def _fn_poll_vote(mid,cid,voter,choice):
153
  poll = polls.get(cid)
154
  if not poll or choice<1 or choice>len(poll["options"]): return
155
  prev = poll["voters"].get(voter)
156
  if prev: poll["votes"][prev]-=1
157
  poll["votes"][choice]+=1
158
  poll["voters"][voter]=choice
159
- client.send_message(mid,cid,f"βœ… Voted for {poll['options'][choice-1]}")
160
 
161
- def _fn_poll_results(mid,cid):
162
  poll = polls.get(cid)
163
  if not poll:
164
- client.send_message(mid,cid,"No active poll.")
165
  return
166
  txt = f"πŸ“Š *Results:* {poll['question']}\n" + "\n".join(
167
  f"{i}. {o}: {poll['votes'][i]}" for i,o in enumerate(poll["options"],1)
168
  )
169
- client.send_message(mid,cid,txt)
170
 
171
- def _fn_poll_end(mid,cid):
172
  poll = polls.pop(cid,None)
173
  if not poll:
174
- client.send_message(mid,cid,"No active poll.")
175
  return
176
  txt = f"πŸ“Š *Final Results:* {poll['question']}\n" + "\n".join(
177
  f"{i}. {o}: {poll['votes'][i]}" for i,o in enumerate(poll["options"],1)
178
  )
179
- client.send_message(mid,cid,txt)
180
 
181
- def _fn_generate_images(mid,cid,prompt,count=1):
182
  for i in range(1,count+1):
183
  try:
184
  img,path,ret_p,url = generate_image(prompt,mid,mid,BotConfig.IMAGE_DIR)
185
  formatted = "\n\n".join(f"_{p.strip()}_" for p in ret_p.split("\n\n") if p.strip())
186
  cap = f"✨ Image {i}/{count}: {url}\n>{chr(8203)} {formatted}"
187
- client.send_media(mid,cid,path,cap,media_type="image")
188
  os.remove(path)
189
  except Exception as e:
190
  logging.warning(f"Img {i}/{count} failed: {e}")
191
- client.send_message(mid,cid,f"😒 Failed to gen image {i}/{count}.")
192
-
193
- def _fn_send_text(mid,cid,message):
194
- client.send_message(mid,cid,message)
195
-
196
- def _fn_voice_reply(mid,cid,prompt):
197
- proccessed_prompt = f"Just say this dialog eaxcatly as it is in a flirty, frinedly, playful, happy and helpful but little bit clumsy in a cute way manner as a cute secretary: {prompt}"
198
- res = generate_voice_reply(proccessed_prompt,model="openai-audio",voice="coral",audio_dir=BotConfig.AUDIO_DIR)
 
 
 
 
 
 
 
 
 
 
 
199
  if res and res[0]:
200
  path,_ = res
201
- client.send_media(mid,cid,path,"",media_type="audio")
202
  os.remove(path)
203
  else:
204
- txt = generate_llm(prompt)
205
- client.send_message(mid,cid,txt)
206
 
207
  # --- Function schema & router ---
208
 
@@ -210,8 +221,7 @@ FUNCTION_SCHEMA = {
210
  "summarize": {"description":"Summarize text","params":["text"]},
211
  "translate": {"description":"Translate text","params":["lang","text"]},
212
  "joke": {"description":"Tell a joke","params":[]},
213
- "weather": {"description":"Creative weather","params":["location"]},
214
- "weather_poem": {"description":"Poetic weather","params":["location"]},
215
  "inspire": {"description":"Inspirational quote","params":[]},
216
  "meme": {"description":"Generate meme","params":["text"]},
217
  "poll_create": {"description":"Create poll","params":["question","options"]},
@@ -246,13 +256,11 @@ help_text = (
246
  "β€’ /translate <lang>|<text>\n"
247
  "β€’ /joke\n"
248
  "β€’ /weather <loc>\n"
249
- "β€’ /weatherpoem <loc>\n"
250
  "β€’ /inspire\n"
251
- "β€’ /trivia / /answer\n"
252
  "β€’ /meme <text>\n"
253
  "β€’ /poll <Q>|… / /results / /endpoll\n"
254
  "β€’ /gen <prompt>|<count>\n"
255
- "Otherwise chat freely or reply to one of my messages to invoke tools."
256
  )
257
 
258
  @app.post("/whatsapp")
@@ -276,7 +284,7 @@ async def whatsapp_webhook(request: Request):
276
  # Slash commands
277
  low = body.lower()
278
  if low=="/help":
279
- client.send_message(mid,chat_id,help_text); return {"success":True}
280
  if low.startswith("/summarize "):
281
  _fn_summarize(mid,chat_id,body[11:].strip()); return {"success":True}
282
  if low.startswith("/translate "):
@@ -344,10 +352,8 @@ async def whatsapp_webhook(request: Request):
344
  if action in dispatch:
345
  dispatch[action]()
346
  else:
347
- # fallback chat
348
- txt = intent.get("message","Sorry, I didn't get that.")
349
- _fn_send_text(mid,chat_id,txt)
350
- task_queue.put({"type":"audio","message_id":mid,"chat_id":chat_id,"prompt":txt})
351
 
352
  return {"success":True}
353
 
@@ -356,7 +362,9 @@ def index():
356
  return "Server is running!"
357
 
358
  if __name__=="__main__":
359
- client.send_message_to(BotConfig.BOT_GROUP_CHAT,
360
- "🌟 Eve is online! Type /help to see commands.")
 
 
361
  import uvicorn
362
  uvicorn.run(app,host="0.0.0.0",port=7860)
 
86
  files = [("file",(os.path.basename(file_path),f,mime))]
87
  return self.send(endpoint,payload,files=files)
88
 
89
+ # Validate env
90
  BotConfig.validate()
91
  client = BotClient(BotConfig)
92
 
 
116
 
117
  def _fn_summarize(mid, cid, text):
118
  s = generate_llm(f"Summarize:\n\n{text}")
119
+ _fn_send_text(mid, cid, s)
120
 
121
  def _fn_translate(mid, cid, lang, text):
122
  r = generate_llm(f"Translate to {lang}:\n\n{text}")
123
+ _fn_send_text(mid, cid, r)
124
 
125
  def _fn_joke(mid, cid):
126
  try:
 
128
  joke = f"{j['setup']}\n\n{j['punchline']}"
129
  except:
130
  joke = generate_llm("Tell me a short joke.")
131
+ _fn_send_text(mid, cid, joke)
132
 
133
+ def _fn_weather(mid, cid, loc):
134
  raw = requests.get(f"http://sl.wttr.in/{loc}?format=4",timeout=5).text
135
  r = generate_llm(f"Give a weather report in Β°C:\n\n{raw}")
136
+ _fn_send_text(mid, cid, r)
 
137
 
138
+ def _fn_inspire(mid, cid):
139
+ q = generate_llm("Give me a unique, random short inspirational quote.")
140
+ _fn_send_text(mid, cid, f"✨ {q}")
141
 
142
+ def _fn_meme(mid, cid, txt):
143
+ client.send_message(mid, cid, "🎨 Generating meme…")
144
  task_queue.put({"type":"image","message_id":mid,"chat_id":cid,"prompt":f"meme: {txt}"})
145
 
146
+ def _fn_poll_create(mid, cid, question, options):
147
  votes = {i+1:0 for i in range(len(options))}
148
  polls[cid] = {"question":question,"options":options,"votes":votes,"voters":{}}
149
  text = f"πŸ“Š *Poll:* {question}\n" + "\n".join(f"{i+1}. {o}" for i,o in enumerate(options))
150
+ _fn_send_text(mid, cid, text)
151
 
152
+ def _fn_poll_vote(mid, cid, voter, choice):
153
  poll = polls.get(cid)
154
  if not poll or choice<1 or choice>len(poll["options"]): return
155
  prev = poll["voters"].get(voter)
156
  if prev: poll["votes"][prev]-=1
157
  poll["votes"][choice]+=1
158
  poll["voters"][voter]=choice
159
+ _fn_send_text(mid, cid, f"βœ… Voted for {poll['options'][choice-1]}")
160
 
161
+ def _fn_poll_results(mid, cid):
162
  poll = polls.get(cid)
163
  if not poll:
164
+ _fn_send_text(mid, cid, "No active poll.")
165
  return
166
  txt = f"πŸ“Š *Results:* {poll['question']}\n" + "\n".join(
167
  f"{i}. {o}: {poll['votes'][i]}" for i,o in enumerate(poll["options"],1)
168
  )
169
+ _fn_send_text(mid, cid, txt)
170
 
171
+ def _fn_poll_end(mid, cid):
172
  poll = polls.pop(cid,None)
173
  if not poll:
174
+ _fn_send_text(mid, cid, "No active poll.")
175
  return
176
  txt = f"πŸ“Š *Final Results:* {poll['question']}\n" + "\n".join(
177
  f"{i}. {o}: {poll['votes'][i]}" for i,o in enumerate(poll["options"],1)
178
  )
179
+ _fn_send_text(mid, cid, txt)
180
 
181
+ def _fn_generate_images(mid, cid, prompt, count=1):
182
  for i in range(1,count+1):
183
  try:
184
  img,path,ret_p,url = generate_image(prompt,mid,mid,BotConfig.IMAGE_DIR)
185
  formatted = "\n\n".join(f"_{p.strip()}_" for p in ret_p.split("\n\n") if p.strip())
186
  cap = f"✨ Image {i}/{count}: {url}\n>{chr(8203)} {formatted}"
187
+ client.send_media(mid, cid, path, cap, media_type="image")
188
  os.remove(path)
189
  except Exception as e:
190
  logging.warning(f"Img {i}/{count} failed: {e}")
191
+ _fn_send_text(mid, cid, f"😒 Failed to generate image {i}/{count}.")
192
+
193
+ def _fn_send_text(mid, cid, message):
194
+ # send text...
195
+ client.send_message(mid, cid, message)
196
+ # ...and queue voice with the same content
197
+ task_queue.put({
198
+ "type": "audio",
199
+ "message_id": mid,
200
+ "chat_id": cid,
201
+ "prompt": message
202
+ })
203
+
204
+ def _fn_voice_reply(mid, cid, prompt):
205
+ processed = (
206
+ f"Just say this exactly as written in a flirty, friendly, playful, "
207
+ f"happy and helpful but a little bit clumsy-cute way: {prompt}"
208
+ )
209
+ res = generate_voice_reply(processed,model="openai-audio",voice="coral",audio_dir=BotConfig.AUDIO_DIR)
210
  if res and res[0]:
211
  path,_ = res
212
+ client.send_media(mid, cid, path, "", media_type="audio")
213
  os.remove(path)
214
  else:
215
+ # fallback to text+voice
216
+ _fn_send_text(mid, cid, prompt)
217
 
218
  # --- Function schema & router ---
219
 
 
221
  "summarize": {"description":"Summarize text","params":["text"]},
222
  "translate": {"description":"Translate text","params":["lang","text"]},
223
  "joke": {"description":"Tell a joke","params":[]},
224
+ "weather": {"description":"Weather report","params":["location"]},
 
225
  "inspire": {"description":"Inspirational quote","params":[]},
226
  "meme": {"description":"Generate meme","params":["text"]},
227
  "poll_create": {"description":"Create poll","params":["question","options"]},
 
256
  "β€’ /translate <lang>|<text>\n"
257
  "β€’ /joke\n"
258
  "β€’ /weather <loc>\n"
 
259
  "β€’ /inspire\n"
 
260
  "β€’ /meme <text>\n"
261
  "β€’ /poll <Q>|… / /results / /endpoll\n"
262
  "β€’ /gen <prompt>|<count>\n"
263
+ "Otherwise chat or reply to my message to invoke tools."
264
  )
265
 
266
  @app.post("/whatsapp")
 
284
  # Slash commands
285
  low = body.lower()
286
  if low=="/help":
287
+ _fn_send_text(mid,chat_id,help_text); return {"success":True}
288
  if low.startswith("/summarize "):
289
  _fn_summarize(mid,chat_id,body[11:].strip()); return {"success":True}
290
  if low.startswith("/translate "):
 
352
  if action in dispatch:
353
  dispatch[action]()
354
  else:
355
+ # fallback to send_text (which also queues voice)
356
+ _fn_send_text(mid,chat_id,intent.get("message","Sorry, I didn't get that."))
 
 
357
 
358
  return {"success":True}
359
 
 
362
  return "Server is running!"
363
 
364
  if __name__=="__main__":
365
+ client.send_message_to(
366
+ BotConfig.BOT_GROUP_CHAT,
367
+ "🌟 Eve is online! Type /help to see commands."
368
+ )
369
  import uvicorn
370
  uvicorn.run(app,host="0.0.0.0",port=7860)