genxai-framework 0.1.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.
Files changed (156) hide show
  1. cli/__init__.py +3 -0
  2. cli/commands/__init__.py +6 -0
  3. cli/commands/approval.py +85 -0
  4. cli/commands/audit.py +127 -0
  5. cli/commands/metrics.py +25 -0
  6. cli/commands/tool.py +389 -0
  7. cli/main.py +32 -0
  8. genxai/__init__.py +81 -0
  9. genxai/api/__init__.py +5 -0
  10. genxai/api/app.py +21 -0
  11. genxai/config/__init__.py +5 -0
  12. genxai/config/settings.py +37 -0
  13. genxai/connectors/__init__.py +19 -0
  14. genxai/connectors/base.py +122 -0
  15. genxai/connectors/kafka.py +92 -0
  16. genxai/connectors/postgres_cdc.py +95 -0
  17. genxai/connectors/registry.py +44 -0
  18. genxai/connectors/sqs.py +94 -0
  19. genxai/connectors/webhook.py +73 -0
  20. genxai/core/__init__.py +37 -0
  21. genxai/core/agent/__init__.py +32 -0
  22. genxai/core/agent/base.py +206 -0
  23. genxai/core/agent/config_io.py +59 -0
  24. genxai/core/agent/registry.py +98 -0
  25. genxai/core/agent/runtime.py +970 -0
  26. genxai/core/communication/__init__.py +6 -0
  27. genxai/core/communication/collaboration.py +44 -0
  28. genxai/core/communication/message_bus.py +192 -0
  29. genxai/core/communication/protocols.py +35 -0
  30. genxai/core/execution/__init__.py +22 -0
  31. genxai/core/execution/metadata.py +181 -0
  32. genxai/core/execution/queue.py +201 -0
  33. genxai/core/graph/__init__.py +30 -0
  34. genxai/core/graph/checkpoints.py +77 -0
  35. genxai/core/graph/edges.py +131 -0
  36. genxai/core/graph/engine.py +813 -0
  37. genxai/core/graph/executor.py +516 -0
  38. genxai/core/graph/nodes.py +161 -0
  39. genxai/core/graph/trigger_runner.py +40 -0
  40. genxai/core/memory/__init__.py +19 -0
  41. genxai/core/memory/base.py +72 -0
  42. genxai/core/memory/embedding.py +327 -0
  43. genxai/core/memory/episodic.py +448 -0
  44. genxai/core/memory/long_term.py +467 -0
  45. genxai/core/memory/manager.py +543 -0
  46. genxai/core/memory/persistence.py +297 -0
  47. genxai/core/memory/procedural.py +461 -0
  48. genxai/core/memory/semantic.py +526 -0
  49. genxai/core/memory/shared.py +62 -0
  50. genxai/core/memory/short_term.py +303 -0
  51. genxai/core/memory/vector_store.py +508 -0
  52. genxai/core/memory/working.py +211 -0
  53. genxai/core/state/__init__.py +6 -0
  54. genxai/core/state/manager.py +293 -0
  55. genxai/core/state/schema.py +115 -0
  56. genxai/llm/__init__.py +14 -0
  57. genxai/llm/base.py +150 -0
  58. genxai/llm/factory.py +329 -0
  59. genxai/llm/providers/__init__.py +1 -0
  60. genxai/llm/providers/anthropic.py +249 -0
  61. genxai/llm/providers/cohere.py +274 -0
  62. genxai/llm/providers/google.py +334 -0
  63. genxai/llm/providers/ollama.py +147 -0
  64. genxai/llm/providers/openai.py +257 -0
  65. genxai/llm/routing.py +83 -0
  66. genxai/observability/__init__.py +6 -0
  67. genxai/observability/logging.py +327 -0
  68. genxai/observability/metrics.py +494 -0
  69. genxai/observability/tracing.py +372 -0
  70. genxai/performance/__init__.py +39 -0
  71. genxai/performance/cache.py +256 -0
  72. genxai/performance/pooling.py +289 -0
  73. genxai/security/audit.py +304 -0
  74. genxai/security/auth.py +315 -0
  75. genxai/security/cost_control.py +528 -0
  76. genxai/security/default_policies.py +44 -0
  77. genxai/security/jwt.py +142 -0
  78. genxai/security/oauth.py +226 -0
  79. genxai/security/pii.py +366 -0
  80. genxai/security/policy_engine.py +82 -0
  81. genxai/security/rate_limit.py +341 -0
  82. genxai/security/rbac.py +247 -0
  83. genxai/security/validation.py +218 -0
  84. genxai/tools/__init__.py +21 -0
  85. genxai/tools/base.py +383 -0
  86. genxai/tools/builtin/__init__.py +131 -0
  87. genxai/tools/builtin/communication/__init__.py +15 -0
  88. genxai/tools/builtin/communication/email_sender.py +159 -0
  89. genxai/tools/builtin/communication/notification_manager.py +167 -0
  90. genxai/tools/builtin/communication/slack_notifier.py +118 -0
  91. genxai/tools/builtin/communication/sms_sender.py +118 -0
  92. genxai/tools/builtin/communication/webhook_caller.py +136 -0
  93. genxai/tools/builtin/computation/__init__.py +15 -0
  94. genxai/tools/builtin/computation/calculator.py +101 -0
  95. genxai/tools/builtin/computation/code_executor.py +183 -0
  96. genxai/tools/builtin/computation/data_validator.py +259 -0
  97. genxai/tools/builtin/computation/hash_generator.py +129 -0
  98. genxai/tools/builtin/computation/regex_matcher.py +201 -0
  99. genxai/tools/builtin/data/__init__.py +15 -0
  100. genxai/tools/builtin/data/csv_processor.py +213 -0
  101. genxai/tools/builtin/data/data_transformer.py +299 -0
  102. genxai/tools/builtin/data/json_processor.py +233 -0
  103. genxai/tools/builtin/data/text_analyzer.py +288 -0
  104. genxai/tools/builtin/data/xml_processor.py +175 -0
  105. genxai/tools/builtin/database/__init__.py +15 -0
  106. genxai/tools/builtin/database/database_inspector.py +157 -0
  107. genxai/tools/builtin/database/mongodb_query.py +196 -0
  108. genxai/tools/builtin/database/redis_cache.py +167 -0
  109. genxai/tools/builtin/database/sql_query.py +145 -0
  110. genxai/tools/builtin/database/vector_search.py +163 -0
  111. genxai/tools/builtin/file/__init__.py +17 -0
  112. genxai/tools/builtin/file/directory_scanner.py +214 -0
  113. genxai/tools/builtin/file/file_compressor.py +237 -0
  114. genxai/tools/builtin/file/file_reader.py +102 -0
  115. genxai/tools/builtin/file/file_writer.py +122 -0
  116. genxai/tools/builtin/file/image_processor.py +186 -0
  117. genxai/tools/builtin/file/pdf_parser.py +144 -0
  118. genxai/tools/builtin/test/__init__.py +15 -0
  119. genxai/tools/builtin/test/async_simulator.py +62 -0
  120. genxai/tools/builtin/test/data_transformer.py +99 -0
  121. genxai/tools/builtin/test/error_generator.py +82 -0
  122. genxai/tools/builtin/test/simple_math.py +94 -0
  123. genxai/tools/builtin/test/string_processor.py +72 -0
  124. genxai/tools/builtin/web/__init__.py +15 -0
  125. genxai/tools/builtin/web/api_caller.py +161 -0
  126. genxai/tools/builtin/web/html_parser.py +330 -0
  127. genxai/tools/builtin/web/http_client.py +187 -0
  128. genxai/tools/builtin/web/url_validator.py +162 -0
  129. genxai/tools/builtin/web/web_scraper.py +170 -0
  130. genxai/tools/custom/my_test_tool_2.py +9 -0
  131. genxai/tools/dynamic.py +105 -0
  132. genxai/tools/mcp_server.py +167 -0
  133. genxai/tools/persistence/__init__.py +6 -0
  134. genxai/tools/persistence/models.py +55 -0
  135. genxai/tools/persistence/service.py +322 -0
  136. genxai/tools/registry.py +227 -0
  137. genxai/tools/security/__init__.py +11 -0
  138. genxai/tools/security/limits.py +214 -0
  139. genxai/tools/security/policy.py +20 -0
  140. genxai/tools/security/sandbox.py +248 -0
  141. genxai/tools/templates.py +435 -0
  142. genxai/triggers/__init__.py +19 -0
  143. genxai/triggers/base.py +104 -0
  144. genxai/triggers/file_watcher.py +75 -0
  145. genxai/triggers/queue.py +68 -0
  146. genxai/triggers/registry.py +82 -0
  147. genxai/triggers/schedule.py +66 -0
  148. genxai/triggers/webhook.py +68 -0
  149. genxai/utils/__init__.py +1 -0
  150. genxai/utils/tokens.py +295 -0
  151. genxai_framework-0.1.0.dist-info/METADATA +495 -0
  152. genxai_framework-0.1.0.dist-info/RECORD +156 -0
  153. genxai_framework-0.1.0.dist-info/WHEEL +5 -0
  154. genxai_framework-0.1.0.dist-info/entry_points.txt +2 -0
  155. genxai_framework-0.1.0.dist-info/licenses/LICENSE +21 -0
  156. genxai_framework-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,543 @@
1
+ """Memory system manager coordinating all memory types."""
2
+
3
+ from typing import Any, Dict, List, Optional, Tuple
4
+ import logging
5
+
6
+ from pathlib import Path
7
+ from genxai.core.memory.base import Memory, MemoryType, MemoryConfig
8
+ from genxai.core.memory.short_term import ShortTermMemory
9
+ from genxai.core.memory.long_term import LongTermMemory
10
+ from genxai.core.memory.episodic import EpisodicMemory, Episode
11
+ from genxai.core.memory.semantic import SemanticMemory, Fact
12
+ from genxai.core.memory.procedural import ProceduralMemory, Procedure
13
+ from genxai.core.memory.working import WorkingMemory
14
+ from genxai.core.memory.vector_store import VectorStoreFactory
15
+ from genxai.core.memory.embedding import EmbeddingServiceFactory
16
+ from genxai.core.memory.persistence import MemoryPersistenceConfig
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class MemorySystem:
22
+ """Comprehensive memory management system.
23
+
24
+ Orchestrates all memory types:
25
+ - Short-term: Recent interactions
26
+ - Long-term: Persistent memories with vector search
27
+ - Episodic: Agent experiences and episodes
28
+ - Semantic: Facts and knowledge
29
+ - Procedural: Learned skills and procedures
30
+ - Working: Active processing context
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ agent_id: str,
36
+ config: Optional[MemoryConfig] = None,
37
+ vector_store_backend: Optional[str] = None,
38
+ embedding_provider: Optional[str] = None,
39
+ persistence_enabled: bool = False,
40
+ persistence_path: Optional[Path] = None,
41
+ persistence_backend: str = "json",
42
+ persistence_sqlite_path: Optional[Path] = None,
43
+ ) -> None:
44
+ """Initialize memory system.
45
+
46
+ Args:
47
+ agent_id: ID of the agent this memory belongs to
48
+ config: Memory configuration
49
+ vector_store_backend: Vector store backend ("chromadb", "pinecone")
50
+ embedding_provider: Embedding provider ("openai", "local", "cohere")
51
+ """
52
+ self.agent_id = agent_id
53
+ self.config = config or MemoryConfig()
54
+ self._persistence = MemoryPersistenceConfig(
55
+ base_dir=persistence_path or Path(".genxai/memory"),
56
+ enabled=persistence_enabled,
57
+ backend=persistence_backend,
58
+ sqlite_path=persistence_sqlite_path,
59
+ )
60
+
61
+ # Initialize short-term memory
62
+ self.short_term = ShortTermMemory(capacity=self.config.short_term_capacity)
63
+
64
+ # Initialize working memory
65
+ self.working = WorkingMemory(capacity=self.config.working_capacity)
66
+
67
+ # Initialize long-term memory with vector store
68
+ self.long_term: Optional[LongTermMemory] = None
69
+ self.vector_store = None
70
+ self.embedding_service = None
71
+
72
+ if self.config.long_term_enabled:
73
+ try:
74
+ # Create vector store
75
+ backend = vector_store_backend or self.config.vector_db
76
+ if backend:
77
+ self.vector_store = VectorStoreFactory.create(
78
+ backend=backend,
79
+ )
80
+
81
+ # Create embedding service
82
+ provider = embedding_provider or "openai"
83
+ if provider:
84
+ self.embedding_service = EmbeddingServiceFactory.create(
85
+ provider=provider,
86
+ )
87
+
88
+ # Initialize long-term memory
89
+ self.long_term = LongTermMemory(
90
+ config=self.config,
91
+ vector_store=self.vector_store,
92
+ embedding_service=self.embedding_service,
93
+ persistence=self._persistence,
94
+ )
95
+ logger.info("Long-term memory initialized with vector store")
96
+ except Exception as e:
97
+ logger.warning(f"Failed to initialize long-term memory: {e}")
98
+ self.long_term = LongTermMemory(
99
+ config=self.config,
100
+ persistence=self._persistence,
101
+ )
102
+
103
+ # Initialize episodic memory
104
+ self.episodic: Optional[EpisodicMemory] = None
105
+ if self.config.episodic_enabled:
106
+ self.episodic = EpisodicMemory(persistence=self._persistence)
107
+ logger.info("Episodic memory initialized")
108
+
109
+ # Initialize semantic memory
110
+ self.semantic: Optional[SemanticMemory] = None
111
+ if self.config.semantic_enabled:
112
+ self.semantic = SemanticMemory(persistence=self._persistence)
113
+ logger.info("Semantic memory initialized")
114
+
115
+ # Initialize procedural memory
116
+ self.procedural: Optional[ProceduralMemory] = None
117
+ if self.config.procedural_enabled:
118
+ self.procedural = ProceduralMemory(persistence=self._persistence)
119
+ logger.info("Procedural memory initialized")
120
+
121
+ logger.info(f"Memory system initialized for agent: {agent_id}")
122
+
123
+ # ==================== Short-term Memory ====================
124
+
125
+ async def add_to_short_term(
126
+ self,
127
+ content: Any,
128
+ metadata: Optional[Dict[str, Any]] = None,
129
+ ) -> None:
130
+ """Add content to short-term memory.
131
+
132
+ Args:
133
+ content: Content to store
134
+ metadata: Optional metadata
135
+ """
136
+ await self.short_term.add(content, metadata)
137
+
138
+ async def get_short_term_context(self, max_tokens: int = 4000) -> str:
139
+ """Get context from short-term memory for LLM.
140
+
141
+ Args:
142
+ max_tokens: Maximum tokens to include
143
+
144
+ Returns:
145
+ Formatted context string
146
+ """
147
+ return await self.short_term.get_context(max_tokens)
148
+
149
+ async def clear_short_term(self) -> None:
150
+ """Clear short-term memory."""
151
+ # clear() is sync; clear_async() is the async variant.
152
+ await self.short_term.clear_async()
153
+
154
+ # ==================== Working Memory ====================
155
+
156
+ def add_to_working(
157
+ self,
158
+ key: str,
159
+ value: Any,
160
+ metadata: Optional[Dict[str, Any]] = None,
161
+ ) -> None:
162
+ """Add item to working memory.
163
+
164
+ Args:
165
+ key: Item key
166
+ value: Item value
167
+ metadata: Optional metadata
168
+ """
169
+ self.working.add(key, value, metadata)
170
+
171
+ def get_from_working(self, key: str) -> Optional[Any]:
172
+ """Get item from working memory.
173
+
174
+ Args:
175
+ key: Item key
176
+
177
+ Returns:
178
+ Item value if found
179
+ """
180
+ return self.working.get(key)
181
+
182
+ def clear_working(self) -> None:
183
+ """Clear working memory."""
184
+ self.working.clear()
185
+
186
+ # ==================== Long-term Memory ====================
187
+
188
+ async def add_to_long_term(
189
+ self,
190
+ memory: Memory,
191
+ ttl: Optional[int] = None,
192
+ ) -> None:
193
+ """Add memory to long-term storage.
194
+
195
+ Args:
196
+ memory: Memory to store
197
+ ttl: Time-to-live in seconds
198
+ """
199
+ if self.long_term is None:
200
+ logger.warning("Long-term memory not enabled")
201
+ return
202
+
203
+ # Generate embedding if vector store available
204
+ if self.embedding_service and self.vector_store:
205
+ try:
206
+ embedding = await self.embedding_service.embed(str(memory.content))
207
+ await self.vector_store.store(memory, embedding)
208
+ logger.debug(f"Stored memory in vector store: {memory.id}")
209
+ except Exception as e:
210
+ logger.error(f"Failed to store in vector store: {e}")
211
+
212
+ # Store in long-term memory
213
+ self.long_term.store(memory, ttl)
214
+
215
+ async def search_long_term(
216
+ self,
217
+ query: str,
218
+ limit: int = 10,
219
+ ) -> List[Tuple[Memory, float]]:
220
+ """Search long-term memory by semantic similarity.
221
+
222
+ Args:
223
+ query: Search query
224
+ limit: Maximum results
225
+
226
+ Returns:
227
+ List of (memory, similarity_score) tuples
228
+ """
229
+ if self.vector_store is None or self.embedding_service is None:
230
+ logger.warning("Vector search not available")
231
+ return []
232
+
233
+ try:
234
+ # Generate query embedding
235
+ query_embedding = await self.embedding_service.embed(query)
236
+
237
+ # Search vector store
238
+ results = await self.vector_store.search(query_embedding, limit=limit)
239
+ return results
240
+ except Exception as e:
241
+ logger.error(f"Failed to search long-term memory: {e}")
242
+ return []
243
+
244
+ # ==================== Episodic Memory ====================
245
+
246
+ async def store_episode(
247
+ self,
248
+ task: str,
249
+ actions: List[Dict[str, Any]],
250
+ outcome: Dict[str, Any],
251
+ duration: float,
252
+ success: bool,
253
+ metadata: Optional[Dict[str, Any]] = None,
254
+ ) -> Optional[Episode]:
255
+ """Store an episode.
256
+
257
+ Args:
258
+ task: Task description
259
+ actions: Actions taken
260
+ outcome: Outcome
261
+ duration: Duration in seconds
262
+ success: Success flag
263
+ metadata: Optional metadata
264
+
265
+ Returns:
266
+ Created episode
267
+ """
268
+ if self.episodic is None:
269
+ logger.warning("Episodic memory not enabled")
270
+ return None
271
+
272
+ return await self.episodic.store_episode(
273
+ agent_id=self.agent_id,
274
+ task=task,
275
+ actions=actions,
276
+ outcome=outcome,
277
+ duration=duration,
278
+ success=success,
279
+ metadata=metadata,
280
+ )
281
+
282
+ async def get_similar_episodes(
283
+ self,
284
+ task: str,
285
+ limit: int = 5,
286
+ ) -> List[Episode]:
287
+ """Get episodes similar to a task.
288
+
289
+ Args:
290
+ task: Task description
291
+ limit: Maximum results
292
+
293
+ Returns:
294
+ List of similar episodes
295
+ """
296
+ if self.episodic is None:
297
+ return []
298
+
299
+ return await self.episodic.retrieve_similar_tasks(task, limit)
300
+
301
+ async def get_success_rate(
302
+ self,
303
+ task_pattern: Optional[str] = None,
304
+ ) -> float:
305
+ """Get success rate for tasks.
306
+
307
+ Args:
308
+ task_pattern: Optional task pattern filter
309
+
310
+ Returns:
311
+ Success rate (0.0 to 1.0)
312
+ """
313
+ if self.episodic is None:
314
+ return 0.0
315
+
316
+ return await self.episodic.get_success_rate(
317
+ agent_id=self.agent_id,
318
+ task_pattern=task_pattern,
319
+ )
320
+
321
+ # ==================== Semantic Memory ====================
322
+
323
+ async def store_fact(
324
+ self,
325
+ subject: str,
326
+ predicate: str,
327
+ object: str,
328
+ confidence: float = 1.0,
329
+ source: Optional[str] = None,
330
+ ) -> Optional[Fact]:
331
+ """Store a fact.
332
+
333
+ Args:
334
+ subject: Subject entity
335
+ predicate: Relationship/property
336
+ object: Object entity/value
337
+ confidence: Confidence score
338
+ source: Source of fact
339
+
340
+ Returns:
341
+ Created fact
342
+ """
343
+ if self.semantic is None:
344
+ logger.warning("Semantic memory not enabled")
345
+ return None
346
+
347
+ return await self.semantic.store_fact(
348
+ subject=subject,
349
+ predicate=predicate,
350
+ object=object,
351
+ confidence=confidence,
352
+ source=source,
353
+ )
354
+
355
+ async def query_facts(
356
+ self,
357
+ subject: Optional[str] = None,
358
+ predicate: Optional[str] = None,
359
+ object: Optional[str] = None,
360
+ ) -> List[Fact]:
361
+ """Query facts.
362
+
363
+ Args:
364
+ subject: Optional subject filter
365
+ predicate: Optional predicate filter
366
+ object: Optional object filter
367
+
368
+ Returns:
369
+ List of matching facts
370
+ """
371
+ if self.semantic is None:
372
+ return []
373
+
374
+ return await self.semantic.query(
375
+ subject=subject,
376
+ predicate=predicate,
377
+ object=object,
378
+ )
379
+
380
+ # ==================== Procedural Memory ====================
381
+
382
+ async def store_procedure(
383
+ self,
384
+ name: str,
385
+ description: str,
386
+ steps: List[Dict[str, Any]],
387
+ preconditions: Optional[List[str]] = None,
388
+ postconditions: Optional[List[str]] = None,
389
+ ) -> Optional[Procedure]:
390
+ """Store a procedure.
391
+
392
+ Args:
393
+ name: Procedure name
394
+ description: Description
395
+ steps: List of steps
396
+ preconditions: Required preconditions
397
+ postconditions: Expected postconditions
398
+
399
+ Returns:
400
+ Created procedure
401
+ """
402
+ if self.procedural is None:
403
+ logger.warning("Procedural memory not enabled")
404
+ return None
405
+
406
+ return await self.procedural.store_procedure(
407
+ name=name,
408
+ description=description,
409
+ steps=steps,
410
+ preconditions=preconditions,
411
+ postconditions=postconditions,
412
+ )
413
+
414
+ async def get_procedure(self, name: str) -> Optional[Procedure]:
415
+ """Get a procedure by name.
416
+
417
+ Args:
418
+ name: Procedure name
419
+
420
+ Returns:
421
+ Procedure if found
422
+ """
423
+ if self.procedural is None:
424
+ return None
425
+
426
+ return await self.procedural.retrieve_procedure(name=name)
427
+
428
+ async def record_procedure_execution(
429
+ self,
430
+ procedure_id: str,
431
+ success: bool,
432
+ duration: float,
433
+ ) -> bool:
434
+ """Record procedure execution.
435
+
436
+ Args:
437
+ procedure_id: Procedure ID
438
+ success: Success flag
439
+ duration: Duration in seconds
440
+
441
+ Returns:
442
+ True if recorded
443
+ """
444
+ if self.procedural is None:
445
+ return False
446
+
447
+ return await self.procedural.record_execution(
448
+ procedure_id=procedure_id,
449
+ success=success,
450
+ duration=duration,
451
+ )
452
+
453
+ # ==================== Memory Consolidation ====================
454
+
455
+ async def consolidate_memories(
456
+ self,
457
+ importance_threshold: float = 0.7,
458
+ ) -> Dict[str, int]:
459
+ """Consolidate important memories from short-term to long-term.
460
+
461
+ Args:
462
+ importance_threshold: Minimum importance to consolidate
463
+
464
+ Returns:
465
+ Statistics about consolidation
466
+ """
467
+ if self.long_term is None:
468
+ logger.warning("Long-term memory not enabled")
469
+ return {"consolidated": 0}
470
+
471
+ consolidated = 0
472
+
473
+ # Get important memories from short-term
474
+ for memory in self.short_term.memories:
475
+ if memory.importance >= importance_threshold:
476
+ # Move to long-term
477
+ await self.add_to_long_term(memory)
478
+ consolidated += 1
479
+
480
+ logger.info(f"Consolidated {consolidated} memories to long-term")
481
+
482
+ return {
483
+ "consolidated": consolidated,
484
+ "threshold": importance_threshold,
485
+ }
486
+
487
+ # ==================== Statistics ====================
488
+
489
+ async def get_stats(self) -> Dict[str, Any]:
490
+ """Get comprehensive memory system statistics.
491
+
492
+ Returns:
493
+ Statistics dictionary
494
+ """
495
+ stats = {
496
+ "agent_id": self.agent_id,
497
+ "short_term": self.short_term.get_stats(),
498
+ "working": self.working.get_stats(),
499
+ }
500
+
501
+ if self.long_term:
502
+ stats["long_term"] = self.long_term.get_stats()
503
+
504
+ if self.episodic:
505
+ stats["episodic"] = await self.episodic.get_stats()
506
+
507
+ if self.semantic:
508
+ stats["semantic"] = await self.semantic.get_stats()
509
+
510
+ if self.procedural:
511
+ stats["procedural"] = await self.procedural.get_stats()
512
+
513
+ if self.vector_store:
514
+ try:
515
+ stats["vector_store"] = await self.vector_store.get_stats()
516
+ except Exception as exc:
517
+ logger.warning("Vector store stats unavailable: %s", exc)
518
+ stats["vector_store"] = {"error": str(exc)}
519
+
520
+ stats["persistence"] = {
521
+ "enabled": self._persistence.enabled,
522
+ "path": str(self._persistence.base_dir),
523
+ }
524
+
525
+ return stats
526
+
527
+ def __repr__(self) -> str:
528
+ """String representation."""
529
+ enabled = []
530
+ if self.short_term:
531
+ enabled.append("short_term")
532
+ if self.working:
533
+ enabled.append("working")
534
+ if self.long_term:
535
+ enabled.append("long_term")
536
+ if self.episodic:
537
+ enabled.append("episodic")
538
+ if self.semantic:
539
+ enabled.append("semantic")
540
+ if self.procedural:
541
+ enabled.append("procedural")
542
+
543
+ return f"MemorySystem(agent_id={self.agent_id}, enabled={enabled})"