Keyvan1986 commited on
Commit
ff2e9c5
·
verified ·
1 Parent(s): ec5fb1b

Update Emma/app.py

Browse files
Files changed (1) hide show
  1. Emma/app.py +70 -63
Emma/app.py CHANGED
@@ -35,7 +35,6 @@ try:
35
  from utils.app_modules.presets import *
36
  from utils.app_modules.overwrites import *
37
  from utils.prompt_utils import *
38
- # نکته: save_local_memory قدیمی حذف شد و با save_memory جایگزین شد
39
  except ImportError:
40
  data_args = {}
41
  boot_actual_name_dict = {'en': 'Emma'}
@@ -102,9 +101,6 @@ def read_apis(path):
102
 
103
  api_keys = read_apis(api_path)
104
 
105
- # نکته: بخش لود کردن memory به صورت سراسری از اینجا حذف شد.
106
- # مدیریت فایل کاملاً به memory_utils سپرده شده است.
107
-
108
  language = 'en'
109
  boot_actual_name = boot_actual_name_dict.get(language, "Emma")
110
  meta_prompt = generate_meta_prompt_dict_chatgpt().get(language, "")
@@ -124,6 +120,7 @@ def chatgpt_chat(prompt, system, history, gpt_config, api_index=0):
124
  messages = [{"role": "system", "content": system}]
125
  if history:
126
  for h in history:
 
127
  if isinstance(h, dict) and 'role' in h and 'content' in h:
128
  messages.append(h)
129
  messages.append({"role": "user", "content": prompt})
@@ -168,7 +165,7 @@ def predict_new(
168
  system_prompt, _ = build_prompt_with_search_memory_llamaindex(
169
  history=history,
170
  query=text,
171
- user_memory=user_memory, # اینجا user_memory تازه دریافت می‌شود
172
  user_name=user_name,
173
  user_memory_index=None,
174
  service_context=None,
@@ -190,14 +187,12 @@ def predict_new(
190
  hist_for_llm = history[-10:] if len(history) > 10 else history
191
  response = chatgpt_chat(text, system_prompt, hist_for_llm, chat_cfg, api_index)
192
 
 
193
  new_history = history + [
194
  {"role": "user", "content": text},
195
  {"role": "assistant", "content": response}
196
  ]
197
 
198
- # نکته مهم: عملیات ذخیره‌سازی از اینجا حذف شد.
199
- # ذخیره‌سازی باید در لایه بالاتر (respond) انجام شود که کل آبجکت مموری را در اختیار دارد.
200
-
201
  return new_history, new_history
202
 
203
  # ==========================================
@@ -205,7 +200,6 @@ def predict_new(
205
  # ==========================================
206
 
207
  def create_gradio_interface():
208
- # استایل‌های CSS قدیمی شما
209
  css = """
210
  .mobile-button button {
211
  width: 100% !important;
@@ -234,8 +228,6 @@ def create_gradio_interface():
234
 
235
  with gr.Blocks(title="EMMA AI", css=css) as demo:
236
 
237
- # State: فقط داده‌های موقت را نگه می‌دارد.
238
- # کل مموری دیگر در State نیست تا از تداخل جلوگیری شود.
239
  state = gr.State({
240
  "history": [],
241
  "user_name": None,
@@ -246,7 +238,6 @@ def create_gradio_interface():
246
 
247
  header = gr.Markdown("## 🧠 EMMA: Your Empathetic Mental Health Assistant\nWelcome! Please enter your name to begin.")
248
 
249
- # --- بخش لاگین ---
250
  with gr.Column(visible=True) as login_col:
251
  with gr.Accordion("🔐 Start New Session", open=True):
252
  with gr.Row():
@@ -258,11 +249,10 @@ def create_gradio_interface():
258
  residence_input = gr.Textbox(label="Place of Residence", placeholder="e.g., Berlin")
259
  start_btn = gr.Button("🎯 Start Session", variant="primary")
260
 
261
- # --- بخش اعلان سیستم ---
262
  system_msg = gr.Textbox(label="🔔 System Messages", interactive=False, max_lines=2, visible=False)
263
 
264
- # --- بخش چت ---
265
  with gr.Column(visible=False) as chat_col:
 
266
  chatbot = gr.Chatbot(height=500, type="messages", label="💬 EMMA Conversation")
267
 
268
  with gr.Row():
@@ -275,26 +265,25 @@ def create_gradio_interface():
275
  switch_user_btn = gr.Button("👥 Switch User", variant="primary", elem_classes=["mobile-button"])
276
 
277
  # ==========================================
278
- # توابع کنترلی UI (اصلاح شده برای ذخیره‌سازی صحیح)
279
  # ==========================================
280
 
281
  def start_session(name, age, gender, job, city, current_state):
282
  if not name or not name.strip():
283
  return (
284
- gr.update(), gr.update(), gr.update(), # login, chat, system
285
  gr.update(value="## ⚠️ Please enter a valid name."),
286
  current_state,
287
- [] # empty history for chatbot
288
  )
289
 
290
- # 1. بارگذاری حافظه تازه از دیسک
291
  memory_data = load_memory()
292
 
293
- # 2. ایجاد یا به‌روزرسانی یوزر در حافظه
294
- # enter_name_llamaindex روی دیکشنری memory_data تغییر ایجاد می‌کند
295
  enter_name_llamaindex(name, memory_data, data_args)
296
 
297
- # 3. ذخیره اطلاعات پروفایل
298
  if name in memory_data:
299
  memory_data[name]["profile"] = {
300
  "age": age, "gender": gender,
@@ -302,32 +291,53 @@ def create_gradio_interface():
302
  }
303
 
304
  # اطمینان از وجود لیست سشن‌ها
305
- if "sessions" not in memory_data[name] or not memory_data[name]["sessions"]:
 
 
 
 
306
  memory_data[name]["sessions"] = [{
307
  "session_id": 0, "date": time.strftime("%Y-%m-%d"), "conversation": []
308
  }]
309
 
310
- # 4. ذخیره کل حافظه روی دیسک (بسیار مهم)
311
  save_memory(memory_data)
312
  print(f"✅ User {name} loaded/created and saved.")
313
 
314
- # 5. به‌روزرسانی State
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  new_st = copy.deepcopy(current_state)
316
  new_st["user_name"] = name
317
  new_st["init"] = True
 
318
 
319
- # استخراج حافظه معنایی برای کانتکست
320
  try:
321
- user_mem = memory_data.get(name, {})
322
  if isinstance(user_mem, dict):
323
  new_st["semantic"] = str(user_mem.get("semantic_memory", ""))
324
-
325
- # بازیابی تاریخچه آخرین سشن (اختیاری - اگر می‌خواهید چت قبلی نمایش داده شود)
326
- last_history = user_mem.get("sessions", [{}])[-1].get("conversation", [])
327
- new_st["history"] = last_history
328
  except:
329
- last_history = []
330
- new_st["history"] = []
331
 
332
  welcome_txt = f"## 🧠 EMMA: Session for {name}"
333
  sys_txt = f"Welcome {name}! Memory loaded successfully."
@@ -338,7 +348,7 @@ def create_gradio_interface():
338
  gr.update(visible=True, value=sys_txt), # Show System Msg
339
  gr.update(value=welcome_txt), # Update Header
340
  new_st,
341
- last_history # نمایش تاریخچه در چت‌بات
342
  )
343
 
344
  def respond(msg, current_state):
@@ -347,39 +357,45 @@ def create_gradio_interface():
347
 
348
  user_name = current_state["user_name"]
349
 
350
- # 1. بارگذاری حافظه تازه برای اطمینان از داشتن آخرین وضعیت
351
  memory_data = load_memory()
352
  user_memory = memory_data.get(user_name, {})
353
 
354
  cat = classify_query_local(msg)
355
 
356
- # 2. تولید پاسخ (فقط تولید، بدون ذخیره)
 
 
357
  _, new_hist = predict_new(
358
  text=msg,
359
- history=current_state["history"],
360
  top_p=0.9, temperature=0.7, max_length_tokens=512, max_context_length_tokens=200,
361
  user_name=user_name,
362
- user_memory=user_memory, # ارسال آبجکت یوزر مموری
363
  api_index=current_state["api_index"],
364
- semantic_memory_text=current_state["semantic"],
365
  query_category=cat
366
  )
367
 
368
- # 3. اعمال تغییرات در آبجکت کل حافظه
369
- if user_name in memory_data and memory_data[user_name].get("sessions"):
370
- memory_data[user_name]["sessions"][-1]["conversation"] = new_hist
 
 
 
 
 
 
 
371
 
372
- # 4. ذخیره نهایی روی دیسک
373
  save_memory(memory_data)
374
 
375
- # 5. آپدیت State گرادیو
376
  new_st = copy.deepcopy(current_state)
377
  new_st["history"] = new_hist
378
 
379
  return new_hist, new_st, ""
380
 
381
  def clear_chat(current_state):
382
- # پاک کردن چت فقط در محیط بصری و State فعلی (بدون حذف از دیتابیس برای امنیت)
383
  new_st = copy.deepcopy(current_state)
384
  new_st["history"] = []
385
  return [], new_st, "Conversation view cleared (Memory retained)."
@@ -389,40 +405,31 @@ def create_gradio_interface():
389
  if not u_name:
390
  return [], current_state, "Error: No user."
391
 
392
- # 1. بارگذاری حافظه
393
  memory_data = load_memory()
394
 
395
  if u_name in memory_data:
396
  try:
397
  user_sessions = memory_data[u_name].get("sessions", [])
398
-
399
- # ایجاد سشن جدید
400
  new_s = {
401
  "session_id": len(user_sessions),
402
  "date": time.strftime("%Y-%m-%d"),
403
- "conversation": []
404
  }
405
-
406
- if "sessions" not in memory_data[u_name]:
407
- memory_data[u_name]["sessions"] = []
408
 
409
  memory_data[u_name]["sessions"].append(new_s)
410
-
411
- # 2. ذخیره تغییرات
412
  save_memory(memory_data)
413
  print(f"🔄 New session created for {u_name}")
414
-
415
  except Exception as e:
416
  print(f"New Session Error: {e}")
417
 
418
- # ریست کردن State
419
  new_st = copy.deepcopy(current_state)
420
  new_st["history"] = []
421
 
422
  return [], new_st, "🆕 New session started & Saved."
423
 
424
  def switch_user_logic(current_state):
425
- # ریست کامل State
426
  new_st = {
427
  "history": [],
428
  "user_name": None,
@@ -431,17 +438,17 @@ def create_gradio_interface():
431
  "init": False
432
  }
433
  return (
434
- gr.update(visible=True), # Show Login
435
- gr.update(visible=False), # Hide Chat
436
- gr.update(visible=False, value=""), # Hide System Msg
437
  gr.update(value="## 🧠 EMMA: Switch User Mode"),
438
  new_st,
439
- gr.update(value=""), # Clear Name Input
440
- [] # Clear Chatbot
441
  )
442
 
443
  # ==========================================
444
- # اتصال رویدادها (Event Listeners)
445
  # ==========================================
446
 
447
  start_btn.click(
@@ -508,7 +515,7 @@ def main():
508
 
509
  demo = create_gradio_interface()
510
 
511
- print("🚀 Launching Gradio Server (Fixed Memory Saving)...")
512
  demo.queue().launch(
513
  server_name="0.0.0.0",
514
  server_port=7860,
 
35
  from utils.app_modules.presets import *
36
  from utils.app_modules.overwrites import *
37
  from utils.prompt_utils import *
 
38
  except ImportError:
39
  data_args = {}
40
  boot_actual_name_dict = {'en': 'Emma'}
 
101
 
102
  api_keys = read_apis(api_path)
103
 
 
 
 
104
  language = 'en'
105
  boot_actual_name = boot_actual_name_dict.get(language, "Emma")
106
  meta_prompt = generate_meta_prompt_dict_chatgpt().get(language, "")
 
120
  messages = [{"role": "system", "content": system}]
121
  if history:
122
  for h in history:
123
+ # اطمینان از فرمت صحیح پیام‌ها قبل از ارسال به API
124
  if isinstance(h, dict) and 'role' in h and 'content' in h:
125
  messages.append(h)
126
  messages.append({"role": "user", "content": prompt})
 
165
  system_prompt, _ = build_prompt_with_search_memory_llamaindex(
166
  history=history,
167
  query=text,
168
+ user_memory=user_memory,
169
  user_name=user_name,
170
  user_memory_index=None,
171
  service_context=None,
 
187
  hist_for_llm = history[-10:] if len(history) > 10 else history
188
  response = chatgpt_chat(text, system_prompt, hist_for_llm, chat_cfg, api_index)
189
 
190
+ # اینجا فرمت جدید دیکشنری را می‌سازیم که با type="messages" سازگار است
191
  new_history = history + [
192
  {"role": "user", "content": text},
193
  {"role": "assistant", "content": response}
194
  ]
195
 
 
 
 
196
  return new_history, new_history
197
 
198
  # ==========================================
 
200
  # ==========================================
201
 
202
  def create_gradio_interface():
 
203
  css = """
204
  .mobile-button button {
205
  width: 100% !important;
 
228
 
229
  with gr.Blocks(title="EMMA AI", css=css) as demo:
230
 
 
 
231
  state = gr.State({
232
  "history": [],
233
  "user_name": None,
 
238
 
239
  header = gr.Markdown("## 🧠 EMMA: Your Empathetic Mental Health Assistant\nWelcome! Please enter your name to begin.")
240
 
 
241
  with gr.Column(visible=True) as login_col:
242
  with gr.Accordion("🔐 Start New Session", open=True):
243
  with gr.Row():
 
249
  residence_input = gr.Textbox(label="Place of Residence", placeholder="e.g., Berlin")
250
  start_btn = gr.Button("🎯 Start Session", variant="primary")
251
 
 
252
  system_msg = gr.Textbox(label="🔔 System Messages", interactive=False, max_lines=2, visible=False)
253
 
 
254
  with gr.Column(visible=False) as chat_col:
255
+ # type="messages" یعنی ورودی باید لیست دیکشنری باشد
256
  chatbot = gr.Chatbot(height=500, type="messages", label="💬 EMMA Conversation")
257
 
258
  with gr.Row():
 
265
  switch_user_btn = gr.Button("👥 Switch User", variant="primary", elem_classes=["mobile-button"])
266
 
267
  # ==========================================
268
+ # توابع کنترلی UI (اصلاح شده)
269
  # ==========================================
270
 
271
  def start_session(name, age, gender, job, city, current_state):
272
  if not name or not name.strip():
273
  return (
274
+ gr.update(), gr.update(), gr.update(),
275
  gr.update(value="## ⚠️ Please enter a valid name."),
276
  current_state,
277
+ []
278
  )
279
 
280
+ # 1. بارگذاری حافظه
281
  memory_data = load_memory()
282
 
283
+ # 2. ایجاد یا به‌روزرسانی یوزر
 
284
  enter_name_llamaindex(name, memory_data, data_args)
285
 
286
+ # 3. آپدیت پروفایل
287
  if name in memory_data:
288
  memory_data[name]["profile"] = {
289
  "age": age, "gender": gender,
 
291
  }
292
 
293
  # اطمینان از وجود لیست سشن‌ها
294
+ if "sessions" not in memory_data[name] or not isinstance(memory_data[name]["sessions"], list):
295
+ memory_data[name]["sessions"] = [{
296
+ "session_id": 0, "date": time.strftime("%Y-%m-%d"), "conversation": []
297
+ }]
298
+ elif len(memory_data[name]["sessions"]) == 0:
299
  memory_data[name]["sessions"] = [{
300
  "session_id": 0, "date": time.strftime("%Y-%m-%d"), "conversation": []
301
  }]
302
 
303
+ # 4. ذخیره حافظه
304
  save_memory(memory_data)
305
  print(f"✅ User {name} loaded/created and saved.")
306
 
307
+ # 5. استخراج و استانداردسازی تاریخچه (FIXED HERE)
308
+ # ------------------------------------------------------------------
309
+ user_mem = memory_data.get(name, {})
310
+ raw_history = []
311
+
312
+ sessions = user_mem.get("sessions", [])
313
+ if sessions and len(sessions) > 0:
314
+ # گرفتن آخرین سشن
315
+ raw_history = sessions[-1].get("conversation", [])
316
+
317
+ # تبدیل فرمت‌های قدیمی یا ناسازگار به فرمت جدید type="messages"
318
+ formatted_history = []
319
+ for item in raw_history:
320
+ # حالت ۱: فرمت قدیمی لیست [user, bot]
321
+ if isinstance(item, list) and len(item) == 2:
322
+ if item[0]: # user
323
+ formatted_history.append({"role": "user", "content": str(item[0])})
324
+ if item[1]: # bot
325
+ formatted_history.append({"role": "assistant", "content": str(item[1])})
326
+ # حالت ۲: فرمت صحیح دیکشنری
327
+ elif isinstance(item, dict) and "role" in item and "content" in item:
328
+ formatted_history.append(item)
329
+ # ------------------------------------------------------------------
330
+
331
  new_st = copy.deepcopy(current_state)
332
  new_st["user_name"] = name
333
  new_st["init"] = True
334
+ new_st["history"] = formatted_history # ذخیره فرمت صحیح در state
335
 
 
336
  try:
 
337
  if isinstance(user_mem, dict):
338
  new_st["semantic"] = str(user_mem.get("semantic_memory", ""))
 
 
 
 
339
  except:
340
+ new_st["semantic"] = ""
 
341
 
342
  welcome_txt = f"## 🧠 EMMA: Session for {name}"
343
  sys_txt = f"Welcome {name}! Memory loaded successfully."
 
348
  gr.update(visible=True, value=sys_txt), # Show System Msg
349
  gr.update(value=welcome_txt), # Update Header
350
  new_st,
351
+ formatted_history # ارسال تاریخچه استاندارد شده به چت‌بات
352
  )
353
 
354
  def respond(msg, current_state):
 
357
 
358
  user_name = current_state["user_name"]
359
 
360
+ # لود مجدد برای اطمینان
361
  memory_data = load_memory()
362
  user_memory = memory_data.get(user_name, {})
363
 
364
  cat = classify_query_local(msg)
365
 
366
+ # استفاده از هیستوری موجود در state که قبلاً استاندارد شده
367
+ current_history = current_state.get("history", [])
368
+
369
  _, new_hist = predict_new(
370
  text=msg,
371
+ history=current_history,
372
  top_p=0.9, temperature=0.7, max_length_tokens=512, max_context_length_tokens=200,
373
  user_name=user_name,
374
+ user_memory=user_memory,
375
  api_index=current_state["api_index"],
376
+ semantic_memory_text=current_state.get("semantic", ""),
377
  query_category=cat
378
  )
379
 
380
+ # ذخیره در آبجکت کل
381
+ if user_name in memory_data:
382
+ sessions = memory_data[user_name].get("sessions", [])
383
+ if sessions:
384
+ sessions[-1]["conversation"] = new_hist
385
+ else:
386
+ # اگر به هر دلیلی سشن نبود بساز
387
+ memory_data[user_name]["sessions"] = [{
388
+ "session_id": 0, "date": time.strftime("%Y-%m-%d"), "conversation": new_hist
389
+ }]
390
 
 
391
  save_memory(memory_data)
392
 
 
393
  new_st = copy.deepcopy(current_state)
394
  new_st["history"] = new_hist
395
 
396
  return new_hist, new_st, ""
397
 
398
  def clear_chat(current_state):
 
399
  new_st = copy.deepcopy(current_state)
400
  new_st["history"] = []
401
  return [], new_st, "Conversation view cleared (Memory retained)."
 
405
  if not u_name:
406
  return [], current_state, "Error: No user."
407
 
 
408
  memory_data = load_memory()
409
 
410
  if u_name in memory_data:
411
  try:
412
  user_sessions = memory_data[u_name].get("sessions", [])
 
 
413
  new_s = {
414
  "session_id": len(user_sessions),
415
  "date": time.strftime("%Y-%m-%d"),
416
+ "conversation": [] # شروع با لیست خالی
417
  }
418
+ if not isinstance(user_sessions, list):
419
+ memory_data[u_name]["sessions"] = []
 
420
 
421
  memory_data[u_name]["sessions"].append(new_s)
 
 
422
  save_memory(memory_data)
423
  print(f"🔄 New session created for {u_name}")
 
424
  except Exception as e:
425
  print(f"New Session Error: {e}")
426
 
 
427
  new_st = copy.deepcopy(current_state)
428
  new_st["history"] = []
429
 
430
  return [], new_st, "🆕 New session started & Saved."
431
 
432
  def switch_user_logic(current_state):
 
433
  new_st = {
434
  "history": [],
435
  "user_name": None,
 
438
  "init": False
439
  }
440
  return (
441
+ gr.update(visible=True),
442
+ gr.update(visible=False),
443
+ gr.update(visible=False, value=""),
444
  gr.update(value="## 🧠 EMMA: Switch User Mode"),
445
  new_st,
446
+ gr.update(value=""),
447
+ []
448
  )
449
 
450
  # ==========================================
451
+ # اتصا�� رویدادها
452
  # ==========================================
453
 
454
  start_btn.click(
 
515
 
516
  demo = create_gradio_interface()
517
 
518
+ print("🚀 Launching Gradio Server (Fixed Message Format)...")
519
  demo.queue().launch(
520
  server_name="0.0.0.0",
521
  server_port=7860,