agent-runtime-core 0.3.0__py3-none-any.whl → 0.4.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.
@@ -8,6 +8,16 @@ For Django integration, you can either:
8
8
  1. Pass pre-instantiated store instances
9
9
  2. Pass store classes with appropriate kwargs
10
10
  3. Use factory functions for request-scoped stores
11
+
12
+ Core stores (always available):
13
+ - MemoryStore: Key-value storage
14
+ - ConversationStore: Conversation history
15
+ - TaskStore: Task lists and progress
16
+ - PreferencesStore: User/agent configuration
17
+
18
+ Optional stores (must be explicitly configured):
19
+ - KnowledgeStore: Facts, summaries, embeddings
20
+ - AuditStore: Logs, errors, metrics
11
21
  """
12
22
 
13
23
  from dataclasses import dataclass, field
@@ -19,6 +29,8 @@ from agent_runtime_core.persistence.base import (
19
29
  ConversationStore,
20
30
  TaskStore,
21
31
  PreferencesStore,
32
+ KnowledgeStore,
33
+ AuditStore,
22
34
  Scope,
23
35
  )
24
36
  from agent_runtime_core.persistence.file import (
@@ -34,6 +46,8 @@ MemoryStoreFactory = Callable[[], MemoryStore]
34
46
  ConversationStoreFactory = Callable[[], ConversationStore]
35
47
  TaskStoreFactory = Callable[[], TaskStore]
36
48
  PreferencesStoreFactory = Callable[[], PreferencesStore]
49
+ KnowledgeStoreFactory = Callable[[], KnowledgeStore]
50
+ AuditStoreFactory = Callable[[], AuditStore]
37
51
 
38
52
 
39
53
  @dataclass
@@ -46,6 +60,9 @@ class PersistenceConfig:
46
60
  - A pre-instantiated store instance
47
61
  - A factory function that returns a store instance
48
62
 
63
+ Core stores (memory, conversations, tasks, preferences) have file-based
64
+ defaults. Optional stores (knowledge, audit) must be explicitly configured.
65
+
49
66
  Example for Django:
50
67
  from myapp.stores import DjangoMemoryStore, DjangoConversationStore
51
68
 
@@ -65,31 +82,47 @@ class PersistenceConfig:
65
82
  config = PersistenceConfig(
66
83
  memory_store_factory=lambda: DjangoMemoryStore(user=get_current_user()),
67
84
  )
85
+
86
+ # Option 4: Enable optional stores
87
+ config = PersistenceConfig(
88
+ knowledge_store=DjangoKnowledgeStore(user=request.user),
89
+ audit_store=DjangoAuditStore(user=request.user),
90
+ )
68
91
  """
69
92
 
70
- # Backend classes (can be swapped for custom implementations)
93
+ # Backend classes for core stores (can be swapped for custom implementations)
71
94
  memory_store_class: Type[MemoryStore] = FileMemoryStore
72
95
  conversation_store_class: Type[ConversationStore] = FileConversationStore
73
96
  task_store_class: Type[TaskStore] = FileTaskStore
74
97
  preferences_store_class: Type[PreferencesStore] = FilePreferencesStore
75
98
 
99
+ # Backend classes for optional stores (no defaults - must be explicitly set)
100
+ knowledge_store_class: Optional[Type[KnowledgeStore]] = None
101
+ audit_store_class: Optional[Type[AuditStore]] = None
102
+
76
103
  # Pre-instantiated store instances (takes precedence over classes)
77
104
  memory_store: Optional[MemoryStore] = None
78
105
  conversation_store: Optional[ConversationStore] = None
79
106
  task_store: Optional[TaskStore] = None
80
107
  preferences_store: Optional[PreferencesStore] = None
108
+ knowledge_store: Optional[KnowledgeStore] = None
109
+ audit_store: Optional[AuditStore] = None
81
110
 
82
111
  # Factory functions (takes precedence over classes, but not instances)
83
112
  memory_store_factory: Optional[MemoryStoreFactory] = None
84
113
  conversation_store_factory: Optional[ConversationStoreFactory] = None
85
114
  task_store_factory: Optional[TaskStoreFactory] = None
86
115
  preferences_store_factory: Optional[PreferencesStoreFactory] = None
116
+ knowledge_store_factory: Optional[KnowledgeStoreFactory] = None
117
+ audit_store_factory: Optional[AuditStoreFactory] = None
87
118
 
88
119
  # Kwargs passed to store class constructors (only used with classes)
89
120
  memory_store_kwargs: dict = field(default_factory=dict)
90
121
  conversation_store_kwargs: dict = field(default_factory=dict)
91
122
  task_store_kwargs: dict = field(default_factory=dict)
92
123
  preferences_store_kwargs: dict = field(default_factory=dict)
124
+ knowledge_store_kwargs: dict = field(default_factory=dict)
125
+ audit_store_kwargs: dict = field(default_factory=dict)
93
126
 
94
127
  # Project directory (convenience for file-based stores)
95
128
  # Only used if store_kwargs doesn't already have project_dir
@@ -100,8 +133,11 @@ class PersistenceManager:
100
133
  """
101
134
  Unified manager for all persistence stores.
102
135
 
103
- Provides access to memory, conversations, tasks, and preferences
104
- with pluggable backends.
136
+ Provides access to core stores (memory, conversations, tasks, preferences)
137
+ and optional stores (knowledge, audit) with pluggable backends.
138
+
139
+ Core stores have file-based defaults. Optional stores return None
140
+ unless explicitly configured.
105
141
 
106
142
  Example:
107
143
  # Use default file-based storage
@@ -120,8 +156,15 @@ class PersistenceManager:
120
156
  config = PersistenceConfig(
121
157
  memory_store=DjangoMemoryStore(user=request.user),
122
158
  conversation_store=DjangoConversationStore(user=request.user),
159
+ # Enable optional stores
160
+ knowledge_store=DjangoKnowledgeStore(user=request.user),
161
+ audit_store=DjangoAuditStore(user=request.user),
123
162
  )
124
163
  manager = PersistenceManager(config)
164
+
165
+ # Check if optional stores are available
166
+ if manager.knowledge:
167
+ await manager.knowledge.save_fact(fact)
125
168
  """
126
169
 
127
170
  def __init__(self, config: Optional[PersistenceConfig] = None):
@@ -130,6 +173,11 @@ class PersistenceManager:
130
173
  self._conversations: Optional[ConversationStore] = None
131
174
  self._tasks: Optional[TaskStore] = None
132
175
  self._preferences: Optional[PreferencesStore] = None
176
+ self._knowledge: Optional[KnowledgeStore] = None
177
+ self._audit: Optional[AuditStore] = None
178
+ # Track if optional stores have been initialized
179
+ self._knowledge_initialized = False
180
+ self._audit_initialized = False
133
181
 
134
182
  def _build_kwargs(self, store_kwargs: dict) -> dict:
135
183
  """Build kwargs for store instantiation."""
@@ -193,6 +241,54 @@ class PersistenceManager:
193
241
  self._preferences = self._config.preferences_store_class(**kwargs)
194
242
  return self._preferences
195
243
 
244
+ @property
245
+ def knowledge(self) -> Optional[KnowledgeStore]:
246
+ """
247
+ Get the knowledge store (optional).
248
+
249
+ Returns None if not configured. Check before using:
250
+ if manager.knowledge:
251
+ await manager.knowledge.save_fact(fact)
252
+ """
253
+ if not self._knowledge_initialized:
254
+ self._knowledge_initialized = True
255
+ if self._config.knowledge_store is not None:
256
+ self._knowledge = self._config.knowledge_store
257
+ elif self._config.knowledge_store_factory is not None:
258
+ self._knowledge = self._config.knowledge_store_factory()
259
+ elif self._config.knowledge_store_class is not None:
260
+ kwargs = self._build_kwargs(self._config.knowledge_store_kwargs)
261
+ self._knowledge = self._config.knowledge_store_class(**kwargs)
262
+ return self._knowledge
263
+
264
+ @property
265
+ def audit(self) -> Optional[AuditStore]:
266
+ """
267
+ Get the audit store (optional).
268
+
269
+ Returns None if not configured. Check before using:
270
+ if manager.audit:
271
+ await manager.audit.log_event(entry)
272
+ """
273
+ if not self._audit_initialized:
274
+ self._audit_initialized = True
275
+ if self._config.audit_store is not None:
276
+ self._audit = self._config.audit_store
277
+ elif self._config.audit_store_factory is not None:
278
+ self._audit = self._config.audit_store_factory()
279
+ elif self._config.audit_store_class is not None:
280
+ kwargs = self._build_kwargs(self._config.audit_store_kwargs)
281
+ self._audit = self._config.audit_store_class(**kwargs)
282
+ return self._audit
283
+
284
+ def has_knowledge(self) -> bool:
285
+ """Check if knowledge store is configured."""
286
+ return self.knowledge is not None
287
+
288
+ def has_audit(self) -> bool:
289
+ """Check if audit store is configured."""
290
+ return self.audit is not None
291
+
196
292
  async def close(self) -> None:
197
293
  """Close all stores."""
198
294
  if self._memory:
@@ -203,6 +299,10 @@ class PersistenceManager:
203
299
  await self._tasks.close()
204
300
  if self._preferences:
205
301
  await self._preferences.close()
302
+ if self._knowledge:
303
+ await self._knowledge.close()
304
+ if self._audit:
305
+ await self._audit.close()
206
306
 
207
307
 
208
308
  # Global manager instance
@@ -215,27 +315,31 @@ def configure_persistence(
215
315
  conversation_store_class: Optional[Type[ConversationStore]] = None,
216
316
  task_store_class: Optional[Type[TaskStore]] = None,
217
317
  preferences_store_class: Optional[Type[PreferencesStore]] = None,
318
+ knowledge_store_class: Optional[Type[KnowledgeStore]] = None,
319
+ audit_store_class: Optional[Type[AuditStore]] = None,
218
320
  project_dir: Optional[Path] = None,
219
321
  **kwargs,
220
322
  ) -> PersistenceConfig:
221
323
  """
222
324
  Configure the global persistence manager.
223
-
325
+
224
326
  Args:
225
327
  memory_store_class: Custom memory store implementation
226
328
  conversation_store_class: Custom conversation store implementation
227
329
  task_store_class: Custom task store implementation
228
330
  preferences_store_class: Custom preferences store implementation
331
+ knowledge_store_class: Custom knowledge store implementation (optional)
332
+ audit_store_class: Custom audit store implementation (optional)
229
333
  project_dir: Project directory for PROJECT scope
230
334
  **kwargs: Additional store-specific configuration
231
-
335
+
232
336
  Returns:
233
337
  The configured PersistenceConfig
234
338
  """
235
339
  global _config, _manager
236
-
340
+
237
341
  config = PersistenceConfig(project_dir=project_dir)
238
-
342
+
239
343
  if memory_store_class:
240
344
  config.memory_store_class = memory_store_class
241
345
  if conversation_store_class:
@@ -244,23 +348,27 @@ def configure_persistence(
244
348
  config.task_store_class = task_store_class
245
349
  if preferences_store_class:
246
350
  config.preferences_store_class = preferences_store_class
247
-
351
+ if knowledge_store_class:
352
+ config.knowledge_store_class = knowledge_store_class
353
+ if audit_store_class:
354
+ config.audit_store_class = audit_store_class
355
+
248
356
  _config = config
249
357
  _manager = None # Reset manager to use new config
250
-
358
+
251
359
  return config
252
360
 
253
361
 
254
362
  def get_persistence_manager() -> PersistenceManager:
255
363
  """
256
364
  Get the global persistence manager.
257
-
365
+
258
366
  Creates a new manager with default config if not configured.
259
367
  """
260
368
  global _manager
261
-
369
+
262
370
  if _manager is None:
263
371
  _manager = PersistenceManager(_config)
264
-
372
+
265
373
  return _manager
266
374