Keyvan1986 commited on
Commit
56daa75
·
verified ·
1 Parent(s): 46c4a32

Update utils/memory_utils.py

Browse files
Files changed (1) hide show
  1. utils/memory_utils.py +37 -37
utils/memory_utils.py CHANGED
@@ -10,7 +10,6 @@ import gradio as gr
10
  from llama_index.core import StorageContext, load_index_from_storage
11
 
12
  # Local Imports setup
13
- # فرض بر این است که مسیرها درست تنظیم شده‌اند
14
  bank_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../memory_bank')
15
  sys.path.append(bank_path)
16
 
@@ -18,16 +17,14 @@ try:
18
  from build_memory_index import build_memory_index
19
  from summarize_memory import summarize_memory
20
  except ImportError:
21
- # print("Warning: Could not import memory build/summary modules.")
22
  def build_memory_index(*args, **kwargs): pass
23
  def summarize_memory(*args, **kwargs): return {}
24
 
25
  # ==========================================
26
  # 1. تنظیمات مسیر (Single Source of Truth)
27
  # ==========================================
28
- # مسیردهی نسبی برای سازگاری با Hugging Face Spaces (Linux)
29
  CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
30
- BASE_DIR = os.path.dirname(CURRENT_DIR) # یک پله بالاتر (روت پروژه)
31
  MEMORIES_DIR = os.path.join(BASE_DIR, "memories")
32
  MEMORY_FILE_PATH = os.path.join(MEMORIES_DIR, "update_memory_0512_eng.json")
33
 
@@ -38,51 +35,59 @@ os.makedirs(MEMORIES_DIR, exist_ok=True)
38
  # 2. توابع اصلی I/O (خواندن و نوشتن)
39
  # ==========================================
40
 
41
- def load_memory():
42
- """
43
- حافظه را از فایل JSON بارگذاری می‌کند.
44
- اگر فایل وجود نداشته باشد یا خراب باشد، یک دیکشنری خالی برمی‌گرداند.
45
- """
46
- if os.path.exists(MEMORY_FILE_PATH):
47
- try:
48
- with open(MEMORY_FILE_PATH, 'r', encoding='utf-8') as f:
49
- return json.load(f)
50
- except (json.JSONDecodeError, FileNotFoundError):
51
- print("⚠️ Memory file is corrupted or not found. Starting with empty memory.")
52
- return {}
53
- return {}
54
-
55
-
56
  def save_memory(data):
57
  """
58
  کل آبجکت حافظه را به صورت ایمن (Atomic Write) در فایل JSON ذخیره می‌کند.
59
  """
60
  try:
61
- # نوشتن در فایل موقت ابتدا برای جلوگیری از خرابی داده در صورت قطع برق/کرش
 
 
 
62
  temp_file = MEMORY_FILE_PATH + ".tmp"
63
  with open(temp_file, "w", encoding="utf-8") as f:
64
  json.dump(data, f, ensure_ascii=False, indent=4)
65
 
66
- # جایگزینی فایل اصلی با فایل موقت
67
  os.replace(temp_file, MEMORY_FILE_PATH)
68
  # print(f"✅ Memory successfully saved to {MEMORY_FILE_PATH}")
69
  except Exception as e:
70
  print(f"❌ CRITICAL ERROR saving memory: {e}")
71
 
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  # ==========================================
74
  # 3. توابع منطق حافظه (Memory Logic)
75
  # ==========================================
76
 
77
  def enter_name_llamaindex(name, memory_data, data_args, update_memory_index=True):
78
  """
79
- کاربر را در دیکشنری حافظه ایجاد یا پیدا می‌کند و ایندکس‌های LlamaIndex را لود می‌کند.
80
-
81
- IMPORTANT: این تابع دیگر فایل را نمی‌خواند/نمی‌نویسد. فقط روی آبجکت memory_data در حافظه RAM کار می‌کند.
82
- ذخیره‌سازی باید توسط فراخواننده (caller) انجام شود.
83
  """
84
 
85
- # 1. مدیریت ساختار دیکشنری در RAM
 
86
  if name not in memory_data:
87
  print(f"🆕 Creating new user profile for: {name}")
88
  memory_data[name] = {
@@ -92,15 +97,19 @@ def enter_name_llamaindex(name, memory_data, data_args, update_memory_index=True
92
  "semantic_memory": {},
93
  "profile": {}
94
  }
 
95
 
96
  user_memory = memory_data[name]
97
 
 
 
 
 
98
  # 2. مدیریت ایندکس‌های وکتوری (LlamaIndex)
99
  sessions_memory = None
100
  episodic_memory = None
101
  semantic_memory = None
102
 
103
- # مسیردهی برای ایندکس‌ها (نسبی و لینوکسی)
104
  base_index_dir = os.path.join(MEMORIES_DIR, "memory_index", "llamaindex", name)
105
 
106
  sessions_path = os.path.join(base_index_dir, "sessions_index.json")
@@ -113,16 +122,11 @@ def enter_name_llamaindex(name, memory_data, data_args, update_memory_index=True
113
  os.path.exists(semantic_path)
114
  )
115
 
116
- # ساخت ایندکس اگر وجود ندارد یا درخواست آپدیت شده است
117
  if update_memory_index or not indices_exist:
118
- # print(f'Initializing memory indices for {name}...')
119
  try:
120
  os.makedirs(base_index_dir, exist_ok=True)
121
- # توجه: build_memory_index ممکن است نیاز به خواندن فایل داشته باشد،
122
- # اما فعلاً فرض می‌کنیم درست کار می‌کند یا safe fail می‌شود.
123
  build_memory_index(memory_data, data_args, name=name)
124
  except Exception as e:
125
- # خطای بیلد ایندکس نباید برنامه را متوقف کند
126
  print(f"Warning: Error building memory index (skipping): {e}")
127
 
128
  # بارگذاری ایندکس‌ها
@@ -148,14 +152,10 @@ def enter_name_llamaindex(name, memory_data, data_args, update_memory_index=True
148
 
149
 
150
  def summarize_memory_event_personality(data_args, memory_data, user_name):
151
- """
152
- Wrapper برای تابع summarize_memory.
153
- """
154
- # ابتدا مطمئن می‌شویم داده‌های فعلی ذخیره شده‌اند تا summarizer فایل به‌روز را بخواند
155
  save_memory(memory_data)
156
 
157
  try:
158
- # تابع summarize_memory احتمالاً خودش فایل را می‌خواند
159
  updated_memory = summarize_memory(MEMORY_FILE_PATH, user_name, language='en')
160
  return updated_memory.get(user_name, {})
161
  except Exception as e:
 
10
  from llama_index.core import StorageContext, load_index_from_storage
11
 
12
  # Local Imports setup
 
13
  bank_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../memory_bank')
14
  sys.path.append(bank_path)
15
 
 
17
  from build_memory_index import build_memory_index
18
  from summarize_memory import summarize_memory
19
  except ImportError:
 
20
  def build_memory_index(*args, **kwargs): pass
21
  def summarize_memory(*args, **kwargs): return {}
22
 
23
  # ==========================================
24
  # 1. تنظیمات مسیر (Single Source of Truth)
25
  # ==========================================
 
26
  CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
27
+ BASE_DIR = os.path.dirname(CURRENT_DIR)
28
  MEMORIES_DIR = os.path.join(BASE_DIR, "memories")
29
  MEMORY_FILE_PATH = os.path.join(MEMORIES_DIR, "update_memory_0512_eng.json")
30
 
 
35
  # 2. توابع اصلی I/O (خواندن و نوشتن)
36
  # ==========================================
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  def save_memory(data):
39
  """
40
  کل آبجکت حافظه را به صورت ایمن (Atomic Write) در فایل JSON ذخیره می‌کند.
41
  """
42
  try:
43
+ # اطمینان مجدد از وجود پوشه
44
+ os.makedirs(MEMORIES_DIR, exist_ok=True)
45
+
46
+ # نوشتن در فایل موقت
47
  temp_file = MEMORY_FILE_PATH + ".tmp"
48
  with open(temp_file, "w", encoding="utf-8") as f:
49
  json.dump(data, f, ensure_ascii=False, indent=4)
50
 
51
+ # جایگزینی فایل اصلی
52
  os.replace(temp_file, MEMORY_FILE_PATH)
53
  # print(f"✅ Memory successfully saved to {MEMORY_FILE_PATH}")
54
  except Exception as e:
55
  print(f"❌ CRITICAL ERROR saving memory: {e}")
56
 
57
 
58
+ def load_memory():
59
+ """
60
+ حافظه را بارگذاری می‌کند. اگر فایل نباشد، آن را می‌سازد.
61
+ """
62
+ if not os.path.exists(MEMORY_FILE_PATH):
63
+ print(f"⚠️ Memory file not found. Creating new file at: {MEMORY_FILE_PATH}")
64
+ # ایجاد فایل خالی فیزیکی
65
+ save_memory({})
66
+ return {}
67
+
68
+ try:
69
+ with open(MEMORY_FILE_PATH, 'r', encoding='utf-8') as f:
70
+ # اگر فایل خالی بود، هندل شود
71
+ content = f.read()
72
+ if not content.strip():
73
+ return {}
74
+ return json.loads(content)
75
+ except (json.JSONDecodeError, FileNotFoundError):
76
+ print("⚠️ Memory file is corrupted. Starting with empty memory.")
77
+ return {}
78
+
79
+
80
  # ==========================================
81
  # 3. توابع منطق حافظه (Memory Logic)
82
  # ==========================================
83
 
84
  def enter_name_llamaindex(name, memory_data, data_args, update_memory_index=True):
85
  """
86
+ کاربر را ایجاد کرده و فایل را فوراً ذخیره می‌کند تا از دست نرود.
 
 
 
87
  """
88
 
89
+ # 1. مدیریت ساختار دیکشنری
90
+ is_new_user = False
91
  if name not in memory_data:
92
  print(f"🆕 Creating new user profile for: {name}")
93
  memory_data[name] = {
 
97
  "semantic_memory": {},
98
  "profile": {}
99
  }
100
+ is_new_user = True
101
 
102
  user_memory = memory_data[name]
103
 
104
+ # نکته مهم: اگر کاربر جدید است، همین الان ذخیره کن تا اگر برنامه کرش کرد، نام بماند
105
+ if is_new_user:
106
+ save_memory(memory_data)
107
+
108
  # 2. مدیریت ایندکس‌های وکتوری (LlamaIndex)
109
  sessions_memory = None
110
  episodic_memory = None
111
  semantic_memory = None
112
 
 
113
  base_index_dir = os.path.join(MEMORIES_DIR, "memory_index", "llamaindex", name)
114
 
115
  sessions_path = os.path.join(base_index_dir, "sessions_index.json")
 
122
  os.path.exists(semantic_path)
123
  )
124
 
 
125
  if update_memory_index or not indices_exist:
 
126
  try:
127
  os.makedirs(base_index_dir, exist_ok=True)
 
 
128
  build_memory_index(memory_data, data_args, name=name)
129
  except Exception as e:
 
130
  print(f"Warning: Error building memory index (skipping): {e}")
131
 
132
  # بارگذاری ایندکس‌ها
 
152
 
153
 
154
  def summarize_memory_event_personality(data_args, memory_data, user_name):
155
+ # ذخیره قبل از سامرایز برای اطمینان
 
 
 
156
  save_memory(memory_data)
157
 
158
  try:
 
159
  updated_memory = summarize_memory(MEMORY_FILE_PATH, user_name, language='en')
160
  return updated_memory.get(user_name, {})
161
  except Exception as e: