atomicmemory 1.0.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 (67) hide show
  1. atomicmemory/__init__.py +166 -0
  2. atomicmemory/_version.py +3 -0
  3. atomicmemory/client/__init__.py +22 -0
  4. atomicmemory/client/async_memory_client.py +202 -0
  5. atomicmemory/client/atomic_memory_client.py +181 -0
  6. atomicmemory/client/memory_client.py +292 -0
  7. atomicmemory/core/__init__.py +34 -0
  8. atomicmemory/core/errors.py +122 -0
  9. atomicmemory/core/events.py +65 -0
  10. atomicmemory/core/logging.py +37 -0
  11. atomicmemory/core/retry.py +124 -0
  12. atomicmemory/core/validation.py +22 -0
  13. atomicmemory/embeddings/__init__.py +16 -0
  14. atomicmemory/embeddings/base.py +39 -0
  15. atomicmemory/embeddings/sentence_transformers.py +104 -0
  16. atomicmemory/kv_cache/__init__.py +17 -0
  17. atomicmemory/kv_cache/adapter.py +50 -0
  18. atomicmemory/kv_cache/memory_storage.py +98 -0
  19. atomicmemory/kv_cache/sqlite_storage.py +122 -0
  20. atomicmemory/memory/__init__.py +82 -0
  21. atomicmemory/memory/filters.py +68 -0
  22. atomicmemory/memory/pipeline.py +42 -0
  23. atomicmemory/memory/provider.py +397 -0
  24. atomicmemory/memory/registry.py +95 -0
  25. atomicmemory/memory/service.py +199 -0
  26. atomicmemory/memory/types.py +398 -0
  27. atomicmemory/providers/__init__.py +5 -0
  28. atomicmemory/providers/atomicmemory/__init__.py +43 -0
  29. atomicmemory/providers/atomicmemory/agents.py +156 -0
  30. atomicmemory/providers/atomicmemory/async_handle_impl.py +198 -0
  31. atomicmemory/providers/atomicmemory/async_provider.py +245 -0
  32. atomicmemory/providers/atomicmemory/audit.py +74 -0
  33. atomicmemory/providers/atomicmemory/config.py +38 -0
  34. atomicmemory/providers/atomicmemory/config_handle.py +123 -0
  35. atomicmemory/providers/atomicmemory/handle.py +513 -0
  36. atomicmemory/providers/atomicmemory/handle_impl.py +325 -0
  37. atomicmemory/providers/atomicmemory/http.py +255 -0
  38. atomicmemory/providers/atomicmemory/lessons.py +133 -0
  39. atomicmemory/providers/atomicmemory/lifecycle.py +202 -0
  40. atomicmemory/providers/atomicmemory/mappers.py +125 -0
  41. atomicmemory/providers/atomicmemory/path.py +20 -0
  42. atomicmemory/providers/atomicmemory/provider.py +300 -0
  43. atomicmemory/providers/atomicmemory/scope_mapper.py +98 -0
  44. atomicmemory/providers/mem0/__init__.py +41 -0
  45. atomicmemory/providers/mem0/async_provider.py +191 -0
  46. atomicmemory/providers/mem0/config.py +51 -0
  47. atomicmemory/providers/mem0/http.py +195 -0
  48. atomicmemory/providers/mem0/mappers.py +145 -0
  49. atomicmemory/providers/mem0/provider.py +202 -0
  50. atomicmemory/py.typed +0 -0
  51. atomicmemory/search/__init__.py +47 -0
  52. atomicmemory/search/chunking.py +161 -0
  53. atomicmemory/search/ranking.py +94 -0
  54. atomicmemory/search/semantic_search.py +130 -0
  55. atomicmemory/search/similarity.py +110 -0
  56. atomicmemory/storage/__init__.py +63 -0
  57. atomicmemory/storage/_mapping.py +305 -0
  58. atomicmemory/storage/async_client.py +208 -0
  59. atomicmemory/storage/client.py +339 -0
  60. atomicmemory/storage/errors.py +115 -0
  61. atomicmemory/storage/types.py +305 -0
  62. atomicmemory/utils/__init__.py +5 -0
  63. atomicmemory/utils/environment.py +23 -0
  64. atomicmemory-1.0.0.dist-info/METADATA +146 -0
  65. atomicmemory-1.0.0.dist-info/RECORD +67 -0
  66. atomicmemory-1.0.0.dist-info/WHEEL +4 -0
  67. atomicmemory-1.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,513 @@
1
+ """AtomicMemory namespace handle — type definitions.
2
+
3
+ Port of `atomicmemory-sdk/src/memory/atomicmemory-provider/handle.ts`.
4
+ Pure Pydantic models + Literal aliases for the types exposed by the
5
+ ``atomicmemory.*`` extension namespace. Implementation lives in
6
+ ``handle_impl.py`` and the per-category modules.
7
+
8
+ The namespace types are intentionally **not** the V3 generic types
9
+ (``Memory``, ``SearchResult``, etc.). Workspace queries must round-trip
10
+ ``workspace_id`` / ``agent_id`` / ``agent_scope`` honestly, which V3's
11
+ flat ``Scope`` cannot represent.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from datetime import datetime
17
+ from typing import Any, Literal
18
+
19
+ from pydantic import BaseModel, ConfigDict, Field
20
+
21
+ # ---------------------------------------------------------------------------
22
+ # Scope (workspace discriminated union)
23
+ # ---------------------------------------------------------------------------
24
+
25
+
26
+ AgentScope = str | list[str]
27
+ """Agent visibility scope. ``"all"|"self"|"others"`` are canonical hints;
28
+ arbitrary strings are treated as a single agent_id filter; lists are
29
+ explicit agent-id sets."""
30
+
31
+
32
+ class UserScope(BaseModel):
33
+ """User-scoped read path — only ``user_id``."""
34
+
35
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
36
+ kind: Literal["user"] = "user"
37
+ user_id: str = Field(alias="userId")
38
+
39
+
40
+ class WorkspaceScope(BaseModel):
41
+ """Workspace-scoped read path — full agent visibility surface."""
42
+
43
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
44
+ kind: Literal["workspace"] = "workspace"
45
+ user_id: str = Field(alias="userId")
46
+ workspace_id: str = Field(alias="workspaceId")
47
+ agent_id: str = Field(alias="agentId")
48
+ agent_scope: AgentScope | None = Field(default=None, alias="agentScope")
49
+
50
+
51
+ MemoryScope = UserScope | WorkspaceScope
52
+
53
+
54
+ # ---------------------------------------------------------------------------
55
+ # Request types — scope-free, route-shaped
56
+ # ---------------------------------------------------------------------------
57
+
58
+
59
+ Visibility = Literal["agent_only", "restricted", "workspace"]
60
+ RetrievalMode = Literal["flat", "tiered", "abstract-aware"]
61
+
62
+
63
+ class AtomicMemoryIngestInput(BaseModel):
64
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
65
+ conversation: str
66
+ source_site: str = Field(alias="sourceSite")
67
+ source_url: str | None = Field(default=None, alias="sourceUrl")
68
+ visibility: Visibility | None = None
69
+ config_override: dict[str, Any] | None = Field(default=None, alias="configOverride")
70
+
71
+
72
+ class AtomicMemorySearchRequest(BaseModel):
73
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
74
+ query: str
75
+ limit: int | None = None
76
+ threshold: float | None = None
77
+ as_of: datetime | None = Field(default=None, alias="asOf")
78
+ retrieval_mode: RetrievalMode | None = Field(default=None, alias="retrievalMode")
79
+ token_budget: int | None = Field(default=None, alias="tokenBudget")
80
+ namespace_scope: str | None = Field(default=None, alias="namespaceScope")
81
+ source_site: str | None = Field(default=None, alias="sourceSite")
82
+ skip_repair: bool | None = Field(default=None, alias="skipRepair")
83
+ config_override: dict[str, Any] | None = Field(default=None, alias="configOverride")
84
+
85
+
86
+ class AtomicMemoryListOptions(BaseModel):
87
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
88
+ limit: int | None = None
89
+ offset: int | None = None
90
+ source_site: str | None = Field(default=None, alias="sourceSite")
91
+ episode_id: str | None = Field(default=None, alias="episodeId")
92
+
93
+
94
+ # ---------------------------------------------------------------------------
95
+ # Response: AtomicMemory-specific memory + search shapes
96
+ # ---------------------------------------------------------------------------
97
+
98
+
99
+ class AtomicMemoryMemory(BaseModel):
100
+ """Mirrors core's memory record with full MemoryScope round-tripped."""
101
+
102
+ model_config = ConfigDict(extra="ignore")
103
+ id: str
104
+ content: str
105
+ scope: MemoryScope
106
+ created_at: datetime
107
+ updated_at: datetime | None = None
108
+ importance: float | None = None
109
+ source_site: str | None = None
110
+ source_url: str | None = None
111
+ episode_id: str | None = None
112
+ visibility: Visibility | None = None
113
+ metadata: dict[str, Any] | None = None
114
+
115
+
116
+ class AtomicMemorySearchResult(BaseModel):
117
+ model_config = ConfigDict(extra="ignore")
118
+ memory: AtomicMemoryMemory
119
+ score: float
120
+ similarity: float | None = None
121
+ ranking_score: float | None = None
122
+ relevance: float | None = None
123
+ importance: float | None = None
124
+
125
+
126
+ class TierAssignment(BaseModel):
127
+ model_config = ConfigDict(extra="ignore")
128
+ memory_id: str
129
+ tier: str
130
+ estimated_tokens: int
131
+
132
+
133
+ class LessonCheck(BaseModel):
134
+ model_config = ConfigDict(extra="ignore")
135
+ safe: bool
136
+ warnings: list[Any] = Field(default_factory=list)
137
+ highest_severity: str
138
+ matched_count: int
139
+
140
+
141
+ class ConsensusInfo(BaseModel):
142
+ model_config = ConfigDict(extra="ignore")
143
+ original_count: int
144
+ filtered_count: int
145
+ removed_count: int
146
+ removed_memory_ids: list[str] = Field(default_factory=list)
147
+
148
+
149
+ class ObservabilityInfo(BaseModel):
150
+ model_config = ConfigDict(extra="ignore")
151
+ retrieval: Any | None = None
152
+ packaging: Any | None = None
153
+ assembly: Any | None = None
154
+
155
+
156
+ class AtomicMemorySearchResultPage(BaseModel):
157
+ model_config = ConfigDict(extra="ignore")
158
+ count: int
159
+ retrieval_mode: str
160
+ scope: MemoryScope
161
+ results: list[AtomicMemorySearchResult] = Field(default_factory=list)
162
+ injection_text: str | None = None
163
+ citations: list[str] | None = None
164
+ tier_assignments: list[TierAssignment] | None = None
165
+ expand_ids: list[str] | None = None
166
+ estimated_context_tokens: int | None = None
167
+ lesson_check: LessonCheck | None = None
168
+ consensus: ConsensusInfo | None = None
169
+ observability: ObservabilityInfo | None = None
170
+
171
+
172
+ class AtomicMemoryIngestResult(BaseModel):
173
+ model_config = ConfigDict(extra="ignore")
174
+ episode_id: str
175
+ facts_extracted: int
176
+ memories_stored: int
177
+ memories_updated: int
178
+ memories_deleted: int
179
+ memories_skipped: int
180
+ stored_memory_ids: list[str] = Field(default_factory=list)
181
+ updated_memory_ids: list[str] = Field(default_factory=list)
182
+ links_created: int
183
+ composites_created: int
184
+
185
+
186
+ class AtomicMemoryListResultPage(BaseModel):
187
+ model_config = ConfigDict(extra="ignore")
188
+ memories: list[AtomicMemoryMemory] = Field(default_factory=list)
189
+ count: int
190
+ cursor: str | None = None
191
+
192
+
193
+ # ---------------------------------------------------------------------------
194
+ # Lifecycle response types
195
+ # ---------------------------------------------------------------------------
196
+
197
+
198
+ class ConsolidationScanResult(BaseModel):
199
+ model_config = ConfigDict(extra="ignore")
200
+ memories_scanned: int
201
+ clusters_found: int
202
+ memories_in_clusters: int
203
+ clusters: list[Any] = Field(default_factory=list)
204
+
205
+
206
+ class ConsolidationExecutionResult(BaseModel):
207
+ model_config = ConfigDict(extra="ignore")
208
+ clusters_consolidated: int
209
+ memories_archived: int
210
+ memories_created: int
211
+ consolidated_memory_ids: list[str] = Field(default_factory=list)
212
+
213
+
214
+ ConsolidationResult = ConsolidationScanResult | ConsolidationExecutionResult
215
+
216
+
217
+ class DecayCandidate(BaseModel):
218
+ model_config = ConfigDict(extra="allow")
219
+ id: str
220
+ retention_score: float
221
+
222
+
223
+ class DecayResult(BaseModel):
224
+ model_config = ConfigDict(extra="ignore")
225
+ memories_evaluated: int
226
+ candidates_for_archival: list[DecayCandidate] = Field(default_factory=list)
227
+ retention_threshold: float
228
+ avg_retention_score: float
229
+ archived: int
230
+
231
+
232
+ CapStatus = Literal["ok", "warn", "exceeded"]
233
+ CapRecommendation = Literal["none", "consolidate", "decay", "consolidate-and-decay"]
234
+
235
+
236
+ class CapCheckResult(BaseModel):
237
+ model_config = ConfigDict(extra="ignore")
238
+ active_memories: int
239
+ max_memories: int
240
+ status: CapStatus
241
+ usage_ratio: float
242
+ recommendation: CapRecommendation
243
+
244
+
245
+ class StatsResult(BaseModel):
246
+ """Open-shape stats payload from core's ``GET /memories/stats``."""
247
+
248
+ model_config = ConfigDict(extra="allow")
249
+
250
+
251
+ class ResetSourceResult(BaseModel):
252
+ model_config = ConfigDict(extra="ignore")
253
+ success: Literal[True] = True
254
+ deleted_memories: int
255
+ deleted_episodes: int
256
+
257
+
258
+ class ReconciliationResult(BaseModel):
259
+ model_config = ConfigDict(extra="ignore")
260
+ processed: int
261
+ resolved: int
262
+ noops: int
263
+ updates: int
264
+ supersedes: int
265
+ deletes: int
266
+ adds: int
267
+ errors: int
268
+ duration_ms: int
269
+
270
+
271
+ class ReconcileStatus(BaseModel):
272
+ """Open-shape reconcile-status payload from core."""
273
+
274
+ model_config = ConfigDict(extra="allow")
275
+
276
+
277
+ # ---------------------------------------------------------------------------
278
+ # Audit response types
279
+ # ---------------------------------------------------------------------------
280
+
281
+
282
+ MutationType = Literal["add", "update", "supersede", "delete", "clarify"]
283
+
284
+
285
+ class MutationSummary(BaseModel):
286
+ model_config = ConfigDict(extra="ignore")
287
+ total_versions: int
288
+ active_versions: int
289
+ superseded_versions: int
290
+ total_claims: int
291
+ by_mutation_type: dict[str, int] = Field(default_factory=dict)
292
+
293
+
294
+ class MutationRecord(BaseModel):
295
+ model_config = ConfigDict(extra="ignore")
296
+ id: str
297
+ claim_id: str
298
+ user_id: str
299
+ memory_id: str | None
300
+ content: str
301
+ mutation_type: MutationType | None
302
+ mutation_reason: str | None
303
+ actor_model: str | None
304
+ contradiction_confidence: float | None
305
+ previous_version_id: str | None
306
+ superseded_by_version_id: str | None
307
+ valid_from: datetime
308
+ valid_to: datetime | None
309
+ created_at: datetime
310
+
311
+
312
+ class RecentMutationsResult(BaseModel):
313
+ model_config = ConfigDict(extra="ignore")
314
+ mutations: list[MutationRecord] = Field(default_factory=list)
315
+ count: int
316
+
317
+
318
+ class AuditTrailEntry(BaseModel):
319
+ model_config = ConfigDict(extra="ignore")
320
+ version_id: str
321
+ claim_id: str
322
+ content: str
323
+ mutation_type: MutationType | None
324
+ mutation_reason: str | None
325
+ actor_model: str | None
326
+ contradiction_confidence: float | None
327
+ previous_version_id: str | None
328
+ superseded_by_version_id: str | None
329
+ valid_from: datetime
330
+ valid_to: datetime | None
331
+ memory_id: str | None
332
+
333
+
334
+ class AuditTrailResult(BaseModel):
335
+ model_config = ConfigDict(extra="ignore")
336
+ memory_id: str
337
+ trail: list[AuditTrailEntry] = Field(default_factory=list)
338
+ version_count: int
339
+
340
+
341
+ # ---------------------------------------------------------------------------
342
+ # Lessons response types
343
+ # ---------------------------------------------------------------------------
344
+
345
+
346
+ LessonType = Literal[
347
+ "injection_blocked",
348
+ "false_memory",
349
+ "contradiction_pattern",
350
+ "user_reported",
351
+ "consensus_violation",
352
+ "trust_violation",
353
+ ]
354
+ LessonSeverity = Literal["low", "medium", "high", "critical"]
355
+
356
+
357
+ class Lesson(BaseModel):
358
+ model_config = ConfigDict(extra="ignore")
359
+ id: str
360
+ user_id: str
361
+ lesson_type: LessonType
362
+ pattern: str
363
+ embedding: list[float] = Field(default_factory=list)
364
+ source_memory_ids: list[str] = Field(default_factory=list)
365
+ source_query: str | None
366
+ severity: LessonSeverity
367
+ active: bool
368
+ metadata: dict[str, Any] = Field(default_factory=dict)
369
+ created_at: datetime
370
+
371
+
372
+ class LessonsListResult(BaseModel):
373
+ model_config = ConfigDict(extra="ignore")
374
+ lessons: list[Lesson] = Field(default_factory=list)
375
+ count: int
376
+
377
+
378
+ class LessonStats(BaseModel):
379
+ model_config = ConfigDict(extra="ignore")
380
+ total_active: int
381
+ by_type: dict[str, int] = Field(default_factory=dict)
382
+
383
+
384
+ class ReportLessonResult(BaseModel):
385
+ model_config = ConfigDict(extra="ignore")
386
+ lesson_id: str
387
+
388
+
389
+ # ---------------------------------------------------------------------------
390
+ # Config response + request types
391
+ # ---------------------------------------------------------------------------
392
+
393
+
394
+ EmbeddingProviderName = Literal["openai", "ollama", "openai-compatible", "transformers"]
395
+ LLMProviderName = Literal[
396
+ "openai",
397
+ "ollama",
398
+ "openai-compatible",
399
+ "transformers",
400
+ "groq",
401
+ "anthropic",
402
+ "google-genai",
403
+ ]
404
+
405
+
406
+ class HealthConfig(BaseModel):
407
+ model_config = ConfigDict(extra="ignore")
408
+ retrieval_profile: str
409
+ embedding_provider: EmbeddingProviderName
410
+ embedding_model: str
411
+ llm_provider: LLMProviderName
412
+ llm_model: str
413
+ clarification_conflict_threshold: float
414
+ max_search_results: int
415
+ hybrid_search_enabled: bool
416
+ iterative_retrieval_enabled: bool
417
+ entity_graph_enabled: bool
418
+ cross_encoder_enabled: bool
419
+ agentic_retrieval_enabled: bool
420
+ repair_loop_enabled: bool
421
+
422
+
423
+ class AtomicMemoryHealthStatus(BaseModel):
424
+ """Distinct from V3's ``HealthStatus`` (capability probe).
425
+
426
+ Mirrors core's ``GET /memories/health`` runtime snapshot.
427
+ """
428
+
429
+ model_config = ConfigDict(extra="ignore")
430
+ status: Literal["ok"] = "ok"
431
+ config: HealthConfig
432
+
433
+
434
+ class ConfigUpdates(BaseModel):
435
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
436
+ similarity_threshold: float | None = Field(default=None, alias="similarityThreshold")
437
+ audn_candidate_threshold: float | None = Field(default=None, alias="audnCandidateThreshold")
438
+ clarification_conflict_threshold: float | None = Field(default=None, alias="clarificationConflictThreshold")
439
+ max_search_results: int | None = Field(default=None, alias="maxSearchResults")
440
+
441
+
442
+ class ConfigUpdateResult(BaseModel):
443
+ model_config = ConfigDict(extra="ignore")
444
+ applied: list[str] = Field(default_factory=list)
445
+ config: HealthConfig
446
+ note: str
447
+
448
+
449
+ # ---------------------------------------------------------------------------
450
+ # Agents response types
451
+ # ---------------------------------------------------------------------------
452
+
453
+
454
+ ConflictResolution = Literal["resolved_new", "resolved_existing", "resolved_both"]
455
+ ConflictStatus = Literal["open", "resolved_new", "resolved_existing", "resolved_both", "auto_resolved"]
456
+
457
+
458
+ class SetTrustResult(BaseModel):
459
+ model_config = ConfigDict(extra="ignore")
460
+ agent_id: str
461
+ trust_level: float
462
+
463
+
464
+ class GetTrustResult(BaseModel):
465
+ model_config = ConfigDict(extra="ignore")
466
+ agent_id: str
467
+ trust_level: float
468
+
469
+
470
+ class AgentConflict(BaseModel):
471
+ model_config = ConfigDict(extra="ignore")
472
+ id: str
473
+ user_id: str
474
+ new_memory_id: str | None
475
+ existing_memory_id: str | None
476
+ new_agent_id: str | None
477
+ existing_agent_id: str | None
478
+ new_trust_level: float | None
479
+ existing_trust_level: float | None
480
+ contradiction_confidence: float
481
+ clarification_note: str | None
482
+ status: ConflictStatus
483
+ resolution_policy: str | None
484
+ resolved_at: datetime | None
485
+ created_at: datetime
486
+ auto_resolve_after: datetime | None
487
+
488
+
489
+ class ConflictsListResult(BaseModel):
490
+ model_config = ConfigDict(extra="ignore")
491
+ conflicts: list[AgentConflict] = Field(default_factory=list)
492
+ count: int
493
+
494
+
495
+ class ResolveConflictResult(BaseModel):
496
+ model_config = ConfigDict(extra="ignore")
497
+ id: str
498
+ status: ConflictResolution
499
+
500
+
501
+ class AutoResolveConflictsResult(BaseModel):
502
+ model_config = ConfigDict(extra="ignore")
503
+ resolved: int
504
+
505
+
506
+ ATOMICMEMORY_EXTENSION_NAMES: tuple[str, ...] = (
507
+ "atomicmemory.base",
508
+ "atomicmemory.lifecycle",
509
+ "atomicmemory.audit",
510
+ "atomicmemory.lessons",
511
+ "atomicmemory.config",
512
+ "atomicmemory.agents",
513
+ )