mem-llm 1.0.5__py3-none-any.whl → 1.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mem-llm might be problematic. Click here for more details.

mem_llm/__init__.py CHANGED
@@ -24,7 +24,7 @@ try:
24
24
  except ImportError:
25
25
  __all_pro__ = []
26
26
 
27
- __version__ = "1.0.5"
27
+ __version__ = "1.0.7"
28
28
  __author__ = "C. Emre Karataş"
29
29
 
30
30
  __all__ = [
mem_llm/mem_agent.py CHANGED
@@ -407,47 +407,76 @@ REMEMBER: Knowledge base = truth. Always use it when provided!"""
407
407
 
408
408
  def _update_user_profile(self, user_id: str, message: str, response: str):
409
409
  """Extract user info from conversation and update profile"""
410
- if not hasattr(self.memory, 'update_profile'):
411
- return
412
-
413
410
  msg_lower = message.lower()
414
- updates = {}
411
+
412
+ # Extract information
413
+ extracted = {}
415
414
 
416
415
  # Extract name
417
- if "my name is" in msg_lower or "i am" in msg_lower or "i'm" in msg_lower:
418
- # Simple name extraction
419
- for phrase in ["my name is ", "i am ", "i'm "]:
416
+ if "my name is" in msg_lower or "i am" in msg_lower or "i'm" in msg_lower or "adım" in msg_lower or "ismim" in msg_lower:
417
+ for phrase in ["my name is ", "i am ", "i'm ", "adım ", "ismim ", "benim adım "]:
420
418
  if phrase in msg_lower:
421
419
  name_part = message[msg_lower.index(phrase) + len(phrase):].strip()
422
420
  name = name_part.split()[0] if name_part else None
423
421
  if name and len(name) > 1:
424
- updates['name'] = name.strip('.,!?')
422
+ extracted['name'] = name.strip('.,!?')
425
423
  break
426
424
 
427
425
  # Extract favorite food
428
- if "favorite food" in msg_lower or "favourite food" in msg_lower:
429
- if "is" in msg_lower:
430
- food = msg_lower.split("is")[-1].strip().strip('.,!?')
426
+ if "favorite food" in msg_lower or "favourite food" in msg_lower or "sevdiğim yemek" in msg_lower or "en sevdiğim" in msg_lower:
427
+ if "is" in msg_lower or ":" in msg_lower:
428
+ food = msg_lower.split("is")[-1].strip() if "is" in msg_lower else msg_lower.split(":")[-1].strip()
429
+ food = food.strip('.,!?')
431
430
  if food and len(food) < 50:
432
- updates['favorite_food'] = food
431
+ extracted['favorite_food'] = food
433
432
 
434
433
  # Extract location
435
- if "i live in" in msg_lower or "i'm from" in msg_lower or "from" in msg_lower:
436
- for phrase in ["i live in ", "i'm from ", "from "]:
434
+ if "i live in" in msg_lower or "i'm from" in msg_lower or "yaşıyorum" in msg_lower or "yaşadığım" in msg_lower:
435
+ for phrase in ["i live in ", "i'm from ", "from ", "yaşıyorum", "yaşadığım yer", "yaşadığım şehir"]:
437
436
  if phrase in msg_lower:
438
437
  loc = message[msg_lower.index(phrase) + len(phrase):].strip()
439
438
  location = loc.split()[0] if loc else None
440
439
  if location and len(location) > 2:
441
- updates['location'] = location.strip('.,!?')
440
+ extracted['location'] = location.strip('.,!?')
442
441
  break
443
442
 
444
443
  # Save updates
445
- if updates:
444
+ if extracted:
446
445
  try:
447
- self.memory.update_profile(user_id, updates)
448
- self.logger.debug(f"Profile updated for {user_id}: {updates}")
449
- except:
450
- pass
446
+ # SQL memory - store in preferences JSON
447
+ if hasattr(self.memory, 'update_user_profile'):
448
+ # Get current profile
449
+ profile = self.memory.get_user_profile(user_id) or {}
450
+
451
+ # Update name directly if extracted
452
+ updates = {}
453
+ if 'name' in extracted:
454
+ updates['name'] = extracted.pop('name')
455
+
456
+ # Store other info in preferences
457
+ if extracted:
458
+ current_prefs = profile.get('preferences')
459
+ if current_prefs:
460
+ try:
461
+ prefs = json.loads(current_prefs) if isinstance(current_prefs, str) else current_prefs
462
+ except:
463
+ prefs = {}
464
+ else:
465
+ prefs = {}
466
+
467
+ prefs.update(extracted)
468
+ updates['preferences'] = json.dumps(prefs)
469
+
470
+ if updates:
471
+ self.memory.update_user_profile(user_id, updates)
472
+ self.logger.debug(f"Profile updated for {user_id}: {extracted}")
473
+
474
+ # JSON memory - direct update
475
+ elif hasattr(self.memory, 'update_profile'):
476
+ self.memory.update_profile(user_id, extracted)
477
+ self.logger.debug(f"Profile updated for {user_id}: {extracted}")
478
+ except Exception as e:
479
+ self.logger.error(f"Error updating profile: {e}")
451
480
 
452
481
  def get_user_profile(self, user_id: Optional[str] = None) -> Dict:
453
482
  """
@@ -457,16 +486,44 @@ REMEMBER: Knowledge base = truth. Always use it when provided!"""
457
486
  user_id: User ID (uses current_user if not specified)
458
487
 
459
488
  Returns:
460
- User profile dictionary
489
+ User profile dictionary with all info (name, favorite_food, location, etc.)
461
490
  """
462
491
  uid = user_id or self.current_user
463
492
  if not uid:
464
493
  return {}
465
494
 
466
495
  try:
467
- memory_data = self.memory.load_memory(uid)
468
- return memory_data.get('profile', {})
469
- except:
496
+ # Check if SQL or JSON memory
497
+ if hasattr(self.memory, 'get_user_profile'):
498
+ # SQL memory - merge preferences into main dict
499
+ profile = self.memory.get_user_profile(uid)
500
+ if not profile:
501
+ return {}
502
+
503
+ # Parse preferences JSON if exists
504
+ result = {
505
+ 'user_id': profile.get('user_id'),
506
+ 'name': profile.get('name'),
507
+ 'first_seen': profile.get('first_seen'),
508
+ 'last_interaction': profile.get('last_interaction'),
509
+ }
510
+
511
+ # Merge preferences
512
+ prefs_str = profile.get('preferences')
513
+ if prefs_str:
514
+ try:
515
+ prefs = json.loads(prefs_str) if isinstance(prefs_str, str) else prefs_str
516
+ result.update(prefs) # Add favorite_food, location, etc.
517
+ except:
518
+ pass
519
+
520
+ return result
521
+ else:
522
+ # JSON memory
523
+ memory_data = self.memory.load_memory(uid)
524
+ return memory_data.get('profile', {})
525
+ except Exception as e:
526
+ self.logger.error(f"Error getting user profile: {e}")
470
527
  return {}
471
528
 
472
529
  def add_knowledge(self, category: str, question: str, answer: str,
mem_llm/memory_manager.py CHANGED
@@ -259,4 +259,54 @@ class MemoryManager:
259
259
  self.load_memory(user_id)
260
260
 
261
261
  return self.user_profiles.get(user_id)
262
+
263
+ def update_user_profile(self, user_id: str, updates: Dict) -> None:
264
+ """
265
+ Update user profile (SQL-compatible alias)
266
+
267
+ Args:
268
+ user_id: User ID
269
+ updates: Fields to update
270
+ """
271
+ return self.update_profile(user_id, updates)
272
+
273
+ def add_user(self, user_id: str, name: Optional[str] = None, metadata: Optional[Dict] = None) -> None:
274
+ """
275
+ Add or update user (SQL-compatible method)
276
+
277
+ Args:
278
+ user_id: User ID
279
+ name: User name (optional)
280
+ metadata: Additional metadata (optional)
281
+ """
282
+ self.load_memory(user_id)
283
+ if name and 'name' not in self.user_profiles[user_id]:
284
+ self.user_profiles[user_id]['name'] = name
285
+ if metadata:
286
+ self.user_profiles[user_id].update(metadata)
287
+ self.save_memory(user_id)
288
+
289
+ def get_statistics(self) -> Dict:
290
+ """
291
+ Get general statistics (SQL-compatible method)
292
+
293
+ Returns:
294
+ Statistics dictionary
295
+ """
296
+ all_users = list(self.memory_dir.glob("*.json"))
297
+ total_interactions = 0
298
+
299
+ for user_file in all_users:
300
+ try:
301
+ with open(user_file, 'r', encoding='utf-8') as f:
302
+ data = json.load(f)
303
+ total_interactions += len(data.get('conversations', []))
304
+ except:
305
+ pass
306
+
307
+ return {
308
+ 'total_users': len(all_users),
309
+ 'total_interactions': total_interactions,
310
+ 'knowledge_base_entries': 0 # JSON doesn't have KB
311
+ }
262
312
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mem-llm
3
- Version: 1.0.5
3
+ Version: 1.0.7
4
4
  Summary: Memory-enabled AI assistant with local LLM support
5
5
  Home-page: https://github.com/emredeveloper/Mem-LLM
6
6
  Author: C. Emre Karataş
@@ -1,15 +1,15 @@
1
- mem_llm/__init__.py,sha256=XF8GqWqOkrqP5N6EPdo3duNxshvQR8zRckbqH3jpPII,920
1
+ mem_llm/__init__.py,sha256=K-nIQ-BtTJzDhgseulljOKMPXuQZS563ffED4brYFm4,920
2
2
  mem_llm/config.yaml.example,sha256=lgmfaU5pxnIm4zYxwgCcgLSohNx1Jw6oh3Qk0Xoe2DE,917
3
3
  mem_llm/config_from_docs.py,sha256=YFhq1SWyK63C-TNMS73ncNHg8sJ-XGOf2idWVCjxFco,4974
4
4
  mem_llm/config_manager.py,sha256=8PIHs21jZWlI-eG9DgekjOvNxU3-U4xH7SbT8Gr-Z6M,7075
5
5
  mem_llm/knowledge_loader.py,sha256=oSNhfYYcx7DlZLVogxnbSwaIydq_Q3__RDJFeZR2XVw,2699
6
6
  mem_llm/llm_client.py,sha256=XW-LALYV4C-Nj2R8XYT2iT2YnTeH6_tUIldMKooY2uY,5461
7
- mem_llm/mem_agent.py,sha256=FYiZyOIadURC0RdsY-aRdaZ53oxtOj0U5Crt2yWEbz8,24058
7
+ mem_llm/mem_agent.py,sha256=kJwlZYRIE6OI06ZG-mtQKzz1_zkjs1ss_DYr4DiaHUw,27140
8
8
  mem_llm/memory_db.py,sha256=UzkMOw_p7svg6d4ZgpBWdPKoILWrJ2hAQSPHvAG_f4M,13563
9
- mem_llm/memory_manager.py,sha256=iXnf5YEJXmQ75jgJ2LEx9zCHxIpZTcLtHlp2eWgFjRg,8335
9
+ mem_llm/memory_manager.py,sha256=CZI3A8pFboHQIgeiXB1h2gZK7mgfbVSU3IxuqE-zXtc,9978
10
10
  mem_llm/memory_tools.py,sha256=ARANFqu_bmL56SlV1RzTjfQsJj-Qe2QvqY0pF92hDxU,8678
11
11
  mem_llm/prompt_templates.py,sha256=tCiQJw3QQKIaH8NsxEKOIaIVxw4XT43PwdmyfCINzzM,6536
12
- mem_llm-1.0.5.dist-info/METADATA,sha256=ag7yXwfZNy67fes7pLyrFdPSAgGoZIvKgFPTx7ZSANo,6505
13
- mem_llm-1.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- mem_llm-1.0.5.dist-info/top_level.txt,sha256=_fU1ML-0JwkaxWdhqpwtmTNaJEOvDMQeJdA8d5WqDn8,8
15
- mem_llm-1.0.5.dist-info/RECORD,,
12
+ mem_llm-1.0.7.dist-info/METADATA,sha256=K2paX5fYmv3U7BNrBbqYI3D6gwfvszaS1HyJJuIJo88,6505
13
+ mem_llm-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ mem_llm-1.0.7.dist-info/top_level.txt,sha256=_fU1ML-0JwkaxWdhqpwtmTNaJEOvDMQeJdA8d5WqDn8,8
15
+ mem_llm-1.0.7.dist-info/RECORD,,