memorisdk 2.1.1__py3-none-any.whl → 2.3.1__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 memorisdk might be problematic. Click here for more details.

@@ -348,24 +348,72 @@ class SQLAlchemyDatabaseManager:
348
348
  def _setup_mysql_fulltext(self, conn):
349
349
  """Setup MySQL FULLTEXT indexes"""
350
350
  try:
351
- # Create FULLTEXT indexes
352
- conn.execute(
353
- text(
354
- "ALTER TABLE short_term_memory ADD FULLTEXT INDEX ft_short_term_search (searchable_content, summary)"
355
- )
351
+ # Check if indexes exist before creating them
352
+ index_check_query = text(
353
+ """
354
+ SELECT COUNT(*) as index_count
355
+ FROM information_schema.statistics
356
+ WHERE table_schema = DATABASE()
357
+ AND index_name IN ('ft_short_term_search', 'ft_long_term_search')
358
+ """
356
359
  )
357
- conn.execute(
358
- text(
359
- "ALTER TABLE long_term_memory ADD FULLTEXT INDEX ft_long_term_search (searchable_content, summary)"
360
+
361
+ result = conn.execute(index_check_query)
362
+ existing_indexes = result.fetchone()[0]
363
+
364
+ if existing_indexes < 2:
365
+ logger.info(
366
+ f"Creating missing MySQL FULLTEXT indexes ({existing_indexes}/2 exist)..."
360
367
  )
361
- )
362
368
 
363
- logger.info("MySQL FULLTEXT indexes setup completed")
369
+ # Check and create short_term_memory index if missing
370
+ short_term_check = conn.execute(
371
+ text(
372
+ """
373
+ SELECT COUNT(*) FROM information_schema.statistics
374
+ WHERE table_schema = DATABASE()
375
+ AND table_name = 'short_term_memory'
376
+ AND index_name = 'ft_short_term_search'
377
+ """
378
+ )
379
+ ).fetchone()[0]
380
+
381
+ if short_term_check == 0:
382
+ conn.execute(
383
+ text(
384
+ "ALTER TABLE short_term_memory ADD FULLTEXT INDEX ft_short_term_search (searchable_content, summary)"
385
+ )
386
+ )
387
+ logger.info("Created ft_short_term_search index")
388
+
389
+ # Check and create long_term_memory index if missing
390
+ long_term_check = conn.execute(
391
+ text(
392
+ """
393
+ SELECT COUNT(*) FROM information_schema.statistics
394
+ WHERE table_schema = DATABASE()
395
+ AND table_name = 'long_term_memory'
396
+ AND index_name = 'ft_long_term_search'
397
+ """
398
+ )
399
+ ).fetchone()[0]
400
+
401
+ if long_term_check == 0:
402
+ conn.execute(
403
+ text(
404
+ "ALTER TABLE long_term_memory ADD FULLTEXT INDEX ft_long_term_search (searchable_content, summary)"
405
+ )
406
+ )
407
+ logger.info("Created ft_long_term_search index")
408
+
409
+ logger.info("MySQL FULLTEXT indexes setup completed")
410
+ else:
411
+ logger.debug(
412
+ "MySQL FULLTEXT indexes already exist (2/2), skipping creation"
413
+ )
364
414
 
365
415
  except Exception as e:
366
- logger.warning(
367
- f"MySQL FULLTEXT setup failed (indexes may already exist): {e}"
368
- )
416
+ logger.warning(f"MySQL FULLTEXT setup failed: {e}")
369
417
 
370
418
  def _setup_postgresql_fts(self, conn):
371
419
  """Setup PostgreSQL full-text search"""
@@ -524,6 +572,28 @@ class SQLAlchemyDatabaseManager:
524
572
  except SQLAlchemyError as e:
525
573
  raise DatabaseError(f"Failed to get chat history: {e}")
526
574
 
575
+ def _check_milestone(self, memory_count: int):
576
+ """
577
+ Check and celebrate memory storage milestones to encourage user engagement.
578
+ Displays celebration messages at key milestones: 10, 50, 100, 500, 1000 memories.
579
+
580
+ Args:
581
+ memory_count: Current count of long-term memories
582
+ """
583
+ milestones = [10, 50, 100, 500, 1000]
584
+
585
+ if memory_count in milestones:
586
+ celebration_msg = (
587
+ f"\n{'=' * 60}\n"
588
+ f"🎉 Milestone Achieved: {memory_count} memories stored!\n"
589
+ f"{'=' * 60}\n"
590
+ f"⭐️ Loving Memori? Give us a star on GitHub!\n"
591
+ f"👉 https://github.com/GibsonAI/memori\n"
592
+ f"Your support helps us build better open AI memory tools ❤️\n"
593
+ f"{'=' * 60}\n"
594
+ )
595
+ logger.info(celebration_msg)
596
+
527
597
  def store_long_term_memory_enhanced(
528
598
  self, memory: ProcessedLongTermMemory, chat_id: str, namespace: str = "default"
529
599
  ) -> str:
@@ -570,6 +640,17 @@ class SQLAlchemyDatabaseManager:
570
640
  session.commit()
571
641
 
572
642
  logger.debug(f"Stored enhanced long-term memory {memory_id}")
643
+
644
+ # Get current memory count and check for milestones
645
+ total_memories = (
646
+ session.query(LongTermMemory)
647
+ .filter(LongTermMemory.namespace == namespace)
648
+ .count()
649
+ )
650
+
651
+ # Celebrate milestone if reached
652
+ self._check_milestone(total_memories)
653
+
573
654
  return memory_id
574
655
 
575
656
  except SQLAlchemyError as e:
@@ -246,33 +246,18 @@ class OpenAIInterceptor:
246
246
  def _is_internal_agent_call(cls, json_data):
247
247
  """Check if this is an internal agent processing call that should not be recorded."""
248
248
  try:
249
- messages = json_data.get("messages", [])
250
- for message in messages:
251
- content = message.get("content", "")
252
- if isinstance(content, str):
253
- # Check for specific internal agent processing patterns
254
- # Made patterns more specific to avoid false positives
255
- internal_patterns = [
256
- "Process this conversation for enhanced memory storage:",
257
- "Enhanced memory processing:",
258
- "Memory classification:",
259
- "Search for relevant memories:",
260
- "Analyze conversation for:",
261
- "Extract entities from:",
262
- "Categorize the following conversation:",
263
- # More specific patterns to avoid blocking legitimate conversations
264
- "INTERNAL_MEMORY_PROCESSING:",
265
- "AGENT_PROCESSING_MODE:",
266
- "MEMORY_AGENT_TASK:",
267
- ]
268
-
269
- # Only flag as internal if it matches specific patterns AND has no user role
270
- for pattern in internal_patterns:
271
- if pattern in content:
272
- # Double-check: if this is a user message, don't filter it
273
- if message.get("role") == "user":
274
- continue
275
- return True
249
+ openai_metadata = json_data.get("metadata", [])
250
+
251
+ # Check for specific internal agent metadata flags
252
+ if isinstance(openai_metadata, list):
253
+ internal_metadata = [
254
+ "INTERNAL_MEMORY_PROCESSING", # used in memory agent and retrieval agent
255
+ "AGENT_PROCESSING_MODE",
256
+ "MEMORY_AGENT_TASK",
257
+ ]
258
+ for internal in internal_metadata:
259
+ if internal in openai_metadata:
260
+ return True
276
261
 
277
262
  return False
278
263
 
memori/utils/logging.py CHANGED
@@ -2,6 +2,7 @@
2
2
  Centralized logging configuration for Memoriai
3
3
  """
4
4
 
5
+ import logging
5
6
  import sys
6
7
  from pathlib import Path
7
8
  from typing import Any
@@ -22,41 +23,35 @@ class LoggingManager:
22
23
  def setup_logging(cls, settings: LoggingSettings, verbose: bool = False) -> None:
23
24
  """Setup logging configuration"""
24
25
  try:
25
- # Remove default handler if it exists
26
26
  if not cls._initialized:
27
27
  logger.remove()
28
28
 
29
29
  if verbose:
30
- # When verbose mode is enabled, disable all other loggers and show only loguru
31
30
  cls._disable_other_loggers()
32
31
 
33
- # Configure console logging with DEBUG level and full formatting
34
32
  logger.add(
35
33
  sys.stderr,
36
34
  level="DEBUG",
37
- format=settings.format,
35
+ format="<green>{time:HH:mm:ss}</green> | <level>{level:8}</level> | {message}",
38
36
  colorize=True,
39
37
  backtrace=True,
40
38
  diagnose=True,
41
39
  )
42
40
  else:
43
- # When verbose is False, minimize loguru output to essential logs only
44
41
  logger.add(
45
42
  sys.stderr,
46
- level="WARNING", # Only show warnings and errors
47
- format="<level>{level}</level>: {message}", # Simplified format
43
+ level="WARNING",
44
+ format="<level>{level}</level>: {message}",
48
45
  colorize=False,
49
46
  backtrace=False,
50
47
  diagnose=False,
51
48
  )
52
49
 
53
- # Configure file logging if enabled
54
50
  if settings.log_to_file:
55
51
  log_path = Path(settings.log_file_path)
56
52
  log_path.parent.mkdir(parents=True, exist_ok=True)
57
53
 
58
54
  if settings.structured_logging:
59
- # JSON structured logging
60
55
  logger.add(
61
56
  log_path,
62
57
  level=settings.level.value,
@@ -67,7 +62,6 @@ class LoggingManager:
67
62
  serialize=True,
68
63
  )
69
64
  else:
70
- # Regular text logging
71
65
  logger.add(
72
66
  log_path,
73
67
  level=settings.level.value,
@@ -96,7 +90,6 @@ class LoggingManager:
96
90
  raise ConfigurationError("Logging not initialized")
97
91
 
98
92
  try:
99
- # Remove existing handlers and recreate with new level
100
93
  logger.remove()
101
94
 
102
95
  if cls._current_config:
@@ -127,76 +120,34 @@ class LoggingManager:
127
120
 
128
121
  @classmethod
129
122
  def _disable_other_loggers(cls) -> None:
130
- """Disable all other loggers when verbose mode is enabled"""
131
- import logging
132
-
133
- # Set the root logger to CRITICAL and disable it
134
- root_logger = logging.getLogger()
135
- root_logger.setLevel(logging.CRITICAL)
136
- root_logger.disabled = True
137
-
138
- # Remove all handlers from the root logger
139
- for handler in root_logger.handlers[:]:
140
- root_logger.removeHandler(handler)
141
-
142
- # Disable common third-party library loggers
143
- third_party_loggers = [
144
- "urllib3",
145
- "requests",
146
- "httpx",
147
- "httpcore",
148
- "openai",
149
- "anthropic",
150
- "litellm",
151
- "sqlalchemy",
152
- "alembic",
153
- "asyncio",
154
- "concurrent.futures",
155
- "charset_normalizer",
156
- "certifi",
157
- "idna",
158
- ]
159
-
160
- for logger_name in third_party_loggers:
161
- lib_logger = logging.getLogger(logger_name)
162
- lib_logger.disabled = True
163
- lib_logger.setLevel(logging.CRITICAL)
164
- # Remove all handlers
165
- for handler in lib_logger.handlers[:]:
166
- lib_logger.removeHandler(handler)
167
-
168
- # Set all existing loggers to CRITICAL level and disable them
169
- for name in list(logging.Logger.manager.loggerDict.keys()):
170
- existing_logger = logging.getLogger(name)
171
- existing_logger.setLevel(logging.CRITICAL)
172
- existing_logger.disabled = True
173
- # Remove all handlers
174
- for handler in existing_logger.handlers[:]:
175
- existing_logger.removeHandler(handler)
176
-
177
- # Also disable warnings from the warnings module
178
- import warnings
179
-
180
- warnings.filterwarnings("ignore")
181
-
182
- # Override the logging module's basicConfig to prevent new loggers
183
- def disabled_basicConfig(*args, **kwargs):
184
- pass
185
-
186
- logging.basicConfig = disabled_basicConfig
187
-
188
- # Override the getLogger function to disable new loggers immediately
189
- original_getLogger = logging.getLogger
190
-
191
- def disabled_getLogger(name=None):
192
- logger_instance = original_getLogger(name)
193
- logger_instance.disabled = True
194
- logger_instance.setLevel(logging.CRITICAL)
195
- for handler in logger_instance.handlers[:]:
196
- logger_instance.removeHandler(handler)
197
- return logger_instance
198
-
199
- logging.getLogger = disabled_getLogger
123
+ """
124
+ Intercept all logs from the standard `logging` module and redirect them to Loguru.
125
+ This ensures all log output is controlled and formatted by Loguru.
126
+ """
127
+
128
+ class InterceptStandardLoggingHandler(logging.Handler):
129
+ def emit(self, record: logging.LogRecord) -> None:
130
+ try:
131
+ level = logger.level(record.levelname).name
132
+ except ValueError:
133
+ level = record.levelno
134
+
135
+ frame, depth = logging.currentframe(), 2
136
+ while (
137
+ frame is not None and frame.f_code.co_filename == logging.__file__
138
+ ):
139
+ frame = frame.f_back
140
+ depth += 1
141
+
142
+ formatted_message = f"[{record.name}] {record.getMessage()}"
143
+
144
+ logger.opt(depth=depth, exception=record.exc_info).log(
145
+ level, formatted_message
146
+ )
147
+
148
+ logging.basicConfig(
149
+ handlers=[InterceptStandardLoggingHandler()], level=0, force=True
150
+ )
200
151
 
201
152
 
202
153
  def get_logger(name: str = "memori") -> "logger":
@@ -58,12 +58,12 @@ class DataValidator:
58
58
  @classmethod
59
59
  def validate_namespace(cls, value: str, field_name: str = "namespace") -> str:
60
60
  """Validate namespace format"""
61
+ if value is None or (isinstance(value, str) and value.strip() == ""):
62
+ return "default"
63
+
61
64
  if not isinstance(value, str):
62
65
  raise ValidationError(f"{field_name} must be a string")
63
66
 
64
- if not value:
65
- raise ValidationError(f"{field_name} cannot be empty")
66
-
67
67
  if len(value) > 64:
68
68
  raise ValidationError(f"{field_name} cannot exceed 64 characters")
69
69
 
@@ -73,7 +73,7 @@ class DataValidator:
73
73
  f"{field_name} can only contain letters, numbers, underscores, and hyphens"
74
74
  )
75
75
 
76
- return value
76
+ return value.strip()
77
77
 
78
78
  @classmethod
79
79
  def validate_importance_score(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorisdk
3
- Version: 2.1.1
3
+ Version: 2.3.1
4
4
  Summary: The Open-Source Memory Layer for AI Agents & Multi-Agent Systems
5
5
  Author-email: GibsonAI Team <noc@gibsonai.com>
6
6
  License: Apache-2.0
@@ -95,7 +95,7 @@ Requires-Dist: pandas>=2.0.0; extra == "all"
95
95
  Requires-Dist: plotly>=5.17.0; extra == "all"
96
96
  Dynamic: license-file
97
97
 
98
- [![GibsonAI](https://github.com/user-attachments/assets/878e341b-5a93-4489-a398-abeca91b6b11)](https://gibsonai.com/)
98
+ [![Memori Labs](https://s3.us-east-1.amazonaws.com/images.memorilabs.ai/banner.png)](https://memorilabs.ai/)
99
99
 
100
100
  # memori
101
101
 
@@ -110,7 +110,7 @@ Dynamic: license-file
110
110
  <p align="center">
111
111
  <a href="https://memori.gibsonai.com/docs">Learn more</a>
112
112
  ·
113
- <a href="https://www.gibsonai.com/discord">Join Discord</a>
113
+ <a href="https://discord.gg/abD4eGym6v">Join Discord</a>
114
114
  </p>
115
115
 
116
116
  <p align="center">
@@ -120,14 +120,20 @@ Dynamic: license-file
120
120
  <a href="https://pepy.tech/projects/memorisdk">
121
121
  <img src="https://static.pepy.tech/badge/memorisdk" alt="Downloads">
122
122
  </a>
123
- <a href="https://opensource.org/licenses/MIT">
124
- <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT">
123
+ <a href="https://opensource.org/license/apache-2-0">
124
+ <img src="https://img.shields.io/badge/license-Apache%20License%202.0-blue" alt="License: Apache 2.0">
125
125
  </a>
126
126
  <a href="https://www.python.org/downloads/">
127
127
  <img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python 3.8+">
128
128
  </a>
129
129
  </p>
130
130
 
131
+ <p align="center">
132
+ <a href="https://github.com/GibsonAI/memori/stargazers">
133
+ <img src="https://img.shields.io/badge/⭐%20Give%20a%20Star-Support%20the%20project-orange?style=for-the-badge" alt="Give a Star">
134
+ </a>
135
+ </p>
136
+
131
137
  ---
132
138
 
133
139
  ## What is Memori
@@ -206,6 +212,8 @@ print("\n💡 Notice: Memori automatically knows about your FastAPI Python proje
206
212
 
207
213
  ---
208
214
 
215
+ ⭐️ **Enjoying Memori?** Give us a star to support open development
216
+
209
217
  > By default, Memori uses in-memory SQLite database. Get **FREE** serverless database instance in [GibsonAI](https://app.gibsonai.com/signup) platform.
210
218
 
211
219
  **🚀 Ready to explore more?**
@@ -326,6 +334,7 @@ memori = Memori(
326
334
  database_connect="sqlite:///my_memory.db",
327
335
  template="basic",
328
336
  conscious_ingest=True, # One-shot context injection
337
+ conscious_memory_limit=100, # Must be an integer between 1 and 500
329
338
  openai_api_key="sk-..."
330
339
  )
331
340
 
@@ -482,6 +491,7 @@ Memori works seamlessly with popular AI frameworks:
482
491
  | [Agno](./examples/integrations/agno_example.py) | Memory-enhanced agent framework integration with persistent conversations | Simple chat agent with memory search |
483
492
  | [AWS Strands](./examples/integrations/aws_strands_example.py) | Professional development coach with Strands SDK and persistent memory | Career coaching agent with goal tracking |
484
493
  | [Azure AI Foundry](./examples/integrations/azure_ai_foundry_example.py) | Azure AI Foundry agents with persistent memory across conversations | Enterprise AI agents with Azure integration |
494
+ | [AutoGen](./examples/integrations/autogen_example.py) | Multi-agent group chat memory recording | Agent chats with memory integration |
485
495
  | [CamelAI](./examples/integrations/camelai_example.py) | Multi-agent communication framework with automatic memory recording and retrieval | Memory-enhanced chat agents with conversation continuity |
486
496
  | [CrewAI](./examples/integrations/crewai_example.py) | Multi-agent system with shared memory across agent interactions | Collaborative agents with memory |
487
497
  | [Digital Ocean AI](./examples/integrations/digital_ocean_example.py) | Memory-enhanced customer support using Digital Ocean's AI platform | Customer support assistant with conversation history |
@@ -502,11 +512,15 @@ Explore Memori's capabilities through these interactive demonstrations:
502
512
  ## 🤝 Contributing
503
513
 
504
514
  - See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup and guidelines.
505
- - Community: [Discord](https://www.gibsonai.com/discord)
515
+ - Community: [Discord](https://discord.gg/abD4eGym6v)
516
+
517
+ ## ⭐️ Star us on GitHub to support the project
518
+
519
+ [![Star History Chart](https://api.star-history.com/svg?repos=GibsonAI/memori&type=date&legend=top-left)](https://www.star-history.com/#GibsonAI/memori&type=date&legend=top-left)
506
520
 
507
521
  ## 📄 License
508
522
 
509
- MIT License - see [LICENSE](./LICENSE) for details.
523
+ Apache 2.0 License - see [LICENSE](./LICENSE) for details.
510
524
 
511
525
  ---
512
526
 
@@ -1,25 +1,25 @@
1
- memori/__init__.py,sha256=u5Y2fGofYR3hZwRLN0lwu24iVztgmDLk0JGZfwhSjW8,3670
1
+ memori/__init__.py,sha256=BXUPF0Td839gaRLZv18OfmWz6ergsJ0lti1w_LM3H2s,3670
2
2
  memori/agents/__init__.py,sha256=9M3IG5R10FfVgT8tUzBZ2pZ0SypSpYkFfhtyvMyeTpE,261
3
- memori/agents/conscious_agent.py,sha256=x3MFps2BSIt9CubjwFUZ_2g4EXESO66aT2lyHx_LiDQ,22225
4
- memori/agents/memory_agent.py,sha256=khCbbBaMfHm7uYxZvIw4JO4kXzM848R_Cual0uSVZ2A,23957
5
- memori/agents/retrieval_agent.py,sha256=_8J50i68AvVxylcEYWDTMfgXnoKO0hx97X8Lo3byg0U,40867
3
+ memori/agents/conscious_agent.py,sha256=JhbwnmMNysOeisJI1MH6o8PLS-WonGAfgCx6sdWb4IM,22324
4
+ memori/agents/memory_agent.py,sha256=krxG3Q1nZwU-MslRa3vTBdaGp-6QnfcIiTEOBfAMr2w,24294
5
+ memori/agents/retrieval_agent.py,sha256=X_ycLR6QQN7iI7X5B9mB8hM-sfBzTwnDgUGFHOr6Th8,42266
6
6
  memori/config/__init__.py,sha256=tQAxopgOsea02u9iId-ocOY86nWWNGC3rvt3AOFcLn8,295
7
7
  memori/config/manager.py,sha256=PnIfp-j8BzvSsomzGZtMOdtARuhaoVwfxj1pJs5hLow,10360
8
8
  memori/config/memory_manager.py,sha256=jEchdcMxNiM825Z2ypsE5vY-uS5mCbd_AKsnQ6o_YW8,10938
9
9
  memori/config/settings.py,sha256=t-Pmz3x-IjMDcdIFJ9VNK37-OeNOhSfFciWtseUVdRc,9795
10
10
  memori/core/__init__.py,sha256=jvhHn-KL3bzRHs11-4B0BCKH6gkAf6Gf_G59If8fD0M,157
11
- memori/core/conversation.py,sha256=kQV59BWy_ZS0RwARXnQGs5KXB1fRh1ftH8rHuNs6a_E,15813
11
+ memori/core/conversation.py,sha256=5MwriLpB4f81VUXfarWUL_2eLUxTERnUJ4ZA8WFM6Jk,16127
12
12
  memori/core/database.py,sha256=aycWOP2TJD5GBZXnAFU2yPDeGKRUjUeep9DoK6hLGas,40075
13
- memori/core/memory.py,sha256=257RDLlLUdKxN4rd2HUhBqjha5Ahx1zpS-TfF3wxhvw,117079
13
+ memori/core/memory.py,sha256=vUBHRwaeLAQDorkoVn3vo2h-PyjDmPcCmOhtkWubuiw,120430
14
14
  memori/core/providers.py,sha256=IH-ep_VYY_-itY31dyqT-ftDlHKE_IzsFED_30tAJaI,6944
15
15
  memori/database/__init__.py,sha256=yungdfis0lyDE2eZFs86miYCAMG4klhS-TLhKq-1K3w,426
16
- memori/database/auto_creator.py,sha256=oMUKuJlLqwG4OxbhkMMjq0e5DDan3KcvAfEM2a56jOQ,12662
16
+ memori/database/auto_creator.py,sha256=M18-PEOesFAfdbmK2hP7wnS4LCcBYGMMRZ-1Onfo_9U,15729
17
17
  memori/database/connection_utils.py,sha256=QQ50IQlrNUd0CWiFQeH76yIi1evbgMv8dDV29QkSAsc,6796
18
18
  memori/database/models.py,sha256=jPsD_ALGHMgv6_nxgizSQ2BTbNTupCMPOuS5EBaUiFU,14826
19
- memori/database/mongodb_manager.py,sha256=aB4vEnL2Jrb0ny4wbhsQGouTwkKfcVGNwsc-D8k7WYA,59270
19
+ memori/database/mongodb_manager.py,sha256=fnApxLe2sdziEgQ2Dp2Z0sKL0K0WnKGJcyalLu1eVhw,60404
20
20
  memori/database/query_translator.py,sha256=ruwzfIVxhcO5ouNamRVlxIUMkesU7xE8N5LzgaPW9Qc,6988
21
- memori/database/search_service.py,sha256=QH0CQaDONR3aSd7Su2C6Ysz4pikbYk3NDFRkP4EcFws,26856
22
- memori/database/sqlalchemy_manager.py,sha256=qSVSUp76CFiAy7CUvwdq3xGeXPGimhZxac0OtnV6XKQ,34926
21
+ memori/database/search_service.py,sha256=uTu6-GarBN5P8DYFefC5CZxJytScz-R5iHW7fFV1fUo,33752
22
+ memori/database/sqlalchemy_manager.py,sha256=p5P2vBFqApty685PUWXerPB7JxHt3RgjqIXCkqU8U6w,38231
23
23
  memori/database/adapters/__init__.py,sha256=QMAo4Ts5ycxSqi0nmcssHRXASwr2KKn0mMu-kYbmFzo,626
24
24
  memori/database/adapters/mongodb_adapter.py,sha256=iZXaQwB0_My1eVz0mqeTZNILIXGnCF_UeOwZ3TAhZao,26537
25
25
  memori/database/adapters/mysql_adapter.py,sha256=HK04a9GAZiKwWZJkVhArNqOCUnHUnJRA-c_MAOPJVUI,12915
@@ -49,23 +49,23 @@ memori/database/templates/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
49
49
  memori/integrations/__init__.py,sha256=LKbF3PLpvIY18nVvfl7uDXivbNeNXQZyYb66g-dWado,2891
50
50
  memori/integrations/anthropic_integration.py,sha256=1wmuXo2cLee-eq743t8F90TArh2lfhLrM6l9Z1e0kn4,8137
51
51
  memori/integrations/litellm_integration.py,sha256=zgQ5reU-t40hl5qQ8jOoVxnA4tB-43ywuVwGKj5vRBo,13226
52
- memori/integrations/openai_integration.py,sha256=S8lTMHosAuzHaOT0xUYTdE31P7rvzhTlxg_4mQSPoEQ,21513
52
+ memori/integrations/openai_integration.py,sha256=H1N3yl7IXLPyTLfFQJ6Q0C6nk2upzg2uRP1yxnU0LUw,20574
53
53
  memori/tools/__init__.py,sha256=0KPbWAFYmvEleacrby4RzhJGW5GPdFiXN6RWwFrbqf4,200
54
54
  memori/tools/memory_tool.py,sha256=umwvskJVGAgcnRfQnjL6Xf1BcJ_p6ORcoq5i_5dwRrM,25098
55
55
  memori/utils/__init__.py,sha256=e3AN4KfomQBQDsr53HwfvOeTtI3QZMzGQMYpRp8l6ow,1757
56
56
  memori/utils/exceptions.py,sha256=SzLHenNe4BWe3bGegz2yoHYTh4aLel5rNCC6x0IvNwM,11933
57
57
  memori/utils/helpers.py,sha256=tYphW25u9qr2rTvtdPoX0avtcH9lwQuOxa9DT5mFEBs,13010
58
58
  memori/utils/input_validator.py,sha256=ZJnMS_DqeZCDuHVkTU_dlN1XPoqN_FqDA_yqMM8imTY,13546
59
- memori/utils/logging.py,sha256=sPaZKzL3DxKYHX5PGEtuWvRC0Sj2ALWSrhzbybq3f4I,7109
59
+ memori/utils/logging.py,sha256=54qD0G95dN-zkz6OcTutJ8Ez3Juz_OWCy1KnTXnaywo,5215
60
60
  memori/utils/pydantic_models.py,sha256=wEB9vu79Z4NiaePdHb3eJmX7lZY5YWA82QD8_xuECCk,12041
61
61
  memori/utils/query_builder.py,sha256=cKv2OFe_G_ap4a7rZ4F2p9nZUIfjgFvquQBfXIBnTls,21386
62
62
  memori/utils/schemas.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  memori/utils/security_audit.py,sha256=SZyqdHyIUzrrnMxO__dAcnB-3x0vSuHW7eW0apOGT2s,21979
64
64
  memori/utils/security_integration.py,sha256=xiyYQ1sEo0yk_0NhWeXzzjTJ60pNbI0SEyAz766iilA,13050
65
65
  memori/utils/transaction_manager.py,sha256=kyxI_gRJUY8b1lq0ZUDN65rNmUC5qIGOyL8obFIysBQ,18735
66
- memori/utils/validators.py,sha256=u5emqDrSkN9JlJxdo5yxcCqs510UDOiLf16F6p-Oyps,11267
67
- memorisdk-2.1.1.dist-info/licenses/LICENSE,sha256=gyrDaYsSODngoYE1l68l_UfjppS-oYDrf1MvY1JGhgE,10430
68
- memorisdk-2.1.1.dist-info/METADATA,sha256=6KWbuv3JjXWmNrCjwqZ-MisJQVK5CqgS9H-0W-AyY0c,19907
69
- memorisdk-2.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
- memorisdk-2.1.1.dist-info/top_level.txt,sha256=Nm3ad0isbJYBzTEce-O_gmkAEiTbAbyilgAhRt8IoGA,7
71
- memorisdk-2.1.1.dist-info/RECORD,,
66
+ memori/utils/validators.py,sha256=-1w3M_DaciOkl-LsXryQtzlbD3i0imDja1_UGGxY1t0,11293
67
+ memorisdk-2.3.1.dist-info/licenses/LICENSE,sha256=gyrDaYsSODngoYE1l68l_UfjppS-oYDrf1MvY1JGhgE,10430
68
+ memorisdk-2.3.1.dist-info/METADATA,sha256=MLB4lyehrJYbnu4Z8c1LqhV7NLeyt6kBXgSkmmaIKqk,20668
69
+ memorisdk-2.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
+ memorisdk-2.3.1.dist-info/top_level.txt,sha256=Nm3ad0isbJYBzTEce-O_gmkAEiTbAbyilgAhRt8IoGA,7
71
+ memorisdk-2.3.1.dist-info/RECORD,,