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.

Files changed (82) hide show
  1. {memorisdk-1.0.2 → memorisdk-2.0.0}/PKG-INFO +44 -17
  2. {memorisdk-1.0.2 → memorisdk-2.0.0}/README.md +18 -14
  3. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/__init__.py +24 -8
  4. memorisdk-2.0.0/memori/agents/conscious_agent.py +344 -0
  5. memorisdk-2.0.0/memori/agents/memory_agent.py +585 -0
  6. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/agents/retrieval_agent.py +416 -60
  7. memorisdk-2.0.0/memori/config/memory_manager.py +323 -0
  8. memorisdk-2.0.0/memori/core/conversation.py +393 -0
  9. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/core/database.py +386 -371
  10. memorisdk-2.0.0/memori/core/memory.py +2491 -0
  11. memorisdk-2.0.0/memori/core/providers.py +217 -0
  12. memorisdk-2.0.0/memori/database/adapters/__init__.py +10 -0
  13. memorisdk-2.0.0/memori/database/adapters/mysql_adapter.py +331 -0
  14. memorisdk-2.0.0/memori/database/adapters/postgresql_adapter.py +291 -0
  15. memorisdk-2.0.0/memori/database/adapters/sqlite_adapter.py +229 -0
  16. memorisdk-2.0.0/memori/database/auto_creator.py +320 -0
  17. memorisdk-2.0.0/memori/database/connection_utils.py +207 -0
  18. memorisdk-2.0.0/memori/database/connectors/base_connector.py +283 -0
  19. memorisdk-2.0.0/memori/database/connectors/mysql_connector.py +381 -0
  20. memorisdk-2.0.0/memori/database/connectors/postgres_connector.py +431 -0
  21. memorisdk-2.0.0/memori/database/connectors/sqlite_connector.py +323 -0
  22. memorisdk-2.0.0/memori/database/models.py +400 -0
  23. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/base_queries.py +1 -1
  24. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/memory_queries.py +91 -2
  25. memorisdk-2.0.0/memori/database/query_translator.py +222 -0
  26. memorisdk-2.0.0/memori/database/schema_generators/__init__.py +7 -0
  27. memorisdk-2.0.0/memori/database/schema_generators/mysql_schema_generator.py +215 -0
  28. memorisdk-2.0.0/memori/database/search/__init__.py +8 -0
  29. memorisdk-2.0.0/memori/database/search/mysql_search_adapter.py +255 -0
  30. memorisdk-2.0.0/memori/database/search/sqlite_search_adapter.py +180 -0
  31. memorisdk-2.0.0/memori/database/search_service.py +548 -0
  32. memorisdk-2.0.0/memori/database/sqlalchemy_manager.py +839 -0
  33. memorisdk-2.0.0/memori/integrations/__init__.py +93 -0
  34. memorisdk-2.0.0/memori/integrations/litellm_integration.py +345 -0
  35. memorisdk-2.0.0/memori/integrations/openai_integration.py +539 -0
  36. memorisdk-2.0.0/memori/utils/input_validator.py +395 -0
  37. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/pydantic_models.py +138 -36
  38. memorisdk-2.0.0/memori/utils/query_builder.py +530 -0
  39. memorisdk-2.0.0/memori/utils/security_audit.py +594 -0
  40. memorisdk-2.0.0/memori/utils/security_integration.py +339 -0
  41. memorisdk-2.0.0/memori/utils/transaction_manager.py +547 -0
  42. {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/PKG-INFO +44 -17
  43. {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/SOURCES.txt +24 -1
  44. {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/requires.txt +28 -1
  45. {memorisdk-1.0.2 → memorisdk-2.0.0}/pyproject.toml +42 -5
  46. memorisdk-1.0.2/memori/agents/conscious_agent.py +0 -506
  47. memorisdk-1.0.2/memori/agents/memory_agent.py +0 -322
  48. memorisdk-1.0.2/memori/core/memory.py +0 -1384
  49. memorisdk-1.0.2/memori/database/connectors/mysql_connector.py +0 -159
  50. memorisdk-1.0.2/memori/database/connectors/postgres_connector.py +0 -158
  51. memorisdk-1.0.2/memori/database/connectors/sqlite_connector.py +0 -148
  52. memorisdk-1.0.2/memori/integrations/__init__.py +0 -68
  53. memorisdk-1.0.2/memori/integrations/litellm_integration.py +0 -11
  54. memorisdk-1.0.2/memori/integrations/openai_integration.py +0 -273
  55. memorisdk-1.0.2/memorisdk.egg-info/entry_points.txt +0 -2
  56. {memorisdk-1.0.2 → memorisdk-2.0.0}/LICENSE +0 -0
  57. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/agents/__init__.py +0 -0
  58. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/__init__.py +0 -0
  59. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/manager.py +0 -0
  60. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/config/settings.py +0 -0
  61. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/core/__init__.py +0 -0
  62. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/__init__.py +0 -0
  63. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/connectors/__init__.py +0 -0
  64. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/__init__.py +0 -0
  65. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/chat_queries.py +0 -0
  66. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/queries/entity_queries.py +0 -0
  67. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/__init__.py +0 -0
  68. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/basic_template.py +0 -0
  69. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/database/templates/schemas/__init__.py +0 -0
  70. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/integrations/anthropic_integration.py +0 -0
  71. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/scripts/llm_text.py +0 -0
  72. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/tools/__init__.py +0 -0
  73. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/tools/memory_tool.py +0 -0
  74. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/__init__.py +0 -0
  75. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/exceptions.py +0 -0
  76. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/helpers.py +0 -0
  77. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/logging.py +0 -0
  78. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/schemas.py +0 -0
  79. {memorisdk-1.0.2 → memorisdk-2.0.0}/memori/utils/validators.py +0 -0
  80. {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/dependency_links.txt +0 -0
  81. {memorisdk-1.0.2 → memorisdk-2.0.0}/memorisdk.egg-info/top_level.txt +0 -0
  82. {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: 1.0.2
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.github.io/memori
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: click>=8.0.0
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
  [![GibsonAI](https://github.com/user-attachments/assets/878e341b-5a93-4489-a398-abeca91b6b11)](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.github.io/memori/">Learn more</a>
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 LiteLLM
147
+ ### Example with OpenAI
125
148
 
126
- 1. Install LiteLLM:
149
+ 1. Install OpenAI:
127
150
 
128
151
  ```bash
129
- pip install litellm
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 litellm import completion
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 = completion(
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 = completion(
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 openai
353
- client = openai.OpenAI()
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
- | 🚀 [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 |
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.github.io/memori/">Learn more</a>
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 LiteLLM
52
+ ### Example with OpenAI
53
53
 
54
- 1. Install LiteLLM:
54
+ 1. Install OpenAI:
55
55
 
56
56
  ```bash
57
- pip install litellm
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 litellm import completion
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 = completion(
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 = completion(
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 openai
281
- client = openai.OpenAI()
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
- | 🚀 [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 |
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__ = "1.0.0"
8
+ __version__ = "2.0.0"
9
9
  __author__ = "Harshal More"
10
10
  __email__ = "harshalmore2468@gmail.com"
11
11
 
12
- # Memory agents
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
- __all__ = [
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}")