memorisdk 1.0.2__tar.gz → 2.0.0__tar.gz
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.
- {memorisdk-1.0.2 → memorisdk-2.0.0}/PKG-INFO +44 -17
- {memorisdk-1.0.2 → memorisdk-2.0.0}/README.md +18 -14
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/__init__.py +24 -8
- memorisdk-2.0.0/memori/agents/conscious_agent.py +344 -0
- memorisdk-2.0.0/memori/agents/memory_agent.py +585 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/agents/retrieval_agent.py +416 -60
- memorisdk-2.0.0/memori/config/memory_manager.py +323 -0
- memorisdk-2.0.0/memori/core/conversation.py +393 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/core/database.py +386 -371
- memorisdk-2.0.0/memori/core/memory.py +2491 -0
- memorisdk-2.0.0/memori/core/providers.py +217 -0
- memorisdk-2.0.0/memori/database/adapters/__init__.py +10 -0
- memorisdk-2.0.0/memori/database/adapters/mysql_adapter.py +331 -0
- memorisdk-2.0.0/memori/database/adapters/postgresql_adapter.py +291 -0
- memorisdk-2.0.0/memori/database/adapters/sqlite_adapter.py +229 -0
- memorisdk-2.0.0/memori/database/auto_creator.py +320 -0
- memorisdk-2.0.0/memori/database/connection_utils.py +207 -0
- memorisdk-2.0.0/memori/database/connectors/base_connector.py +283 -0
- memorisdk-2.0.0/memori/database/connectors/mysql_connector.py +381 -0
- memorisdk-2.0.0/memori/database/connectors/postgres_connector.py +431 -0
- memorisdk-2.0.0/memori/database/connectors/sqlite_connector.py +323 -0
- memorisdk-2.0.0/memori/database/models.py +400 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/base_queries.py +1 -1
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/memory_queries.py +91 -2
- memorisdk-2.0.0/memori/database/query_translator.py +222 -0
- memorisdk-2.0.0/memori/database/schema_generators/__init__.py +7 -0
- memorisdk-2.0.0/memori/database/schema_generators/mysql_schema_generator.py +215 -0
- memorisdk-2.0.0/memori/database/search/__init__.py +8 -0
- memorisdk-2.0.0/memori/database/search/mysql_search_adapter.py +255 -0
- memorisdk-2.0.0/memori/database/search/sqlite_search_adapter.py +180 -0
- memorisdk-2.0.0/memori/database/search_service.py +548 -0
- memorisdk-2.0.0/memori/database/sqlalchemy_manager.py +839 -0
- memorisdk-2.0.0/memori/integrations/__init__.py +93 -0
- memorisdk-2.0.0/memori/integrations/litellm_integration.py +345 -0
- memorisdk-2.0.0/memori/integrations/openai_integration.py +539 -0
- memorisdk-2.0.0/memori/utils/input_validator.py +395 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/pydantic_models.py +138 -36
- memorisdk-2.0.0/memori/utils/query_builder.py +530 -0
- memorisdk-2.0.0/memori/utils/security_audit.py +594 -0
- memorisdk-2.0.0/memori/utils/security_integration.py +339 -0
- memorisdk-2.0.0/memori/utils/transaction_manager.py +547 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/PKG-INFO +44 -17
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/SOURCES.txt +24 -1
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/requires.txt +28 -1
- {memorisdk-1.0.2 → memorisdk-2.0.0}/pyproject.toml +42 -5
- memorisdk-1.0.2/memori/agents/conscious_agent.py +0 -506
- memorisdk-1.0.2/memori/agents/memory_agent.py +0 -322
- memorisdk-1.0.2/memori/core/memory.py +0 -1384
- memorisdk-1.0.2/memori/database/connectors/mysql_connector.py +0 -159
- memorisdk-1.0.2/memori/database/connectors/postgres_connector.py +0 -158
- memorisdk-1.0.2/memori/database/connectors/sqlite_connector.py +0 -148
- memorisdk-1.0.2/memori/integrations/__init__.py +0 -68
- memorisdk-1.0.2/memori/integrations/litellm_integration.py +0 -11
- memorisdk-1.0.2/memori/integrations/openai_integration.py +0 -273
- memorisdk-1.0.2/memorisdk.egg-info/entry_points.txt +0 -2
- {memorisdk-1.0.2 → memorisdk-2.0.0}/LICENSE +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/agents/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/manager.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/settings.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/core/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/connectors/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/chat_queries.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/entity_queries.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/basic_template.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/schemas/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/integrations/anthropic_integration.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/scripts/llm_text.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/tools/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/tools/memory_tool.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/__init__.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/exceptions.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/helpers.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/logging.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/schemas.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/validators.py +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/dependency_links.txt +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/top_level.txt +0 -0
- {memorisdk-1.0.2 → memorisdk-2.0.0}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memorisdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
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
|
|
7
7
|
Project-URL: Homepage, https://github.com/GibsonAI/memori
|
|
8
|
-
Project-URL: Documentation, https://gibsonai.
|
|
8
|
+
Project-URL: Documentation, https://memori.gibsonai.com/docs
|
|
9
9
|
Project-URL: Repository, https://github.com/GibsonAI/memori.git
|
|
10
10
|
Project-URL: Bug Tracker, https://github.com/GibsonAI/memori/issues
|
|
11
11
|
Project-URL: Changelog, https://github.com/GibsonAI/memori/blob/main/CHANGELOG.md
|
|
@@ -31,8 +31,9 @@ License-File: LICENSE
|
|
|
31
31
|
Requires-Dist: loguru>=0.6.0
|
|
32
32
|
Requires-Dist: pydantic>=2.0.0
|
|
33
33
|
Requires-Dist: python-dotenv>=1.0.0
|
|
34
|
-
Requires-Dist:
|
|
34
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
35
35
|
Requires-Dist: openai>=1.0.0
|
|
36
|
+
Requires-Dist: litellm>=1.0.0
|
|
36
37
|
Provides-Extra: dev
|
|
37
38
|
Requires-Dist: black>=23.0; extra == "dev"
|
|
38
39
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
@@ -40,6 +41,9 @@ Requires-Dist: isort>=5.9.0; extra == "dev"
|
|
|
40
41
|
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
41
42
|
Requires-Dist: pre-commit>=2.15; extra == "dev"
|
|
42
43
|
Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-cov>=2.0; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest-asyncio>=0.18.0; extra == "dev"
|
|
43
47
|
Provides-Extra: docs
|
|
44
48
|
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
|
|
45
49
|
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
|
|
@@ -50,15 +54,31 @@ Provides-Extra: postgres
|
|
|
50
54
|
Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
|
|
51
55
|
Provides-Extra: mysql
|
|
52
56
|
Requires-Dist: PyMySQL>=1.0.0; extra == "mysql"
|
|
57
|
+
Provides-Extra: databases
|
|
58
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "databases"
|
|
59
|
+
Requires-Dist: PyMySQL>=1.0.0; extra == "databases"
|
|
60
|
+
Provides-Extra: anthropic
|
|
61
|
+
Requires-Dist: anthropic>=0.3.0; extra == "anthropic"
|
|
62
|
+
Provides-Extra: litellm
|
|
63
|
+
Requires-Dist: litellm>=1.0.0; extra == "litellm"
|
|
53
64
|
Provides-Extra: integrations
|
|
54
65
|
Requires-Dist: litellm>=1.0.0; extra == "integrations"
|
|
55
66
|
Requires-Dist: anthropic>=0.3.0; extra == "integrations"
|
|
67
|
+
Provides-Extra: demos
|
|
68
|
+
Requires-Dist: streamlit>=1.28.0; extra == "demos"
|
|
69
|
+
Requires-Dist: pandas>=2.0.0; extra == "demos"
|
|
70
|
+
Requires-Dist: plotly>=5.17.0; extra == "demos"
|
|
71
|
+
Requires-Dist: crewai>=0.152.0; extra == "demos"
|
|
72
|
+
Requires-Dist: crewai-tools>=0.59.0; extra == "demos"
|
|
56
73
|
Provides-Extra: all
|
|
57
74
|
Requires-Dist: black>=23.0; extra == "all"
|
|
58
75
|
Requires-Dist: ruff>=0.1.0; extra == "all"
|
|
59
76
|
Requires-Dist: isort>=5.9.0; extra == "all"
|
|
60
77
|
Requires-Dist: mypy>=1.0; extra == "all"
|
|
61
78
|
Requires-Dist: pre-commit>=2.15; extra == "all"
|
|
79
|
+
Requires-Dist: pytest>=6.0; extra == "all"
|
|
80
|
+
Requires-Dist: pytest-cov>=2.0; extra == "all"
|
|
81
|
+
Requires-Dist: pytest-asyncio>=0.18.0; extra == "all"
|
|
62
82
|
Requires-Dist: mkdocs>=1.5.0; extra == "all"
|
|
63
83
|
Requires-Dist: mkdocs-material>=9.0.0; extra == "all"
|
|
64
84
|
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2.0; extra == "all"
|
|
@@ -68,6 +88,9 @@ Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
|
|
|
68
88
|
Requires-Dist: PyMySQL>=1.0.0; extra == "all"
|
|
69
89
|
Requires-Dist: litellm>=1.0.0; extra == "all"
|
|
70
90
|
Requires-Dist: anthropic>=0.3.0; extra == "all"
|
|
91
|
+
Requires-Dist: streamlit>=1.28.0; extra == "all"
|
|
92
|
+
Requires-Dist: pandas>=2.0.0; extra == "all"
|
|
93
|
+
Requires-Dist: plotly>=5.17.0; extra == "all"
|
|
71
94
|
Dynamic: license-file
|
|
72
95
|
|
|
73
96
|
[](https://gibsonai.com/)
|
|
@@ -83,7 +106,7 @@ Dynamic: license-file
|
|
|
83
106
|
</p>
|
|
84
107
|
|
|
85
108
|
<p align="center">
|
|
86
|
-
<a href="https://gibsonai.
|
|
109
|
+
<a href="https://memori.gibsonai.com/docs">Learn more</a>
|
|
87
110
|
·
|
|
88
111
|
<a href="https://www.gibsonai.com/discord">Join Discord</a>
|
|
89
112
|
</p>
|
|
@@ -121,12 +144,12 @@ Install Memori:
|
|
|
121
144
|
pip install memorisdk
|
|
122
145
|
```
|
|
123
146
|
|
|
124
|
-
### Example with
|
|
147
|
+
### Example with OpenAI
|
|
125
148
|
|
|
126
|
-
1. Install
|
|
149
|
+
1. Install OpenAI:
|
|
127
150
|
|
|
128
151
|
```bash
|
|
129
|
-
pip install
|
|
152
|
+
pip install openai
|
|
130
153
|
```
|
|
131
154
|
|
|
132
155
|
2. Set OpenAI API Key:
|
|
@@ -139,14 +162,17 @@ export OPENAI_API_KEY="sk-your-openai-key-here"
|
|
|
139
162
|
|
|
140
163
|
```python
|
|
141
164
|
from memori import Memori
|
|
142
|
-
from
|
|
165
|
+
from openai import OpenAI
|
|
166
|
+
|
|
167
|
+
# Initialize OpenAI client
|
|
168
|
+
openai_client = OpenAI()
|
|
143
169
|
|
|
144
170
|
# Initialize memory
|
|
145
171
|
memori = Memori(conscious_ingest=True)
|
|
146
172
|
memori.enable()
|
|
147
173
|
|
|
148
174
|
print("=== First Conversation - Establishing Context ===")
|
|
149
|
-
response1 =
|
|
175
|
+
response1 = openai_client.chat.completions.create(
|
|
150
176
|
model="gpt-4o-mini",
|
|
151
177
|
messages=[{
|
|
152
178
|
"role": "user",
|
|
@@ -158,7 +184,7 @@ print("Assistant:", response1.choices[0].message.content)
|
|
|
158
184
|
print("\n" + "="*50)
|
|
159
185
|
print("=== Second Conversation - Memory Provides Context ===")
|
|
160
186
|
|
|
161
|
-
response2 =
|
|
187
|
+
response2 = openai_client.chat.completions.create(
|
|
162
188
|
model="gpt-4o-mini",
|
|
163
189
|
messages=[{
|
|
164
190
|
"role": "user",
|
|
@@ -344,15 +370,15 @@ Works with **ANY** LLM library:
|
|
|
344
370
|
```python
|
|
345
371
|
memori.enable() # Enable universal recording
|
|
346
372
|
|
|
347
|
-
# LiteLLM (recommended)
|
|
348
|
-
from litellm import completion
|
|
349
|
-
completion(model="gpt-4", messages=[...])
|
|
350
|
-
|
|
351
373
|
# OpenAI
|
|
352
|
-
import
|
|
353
|
-
client =
|
|
374
|
+
from openai import OpenAI
|
|
375
|
+
client = OpenAI()
|
|
354
376
|
client.chat.completions.create(...)
|
|
355
377
|
|
|
378
|
+
# LiteLLM
|
|
379
|
+
from litellm import completion
|
|
380
|
+
completion(model="gpt-4", messages=[...])
|
|
381
|
+
|
|
356
382
|
# Anthropic
|
|
357
383
|
import anthropic
|
|
358
384
|
client = anthropic.Anthropic()
|
|
@@ -443,7 +469,8 @@ Memori works seamlessly with popular AI frameworks:
|
|
|
443
469
|
| 👥 [CrewAI](./examples/integrations/crewai_example.py) | Multi-agent system with shared memory across agent interactions | Collaborative agents with memory | Agent coordination, shared memory, task-based workflows |
|
|
444
470
|
| 🌊 [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 | Context injection, session continuity, support analytics |
|
|
445
471
|
| 🔗 [LangChain](./examples/integrations/langchain_example.py) | Enterprise-grade agent framework with advanced memory integration | AI assistant with LangChain tools and memory | Custom tools, agent executors, memory persistence, error handling |
|
|
446
|
-
|
|
|
472
|
+
| � [OpenAI Agent](./examples/integrations/openai_agent_example.py) | Memory-enhanced OpenAI Agent with function calling and user preference tracking | Interactive assistant with memory search and user info storage | Function calling tools, memory search, preference tracking, async conversations |
|
|
473
|
+
| �🚀 [Swarms](./examples/integrations/swarms_example.py) | Multi-agent system framework with persistent memory capabilities | Memory-enhanced Swarms agents with auto/conscious ingestion | Agent memory persistence, multi-agent coordination, contextual awareness |
|
|
447
474
|
|
|
448
475
|
## Interactive Demos
|
|
449
476
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
14
|
-
<a href="https://gibsonai.
|
|
14
|
+
<a href="https://memori.gibsonai.com/docs">Learn more</a>
|
|
15
15
|
·
|
|
16
16
|
<a href="https://www.gibsonai.com/discord">Join Discord</a>
|
|
17
17
|
</p>
|
|
@@ -49,12 +49,12 @@ Install Memori:
|
|
|
49
49
|
pip install memorisdk
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
### Example with
|
|
52
|
+
### Example with OpenAI
|
|
53
53
|
|
|
54
|
-
1. Install
|
|
54
|
+
1. Install OpenAI:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
pip install
|
|
57
|
+
pip install openai
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
2. Set OpenAI API Key:
|
|
@@ -67,14 +67,17 @@ export OPENAI_API_KEY="sk-your-openai-key-here"
|
|
|
67
67
|
|
|
68
68
|
```python
|
|
69
69
|
from memori import Memori
|
|
70
|
-
from
|
|
70
|
+
from openai import OpenAI
|
|
71
|
+
|
|
72
|
+
# Initialize OpenAI client
|
|
73
|
+
openai_client = OpenAI()
|
|
71
74
|
|
|
72
75
|
# Initialize memory
|
|
73
76
|
memori = Memori(conscious_ingest=True)
|
|
74
77
|
memori.enable()
|
|
75
78
|
|
|
76
79
|
print("=== First Conversation - Establishing Context ===")
|
|
77
|
-
response1 =
|
|
80
|
+
response1 = openai_client.chat.completions.create(
|
|
78
81
|
model="gpt-4o-mini",
|
|
79
82
|
messages=[{
|
|
80
83
|
"role": "user",
|
|
@@ -86,7 +89,7 @@ print("Assistant:", response1.choices[0].message.content)
|
|
|
86
89
|
print("\n" + "="*50)
|
|
87
90
|
print("=== Second Conversation - Memory Provides Context ===")
|
|
88
91
|
|
|
89
|
-
response2 =
|
|
92
|
+
response2 = openai_client.chat.completions.create(
|
|
90
93
|
model="gpt-4o-mini",
|
|
91
94
|
messages=[{
|
|
92
95
|
"role": "user",
|
|
@@ -272,15 +275,15 @@ Works with **ANY** LLM library:
|
|
|
272
275
|
```python
|
|
273
276
|
memori.enable() # Enable universal recording
|
|
274
277
|
|
|
275
|
-
# LiteLLM (recommended)
|
|
276
|
-
from litellm import completion
|
|
277
|
-
completion(model="gpt-4", messages=[...])
|
|
278
|
-
|
|
279
278
|
# OpenAI
|
|
280
|
-
import
|
|
281
|
-
client =
|
|
279
|
+
from openai import OpenAI
|
|
280
|
+
client = OpenAI()
|
|
282
281
|
client.chat.completions.create(...)
|
|
283
282
|
|
|
283
|
+
# LiteLLM
|
|
284
|
+
from litellm import completion
|
|
285
|
+
completion(model="gpt-4", messages=[...])
|
|
286
|
+
|
|
284
287
|
# Anthropic
|
|
285
288
|
import anthropic
|
|
286
289
|
client = anthropic.Anthropic()
|
|
@@ -371,7 +374,8 @@ Memori works seamlessly with popular AI frameworks:
|
|
|
371
374
|
| 👥 [CrewAI](./examples/integrations/crewai_example.py) | Multi-agent system with shared memory across agent interactions | Collaborative agents with memory | Agent coordination, shared memory, task-based workflows |
|
|
372
375
|
| 🌊 [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 | Context injection, session continuity, support analytics |
|
|
373
376
|
| 🔗 [LangChain](./examples/integrations/langchain_example.py) | Enterprise-grade agent framework with advanced memory integration | AI assistant with LangChain tools and memory | Custom tools, agent executors, memory persistence, error handling |
|
|
374
|
-
|
|
|
377
|
+
| � [OpenAI Agent](./examples/integrations/openai_agent_example.py) | Memory-enhanced OpenAI Agent with function calling and user preference tracking | Interactive assistant with memory search and user info storage | Function calling tools, memory search, preference tracking, async conversations |
|
|
378
|
+
| �🚀 [Swarms](./examples/integrations/swarms_example.py) | Multi-agent system framework with persistent memory capabilities | Memory-enhanced Swarms agents with auto/conscious ingestion | Agent memory persistence, multi-agent coordination, contextual awareness |
|
|
375
379
|
|
|
376
380
|
## Interactive Demos
|
|
377
381
|
|
|
@@ -5,13 +5,11 @@ Professional-grade memory layer with comprehensive error handling, configuration
|
|
|
5
5
|
management, and modular architecture for production AI systems.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "
|
|
8
|
+
__version__ = "2.0.0"
|
|
9
9
|
__author__ = "Harshal More"
|
|
10
10
|
__email__ = "harshalmore2468@gmail.com"
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
from .agents.memory_agent import MemoryAgent
|
|
14
|
-
from .agents.retrieval_agent import MemorySearchEngine
|
|
12
|
+
from typing import Any, Optional
|
|
15
13
|
|
|
16
14
|
# Configuration system
|
|
17
15
|
from .config import (
|
|
@@ -72,7 +70,22 @@ from .utils import ( # Pydantic models; Enhanced exceptions; Validators and hel
|
|
|
72
70
|
get_logger,
|
|
73
71
|
)
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
# Memory agents (dynamically imported to avoid import errors)
|
|
74
|
+
MemoryAgent: Optional[Any] = None
|
|
75
|
+
MemorySearchEngine: Optional[Any] = None
|
|
76
|
+
_AGENTS_AVAILABLE = False
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
from .agents.memory_agent import MemoryAgent
|
|
80
|
+
from .agents.retrieval_agent import MemorySearchEngine
|
|
81
|
+
|
|
82
|
+
_AGENTS_AVAILABLE = True
|
|
83
|
+
except ImportError:
|
|
84
|
+
# Agents are not available, use placeholder None values
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
# Build __all__ list dynamically based on available components
|
|
88
|
+
_all_components = [
|
|
76
89
|
# Core
|
|
77
90
|
"Memori",
|
|
78
91
|
"DatabaseManager",
|
|
@@ -82,9 +95,6 @@ __all__ = [
|
|
|
82
95
|
"AgentSettings",
|
|
83
96
|
"LoggingSettings",
|
|
84
97
|
"ConfigManager",
|
|
85
|
-
# Agents
|
|
86
|
-
"MemoryAgent",
|
|
87
|
-
"MemorySearchEngine",
|
|
88
98
|
# Database
|
|
89
99
|
"SQLiteConnector",
|
|
90
100
|
"PostgreSQLConnector",
|
|
@@ -138,3 +148,9 @@ __all__ = [
|
|
|
138
148
|
"LoggingManager",
|
|
139
149
|
"get_logger",
|
|
140
150
|
]
|
|
151
|
+
|
|
152
|
+
# Add agents only if available
|
|
153
|
+
if _AGENTS_AVAILABLE:
|
|
154
|
+
_all_components.extend(["MemoryAgent", "MemorySearchEngine"])
|
|
155
|
+
|
|
156
|
+
__all__ = _all_components
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Conscious Agent for User Context Management
|
|
3
|
+
|
|
4
|
+
This agent copies conscious-info labeled memories from long-term memory
|
|
5
|
+
directly to short-term memory for immediate context availability.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import List
|
|
11
|
+
|
|
12
|
+
from loguru import logger
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ConsciouscAgent:
|
|
16
|
+
"""
|
|
17
|
+
Agent that copies conscious-info labeled memories from long-term memory
|
|
18
|
+
directly to short-term memory for immediate context availability.
|
|
19
|
+
|
|
20
|
+
Runs once at program startup when conscious_ingest=True.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self):
|
|
24
|
+
"""Initialize the conscious agent"""
|
|
25
|
+
self.context_initialized = False
|
|
26
|
+
|
|
27
|
+
async def run_conscious_ingest(
|
|
28
|
+
self, db_manager, namespace: str = "default"
|
|
29
|
+
) -> bool:
|
|
30
|
+
"""
|
|
31
|
+
Run conscious context ingestion once at program startup
|
|
32
|
+
|
|
33
|
+
Copies all conscious-info labeled memories from long-term memory
|
|
34
|
+
directly to short-term memory as permanent context
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
db_manager: Database manager instance
|
|
38
|
+
namespace: Memory namespace
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
True if memories were copied, False otherwise
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
# Get all conscious-info labeled memories
|
|
45
|
+
conscious_memories = await self._get_conscious_memories(
|
|
46
|
+
db_manager, namespace
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if not conscious_memories:
|
|
50
|
+
logger.info("ConsciouscAgent: No conscious-info memories found")
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
# Copy each conscious-info memory directly to short-term memory
|
|
54
|
+
copied_count = 0
|
|
55
|
+
for memory_row in conscious_memories:
|
|
56
|
+
success = await self._copy_memory_to_short_term(
|
|
57
|
+
db_manager, namespace, memory_row
|
|
58
|
+
)
|
|
59
|
+
if success:
|
|
60
|
+
copied_count += 1
|
|
61
|
+
|
|
62
|
+
# Mark memories as processed
|
|
63
|
+
memory_ids = [
|
|
64
|
+
row[0] for row in conscious_memories
|
|
65
|
+
] # memory_id is first column
|
|
66
|
+
await self._mark_memories_processed(db_manager, memory_ids, namespace)
|
|
67
|
+
|
|
68
|
+
self.context_initialized = True
|
|
69
|
+
logger.info(
|
|
70
|
+
f"ConsciouscAgent: Copied {copied_count} conscious-info memories to short-term memory"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return copied_count > 0
|
|
74
|
+
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.error(f"ConsciouscAgent: Conscious ingest failed: {e}")
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
async def initialize_existing_conscious_memories(
|
|
80
|
+
self, db_manager, namespace: str = "default"
|
|
81
|
+
) -> bool:
|
|
82
|
+
"""
|
|
83
|
+
Initialize by copying ALL existing conscious-info memories to short-term memory
|
|
84
|
+
This is called when both auto_ingest=True and conscious_ingest=True
|
|
85
|
+
to ensure essential conscious information is immediately available
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
db_manager: Database manager instance
|
|
89
|
+
namespace: Memory namespace
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
True if memories were processed, False otherwise
|
|
93
|
+
"""
|
|
94
|
+
try:
|
|
95
|
+
from sqlalchemy import text
|
|
96
|
+
|
|
97
|
+
with db_manager._get_connection() as connection:
|
|
98
|
+
# Get ALL conscious-info labeled memories from long-term memory
|
|
99
|
+
cursor = connection.execute(
|
|
100
|
+
text(
|
|
101
|
+
"""SELECT memory_id, processed_data, summary, searchable_content,
|
|
102
|
+
importance_score, created_at
|
|
103
|
+
FROM long_term_memory
|
|
104
|
+
WHERE namespace = :namespace AND classification = 'conscious-info'
|
|
105
|
+
ORDER BY importance_score DESC, created_at DESC"""
|
|
106
|
+
),
|
|
107
|
+
{"namespace": namespace},
|
|
108
|
+
)
|
|
109
|
+
existing_conscious_memories = cursor.fetchall()
|
|
110
|
+
|
|
111
|
+
if not existing_conscious_memories:
|
|
112
|
+
logger.debug(
|
|
113
|
+
"ConsciouscAgent: No existing conscious-info memories found for initialization"
|
|
114
|
+
)
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
copied_count = 0
|
|
118
|
+
for memory_row in existing_conscious_memories:
|
|
119
|
+
success = await self._copy_memory_to_short_term(
|
|
120
|
+
db_manager, namespace, memory_row
|
|
121
|
+
)
|
|
122
|
+
if success:
|
|
123
|
+
copied_count += 1
|
|
124
|
+
|
|
125
|
+
if copied_count > 0:
|
|
126
|
+
logger.info(
|
|
127
|
+
f"ConsciouscAgent: Initialized {copied_count} existing conscious-info memories to short-term memory"
|
|
128
|
+
)
|
|
129
|
+
return True
|
|
130
|
+
else:
|
|
131
|
+
logger.debug(
|
|
132
|
+
"ConsciouscAgent: No new conscious memories to initialize (all were duplicates)"
|
|
133
|
+
)
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(
|
|
138
|
+
f"ConsciouscAgent: Failed to initialize existing conscious memories: {e}"
|
|
139
|
+
)
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
async def check_for_context_updates(
|
|
143
|
+
self, db_manager, namespace: str = "default"
|
|
144
|
+
) -> bool:
|
|
145
|
+
"""
|
|
146
|
+
Check for new conscious-info memories and copy them to short-term memory
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
db_manager: Database manager instance
|
|
150
|
+
namespace: Memory namespace
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
True if new memories were copied, False otherwise
|
|
154
|
+
"""
|
|
155
|
+
try:
|
|
156
|
+
# Get unprocessed conscious memories
|
|
157
|
+
new_memories = await self._get_unprocessed_conscious_memories(
|
|
158
|
+
db_manager, namespace
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
if not new_memories:
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
# Copy each new memory directly to short-term memory
|
|
165
|
+
copied_count = 0
|
|
166
|
+
for memory_row in new_memories:
|
|
167
|
+
success = await self._copy_memory_to_short_term(
|
|
168
|
+
db_manager, namespace, memory_row
|
|
169
|
+
)
|
|
170
|
+
if success:
|
|
171
|
+
copied_count += 1
|
|
172
|
+
|
|
173
|
+
# Mark new memories as processed
|
|
174
|
+
memory_ids = [row[0] for row in new_memories] # memory_id is first column
|
|
175
|
+
await self._mark_memories_processed(db_manager, memory_ids, namespace)
|
|
176
|
+
|
|
177
|
+
logger.info(
|
|
178
|
+
f"ConsciouscAgent: Copied {copied_count} new conscious-info memories to short-term memory"
|
|
179
|
+
)
|
|
180
|
+
return copied_count > 0
|
|
181
|
+
|
|
182
|
+
except Exception as e:
|
|
183
|
+
logger.error(f"ConsciouscAgent: Context update failed: {e}")
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
async def _get_conscious_memories(self, db_manager, namespace: str) -> List[tuple]:
|
|
187
|
+
"""Get all conscious-info labeled memories from long-term memory"""
|
|
188
|
+
try:
|
|
189
|
+
from sqlalchemy import text
|
|
190
|
+
|
|
191
|
+
with db_manager._get_connection() as connection:
|
|
192
|
+
cursor = connection.execute(
|
|
193
|
+
text(
|
|
194
|
+
"""SELECT memory_id, processed_data, summary, searchable_content,
|
|
195
|
+
importance_score, created_at
|
|
196
|
+
FROM long_term_memory
|
|
197
|
+
WHERE namespace = :namespace AND classification = 'conscious-info'
|
|
198
|
+
ORDER BY importance_score DESC, created_at DESC"""
|
|
199
|
+
),
|
|
200
|
+
{"namespace": namespace},
|
|
201
|
+
)
|
|
202
|
+
return cursor.fetchall()
|
|
203
|
+
|
|
204
|
+
except Exception as e:
|
|
205
|
+
logger.error(f"ConsciouscAgent: Failed to get conscious memories: {e}")
|
|
206
|
+
return []
|
|
207
|
+
|
|
208
|
+
async def _get_unprocessed_conscious_memories(
|
|
209
|
+
self, db_manager, namespace: str
|
|
210
|
+
) -> List[tuple]:
|
|
211
|
+
"""Get unprocessed conscious-info labeled memories from long-term memory"""
|
|
212
|
+
try:
|
|
213
|
+
from sqlalchemy import text
|
|
214
|
+
|
|
215
|
+
with db_manager._get_connection() as connection:
|
|
216
|
+
cursor = connection.execute(
|
|
217
|
+
text(
|
|
218
|
+
"""SELECT memory_id, processed_data, summary, searchable_content,
|
|
219
|
+
importance_score, created_at
|
|
220
|
+
FROM long_term_memory
|
|
221
|
+
WHERE namespace = :namespace AND classification = 'conscious-info'
|
|
222
|
+
AND conscious_processed = :conscious_processed
|
|
223
|
+
ORDER BY importance_score DESC, created_at DESC"""
|
|
224
|
+
),
|
|
225
|
+
{"namespace": namespace, "conscious_processed": False},
|
|
226
|
+
)
|
|
227
|
+
return cursor.fetchall()
|
|
228
|
+
|
|
229
|
+
except Exception as e:
|
|
230
|
+
logger.error(f"ConsciouscAgent: Failed to get unprocessed memories: {e}")
|
|
231
|
+
return []
|
|
232
|
+
|
|
233
|
+
async def _copy_memory_to_short_term(
|
|
234
|
+
self, db_manager, namespace: str, memory_row: tuple
|
|
235
|
+
) -> bool:
|
|
236
|
+
"""Copy a conscious memory directly to short-term memory with duplicate filtering"""
|
|
237
|
+
try:
|
|
238
|
+
(
|
|
239
|
+
memory_id,
|
|
240
|
+
processed_data,
|
|
241
|
+
summary,
|
|
242
|
+
searchable_content,
|
|
243
|
+
importance_score,
|
|
244
|
+
_,
|
|
245
|
+
) = memory_row
|
|
246
|
+
|
|
247
|
+
from sqlalchemy import text
|
|
248
|
+
|
|
249
|
+
with db_manager._get_connection() as connection:
|
|
250
|
+
# Check if similar content already exists in short-term memory
|
|
251
|
+
existing_check = connection.execute(
|
|
252
|
+
text(
|
|
253
|
+
"""SELECT COUNT(*) FROM short_term_memory
|
|
254
|
+
WHERE namespace = :namespace
|
|
255
|
+
AND category_primary = 'conscious_context'
|
|
256
|
+
AND (searchable_content = :searchable_content
|
|
257
|
+
OR summary = :summary)"""
|
|
258
|
+
),
|
|
259
|
+
{
|
|
260
|
+
"namespace": namespace,
|
|
261
|
+
"searchable_content": searchable_content,
|
|
262
|
+
"summary": summary,
|
|
263
|
+
},
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
existing_count = existing_check.scalar()
|
|
267
|
+
if existing_count > 0:
|
|
268
|
+
logger.debug(
|
|
269
|
+
f"ConsciouscAgent: Skipping duplicate memory {memory_id} - similar content already exists in short-term memory"
|
|
270
|
+
)
|
|
271
|
+
return False
|
|
272
|
+
|
|
273
|
+
# Create short-term memory ID
|
|
274
|
+
short_term_id = (
|
|
275
|
+
f"conscious_{memory_id}_{int(datetime.now().timestamp())}"
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# Insert directly into short-term memory with conscious_context category
|
|
279
|
+
connection.execute(
|
|
280
|
+
text(
|
|
281
|
+
"""INSERT INTO short_term_memory (
|
|
282
|
+
memory_id, processed_data, importance_score, category_primary,
|
|
283
|
+
retention_type, namespace, created_at, expires_at,
|
|
284
|
+
searchable_content, summary, is_permanent_context
|
|
285
|
+
) VALUES (:memory_id, :processed_data, :importance_score, :category_primary,
|
|
286
|
+
:retention_type, :namespace, :created_at, :expires_at,
|
|
287
|
+
:searchable_content, :summary, :is_permanent_context)"""
|
|
288
|
+
),
|
|
289
|
+
{
|
|
290
|
+
"memory_id": short_term_id,
|
|
291
|
+
"processed_data": (
|
|
292
|
+
json.dumps(processed_data)
|
|
293
|
+
if isinstance(processed_data, dict)
|
|
294
|
+
else processed_data
|
|
295
|
+
),
|
|
296
|
+
"importance_score": importance_score,
|
|
297
|
+
"category_primary": "conscious_context", # Use conscious_context category
|
|
298
|
+
"retention_type": "permanent",
|
|
299
|
+
"namespace": namespace,
|
|
300
|
+
"created_at": datetime.now().isoformat(),
|
|
301
|
+
"expires_at": None, # No expiration (permanent)
|
|
302
|
+
"searchable_content": searchable_content, # Copy exact searchable_content
|
|
303
|
+
"summary": summary, # Copy exact summary
|
|
304
|
+
"is_permanent_context": True, # is_permanent_context = True
|
|
305
|
+
},
|
|
306
|
+
)
|
|
307
|
+
connection.commit()
|
|
308
|
+
|
|
309
|
+
logger.debug(
|
|
310
|
+
f"ConsciouscAgent: Copied memory {memory_id} to short-term as {short_term_id}"
|
|
311
|
+
)
|
|
312
|
+
return True
|
|
313
|
+
|
|
314
|
+
except Exception as e:
|
|
315
|
+
logger.error(
|
|
316
|
+
f"ConsciouscAgent: Failed to copy memory {memory_row[0]} to short-term: {e}"
|
|
317
|
+
)
|
|
318
|
+
return False
|
|
319
|
+
|
|
320
|
+
async def _mark_memories_processed(
|
|
321
|
+
self, db_manager, memory_ids: List[str], namespace: str
|
|
322
|
+
):
|
|
323
|
+
"""Mark memories as processed for conscious context"""
|
|
324
|
+
try:
|
|
325
|
+
from sqlalchemy import text
|
|
326
|
+
|
|
327
|
+
with db_manager._get_connection() as connection:
|
|
328
|
+
for memory_id in memory_ids:
|
|
329
|
+
connection.execute(
|
|
330
|
+
text(
|
|
331
|
+
"""UPDATE long_term_memory
|
|
332
|
+
SET conscious_processed = :conscious_processed
|
|
333
|
+
WHERE memory_id = :memory_id AND namespace = :namespace"""
|
|
334
|
+
),
|
|
335
|
+
{
|
|
336
|
+
"memory_id": memory_id,
|
|
337
|
+
"namespace": namespace,
|
|
338
|
+
"conscious_processed": True,
|
|
339
|
+
},
|
|
340
|
+
)
|
|
341
|
+
connection.commit()
|
|
342
|
+
|
|
343
|
+
except Exception as e:
|
|
344
|
+
logger.error(f"ConsciouscAgent: Failed to mark memories processed: {e}")
|