memorygraphMCP 0.11.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memorygraph/__init__.py +50 -0
- memorygraph/__main__.py +12 -0
- memorygraph/advanced_tools.py +509 -0
- memorygraph/analytics/__init__.py +46 -0
- memorygraph/analytics/advanced_queries.py +727 -0
- memorygraph/backends/__init__.py +21 -0
- memorygraph/backends/base.py +179 -0
- memorygraph/backends/cloud.py +75 -0
- memorygraph/backends/cloud_backend.py +858 -0
- memorygraph/backends/factory.py +577 -0
- memorygraph/backends/falkordb_backend.py +749 -0
- memorygraph/backends/falkordblite_backend.py +746 -0
- memorygraph/backends/ladybugdb_backend.py +242 -0
- memorygraph/backends/memgraph_backend.py +327 -0
- memorygraph/backends/neo4j_backend.py +298 -0
- memorygraph/backends/sqlite_fallback.py +463 -0
- memorygraph/backends/turso.py +448 -0
- memorygraph/cli.py +743 -0
- memorygraph/cloud_database.py +297 -0
- memorygraph/config.py +295 -0
- memorygraph/database.py +933 -0
- memorygraph/graph_analytics.py +631 -0
- memorygraph/integration/__init__.py +69 -0
- memorygraph/integration/context_capture.py +426 -0
- memorygraph/integration/project_analysis.py +583 -0
- memorygraph/integration/workflow_tracking.py +492 -0
- memorygraph/intelligence/__init__.py +59 -0
- memorygraph/intelligence/context_retrieval.py +447 -0
- memorygraph/intelligence/entity_extraction.py +386 -0
- memorygraph/intelligence/pattern_recognition.py +420 -0
- memorygraph/intelligence/temporal.py +374 -0
- memorygraph/migration/__init__.py +27 -0
- memorygraph/migration/manager.py +579 -0
- memorygraph/migration/models.py +142 -0
- memorygraph/migration/scripts/__init__.py +17 -0
- memorygraph/migration/scripts/bitemporal_migration.py +595 -0
- memorygraph/migration/scripts/multitenancy_migration.py +452 -0
- memorygraph/migration_tools_module.py +146 -0
- memorygraph/models.py +684 -0
- memorygraph/proactive/__init__.py +46 -0
- memorygraph/proactive/outcome_learning.py +444 -0
- memorygraph/proactive/predictive.py +410 -0
- memorygraph/proactive/session_briefing.py +399 -0
- memorygraph/relationships.py +668 -0
- memorygraph/server.py +883 -0
- memorygraph/sqlite_database.py +1876 -0
- memorygraph/tools/__init__.py +59 -0
- memorygraph/tools/activity_tools.py +262 -0
- memorygraph/tools/memory_tools.py +315 -0
- memorygraph/tools/migration_tools.py +181 -0
- memorygraph/tools/relationship_tools.py +147 -0
- memorygraph/tools/search_tools.py +406 -0
- memorygraph/tools/temporal_tools.py +339 -0
- memorygraph/utils/__init__.py +10 -0
- memorygraph/utils/context_extractor.py +429 -0
- memorygraph/utils/error_handling.py +151 -0
- memorygraph/utils/export_import.py +425 -0
- memorygraph/utils/graph_algorithms.py +200 -0
- memorygraph/utils/pagination.py +149 -0
- memorygraph/utils/project_detection.py +133 -0
- memorygraphmcp-0.11.7.dist-info/METADATA +970 -0
- memorygraphmcp-0.11.7.dist-info/RECORD +65 -0
- memorygraphmcp-0.11.7.dist-info/WHEEL +4 -0
- memorygraphmcp-0.11.7.dist-info/entry_points.txt +2 -0
- memorygraphmcp-0.11.7.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cloud-specific database implementation for MemoryGraph.
|
|
3
|
+
|
|
4
|
+
This module provides a CloudMemoryDatabase class that wraps the CloudBackend
|
|
5
|
+
to provide the same interface as MemoryDatabase for tool handlers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import uuid
|
|
10
|
+
from typing import Dict, List, Optional, Any, Tuple
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
|
|
13
|
+
from .models import (
|
|
14
|
+
Memory, MemoryType, Relationship, RelationshipType,
|
|
15
|
+
RelationshipProperties, SearchQuery, MemoryContext,
|
|
16
|
+
MemoryError, MemoryNotFoundError, RelationshipError,
|
|
17
|
+
ValidationError, DatabaseConnectionError, SchemaError, PaginatedResult
|
|
18
|
+
)
|
|
19
|
+
from .backends.cloud_backend import CloudBackend
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CloudMemoryDatabase:
|
|
25
|
+
"""Cloud-specific implementation of memory database operations.
|
|
26
|
+
|
|
27
|
+
This class wraps CloudBackend to provide the same interface expected by
|
|
28
|
+
the MCP tool handlers, delegating to the CloudBackend's REST API methods.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, backend: CloudBackend) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Initialize with a Cloud backend connection.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
backend: CloudBackend instance
|
|
37
|
+
"""
|
|
38
|
+
self.backend = backend
|
|
39
|
+
|
|
40
|
+
async def close(self) -> None:
|
|
41
|
+
"""Close the backend connection."""
|
|
42
|
+
if self.backend:
|
|
43
|
+
await self.backend.disconnect()
|
|
44
|
+
|
|
45
|
+
async def initialize_schema(self) -> None:
|
|
46
|
+
"""
|
|
47
|
+
Initialize schema (no-op for cloud backend).
|
|
48
|
+
|
|
49
|
+
Schema is managed by the cloud service.
|
|
50
|
+
"""
|
|
51
|
+
logger.info("Schema initialization skipped - managed by cloud service")
|
|
52
|
+
await self.backend.initialize_schema()
|
|
53
|
+
|
|
54
|
+
async def store_memory(self, memory: Memory) -> str:
|
|
55
|
+
"""
|
|
56
|
+
Store a memory in the cloud and return its ID.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
memory: Memory object to store
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
ID of the stored memory
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
DatabaseConnectionError: If storage fails
|
|
66
|
+
"""
|
|
67
|
+
if not memory.id:
|
|
68
|
+
memory.id = str(uuid.uuid4())
|
|
69
|
+
|
|
70
|
+
return await self.backend.store_memory(memory)
|
|
71
|
+
|
|
72
|
+
async def get_memory(self, memory_id: str, include_relationships: bool = True) -> Optional[Memory]:
|
|
73
|
+
"""
|
|
74
|
+
Retrieve a memory by ID.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
memory_id: ID of the memory to retrieve
|
|
78
|
+
include_relationships: Whether to include relationships (not currently used by cloud backend)
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Memory object if found, None otherwise
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
DatabaseConnectionError: If query fails
|
|
85
|
+
"""
|
|
86
|
+
return await self.backend.get_memory(memory_id)
|
|
87
|
+
|
|
88
|
+
async def search_memories(self, search_query: SearchQuery) -> List[Memory]:
|
|
89
|
+
"""
|
|
90
|
+
Search for memories based on query parameters.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
search_query: SearchQuery object with filter criteria
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
List of Memory objects matching the search criteria
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
DatabaseConnectionError: If search fails
|
|
100
|
+
"""
|
|
101
|
+
return await self.backend.search_memories(search_query)
|
|
102
|
+
|
|
103
|
+
async def search_memories_paginated(self, search_query: SearchQuery) -> PaginatedResult:
|
|
104
|
+
"""
|
|
105
|
+
Search for memories with pagination support.
|
|
106
|
+
|
|
107
|
+
Note: Cloud API does not return total count, so total_count is set to -1
|
|
108
|
+
to indicate unknown. Use has_more to determine if more pages exist.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
search_query: SearchQuery object with filter criteria, limit, and offset
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
PaginatedResult with memories and pagination metadata.
|
|
115
|
+
total_count is -1 (unknown) since cloud API doesn't provide it.
|
|
116
|
+
|
|
117
|
+
Raises:
|
|
118
|
+
DatabaseConnectionError: If search fails
|
|
119
|
+
"""
|
|
120
|
+
# CloudBackend's search_memories already handles pagination via limit/offset
|
|
121
|
+
memories = await self.backend.search_memories(search_query)
|
|
122
|
+
|
|
123
|
+
# Cloud API doesn't return total count - use -1 to indicate unknown
|
|
124
|
+
# has_more is determined by whether we got a full page of results
|
|
125
|
+
has_more = len(memories) == search_query.limit
|
|
126
|
+
next_offset = (search_query.offset + search_query.limit) if has_more else None
|
|
127
|
+
|
|
128
|
+
return PaginatedResult(
|
|
129
|
+
results=memories,
|
|
130
|
+
total_count=-1, # Unknown - cloud API doesn't provide total count
|
|
131
|
+
limit=search_query.limit,
|
|
132
|
+
offset=search_query.offset,
|
|
133
|
+
has_more=has_more,
|
|
134
|
+
next_offset=next_offset
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
async def update_memory(self, memory: Memory) -> bool:
|
|
138
|
+
"""
|
|
139
|
+
Update an existing memory.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
memory: Memory object with updated fields
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
True if update succeeded, False if memory not found
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
ValidationError: If memory ID is missing
|
|
149
|
+
DatabaseConnectionError: If update fails due to connection issues
|
|
150
|
+
"""
|
|
151
|
+
if not memory.id:
|
|
152
|
+
raise ValidationError("Memory must have an ID to update")
|
|
153
|
+
|
|
154
|
+
# Convert memory to update dict
|
|
155
|
+
updates = {
|
|
156
|
+
"title": memory.title,
|
|
157
|
+
"content": memory.content,
|
|
158
|
+
"summary": memory.summary,
|
|
159
|
+
"tags": memory.tags,
|
|
160
|
+
"importance": memory.importance,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Remove None values
|
|
164
|
+
updates = {k: v for k, v in updates.items() if v is not None}
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
result = await self.backend.update_memory(memory.id, updates)
|
|
168
|
+
return result is not None
|
|
169
|
+
except MemoryNotFoundError:
|
|
170
|
+
# Memory doesn't exist - return False as per interface contract
|
|
171
|
+
return False
|
|
172
|
+
|
|
173
|
+
async def delete_memory(self, memory_id: str) -> bool:
|
|
174
|
+
"""
|
|
175
|
+
Delete a memory and all its relationships.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
memory_id: ID of the memory to delete
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
True if deletion succeeded, False otherwise
|
|
182
|
+
|
|
183
|
+
Raises:
|
|
184
|
+
DatabaseConnectionError: If deletion fails
|
|
185
|
+
"""
|
|
186
|
+
return await self.backend.delete_memory(memory_id)
|
|
187
|
+
|
|
188
|
+
async def create_relationship(
|
|
189
|
+
self,
|
|
190
|
+
from_memory_id: str,
|
|
191
|
+
to_memory_id: str,
|
|
192
|
+
relationship_type: RelationshipType,
|
|
193
|
+
properties: RelationshipProperties = None
|
|
194
|
+
) -> str:
|
|
195
|
+
"""
|
|
196
|
+
Create a relationship between two memories.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
from_memory_id: Source memory ID
|
|
200
|
+
to_memory_id: Target memory ID
|
|
201
|
+
relationship_type: Type of relationship
|
|
202
|
+
properties: Relationship properties (optional)
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
ID of the created relationship
|
|
206
|
+
|
|
207
|
+
Raises:
|
|
208
|
+
RelationshipError: If relationship creation fails
|
|
209
|
+
DatabaseConnectionError: If database operation fails
|
|
210
|
+
"""
|
|
211
|
+
return await self.backend.create_relationship(
|
|
212
|
+
from_memory_id=from_memory_id,
|
|
213
|
+
to_memory_id=to_memory_id,
|
|
214
|
+
relationship_type=relationship_type,
|
|
215
|
+
properties=properties
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
async def get_related_memories(
|
|
219
|
+
self,
|
|
220
|
+
memory_id: str,
|
|
221
|
+
relationship_types: List[RelationshipType] = None,
|
|
222
|
+
max_depth: int = 2
|
|
223
|
+
) -> List[Tuple[Memory, Relationship]]:
|
|
224
|
+
"""
|
|
225
|
+
Get memories related to a specific memory.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
memory_id: ID of the memory to find relations for
|
|
229
|
+
relationship_types: Filter by specific relationship types (optional)
|
|
230
|
+
max_depth: Maximum depth for graph traversal
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
List of tuples containing (Memory, Relationship)
|
|
234
|
+
|
|
235
|
+
Raises:
|
|
236
|
+
DatabaseConnectionError: If query fails
|
|
237
|
+
"""
|
|
238
|
+
return await self.backend.get_related_memories(
|
|
239
|
+
memory_id=memory_id,
|
|
240
|
+
relationship_types=relationship_types,
|
|
241
|
+
max_depth=max_depth
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
async def update_relationship_properties(
|
|
245
|
+
self,
|
|
246
|
+
from_memory_id: str,
|
|
247
|
+
to_memory_id: str,
|
|
248
|
+
relationship_type: RelationshipType,
|
|
249
|
+
properties: RelationshipProperties
|
|
250
|
+
) -> bool:
|
|
251
|
+
"""
|
|
252
|
+
Update properties of an existing relationship.
|
|
253
|
+
|
|
254
|
+
Note: Cloud backend does not yet support updating relationship properties.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
from_memory_id: Source memory ID
|
|
258
|
+
to_memory_id: Target memory ID
|
|
259
|
+
relationship_type: Type of relationship to update
|
|
260
|
+
properties: Updated relationship properties
|
|
261
|
+
|
|
262
|
+
Raises:
|
|
263
|
+
NotImplementedError: Cloud backend does not support this operation
|
|
264
|
+
"""
|
|
265
|
+
raise NotImplementedError(
|
|
266
|
+
"Cloud backend does not yet support updating relationship properties. "
|
|
267
|
+
f"Attempted to update: {from_memory_id} -{relationship_type.value}-> {to_memory_id}"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
async def get_memory_statistics(self) -> Dict[str, Any]:
|
|
271
|
+
"""
|
|
272
|
+
Get database statistics and metrics.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
Dictionary containing various database statistics
|
|
276
|
+
|
|
277
|
+
Raises:
|
|
278
|
+
DatabaseConnectionError: If query fails
|
|
279
|
+
"""
|
|
280
|
+
return await self.backend.get_statistics()
|
|
281
|
+
|
|
282
|
+
async def get_recent_activity(
|
|
283
|
+
self,
|
|
284
|
+
days: int = 7,
|
|
285
|
+
project: Optional[str] = None
|
|
286
|
+
) -> Dict[str, Any]:
|
|
287
|
+
"""
|
|
288
|
+
Get recent memory activity summary.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
days: Number of days to look back
|
|
292
|
+
project: Optional project filter
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
Activity summary dictionary
|
|
296
|
+
"""
|
|
297
|
+
return await self.backend.get_recent_activity(days=days, project=project)
|
memorygraph/config.py
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration management for MemoryGraph.
|
|
3
|
+
|
|
4
|
+
This module centralizes all configuration options and environment variable handling
|
|
5
|
+
for the multi-backend memory server.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import Optional, List
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BackendType(Enum):
|
|
14
|
+
"""Supported backend types."""
|
|
15
|
+
NEO4J = "neo4j"
|
|
16
|
+
MEMGRAPH = "memgraph"
|
|
17
|
+
SQLITE = "sqlite"
|
|
18
|
+
TURSO = "turso"
|
|
19
|
+
CLOUD = "cloud"
|
|
20
|
+
FALKORDB = "falkordb"
|
|
21
|
+
FALKORDBLITE = "falkordblite"
|
|
22
|
+
AUTO = "auto"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Tool profile definitions
|
|
26
|
+
# Core mode: Essential tools for daily use (9 tools)
|
|
27
|
+
# Extended mode: Core + advanced analytics (11 tools)
|
|
28
|
+
TOOL_PROFILES = {
|
|
29
|
+
"core": [
|
|
30
|
+
# Essential memory operations (5 tools)
|
|
31
|
+
"store_memory",
|
|
32
|
+
"get_memory",
|
|
33
|
+
"search_memories",
|
|
34
|
+
"update_memory",
|
|
35
|
+
"delete_memory",
|
|
36
|
+
# Essential relationship operations (2 tools)
|
|
37
|
+
"create_relationship",
|
|
38
|
+
"get_related_memories",
|
|
39
|
+
# Discovery and navigation (2 tools)
|
|
40
|
+
"recall_memories", # Primary search with fuzzy matching
|
|
41
|
+
"get_recent_activity", # Session briefing
|
|
42
|
+
],
|
|
43
|
+
"extended": [
|
|
44
|
+
# All Core tools (9)
|
|
45
|
+
"store_memory",
|
|
46
|
+
"get_memory",
|
|
47
|
+
"search_memories",
|
|
48
|
+
"update_memory",
|
|
49
|
+
"delete_memory",
|
|
50
|
+
"create_relationship",
|
|
51
|
+
"get_related_memories",
|
|
52
|
+
"recall_memories",
|
|
53
|
+
"get_recent_activity",
|
|
54
|
+
# Advanced analytics (2 additional)
|
|
55
|
+
"get_memory_statistics", # Database stats
|
|
56
|
+
"search_relationships_by_context", # Complex relationship queries
|
|
57
|
+
# Contextual search (1 additional)
|
|
58
|
+
"contextual_search", # Scoped search within related memories
|
|
59
|
+
],
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Config:
|
|
64
|
+
"""
|
|
65
|
+
Configuration class for the memory server.
|
|
66
|
+
|
|
67
|
+
Environment Variables:
|
|
68
|
+
MEMORY_BACKEND: Backend type (neo4j|memgraph|sqlite|turso|cloud|falkordb|falkordblite|auto) [default: sqlite]
|
|
69
|
+
|
|
70
|
+
Neo4j Configuration:
|
|
71
|
+
MEMORY_NEO4J_URI or NEO4J_URI: Connection URI [default: bolt://localhost:7687]
|
|
72
|
+
MEMORY_NEO4J_USER or NEO4J_USER: Username [default: neo4j]
|
|
73
|
+
MEMORY_NEO4J_PASSWORD or NEO4J_PASSWORD: Password [required for Neo4j]
|
|
74
|
+
|
|
75
|
+
Memgraph Configuration:
|
|
76
|
+
MEMORY_MEMGRAPH_URI: Connection URI [default: bolt://localhost:7687]
|
|
77
|
+
MEMORY_MEMGRAPH_USER: Username [default: ""]
|
|
78
|
+
MEMORY_MEMGRAPH_PASSWORD: Password [default: ""]
|
|
79
|
+
|
|
80
|
+
SQLite Configuration:
|
|
81
|
+
MEMORY_SQLITE_PATH: Database file path [default: ~/.memorygraph/memory.db]
|
|
82
|
+
|
|
83
|
+
Turso Configuration:
|
|
84
|
+
MEMORY_TURSO_PATH: Local database file path [default: ~/.memorygraph/memory.db]
|
|
85
|
+
TURSO_DATABASE_URL: Turso database URL (e.g., libsql://your-db.turso.io)
|
|
86
|
+
TURSO_AUTH_TOKEN: Turso authentication token
|
|
87
|
+
|
|
88
|
+
Cloud Configuration:
|
|
89
|
+
MEMORYGRAPH_API_KEY: API key for MemoryGraph Cloud (required for cloud backend)
|
|
90
|
+
MEMORYGRAPH_API_URL: Cloud API base URL [default: https://graph-api.memorygraph.dev]
|
|
91
|
+
MEMORYGRAPH_TIMEOUT: Request timeout in seconds [default: 30]
|
|
92
|
+
|
|
93
|
+
Tool Profile Configuration:
|
|
94
|
+
MEMORY_TOOL_PROFILE: Tool profile (core|extended) [default: core]
|
|
95
|
+
|
|
96
|
+
Logging Configuration:
|
|
97
|
+
MEMORY_LOG_LEVEL: Log level (DEBUG|INFO|WARNING|ERROR) [default: INFO]
|
|
98
|
+
|
|
99
|
+
Multi-Tenancy Configuration (Phase 1):
|
|
100
|
+
MEMORY_MULTI_TENANT_MODE: Enable multi-tenant features [default: false]
|
|
101
|
+
MEMORY_DEFAULT_TENANT: Default tenant ID for single-tenant mode [default: default]
|
|
102
|
+
MEMORY_REQUIRE_AUTH: Require authentication for operations [default: false]
|
|
103
|
+
|
|
104
|
+
Authentication Configuration (Future - Phase 3):
|
|
105
|
+
MEMORY_AUTH_PROVIDER: Authentication provider (none|jwt|oauth2) [default: none]
|
|
106
|
+
MEMORY_JWT_SECRET: JWT signing secret (required if auth_provider=jwt)
|
|
107
|
+
MEMORY_JWT_ALGORITHM: JWT algorithm [default: HS256]
|
|
108
|
+
|
|
109
|
+
Audit Configuration (Future - Phase 4):
|
|
110
|
+
MEMORY_ENABLE_AUDIT_LOG: Log all access events [default: false]
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
# Backend Selection
|
|
114
|
+
BACKEND: str = os.getenv("MEMORY_BACKEND", "sqlite")
|
|
115
|
+
|
|
116
|
+
# Neo4j Configuration
|
|
117
|
+
NEO4J_URI: str = os.getenv("MEMORY_NEO4J_URI") or os.getenv("NEO4J_URI", "bolt://localhost:7687")
|
|
118
|
+
NEO4J_USER: str = os.getenv("MEMORY_NEO4J_USER") or os.getenv("NEO4J_USER", "neo4j")
|
|
119
|
+
NEO4J_PASSWORD: Optional[str] = os.getenv("MEMORY_NEO4J_PASSWORD") or os.getenv("NEO4J_PASSWORD")
|
|
120
|
+
NEO4J_DATABASE: str = os.getenv("MEMORY_NEO4J_DATABASE", "neo4j")
|
|
121
|
+
|
|
122
|
+
# Memgraph Configuration
|
|
123
|
+
MEMGRAPH_URI: str = os.getenv("MEMORY_MEMGRAPH_URI", "bolt://localhost:7687")
|
|
124
|
+
MEMGRAPH_USER: str = os.getenv("MEMORY_MEMGRAPH_USER", "")
|
|
125
|
+
MEMGRAPH_PASSWORD: str = os.getenv("MEMORY_MEMGRAPH_PASSWORD", "")
|
|
126
|
+
|
|
127
|
+
# SQLite Configuration
|
|
128
|
+
SQLITE_PATH: str = os.getenv("MEMORY_SQLITE_PATH", os.path.expanduser("~/.memorygraph/memory.db"))
|
|
129
|
+
|
|
130
|
+
# Turso Configuration
|
|
131
|
+
TURSO_PATH: str = os.getenv("MEMORY_TURSO_PATH", os.path.expanduser("~/.memorygraph/memory.db"))
|
|
132
|
+
TURSO_DATABASE_URL: Optional[str] = os.getenv("TURSO_DATABASE_URL")
|
|
133
|
+
TURSO_AUTH_TOKEN: Optional[str] = os.getenv("TURSO_AUTH_TOKEN")
|
|
134
|
+
|
|
135
|
+
# Cloud Configuration
|
|
136
|
+
MEMORYGRAPH_API_KEY: Optional[str] = os.getenv("MEMORYGRAPH_API_KEY")
|
|
137
|
+
MEMORYGRAPH_API_URL: str = os.getenv("MEMORYGRAPH_API_URL", "https://graph-api.memorygraph.dev")
|
|
138
|
+
MEMORYGRAPH_TIMEOUT: int = int(os.getenv("MEMORYGRAPH_TIMEOUT", "30"))
|
|
139
|
+
|
|
140
|
+
# Tool Profile Configuration
|
|
141
|
+
TOOL_PROFILE: str = os.getenv("MEMORY_TOOL_PROFILE", "core")
|
|
142
|
+
|
|
143
|
+
# Logging Configuration
|
|
144
|
+
LOG_LEVEL: str = os.getenv("MEMORY_LOG_LEVEL", "INFO")
|
|
145
|
+
|
|
146
|
+
# Feature Flags
|
|
147
|
+
AUTO_EXTRACT_ENTITIES: bool = os.getenv("MEMORY_AUTO_EXTRACT_ENTITIES", "true").lower() == "true"
|
|
148
|
+
SESSION_BRIEFING: bool = os.getenv("MEMORY_SESSION_BRIEFING", "true").lower() == "true"
|
|
149
|
+
BRIEFING_VERBOSITY: str = os.getenv("MEMORY_BRIEFING_VERBOSITY", "standard")
|
|
150
|
+
BRIEFING_RECENCY_DAYS: int = int(os.getenv("MEMORY_BRIEFING_RECENCY_DAYS", "7"))
|
|
151
|
+
|
|
152
|
+
# Relationship Configuration
|
|
153
|
+
ALLOW_RELATIONSHIP_CYCLES: bool = os.getenv("MEMORY_ALLOW_CYCLES", "false").lower() == "true"
|
|
154
|
+
|
|
155
|
+
# Multi-Tenancy Configuration (Phase 1)
|
|
156
|
+
MULTI_TENANT_MODE: bool = os.getenv("MEMORY_MULTI_TENANT_MODE", "false").lower() == "true"
|
|
157
|
+
DEFAULT_TENANT: str = os.getenv("MEMORY_DEFAULT_TENANT", "default")
|
|
158
|
+
REQUIRE_AUTH: bool = os.getenv("MEMORY_REQUIRE_AUTH", "false").lower() == "true"
|
|
159
|
+
|
|
160
|
+
# Authentication Configuration (Future Phase 3)
|
|
161
|
+
AUTH_PROVIDER: str = os.getenv("MEMORY_AUTH_PROVIDER", "none")
|
|
162
|
+
JWT_SECRET: Optional[str] = os.getenv("MEMORY_JWT_SECRET")
|
|
163
|
+
JWT_ALGORITHM: str = os.getenv("MEMORY_JWT_ALGORITHM", "HS256")
|
|
164
|
+
|
|
165
|
+
# Audit Configuration (Future Phase 4)
|
|
166
|
+
ENABLE_AUDIT_LOG: bool = os.getenv("MEMORY_ENABLE_AUDIT_LOG", "false").lower() == "true"
|
|
167
|
+
|
|
168
|
+
@classmethod
|
|
169
|
+
def get_backend_type(cls) -> BackendType:
|
|
170
|
+
"""
|
|
171
|
+
Get the configured backend type.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
BackendType enum value
|
|
175
|
+
"""
|
|
176
|
+
backend_str = cls.BACKEND.lower()
|
|
177
|
+
try:
|
|
178
|
+
return BackendType(backend_str)
|
|
179
|
+
except ValueError:
|
|
180
|
+
return BackendType.AUTO
|
|
181
|
+
|
|
182
|
+
@classmethod
|
|
183
|
+
def is_neo4j_configured(cls) -> bool:
|
|
184
|
+
"""Check if Neo4j backend is properly configured."""
|
|
185
|
+
return bool(cls.NEO4J_PASSWORD)
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def is_memgraph_configured(cls) -> bool:
|
|
189
|
+
"""Check if Memgraph backend is configured."""
|
|
190
|
+
return bool(cls.MEMGRAPH_URI)
|
|
191
|
+
|
|
192
|
+
@classmethod
|
|
193
|
+
def is_multi_tenant_mode(cls) -> bool:
|
|
194
|
+
"""
|
|
195
|
+
Check if multi-tenant mode is enabled.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
True if MEMORY_MULTI_TENANT_MODE=true, False otherwise
|
|
199
|
+
"""
|
|
200
|
+
return cls.MULTI_TENANT_MODE
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def get_default_tenant(cls) -> str:
|
|
204
|
+
"""
|
|
205
|
+
Get default tenant ID for single-tenant mode.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
The default tenant identifier
|
|
209
|
+
"""
|
|
210
|
+
return cls.DEFAULT_TENANT
|
|
211
|
+
|
|
212
|
+
@classmethod
|
|
213
|
+
def get_enabled_tools(cls) -> Optional[List[str]]:
|
|
214
|
+
"""
|
|
215
|
+
Get the list of enabled tools based on the configured profile.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
List of tool names to enable, or None for legacy profiles (defaults to core)
|
|
219
|
+
"""
|
|
220
|
+
profile = cls.TOOL_PROFILE.lower()
|
|
221
|
+
# Map legacy profiles to new ones
|
|
222
|
+
legacy_map = {
|
|
223
|
+
"lite": "core",
|
|
224
|
+
"standard": "extended",
|
|
225
|
+
"full": "extended"
|
|
226
|
+
}
|
|
227
|
+
profile = legacy_map.get(profile, profile)
|
|
228
|
+
return TOOL_PROFILES.get(profile, TOOL_PROFILES["core"])
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
def get_config_summary(cls) -> dict:
|
|
232
|
+
"""
|
|
233
|
+
Get a summary of current configuration (without sensitive data).
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Dictionary with configuration summary
|
|
237
|
+
"""
|
|
238
|
+
return {
|
|
239
|
+
"backend": cls.BACKEND,
|
|
240
|
+
"neo4j": {
|
|
241
|
+
"uri": cls.NEO4J_URI,
|
|
242
|
+
"user": cls.NEO4J_USER,
|
|
243
|
+
"password_configured": bool(cls.NEO4J_PASSWORD),
|
|
244
|
+
"database": cls.NEO4J_DATABASE
|
|
245
|
+
},
|
|
246
|
+
"memgraph": {
|
|
247
|
+
"uri": cls.MEMGRAPH_URI,
|
|
248
|
+
"user": cls.MEMGRAPH_USER,
|
|
249
|
+
"password_configured": bool(cls.MEMGRAPH_PASSWORD)
|
|
250
|
+
},
|
|
251
|
+
"sqlite": {
|
|
252
|
+
"path": cls.SQLITE_PATH
|
|
253
|
+
},
|
|
254
|
+
"turso": {
|
|
255
|
+
"path": cls.TURSO_PATH,
|
|
256
|
+
"database_url": cls.TURSO_DATABASE_URL,
|
|
257
|
+
"auth_token_configured": bool(cls.TURSO_AUTH_TOKEN)
|
|
258
|
+
},
|
|
259
|
+
"cloud": {
|
|
260
|
+
"api_url": cls.MEMORYGRAPH_API_URL,
|
|
261
|
+
"api_key_configured": bool(cls.MEMORYGRAPH_API_KEY),
|
|
262
|
+
"timeout": cls.MEMORYGRAPH_TIMEOUT
|
|
263
|
+
},
|
|
264
|
+
"logging": {
|
|
265
|
+
"level": cls.LOG_LEVEL
|
|
266
|
+
},
|
|
267
|
+
"features": {
|
|
268
|
+
"auto_extract_entities": cls.AUTO_EXTRACT_ENTITIES,
|
|
269
|
+
"session_briefing": cls.SESSION_BRIEFING,
|
|
270
|
+
"briefing_verbosity": cls.BRIEFING_VERBOSITY,
|
|
271
|
+
"briefing_recency_days": cls.BRIEFING_RECENCY_DAYS
|
|
272
|
+
},
|
|
273
|
+
"relationships": {
|
|
274
|
+
"allow_cycles": cls.ALLOW_RELATIONSHIP_CYCLES
|
|
275
|
+
},
|
|
276
|
+
"multi_tenancy": {
|
|
277
|
+
"enabled": cls.MULTI_TENANT_MODE,
|
|
278
|
+
"default_tenant": cls.DEFAULT_TENANT,
|
|
279
|
+
"require_auth": cls.REQUIRE_AUTH,
|
|
280
|
+
"auth_provider": cls.AUTH_PROVIDER,
|
|
281
|
+
"jwt_secret_configured": bool(cls.JWT_SECRET),
|
|
282
|
+
"audit_log_enabled": cls.ENABLE_AUDIT_LOG
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# Convenience function for getting config
|
|
288
|
+
def get_config() -> Config:
|
|
289
|
+
"""
|
|
290
|
+
Get the global configuration instance.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
Config instance
|
|
294
|
+
"""
|
|
295
|
+
return Config
|