memorisdk 1.0.0__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.

Files changed (44) hide show
  1. memoriai/__init__.py +140 -0
  2. memoriai/agents/__init__.py +7 -0
  3. memoriai/agents/conscious_agent.py +506 -0
  4. memoriai/agents/memory_agent.py +322 -0
  5. memoriai/agents/retrieval_agent.py +579 -0
  6. memoriai/config/__init__.py +14 -0
  7. memoriai/config/manager.py +281 -0
  8. memoriai/config/settings.py +287 -0
  9. memoriai/core/__init__.py +6 -0
  10. memoriai/core/database.py +966 -0
  11. memoriai/core/memory.py +1349 -0
  12. memoriai/database/__init__.py +5 -0
  13. memoriai/database/connectors/__init__.py +9 -0
  14. memoriai/database/connectors/mysql_connector.py +159 -0
  15. memoriai/database/connectors/postgres_connector.py +158 -0
  16. memoriai/database/connectors/sqlite_connector.py +148 -0
  17. memoriai/database/queries/__init__.py +15 -0
  18. memoriai/database/queries/base_queries.py +204 -0
  19. memoriai/database/queries/chat_queries.py +157 -0
  20. memoriai/database/queries/entity_queries.py +236 -0
  21. memoriai/database/queries/memory_queries.py +178 -0
  22. memoriai/database/templates/__init__.py +0 -0
  23. memoriai/database/templates/basic_template.py +0 -0
  24. memoriai/database/templates/schemas/__init__.py +0 -0
  25. memoriai/integrations/__init__.py +68 -0
  26. memoriai/integrations/anthropic_integration.py +194 -0
  27. memoriai/integrations/litellm_integration.py +11 -0
  28. memoriai/integrations/openai_integration.py +273 -0
  29. memoriai/scripts/llm_text.py +50 -0
  30. memoriai/tools/__init__.py +5 -0
  31. memoriai/tools/memory_tool.py +544 -0
  32. memoriai/utils/__init__.py +89 -0
  33. memoriai/utils/exceptions.py +418 -0
  34. memoriai/utils/helpers.py +433 -0
  35. memoriai/utils/logging.py +204 -0
  36. memoriai/utils/pydantic_models.py +258 -0
  37. memoriai/utils/schemas.py +0 -0
  38. memoriai/utils/validators.py +339 -0
  39. memorisdk-1.0.0.dist-info/METADATA +386 -0
  40. memorisdk-1.0.0.dist-info/RECORD +44 -0
  41. memorisdk-1.0.0.dist-info/WHEEL +5 -0
  42. memorisdk-1.0.0.dist-info/entry_points.txt +2 -0
  43. memorisdk-1.0.0.dist-info/licenses/LICENSE +203 -0
  44. memorisdk-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,178 @@
1
+ """
2
+ Memory-related database queries
3
+ """
4
+
5
+ from typing import Dict
6
+
7
+ from .base_queries import BaseQueries
8
+
9
+
10
+ class MemoryQueries(BaseQueries):
11
+ """Centralized memory-related SQL queries"""
12
+
13
+ def get_table_creation_queries(self) -> Dict[str, str]:
14
+ """Memory table creation queries"""
15
+ from .base_queries import SchemaQueries
16
+
17
+ return {
18
+ "short_term_memory": SchemaQueries.TABLE_CREATION["short_term_memory"],
19
+ "long_term_memory": SchemaQueries.TABLE_CREATION["long_term_memory"],
20
+ "rules_memory": SchemaQueries.TABLE_CREATION["rules_memory"],
21
+ }
22
+
23
+ def get_index_creation_queries(self) -> Dict[str, str]:
24
+ """Memory index creation queries"""
25
+ from .base_queries import SchemaQueries
26
+
27
+ return {
28
+ k: v
29
+ for k, v in SchemaQueries.INDEX_CREATION.items()
30
+ if any(table in k for table in ["short_term", "long_term", "rules"])
31
+ }
32
+
33
+ def get_trigger_creation_queries(self) -> Dict[str, str]:
34
+ """Memory trigger creation queries"""
35
+ from .base_queries import SchemaQueries
36
+
37
+ return SchemaQueries.TRIGGER_CREATION
38
+
39
+ # INSERT Queries
40
+ INSERT_SHORT_TERM_MEMORY = """
41
+ INSERT INTO short_term_memory (
42
+ memory_id, chat_id, processed_data, importance_score, category_primary,
43
+ retention_type, namespace, created_at, expires_at, searchable_content, summary
44
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
45
+ """
46
+
47
+ INSERT_LONG_TERM_MEMORY = """
48
+ INSERT INTO long_term_memory (
49
+ memory_id, original_chat_id, processed_data, importance_score, category_primary,
50
+ retention_type, namespace, created_at, searchable_content, summary,
51
+ novelty_score, relevance_score, actionability_score
52
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
53
+ """
54
+
55
+ INSERT_RULES_MEMORY = """
56
+ INSERT INTO rules_memory (
57
+ rule_id, rule_text, rule_type, priority, active, context_conditions,
58
+ namespace, created_at, updated_at, processed_data, metadata
59
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
60
+ """
61
+
62
+ # SELECT Queries
63
+ SELECT_MEMORIES_BY_NAMESPACE = """
64
+ SELECT memory_id, processed_data, importance_score, category_primary, created_at, summary
65
+ FROM {table}
66
+ WHERE namespace = ?
67
+ ORDER BY importance_score DESC, created_at DESC
68
+ LIMIT ?
69
+ """
70
+
71
+ SELECT_MEMORIES_BY_CATEGORY = """
72
+ SELECT memory_id, processed_data, importance_score, created_at, summary
73
+ FROM {table}
74
+ WHERE namespace = ? AND category_primary = ?
75
+ ORDER BY importance_score DESC, created_at DESC
76
+ LIMIT ?
77
+ """
78
+
79
+ SELECT_MEMORIES_BY_IMPORTANCE = """
80
+ SELECT memory_id, processed_data, importance_score, created_at, summary
81
+ FROM {table}
82
+ WHERE namespace = ? AND importance_score >= ?
83
+ ORDER BY importance_score DESC, created_at DESC
84
+ LIMIT ?
85
+ """
86
+
87
+ SELECT_EXPIRED_MEMORIES = """
88
+ SELECT memory_id, processed_data
89
+ FROM short_term_memory
90
+ WHERE namespace = ? AND expires_at <= ?
91
+ """
92
+
93
+ SELECT_MEMORY_BY_ID = """
94
+ SELECT * FROM {table} WHERE memory_id = ? AND namespace = ?
95
+ """
96
+
97
+ # UPDATE Queries
98
+ UPDATE_MEMORY_ACCESS = """
99
+ UPDATE {table}
100
+ SET access_count = access_count + 1, last_accessed = ?
101
+ WHERE memory_id = ? AND namespace = ?
102
+ """
103
+
104
+ UPDATE_MEMORY_IMPORTANCE = """
105
+ UPDATE {table}
106
+ SET importance_score = ?
107
+ WHERE memory_id = ? AND namespace = ?
108
+ """
109
+
110
+ UPDATE_RULE_STATUS = """
111
+ UPDATE rules_memory
112
+ SET active = ?, updated_at = ?
113
+ WHERE rule_id = ? AND namespace = ?
114
+ """
115
+
116
+ # DELETE Queries
117
+ DELETE_MEMORY = """
118
+ DELETE FROM {table} WHERE memory_id = ? AND namespace = ?
119
+ """
120
+
121
+ DELETE_EXPIRED_MEMORIES = """
122
+ DELETE FROM short_term_memory
123
+ WHERE namespace = ? AND expires_at <= ?
124
+ """
125
+
126
+ DELETE_MEMORIES_BY_CATEGORY = """
127
+ DELETE FROM {table}
128
+ WHERE namespace = ? AND category_primary = ?
129
+ """
130
+
131
+ # SEARCH Queries
132
+ SEARCH_MEMORIES_FTS = """
133
+ SELECT m.memory_id, m.memory_type, m.namespace, m.searchable_content, m.summary, m.category_primary
134
+ FROM memory_search_fts m
135
+ WHERE m.searchable_content MATCH ? AND m.namespace = ?
136
+ ORDER BY rank
137
+ LIMIT ?
138
+ """
139
+
140
+ SEARCH_MEMORIES_SEMANTIC = """
141
+ SELECT memory_id, processed_data, importance_score, searchable_content, summary
142
+ FROM {table}
143
+ WHERE namespace = ? AND (
144
+ searchable_content LIKE ? OR
145
+ summary LIKE ? OR
146
+ category_primary = ?
147
+ )
148
+ ORDER BY importance_score DESC, created_at DESC
149
+ LIMIT ?
150
+ """
151
+
152
+ # ANALYTICS Queries
153
+ COUNT_MEMORIES_BY_CATEGORY = """
154
+ SELECT category_primary, COUNT(*) as count
155
+ FROM {table}
156
+ WHERE namespace = ?
157
+ GROUP BY category_primary
158
+ ORDER BY count DESC
159
+ """
160
+
161
+ GET_MEMORY_STATISTICS = """
162
+ SELECT
163
+ COUNT(*) as total_memories,
164
+ AVG(importance_score) as avg_importance,
165
+ MAX(importance_score) as max_importance,
166
+ MIN(importance_score) as min_importance,
167
+ COUNT(DISTINCT category_primary) as unique_categories
168
+ FROM {table}
169
+ WHERE namespace = ?
170
+ """
171
+
172
+ GET_RECENT_MEMORIES = """
173
+ SELECT memory_id, summary, importance_score, created_at
174
+ FROM {table}
175
+ WHERE namespace = ? AND created_at >= ?
176
+ ORDER BY created_at DESC
177
+ LIMIT ?
178
+ """
File without changes
File without changes
File without changes
@@ -0,0 +1,68 @@
1
+ """
2
+ Universal LLM Integration - Plug-and-Play Memory Recording
3
+
4
+ 🎯 SIMPLE USAGE (RECOMMENDED):
5
+ Just call memori.enable() and use ANY LLM library normally!
6
+
7
+ ```python
8
+ from memoriai import Memori
9
+
10
+ memori = Memori(...)
11
+ memori.enable() # 🎉 That's it!
12
+
13
+ # Now use ANY LLM library normally - all calls will be auto-recorded:
14
+
15
+ # LiteLLM (native callbacks)
16
+ from litellm import completion
17
+ completion(model="gpt-4o", messages=[...]) # ✅ Auto-recorded
18
+
19
+ # Direct OpenAI (auto-wrapping)
20
+ import openai
21
+ client = openai.OpenAI(api_key="...")
22
+ client.chat.completions.create(...) # ✅ Auto-recorded
23
+
24
+ # Direct Anthropic (auto-wrapping)
25
+ import anthropic
26
+ client = anthropic.Anthropic(api_key="...")
27
+ client.messages.create(...) # ✅ Auto-recorded
28
+ ```
29
+
30
+ The universal system automatically detects and records ALL LLM providers
31
+ without requiring wrapper classes or complex setup.
32
+ """
33
+
34
+ from typing import Any, Dict, List
35
+
36
+ from loguru import logger
37
+
38
+ # Legacy imports (all deprecated)
39
+ from . import anthropic_integration, litellm_integration, openai_integration
40
+
41
+ __all__ = [
42
+ # Wrapper classes for direct SDK usage
43
+ "MemoriOpenAI",
44
+ "MemoriAnthropic",
45
+ ]
46
+
47
+
48
+ # For backward compatibility, provide simple passthrough
49
+ try:
50
+ from .anthropic_integration import MemoriAnthropic
51
+ from .openai_integration import MemoriOpenAI
52
+
53
+ # But warn users about the better way
54
+ def __getattr__(name):
55
+ if name in ["MemoriOpenAI", "MemoriAnthropic"]:
56
+ logger.warning(
57
+ f"🚨 {name} wrapper classes are deprecated!\n"
58
+ f"✅ NEW SIMPLE WAY: Use memori.enable() and import {name.replace('Memori', '').lower()} normally"
59
+ )
60
+ if name == "MemoriOpenAI":
61
+ return MemoriOpenAI
62
+ elif name == "MemoriAnthropic":
63
+ return MemoriAnthropic
64
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
65
+
66
+ except ImportError:
67
+ # Wrapper classes not available, that's fine
68
+ pass
@@ -0,0 +1,194 @@
1
+ """
2
+ Anthropic Integration - Clean wrapper without monkey-patching
3
+
4
+ RECOMMENDED: Use LiteLLM instead for unified API and native callback support.
5
+ This integration is provided for direct Anthropic SDK usage.
6
+
7
+ Usage:
8
+ from memoriai.integrations.anthropic_integration import MemoriAnthropic
9
+
10
+ # Initialize with your memori instance
11
+ client = MemoriAnthropic(memori_instance, api_key="your-key")
12
+
13
+ # Use exactly like Anthropic client
14
+ response = client.messages.create(...)
15
+ """
16
+
17
+ from typing import Optional
18
+
19
+ from loguru import logger
20
+
21
+
22
+ class MemoriAnthropic:
23
+ """
24
+ Clean Anthropic wrapper that automatically records conversations
25
+ without monkey-patching. Drop-in replacement for Anthropic client.
26
+ """
27
+
28
+ def __init__(self, memori_instance, api_key: Optional[str] = None, **kwargs):
29
+ """
30
+ Initialize MemoriAnthropic wrapper
31
+
32
+ Args:
33
+ memori_instance: Memori instance for recording conversations
34
+ api_key: Anthropic API key
35
+ **kwargs: Additional arguments passed to Anthropic client
36
+ """
37
+ try:
38
+ import anthropic
39
+
40
+ self._anthropic = anthropic.Anthropic(api_key=api_key, **kwargs)
41
+ self._memori = memori_instance
42
+
43
+ # Create wrapped messages
44
+ self.messages = self._create_messages_wrapper()
45
+
46
+ # Pass through other attributes
47
+ for attr in dir(self._anthropic):
48
+ if not attr.startswith("_") and attr not in ["messages"]:
49
+ setattr(self, attr, getattr(self._anthropic, attr))
50
+
51
+ except ImportError as err:
52
+ raise ImportError(
53
+ "Anthropic package required: pip install anthropic"
54
+ ) from err
55
+
56
+ def _create_messages_wrapper(self):
57
+ """Create wrapped messages"""
58
+
59
+ class MessagesWrapper:
60
+ def __init__(self, anthropic_client, memori_instance):
61
+ self._anthropic = anthropic_client
62
+ self._memori = memori_instance
63
+
64
+ def create(self, **kwargs):
65
+ # Inject context if conscious ingestion is enabled
66
+ if self._memori.is_enabled and self._memori.conscious_ingest:
67
+ kwargs = self._inject_context(kwargs)
68
+
69
+ # Make the actual API call
70
+ response = self._anthropic.messages.create(**kwargs)
71
+
72
+ # Record conversation if memori is enabled
73
+ if self._memori.is_enabled:
74
+ self._record_conversation(kwargs, response)
75
+
76
+ return response
77
+
78
+ def _inject_context(self, kwargs):
79
+ """Inject relevant context into messages"""
80
+ try:
81
+ # Extract user input from messages
82
+ user_input = ""
83
+ for msg in reversed(kwargs.get("messages", [])):
84
+ if msg.get("role") == "user":
85
+ content = msg.get("content", "")
86
+ if isinstance(content, list):
87
+ # Handle content blocks
88
+ user_input = " ".join(
89
+ [
90
+ block.get("text", "")
91
+ for block in content
92
+ if isinstance(block, dict)
93
+ and block.get("type") == "text"
94
+ ]
95
+ )
96
+ else:
97
+ user_input = content
98
+ break
99
+
100
+ if user_input:
101
+ # Fetch relevant context
102
+ context = self._memori.retrieve_context(user_input, limit=3)
103
+
104
+ if context:
105
+ # Create a context prompt
106
+ context_prompt = "--- Relevant Memories ---\n"
107
+ for mem in context:
108
+ if isinstance(mem, dict):
109
+ summary = mem.get("summary", "") or mem.get(
110
+ "content", ""
111
+ )
112
+ context_prompt += f"- {summary}\n"
113
+ else:
114
+ context_prompt += f"- {str(mem)}\n"
115
+ context_prompt += "-------------------------\n"
116
+
117
+ # Inject context into the system parameter
118
+ if kwargs.get("system"):
119
+ # Prepend to existing system message
120
+ kwargs["system"] = context_prompt + kwargs["system"]
121
+ else:
122
+ # Add as system message
123
+ kwargs["system"] = context_prompt
124
+
125
+ logger.debug(f"Injected context: {len(context)} memories")
126
+ except Exception as e:
127
+ logger.error(f"Context injection failed: {e}")
128
+
129
+ return kwargs
130
+
131
+ def _record_conversation(self, kwargs, response):
132
+ """Record the conversation"""
133
+ try:
134
+ # Extract details
135
+ messages = kwargs.get("messages", [])
136
+ model = kwargs.get("model", "claude-unknown")
137
+
138
+ # Find user input (last user message)
139
+ user_input = ""
140
+ for message in reversed(messages):
141
+ if message.get("role") == "user":
142
+ content = message.get("content", "")
143
+ if isinstance(content, list):
144
+ # Handle content blocks
145
+ user_input = " ".join(
146
+ [
147
+ block.get("text", "")
148
+ for block in content
149
+ if isinstance(block, dict)
150
+ and block.get("type") == "text"
151
+ ]
152
+ )
153
+ else:
154
+ user_input = content
155
+ break
156
+
157
+ # Extract AI response
158
+ ai_output = ""
159
+ if hasattr(response, "content") and response.content:
160
+ if isinstance(response.content, list):
161
+ # Handle content blocks
162
+ ai_output = " ".join(
163
+ [
164
+ block.text
165
+ for block in response.content
166
+ if hasattr(block, "text")
167
+ ]
168
+ )
169
+ else:
170
+ ai_output = str(response.content)
171
+
172
+ # Calculate tokens used
173
+ tokens_used = 0
174
+ if hasattr(response, "usage") and response.usage:
175
+ input_tokens = getattr(response.usage, "input_tokens", 0)
176
+ output_tokens = getattr(response.usage, "output_tokens", 0)
177
+ tokens_used = input_tokens + output_tokens
178
+
179
+ # Record conversation
180
+ self._memori.record_conversation(
181
+ user_input=user_input,
182
+ ai_output=ai_output,
183
+ model=model,
184
+ metadata={
185
+ "integration": "anthropic_wrapper",
186
+ "api_type": "messages",
187
+ "tokens_used": tokens_used,
188
+ "auto_recorded": True,
189
+ },
190
+ )
191
+ except Exception as e:
192
+ logger.error(f"Failed to record Anthropic conversation: {e}")
193
+
194
+ return MessagesWrapper(self._anthropic, self._memori)
@@ -0,0 +1,11 @@
1
+ """
2
+ LiteLLM Integration - DEPRECATED
3
+
4
+ This integration is deprecated. LiteLLM now uses native callbacks
5
+ implemented directly in memoriai/core/memory.py
6
+
7
+ The native callback system is more robust and uses LiteLLM's official
8
+ extension mechanism instead of monkey-patching.
9
+
10
+ Use: memori.enable() which registers with LiteLLM's success_callback system.
11
+ """